View Javadoc
1   /**
2    * Portions of this software was developed by employees of the National Institute
3    * of Standards and Technology (NIST), an agency of the Federal Government and is
4    * being made available as a public service. Pursuant to title 17 United States
5    * Code Section 105, works of NIST employees are not subject to copyright
6    * protection in the United States. This software may be subject to foreign
7    * copyright. Permission in the United States and in foreign countries, to the
8    * extent that NIST may hold copyright, to use, copy, modify, create derivative
9    * works, and distribute this software and its documentation without fee is hereby
10   * granted on a non-exclusive basis, provided that this notice and disclaimer
11   * of warranty appears in all copies.
12   *
13   * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER
14   * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY
15   * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM
17   * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE
18   * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE.  IN NO EVENT
19   * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT,
20   * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM,
21   * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY,
22   * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR
23   * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT
24   * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER.
25   */
26  
27  package gov.nist.secauto.swid.builder;
28  
29  import static gov.nist.secauto.swid.builder.util.Util.requireNonEmpty;
30  
31  import gov.nist.secauto.swid.builder.resource.EvidenceBuilder;
32  import gov.nist.secauto.swid.builder.resource.PayloadBuilder;
33  
34  import java.math.BigInteger;
35  import java.util.LinkedList;
36  import java.util.List;
37  import java.util.Locale;
38  import java.util.Objects;
39  
40  public class SWIDBuilder extends AbstractLanguageSpecificBuilder<SWIDBuilder> {
41    private TagType tagType = TagType.PRIMARY;
42    private String name;
43    private String tagId;
44    private BigInteger tagVersion = SWIDConstants.TAG_VERSION_DEFAULT;
45    private String version;
46    private VersionScheme versionScheme;
47    private List<EntityBuilder> entities = new LinkedList<>();
48    private EvidenceBuilder evidence;
49    private List<LinkBuilder> links = new LinkedList<>();
50    private List<MetaBuilder> metas = new LinkedList<>();
51    private PayloadBuilder payload;
52    private String media;
53  
54    protected SWIDBuilder() {
55      super();
56    }
57  
58    @Override
59    public void reset() {
60      super.reset();
61  
62      language(Locale.getDefault().toLanguageTag());
63  
64      this.tagType = TagType.PRIMARY;
65      this.name = null;
66      this.tagId = null;
67      this.tagVersion = SWIDConstants.TAG_VERSION_DEFAULT;
68      this.version = null;
69      this.versionScheme = null;
70      this.entities = new LinkedList<>();
71      ;
72      this.evidence = null;
73      this.links = new LinkedList<>();
74      ;
75      this.metas = new LinkedList<>();
76      ;
77      this.payload = null;
78      this.media = null;
79    }
80  
81    public static SWIDBuilder create() {
82      return new SWIDBuilder();
83    }
84  
85    public String getTagId() {
86      return tagId;
87    }
88  
89    public TagType getTagType() {
90      return tagType;
91    }
92  
93    public String getName() {
94      return name;
95    }
96  
97    public BigInteger getTagVersion() {
98      return tagVersion;
99    }
100 
101   public String getVersion() {
102     return (version == null ? SWIDConstants.VERSION_DEFAULT : version);
103   }
104 
105   public VersionScheme getVersionScheme() {
106     return (versionScheme == null ? SWIDConstants.VERSION_SCHEME_DEFAULT : versionScheme);
107   }
108 
109   public List<EntityBuilder> getEntities() {
110     return entities;
111   }
112 
113   public EvidenceBuilder getEvidence() {
114     return evidence;
115   }
116 
117   public PayloadBuilder getPayload() {
118     return payload;
119   }
120 
121   /**
122    * Provide a new evidence node if a previous evidence node was not provided, or the cached node if
123    * one already exists.
124    * 
125    * @return the evidence node builder instance
126    */
127   public EvidenceBuilder newEvidence() {
128     if (evidence == null) {
129       evidence = EvidenceBuilder.create();
130     }
131     return evidence;
132   }
133 
134   public List<LinkBuilder> getLinks() {
135     return links;
136   }
137 
138   public List<MetaBuilder> getMetas() {
139     return metas;
140   }
141 
142   /**
143    * Retrieves the existing PayloadBuilder or creates a new one if no PayloadBuilder has been created
144    * already.
145    * 
146    * @return the payload builder
147    */
148   public PayloadBuilder newPayload() {
149     if (payload == null) {
150       payload = PayloadBuilder.create();
151     }
152     return payload;
153   }
154 
155   public String getMedia() {
156     return media;
157   }
158 
159   /**
160    * Sets the to-be-built tag's product type to the provided value.
161    * 
162    * @param type
163    *          the new type to set
164    * @return the same builder instance
165    */
166   public SWIDBuilder tagType(TagType type) {
167     Objects.requireNonNull(type, "tagType");
168     this.tagType = type;
169     return this;
170   }
171 
172   /**
173    * Sets the to-be-built tag's product name to the provided value.
174    * 
175    * @param name
176    *          the name of the software product
177    * @return the same builder instance
178    */
179   public SWIDBuilder name(String name) {
180     requireNonEmpty(name, "name");
181     this.name = name;
182     return this;
183   }
184 
185   /**
186    * Sets the to-be-built tag's product tag identifier to the provided value.
187    * 
188    * @param id
189    *          the tag identifier for the software product
190    * @return the same builder instance
191    */
192   public SWIDBuilder tagId(String id) {
193     requireNonEmpty(id, "id");
194     this.tagId = id;
195     return this;
196   }
197 
198   public SWIDBuilder tagVersion(long version) {
199     return tagVersion(BigInteger.valueOf(version));
200   }
201 
202   /**
203    * Set the tag's tag version.
204    * 
205    * @param version
206    *          the version value to use
207    * @return the same builder instance
208    */
209   public SWIDBuilder tagVersion(BigInteger version) {
210     Objects.requireNonNull(version, "tagVersion");
211     this.tagVersion = version;
212     return this;
213   }
214 
215   /**
216    * Sets the to-be-built SWID tag's version to the provided value.
217    * 
218    * @param version
219    *          the version value to use
220    * @return the same builder instance
221    */
222   public SWIDBuilder version(String version) {
223     requireNonEmpty(version, "version");
224     if (SWIDConstants.VERSION_DEFAULT.equals(version)) {
225       this.version = null;
226     } else {
227       this.version = version;
228     }
229     return this;
230   }
231 
232   /**
233    * Sets the to-be-built SWID tag's versionSchema to the provided value. The version scheme
234    * identifies the structure of the provided version.
235    * 
236    * @see VersionScheme#lookupByIndex(int)
237    * @see VersionScheme#lookupByName(String)
238    * @see VersionScheme#assignPrivateVersionScheme(int, String)
239    * @param scheme
240    *          the version scheme for the tag
241    * @return the same builder instance
242    * @see #version(String)
243    */
244   public SWIDBuilder versionScheme(VersionScheme scheme) {
245     Objects.requireNonNull(scheme, "versionScheme");
246     this.versionScheme = scheme;
247     return this;
248   }
249 
250   /**
251    * Sets the to-be-built SWID tag's media to the provided value.
252    * 
253    * @param media
254    *          the media value to use
255    * @return the same builder instance
256    */
257   public SWIDBuilder media(String media) {
258     Objects.requireNonNull(media, "media");
259     this.media = media;
260     return this;
261   }
262 
263   /**
264    * Adds a new entity to the tag.
265    * 
266    * @param entity
267    *          a entity builder representing the new entity to add
268    * @return the same builder instance
269    */
270   public SWIDBuilder addEntity(EntityBuilder entity) {
271     Objects.requireNonNull(entity, "entity");
272     this.entities.add(entity);
273     return this;
274   }
275 
276   /**
277    * Adds a new link to the tag.
278    * 
279    * @param link
280    *          a link builder representing the new link to add
281    * @return the same builder instance
282    */
283   public SWIDBuilder addLink(LinkBuilder link) {
284     Objects.requireNonNull(link, "link");
285     this.links.add(link);
286     return this;
287   }
288 
289   /**
290    * Adds a new meta to the tag.
291    * 
292    * @param meta
293    *          a meta builder representing the new meta to add
294    * @return the same builder instance
295    */
296   public SWIDBuilder addMeta(MetaBuilder meta) {
297     Objects.requireNonNull(meta, "meta");
298     this.metas.add(meta);
299     return this;
300   }
301 
302   /**
303    * Adds a new payload to the tag.
304    * 
305    * @param payload
306    *          a payload builder representing the new payload to add
307    * @return the same builder instance
308    */
309   public SWIDBuilder payload(PayloadBuilder payload) {
310     Objects.requireNonNull(payload, "payload");
311     this.payload = payload;
312     return this;
313   }
314 
315   /**
316    * Adds a new evidence to the tag.
317    * 
318    * @param evidence
319    *          a evidence builder representing the new evidence to add
320    * @return the same builder instance
321    */
322   public SWIDBuilder evidence(EvidenceBuilder evidence) {
323     Objects.requireNonNull(evidence, "evidence");
324     this.evidence = evidence;
325     return this;
326   }
327 
328   @Override
329   public void validate() throws ValidationException {
330     super.validate();
331     validateNonEmpty("name", name);
332     validateNonEmpty("tagId", tagId);
333     validateNonEmpty("entity", entities);
334     boolean foundTagCreator = false;
335     for (EntityBuilder entity : entities) {
336       entity.validate();
337       if (entity.getRoles().contains(KnownRole.TAG_CREATOR)) {
338         foundTagCreator = true;
339       }
340     }
341     if (!foundTagCreator) {
342       throw new ValidationException(
343           "at least one entity wwith the role '" + KnownRole.TAG_CREATOR.getName() + "' must be provided");
344     }
345 
346     if (payload != null && evidence != null) {
347       throw new ValidationException("Only one of evidence or payload must be provided");
348     }
349 
350     if (payload != null) {
351       payload.validate();
352     }
353 
354     if (evidence != null) {
355       evidence.validate();
356     }
357 
358     if (!links.isEmpty()) {
359       for (LinkBuilder link : links) {
360         link.validate();
361       }
362     }
363 
364     if (!metas.isEmpty()) {
365       for (MetaBuilder meta : metas) {
366         meta.validate();
367       }
368     }
369   }
370 
371 }