View Javadoc
1   package gov.nist.secauto.oscal.lib.model;
2   
3   import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValue;
4   import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValues;
5   import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly;
6   import gov.nist.secauto.metaschema.binding.model.annotations.BoundField;
7   import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue;
8   import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag;
9   import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs;
10  import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly;
11  import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints;
12  import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior;
13  import gov.nist.secauto.metaschema.model.common.constraint.IConstraint;
14  import gov.nist.secauto.metaschema.model.common.datatype.adapter.DateTimeWithTZAdapter;
15  import gov.nist.secauto.metaschema.model.common.datatype.adapter.TokenAdapter;
16  import gov.nist.secauto.metaschema.model.common.datatype.adapter.UriReferenceAdapter;
17  import gov.nist.secauto.metaschema.model.common.datatype.adapter.UuidAdapter;
18  import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine;
19  import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter;
20  import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultiline;
21  import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter;
22  import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
23  import java.lang.Override;
24  import java.lang.String;
25  import java.net.URI;
26  import java.time.ZonedDateTime;
27  import java.util.LinkedList;
28  import java.util.List;
29  import java.util.UUID;
30  import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle;
31  import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
32  
33  /**
34   * Describes an individual observation.
35   */
36  @MetaschemaAssembly(
37      formalName = "Observation",
38      description = "Describes an individual observation.",
39      name = "observation",
40      metaschema = OscalAssessmentCommonMetaschema.class
41  )
42  public class Observation {
43    @BoundFlag(
44        formalName = "Observation Universally Unique Identifier",
45        description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented), [globally unique](https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique) identifier with *cross-instance* scope that can be used to reference this observation elsewhere in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#scope). The locally defined *UUID* of the `observation` can be used to reference the data item locally or globally (e.g., in an imorted OSCAL instance). This UUID should be assigned [per-subject](https://pages.nist.gov/OSCAL/concepts/identifier-use/#consistency), which means it should be consistently used to identify the same subject across revisions of the document.",
46        useName = "uuid",
47        required = true,
48        typeAdapter = UuidAdapter.class
49    )
50    private UUID _uuid;
51  
52    /**
53     * "The title for this observation."
54     */
55    @BoundField(
56        formalName = "Observation Title",
57        description = "The title for this observation.",
58        useName = "title"
59    )
60    @BoundFieldValue(
61        typeAdapter = MarkupLineAdapter.class
62    )
63    private MarkupLine _title;
64  
65    /**
66     * "A human-readable description of this assessment observation."
67     */
68    @BoundField(
69        formalName = "Observation Description",
70        description = "A human-readable description of this assessment observation.",
71        useName = "description",
72        minOccurs = 1
73    )
74    @BoundFieldValue(
75        typeAdapter = MarkupMultilineAdapter.class
76    )
77    private MarkupMultiline _description;
78  
79    @BoundAssembly(
80        formalName = "Property",
81        description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
82        useName = "prop",
83        maxOccurs = -1
84    )
85    @GroupAs(
86        name = "props",
87        inJson = JsonGroupAsBehavior.LIST
88    )
89    private List<Property> _props;
90  
91    @BoundAssembly(
92        formalName = "Link",
93        description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
94        useName = "link",
95        maxOccurs = -1
96    )
97    @GroupAs(
98        name = "links",
99        inJson = JsonGroupAsBehavior.LIST
100   )
101   private List<Link> _links;
102 
103   /**
104    * "Identifies how the observation was made."
105    */
106   @BoundField(
107       formalName = "Observation Method",
108       description = "Identifies how the observation was made.",
109       useName = "method",
110       minOccurs = 1,
111       maxOccurs = -1
112   )
113   @ValueConstraints(
114       allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, allowOthers = true, values = {@AllowedValue(value = "EXAMINE", description = "An inspection was performed."), @AllowedValue(value = "INTERVIEW", description = "An interview was performed."), @AllowedValue(value = "TEST", description = "A manual or automated test was performed."), @AllowedValue(value = "UNKNOWN", description = "This is only for use when converting historic content to OSCAL, where the conversion process cannot initially identify the appropriate method(s).")})
115   )
116   @GroupAs(
117       name = "methods",
118       inJson = JsonGroupAsBehavior.LIST
119   )
120   private List<String> _methods;
121 
122   /**
123    * "Identifies the nature of the observation. More than one may be used to further qualify and enable filtering."
124    */
125   @BoundField(
126       formalName = "Observation Type",
127       description = "Identifies the nature of the observation. More than one may be used to further qualify and enable filtering.",
128       useName = "type",
129       maxOccurs = -1
130   )
131   @BoundFieldValue(
132       typeAdapter = TokenAdapter.class
133   )
134   @ValueConstraints(
135       allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, allowOthers = true, values = {@AllowedValue(value = "ssp-statement-issue", description = "A difference between the SSP implementation statement, and actual implementation."), @AllowedValue(value = "control-objective", description = "An observation about the status of a the associated control objective."), @AllowedValue(value = "mitigation", description = "A mitigating factor was identified."), @AllowedValue(value = "finding", description = "An assessment finding. Used for observations made by tools, penetration testing, and other means."), @AllowedValue(value = "historic", description = "An observation from a past assessment, which was converted to OSCAL at a later date.")})
136   )
137   @GroupAs(
138       name = "types",
139       inJson = JsonGroupAsBehavior.LIST
140   )
141   private List<String> _types;
142 
143   @BoundAssembly(
144       formalName = "Origin",
145       description = "Identifies the source of the finding, such as a tool, interviewed person, or activity.",
146       useName = "origin",
147       maxOccurs = -1,
148       remarks = "Used to identify the individual and/or tool that gathered the evidence resulting in the observation identification."
149   )
150   @GroupAs(
151       name = "origins",
152       inJson = JsonGroupAsBehavior.LIST
153   )
154   private List<Origin> _origins;
155 
156   @BoundAssembly(
157       formalName = "Identifies the Subject",
158       description = "A [human-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#human-oriented) identifier reference to a resource. Use type to indicate whether the identified resource is a component, inventory item, location, user, or something else.",
159       useName = "subject",
160       maxOccurs = -1,
161       remarks = "Identifies who was interviewed, or what was tested or inspected."
162   )
163   @GroupAs(
164       name = "subjects",
165       inJson = JsonGroupAsBehavior.LIST
166   )
167   private List<SubjectReference> _subjects;
168 
169   /**
170    * "Links this observation to relevant evidence."
171    */
172   @BoundAssembly(
173       formalName = "Relevant Evidence",
174       description = "Links this observation to relevant evidence.",
175       useName = "relevant-evidence",
176       maxOccurs = -1
177   )
178   @GroupAs(
179       name = "relevant-evidence",
180       inJson = JsonGroupAsBehavior.LIST
181   )
182   private List<RelevantEvidence> _relevantEvidence;
183 
184   /**
185    * "Date/time stamp identifying when the finding information was collected."
186    */
187   @BoundField(
188       formalName = "Collected Field",
189       description = "Date/time stamp identifying when the finding information was collected.",
190       useName = "collected",
191       minOccurs = 1
192   )
193   @BoundFieldValue(
194       typeAdapter = DateTimeWithTZAdapter.class
195   )
196   private ZonedDateTime _collected;
197 
198   /**
199    * "Date/time identifying when the finding information is out-of-date and no longer valid. Typically used with continuous assessment scenarios."
200    */
201   @BoundField(
202       formalName = "Expires Field",
203       description = "Date/time identifying when the finding information is out-of-date and no longer valid. Typically used with continuous assessment scenarios.",
204       useName = "expires"
205   )
206   @BoundFieldValue(
207       typeAdapter = DateTimeWithTZAdapter.class
208   )
209   private ZonedDateTime _expires;
210 
211   @BoundField(
212       formalName = "Remarks",
213       description = "Additional commentary about the containing object.",
214       useName = "remarks"
215   )
216   @BoundFieldValue(
217       typeAdapter = MarkupMultilineAdapter.class
218   )
219   private MarkupMultiline _remarks;
220 
221   public Observation() {
222   }
223 
224   public UUID getUuid() {
225     return _uuid;
226   }
227 
228   public void setUuid(UUID value) {
229     _uuid = value;
230   }
231 
232   public MarkupLine getTitle() {
233     return _title;
234   }
235 
236   public void setTitle(MarkupLine value) {
237     _title = value;
238   }
239 
240   public MarkupMultiline getDescription() {
241     return _description;
242   }
243 
244   public void setDescription(MarkupMultiline value) {
245     _description = value;
246   }
247 
248   public List<Property> getProps() {
249     return _props;
250   }
251 
252   public void setProps(List<Property> value) {
253     _props = value;
254   }
255 
256   /**
257    * Add a new {@link Property} item to the underlying collection.
258    * @param item the item to add
259    * @return {@code true}
260    */
261   public boolean addProp(Property item) {
262     Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
263     if (_props == null) {
264       _props = new LinkedList<>();
265     }
266     return _props.add(value);
267   }
268 
269   /**
270    * Remove the first matching {@link Property} item from the underlying collection.
271    * @param item the item to remove
272    * @return {@code true} if the item was removed or {@code false} otherwise
273    */
274   public boolean removeProp(Property item) {
275     Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
276     return _props == null ? false : _props.remove(value);
277   }
278 
279   public List<Link> getLinks() {
280     return _links;
281   }
282 
283   public void setLinks(List<Link> value) {
284     _links = value;
285   }
286 
287   /**
288    * Add a new {@link Link} item to the underlying collection.
289    * @param item the item to add
290    * @return {@code true}
291    */
292   public boolean addLink(Link item) {
293     Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
294     if (_links == null) {
295       _links = new LinkedList<>();
296     }
297     return _links.add(value);
298   }
299 
300   /**
301    * Remove the first matching {@link Link} item from the underlying collection.
302    * @param item the item to remove
303    * @return {@code true} if the item was removed or {@code false} otherwise
304    */
305   public boolean removeLink(Link item) {
306     Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
307     return _links == null ? false : _links.remove(value);
308   }
309 
310   public List<String> getMethods() {
311     return _methods;
312   }
313 
314   public void setMethods(List<String> value) {
315     _methods = value;
316   }
317 
318   /**
319    * Add a new {@link String} item to the underlying collection.
320    * @param item the item to add
321    * @return {@code true}
322    */
323   public boolean addMethod(String item) {
324     String value = ObjectUtils.requireNonNull(item,"item cannot be null");
325     if (_methods == null) {
326       _methods = new LinkedList<>();
327     }
328     return _methods.add(value);
329   }
330 
331   /**
332    * Remove the first matching {@link String} item from the underlying collection.
333    * @param item the item to remove
334    * @return {@code true} if the item was removed or {@code false} otherwise
335    */
336   public boolean removeMethod(String item) {
337     String value = ObjectUtils.requireNonNull(item,"item cannot be null");
338     return _methods == null ? false : _methods.remove(value);
339   }
340 
341   public List<String> getTypes() {
342     return _types;
343   }
344 
345   public void setTypes(List<String> value) {
346     _types = value;
347   }
348 
349   /**
350    * Add a new {@link String} item to the underlying collection.
351    * @param item the item to add
352    * @return {@code true}
353    */
354   public boolean addType(String item) {
355     String value = ObjectUtils.requireNonNull(item,"item cannot be null");
356     if (_types == null) {
357       _types = new LinkedList<>();
358     }
359     return _types.add(value);
360   }
361 
362   /**
363    * Remove the first matching {@link String} item from the underlying collection.
364    * @param item the item to remove
365    * @return {@code true} if the item was removed or {@code false} otherwise
366    */
367   public boolean removeType(String item) {
368     String value = ObjectUtils.requireNonNull(item,"item cannot be null");
369     return _types == null ? false : _types.remove(value);
370   }
371 
372   public List<Origin> getOrigins() {
373     return _origins;
374   }
375 
376   public void setOrigins(List<Origin> value) {
377     _origins = value;
378   }
379 
380   /**
381    * Add a new {@link Origin} item to the underlying collection.
382    * @param item the item to add
383    * @return {@code true}
384    */
385   public boolean addOrigin(Origin item) {
386     Origin value = ObjectUtils.requireNonNull(item,"item cannot be null");
387     if (_origins == null) {
388       _origins = new LinkedList<>();
389     }
390     return _origins.add(value);
391   }
392 
393   /**
394    * Remove the first matching {@link Origin} item from the underlying collection.
395    * @param item the item to remove
396    * @return {@code true} if the item was removed or {@code false} otherwise
397    */
398   public boolean removeOrigin(Origin item) {
399     Origin value = ObjectUtils.requireNonNull(item,"item cannot be null");
400     return _origins == null ? false : _origins.remove(value);
401   }
402 
403   public List<SubjectReference> getSubjects() {
404     return _subjects;
405   }
406 
407   public void setSubjects(List<SubjectReference> value) {
408     _subjects = value;
409   }
410 
411   /**
412    * Add a new {@link SubjectReference} item to the underlying collection.
413    * @param item the item to add
414    * @return {@code true}
415    */
416   public boolean addSubject(SubjectReference item) {
417     SubjectReference value = ObjectUtils.requireNonNull(item,"item cannot be null");
418     if (_subjects == null) {
419       _subjects = new LinkedList<>();
420     }
421     return _subjects.add(value);
422   }
423 
424   /**
425    * Remove the first matching {@link SubjectReference} item from the underlying collection.
426    * @param item the item to remove
427    * @return {@code true} if the item was removed or {@code false} otherwise
428    */
429   public boolean removeSubject(SubjectReference item) {
430     SubjectReference value = ObjectUtils.requireNonNull(item,"item cannot be null");
431     return _subjects == null ? false : _subjects.remove(value);
432   }
433 
434   public List<RelevantEvidence> getRelevantEvidence() {
435     return _relevantEvidence;
436   }
437 
438   public void setRelevantEvidence(List<RelevantEvidence> value) {
439     _relevantEvidence = value;
440   }
441 
442   /**
443    * Add a new {@link RelevantEvidence} item to the underlying collection.
444    * @param item the item to add
445    * @return {@code true}
446    */
447   public boolean addRelevantEvidence(RelevantEvidence item) {
448     RelevantEvidence value = ObjectUtils.requireNonNull(item,"item cannot be null");
449     if (_relevantEvidence == null) {
450       _relevantEvidence = new LinkedList<>();
451     }
452     return _relevantEvidence.add(value);
453   }
454 
455   /**
456    * Remove the first matching {@link RelevantEvidence} item from the underlying collection.
457    * @param item the item to remove
458    * @return {@code true} if the item was removed or {@code false} otherwise
459    */
460   public boolean removeRelevantEvidence(RelevantEvidence item) {
461     RelevantEvidence value = ObjectUtils.requireNonNull(item,"item cannot be null");
462     return _relevantEvidence == null ? false : _relevantEvidence.remove(value);
463   }
464 
465   public ZonedDateTime getCollected() {
466     return _collected;
467   }
468 
469   public void setCollected(ZonedDateTime value) {
470     _collected = value;
471   }
472 
473   public ZonedDateTime getExpires() {
474     return _expires;
475   }
476 
477   public void setExpires(ZonedDateTime value) {
478     _expires = value;
479   }
480 
481   public MarkupMultiline getRemarks() {
482     return _remarks;
483   }
484 
485   public void setRemarks(MarkupMultiline value) {
486     _remarks = value;
487   }
488 
489   @Override
490   public String toString() {
491     return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
492   }
493 
494   /**
495    * Links this observation to relevant evidence.
496    */
497   @MetaschemaAssembly(
498       formalName = "Relevant Evidence",
499       description = "Links this observation to relevant evidence.",
500       name = "relevant-evidence",
501       metaschema = OscalAssessmentCommonMetaschema.class
502   )
503   public static class RelevantEvidence {
504     @BoundFlag(
505         formalName = "Relevant Evidence Reference",
506         description = "A resolvable URL reference to relevant evidence.",
507         useName = "href",
508         typeAdapter = UriReferenceAdapter.class,
509         remarks = "This value may be one of:\n"
510                 + "\n"
511                 + "1. an [absolute URI](https://pages.nist.gov/OSCAL/concepts/uri-use/#absolute-uri) that points to a network resolvable resource,\n"
512                 + "2. a [relative reference](https://pages.nist.gov/OSCAL/concepts/uri-use/#relative-reference) pointing to a network resolvable resource whose base URI is the URI of the containing document, or\n"
513                 + "3. a bare URI fragment (i.e., \\`#uuid\\`) pointing to a `back-matter` resource in this or an imported document (see [linking to another OSCAL object](https://pages.nist.gov/OSCAL/concepts/uri-use/#linking-to-another-oscal-object))."
514     )
515     private URI _href;
516 
517     /**
518      * "A human-readable description of this evidence."
519      */
520     @BoundField(
521         formalName = "Relevant Evidence Description",
522         description = "A human-readable description of this evidence.",
523         useName = "description",
524         minOccurs = 1
525     )
526     @BoundFieldValue(
527         typeAdapter = MarkupMultilineAdapter.class
528     )
529     private MarkupMultiline _description;
530 
531     @BoundAssembly(
532         formalName = "Property",
533         description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
534         useName = "prop",
535         maxOccurs = -1
536     )
537     @GroupAs(
538         name = "props",
539         inJson = JsonGroupAsBehavior.LIST
540     )
541     private List<Property> _props;
542 
543     @BoundAssembly(
544         formalName = "Link",
545         description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
546         useName = "link",
547         maxOccurs = -1
548     )
549     @GroupAs(
550         name = "links",
551         inJson = JsonGroupAsBehavior.LIST
552     )
553     private List<Link> _links;
554 
555     @BoundField(
556         formalName = "Remarks",
557         description = "Additional commentary about the containing object.",
558         useName = "remarks"
559     )
560     @BoundFieldValue(
561         typeAdapter = MarkupMultilineAdapter.class
562     )
563     private MarkupMultiline _remarks;
564 
565     public RelevantEvidence() {
566     }
567 
568     public URI getHref() {
569       return _href;
570     }
571 
572     public void setHref(URI value) {
573       _href = value;
574     }
575 
576     public MarkupMultiline getDescription() {
577       return _description;
578     }
579 
580     public void setDescription(MarkupMultiline value) {
581       _description = value;
582     }
583 
584     public List<Property> getProps() {
585       return _props;
586     }
587 
588     public void setProps(List<Property> value) {
589       _props = value;
590     }
591 
592     /**
593      * Add a new {@link Property} item to the underlying collection.
594      * @param item the item to add
595      * @return {@code true}
596      */
597     public boolean addProp(Property item) {
598       Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
599       if (_props == null) {
600         _props = new LinkedList<>();
601       }
602       return _props.add(value);
603     }
604 
605     /**
606      * Remove the first matching {@link Property} item from the underlying collection.
607      * @param item the item to remove
608      * @return {@code true} if the item was removed or {@code false} otherwise
609      */
610     public boolean removeProp(Property item) {
611       Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
612       return _props == null ? false : _props.remove(value);
613     }
614 
615     public List<Link> getLinks() {
616       return _links;
617     }
618 
619     public void setLinks(List<Link> value) {
620       _links = value;
621     }
622 
623     /**
624      * Add a new {@link Link} item to the underlying collection.
625      * @param item the item to add
626      * @return {@code true}
627      */
628     public boolean addLink(Link item) {
629       Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
630       if (_links == null) {
631         _links = new LinkedList<>();
632       }
633       return _links.add(value);
634     }
635 
636     /**
637      * Remove the first matching {@link Link} item from the underlying collection.
638      * @param item the item to remove
639      * @return {@code true} if the item was removed or {@code false} otherwise
640      */
641     public boolean removeLink(Link item) {
642       Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
643       return _links == null ? false : _links.remove(value);
644     }
645 
646     public MarkupMultiline getRemarks() {
647       return _remarks;
648     }
649 
650     public void setRemarks(MarkupMultiline value) {
651       _remarks = value;
652     }
653 
654     @Override
655     public String toString() {
656       return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
657     }
658   }
659 }