blob: 1eb83b4b2a44994582b4c8ae8c294d623e74c503 [file] [log] [blame]
Thomas Vachuska02aeb032015-01-06 22:36:30 -08001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2015-present Open Networking Foundation
Thomas Vachuska02aeb032015-01-06 22:36:30 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.onosproject.core;
17
Simon Huntc2da4882016-01-21 13:24:47 -080018import com.google.common.collect.ImmutableList;
19import com.google.common.collect.ImmutableSet;
Ray Milkey47c95412017-09-15 10:40:48 -070020
21import org.onosproject.app.ApplicationDescription;
Changhoon Yoonb856b812015-08-10 03:47:19 +090022import org.onosproject.security.Permission;
23
Thomas Vachuska02aeb032015-01-06 22:36:30 -080024import java.net.URI;
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +090025import java.util.Set;
26import java.util.Optional;
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080027import java.util.List;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080028import java.util.Objects;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080029
30import static com.google.common.base.MoreObjects.toStringHelper;
31import static com.google.common.base.Preconditions.checkArgument;
32import static com.google.common.base.Preconditions.checkNotNull;
33
34/**
35 * Default implementation of network control/management application descriptor.
36 */
Ray Milkey47c95412017-09-15 10:40:48 -070037public final class DefaultApplication implements Application {
Thomas Vachuska02aeb032015-01-06 22:36:30 -080038
39 private final ApplicationId appId;
40 private final Version version;
Simon Huntafae2f72016-03-04 21:18:23 -080041 private final String title;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080042 private final String description;
Jian Lic35415d2016-01-14 17:22:31 -080043 private final String category;
44 private final String url;
45 private final String readme;
46 private final byte[] icon;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080047 private final String origin;
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +090048 private final ApplicationRole role;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080049 private final Set<Permission> permissions;
50 private final Optional<URI> featuresRepo;
Thomas Vachuskaebf5e542015-02-03 19:38:13 -080051 private final List<String> features;
Thomas Vachuska761f0042015-11-11 19:10:17 -080052 private final List<String> requiredApps;
Thomas Vachuska02aeb032015-01-06 22:36:30 -080053
54 /**
Ray Milkey47c95412017-09-15 10:40:48 -070055 * Default constructor is hidden to prevent calls to new.
56 */
57 private DefaultApplication() {
58 // should never happen
59 throw new UnsupportedOperationException();
60 }
61
62 /**
Thomas Vachuska02aeb032015-01-06 22:36:30 -080063 * Creates a new application descriptor using the supplied data.
64 *
65 * @param appId application identifier
66 * @param version application version
Simon Huntafae2f72016-03-04 21:18:23 -080067 * @param title application title
Thomas Vachuska02aeb032015-01-06 22:36:30 -080068 * @param description application description
69 * @param origin origin company
Jian Lic35415d2016-01-14 17:22:31 -080070 * @param category application category
71 * @param url application URL
72 * @param readme application readme
73 * @param icon application icon
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +090074 * @param role application role
Thomas Vachuska02aeb032015-01-06 22:36:30 -080075 * @param permissions requested permissions
76 * @param featuresRepo optional features repo URI
77 * @param features application features
Thomas Vachuska761f0042015-11-11 19:10:17 -080078 * @param requiredApps list of required application names
Thomas Vachuska02aeb032015-01-06 22:36:30 -080079 */
Ray Milkey47c95412017-09-15 10:40:48 -070080 private DefaultApplication(ApplicationId appId, Version version, String title,
Jian Lic35415d2016-01-14 17:22:31 -080081 String description, String origin, String category,
82 String url, String readme, byte[] icon,
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +090083 ApplicationRole role, Set<Permission> permissions,
Thomas Vachuska761f0042015-11-11 19:10:17 -080084 Optional<URI> featuresRepo, List<String> features,
85 List<String> requiredApps) {
Ray Milkey47c95412017-09-15 10:40:48 -070086 this.appId = appId;
87 this.version = version;
88 this.title = title;
89 this.description = description;
90 this.origin = origin;
91 this.category = category;
Jian Li01b0f5952016-01-20 11:02:07 -080092 this.url = url;
Ray Milkey47c95412017-09-15 10:40:48 -070093 this.readme = readme;
Simon Huntc2da4882016-01-21 13:24:47 -080094 this.icon = icon == null ? new byte[0] : icon.clone();
Ray Milkey47c95412017-09-15 10:40:48 -070095 this.role = role;
96 this.permissions = ImmutableSet.copyOf(permissions);
97 this.featuresRepo = featuresRepo;
98 this.features = ImmutableList.copyOf(features);
99 this.requiredApps = ImmutableList.copyOf(requiredApps);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800100 }
101
102 @Override
103 public ApplicationId id() {
104 return appId;
105 }
106
107 @Override
108 public Version version() {
109 return version;
110 }
111
112 @Override
Simon Huntafae2f72016-03-04 21:18:23 -0800113 public String title() {
114 return title;
115 }
116
117 @Override
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800118 public String description() {
119 return description;
120 }
121
122 @Override
Jian Lic35415d2016-01-14 17:22:31 -0800123 public String category() {
124 return category;
125 }
126
127 @Override
128 public String url() {
129 return url;
130 }
131
132 @Override
133 public String readme() {
134 return readme;
135 }
136
137 @Override
138 public byte[] icon() {
Simon Huntc2da4882016-01-21 13:24:47 -0800139 return icon.clone();
Jian Lic35415d2016-01-14 17:22:31 -0800140 }
141
142 @Override
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800143 public String origin() {
144 return origin;
145 }
146
147 @Override
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +0900148 public ApplicationRole role() {
149 return role;
150 }
151
152 @Override
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800153 public Set<Permission> permissions() {
154 return permissions;
155 }
156
157 @Override
158 public Optional<URI> featuresRepo() {
159 return featuresRepo;
160 }
161
162 @Override
Thomas Vachuskaebf5e542015-02-03 19:38:13 -0800163 public List<String> features() {
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800164 return features;
165 }
166
167 @Override
Thomas Vachuska761f0042015-11-11 19:10:17 -0800168 public List<String> requiredApps() {
169 return requiredApps;
170 }
171
172 @Override
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800173 public int hashCode() {
Simon Huntafae2f72016-03-04 21:18:23 -0800174 return Objects.hash(appId, version, title, description, origin, category, url,
Jian Lic35415d2016-01-14 17:22:31 -0800175 readme, role, permissions, featuresRepo, features, requiredApps);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800176 }
177
178 @Override
179 public boolean equals(Object obj) {
180 if (this == obj) {
181 return true;
182 }
183 if (obj == null || getClass() != obj.getClass()) {
184 return false;
185 }
186 final DefaultApplication other = (DefaultApplication) obj;
Simon Huntafae2f72016-03-04 21:18:23 -0800187 // TODO: review -- do ALL the fields need to be included?
188 // It is debatable whether fields like description, url, and readme,
189 // need to be included in the notion of equivalence.
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800190 return Objects.equals(this.appId, other.appId) &&
191 Objects.equals(this.version, other.version) &&
Simon Huntafae2f72016-03-04 21:18:23 -0800192 Objects.equals(this.title, other.title) &&
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800193 Objects.equals(this.description, other.description) &&
194 Objects.equals(this.origin, other.origin) &&
Jian Lic35415d2016-01-14 17:22:31 -0800195 Objects.equals(this.category, other.category) &&
196 Objects.equals(this.url, other.url) &&
197 Objects.equals(this.readme, other.readme) &&
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +0900198 Objects.equals(this.role, other.role) &&
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800199 Objects.equals(this.permissions, other.permissions) &&
200 Objects.equals(this.featuresRepo, other.featuresRepo) &&
Thomas Vachuska761f0042015-11-11 19:10:17 -0800201 Objects.equals(this.features, other.features) &&
202 Objects.equals(this.requiredApps, other.requiredApps);
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800203 }
204
205 @Override
206 public String toString() {
207 return toStringHelper(this)
208 .add("appId", appId)
209 .add("version", version)
Simon Huntafae2f72016-03-04 21:18:23 -0800210 .add("title", title)
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800211 .add("description", description)
212 .add("origin", origin)
Jian Lic35415d2016-01-14 17:22:31 -0800213 .add("category", category)
214 .add("url", url)
215 .add("readme", readme)
Changhoon Yoonbdeb88a2015-05-12 20:35:31 +0900216 .add("role", role)
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800217 .add("permissions", permissions)
218 .add("featuresRepo", featuresRepo)
219 .add("features", features)
Thomas Vachuska761f0042015-11-11 19:10:17 -0800220 .add("requiredApps", requiredApps)
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800221 .toString();
222 }
Ray Milkey47c95412017-09-15 10:40:48 -0700223
224 /**
225 * Returns a default application builder.
226 *
227 * @return builder
228 */
229 public static Builder builder() {
230 return new Builder();
231 }
232
233 /**
234 * Creates a new builder as a copy of an existing builder.
235 *
236 * @param builder existing builder to copy
237 * @return new builder
238 */
239 public static Builder builder(Builder builder) {
240 return new Builder(builder);
241 }
242
243 /**
244 * Creates a new builder as a copy of an existing application.
245 *
246 * @param application existing application to copy
247 * @return new builder
248 */
249 public static Builder builder(Application application) {
250 return new Builder(application);
251 }
252
253 /**
254 * Creates a new builder as a copy of an existing application description.
255 *
256 * @param appDesc existing application description
257 * @return new builder
258 */
259 public static Builder builder(ApplicationDescription appDesc) {
260 return new Builder(appDesc);
261 }
262
263
264 /**
265 * Default application builder.
266 */
267 public static final class Builder {
268
269 private ApplicationId appId;
270 private Version version;
271 private String title;
272 private String description;
273 private String category;
274 private String url;
275 private String readme;
276 private byte[] icon;
277 private String origin;
278 private ApplicationRole role;
279 private Set<Permission> permissions;
280 private Optional<URI> featuresRepo;
281 private List<String> features;
282 private List<String> requiredApps;
283
284 /**
285 * Default constructor for the builder.
286 */
287 public Builder() {}
288
289 /**
290 * Updates the builder to be a copy of an existing builder.
291 *
292 * @param builder existing builder to copy
293 */
294 public Builder(Builder builder) {
295 this.appId = builder.appId;
296 this.version = builder.version;
297 this.title = builder.title;
298 this.description = builder.description;
299 this.category = builder.category;
300 this.url = builder.url;
301 this.readme = builder.readme;
302 this.icon = builder.icon;
303 this.origin = builder.origin;
304 this.role = builder.role;
305 this.permissions = builder.permissions;
306 this.featuresRepo = builder.featuresRepo;
307 this.features = builder.features;
308 this.requiredApps = builder.requiredApps;
309 }
310
311 /**
312 * Updates the builder to be a copy of an existing application.
313 *
314 * @param application existing application to copy
315 */
316 public Builder(Application application) {
317 this.appId = application.id();
318 this.version = application.version();
319 this.title = application.title();
320 this.description = application.description();
321 this.category = application.category();
322 this.url = application.url();
323 this.readme = application.readme();
324 this.icon = application.icon();
325 this.origin = application.origin();
326 this.role = application.role();
327 this.permissions = application.permissions();
328 this.featuresRepo = application.featuresRepo();
329 this.features = application.features();
330 this.requiredApps = application.requiredApps();
331 }
332
333 /**
334 * Updates the builder to be a copy of an existing application description.
335 *
336 * @param appDesc existing application description
337 */
338 public Builder(ApplicationDescription appDesc) {
339 this.version = appDesc.version();
340 this.title = appDesc.title();
341 this.description = appDesc.description();
342 this.category = appDesc.category();
343 this.url = appDesc.url();
344 this.readme = appDesc.readme();
345 this.icon = appDesc.icon();
346 this.origin = appDesc.origin();
347 this.role = appDesc.role();
348 this.permissions = appDesc.permissions();
349 this.featuresRepo = appDesc.featuresRepo();
350 this.features = appDesc.features();
351 this.requiredApps = appDesc.requiredApps();
352 }
353
354 /**
355 * Adds an application id.
356 *
357 * @param appId application id
358 * @return builder
359 */
360 public Builder withAppId(ApplicationId appId) {
361 this.appId = appId;
362 return this;
363 }
364
365 /**
366 * Adds a version string.
367 *
368 * @param version version string
369 * @return builder
370 */
371 public Builder withVersion(Version version) {
372 this.version = version;
373 return this;
374 }
375
376 /**
377 * Adds a title string.
378 *
379 * @param title title string
380 * @return builder
381 */
382 public Builder withTitle(String title) {
383 this.title = title;
384 return this;
385 }
386
387 /**
388 * Adds a description string.
389 *
390 * @param description description string
391 * @return builder
392 */
393 public Builder withDescription(String description) {
394 this.description = description;
395 return this;
396 }
397
398 /**
399 * Adds a category string.
400 *
401 * @param category category string
402 * @return builder
403 */
404 public Builder withCategory(String category) {
405 this.category = category;
406 return this;
407 }
408
409 /**
410 * Adds a URL string.
411 *
412 * @param url url string
413 * @return builder
414 */
415 public Builder withUrl(String url) {
416 this.url = url;
417 return this;
418 }
419
420 /**
421 * Adds a readme string.
422 *
423 * @param readme readme string
424 * @return builder
425 */
426 public Builder withReadme(String readme) {
427 this.readme = readme;
428 return this;
429 }
430
431 /**
432 * Adds an icon.
433 *
434 * @param icon icon data
435 * @return builder
436 */
437 public Builder withIcon(byte[] icon) {
438 this.icon = icon;
439 return this;
440 }
441
442 /**
443 * Adds an origin string.
444 *
445 * @param origin origin string
446 * @return builder
447 */
448 public Builder withOrigin(String origin) {
449 this.origin = origin;
450 return this;
451 }
452
453 /**
454 * Adds an application role.
455 *
456 * @param role application role
457 * @return builder
458 */
459 public Builder withRole(ApplicationRole role) {
460 this.role = role;
461 return this;
462 }
463
464 /**
465 * Adds a permissions set.
466 *
467 * @param permissions permissions set
468 * @return builder
469 */
470 public Builder withPermissions(Set<Permission> permissions) {
471 this.permissions = permissions;
472 return this;
473 }
474
475 /**
476 * Adds a URI for a features repository.
477 *
478 * @param featuresRepo Optional URI for a features repository
479 * @return builder
480 */
481 public Builder withFeaturesRepo(Optional<URI> featuresRepo) {
482 this.featuresRepo = featuresRepo;
483 return this;
484 }
485
486 /**
487 * Adds a features list.
488 *
489 * @param features features list
490 * @return builder
491 */
492 public Builder withFeatures(List<String> features) {
493 this.features = features;
494 return this;
495 }
496
497 /**
498 * Adds a list of required applications.
499 *
500 * @param requiredApps List of name strings of required applications
501 * @return builder
502 */
503 public Builder withRequiredApps(List<String> requiredApps) {
504 this.requiredApps = requiredApps;
505 return this;
506 }
507
508 /**
509 * Builds a default application object from the gathered parameters.
510 *
511 * @return new default application
512 */
513 public DefaultApplication build() {
514 checkNotNull(appId, "ID cannot be null");
515 checkNotNull(version, "Version cannot be null");
516 checkNotNull(title, "Title cannot be null");
517 checkNotNull(description, "Description cannot be null");
518 checkNotNull(origin, "Origin cannot be null");
519 checkNotNull(category, "Category cannot be null");
520 checkNotNull(readme, "Readme cannot be null");
521 checkNotNull(role, "Role cannot be null");
522 checkNotNull(permissions, "Permissions cannot be null");
523 checkNotNull(featuresRepo, "Features repo cannot be null");
524 checkNotNull(features, "Features cannot be null");
525 checkNotNull(requiredApps, "Required apps cannot be null");
526 checkArgument(!features.isEmpty(), "There must be at least one feature");
527
528 return new DefaultApplication(appId, version, title,
529 description, origin, category,
530 url, readme, icon,
531 role, permissions,
532 featuresRepo, features,
533 requiredApps);
534 }
535 }
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800536}