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
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
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
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
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
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
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
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
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
258
259
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
271
272
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
289
290
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
302
303
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
320
321
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
333
334
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
351
352
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
364
365
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
382
383
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
395
396
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
413
414
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
426
427
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
444
445
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
457
458
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
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
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
594
595
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
607
608
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
625
626
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
638
639
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 }