001package gov.nist.secauto.oscal.lib.model; 002 003import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly; 004import gov.nist.secauto.metaschema.binding.model.annotations.BoundField; 005import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue; 006import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag; 007import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs; 008import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly; 009import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior; 010import gov.nist.secauto.metaschema.model.common.datatype.adapter.UuidAdapter; 011import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine; 012import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter; 013import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultiline; 014import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter; 015import gov.nist.secauto.metaschema.model.common.util.ObjectUtils; 016import java.lang.Override; 017import java.lang.String; 018import java.util.LinkedList; 019import java.util.List; 020import java.util.UUID; 021import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle; 022import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 023 024/** 025 * Describes an individual finding. 026 */ 027@MetaschemaAssembly( 028 formalName = "Finding", 029 description = "Describes an individual finding.", 030 name = "finding", 031 metaschema = OscalAssessmentCommonMetaschema.class 032) 033public class Finding { 034 @BoundFlag( 035 formalName = "Finding Universally Unique Identifier", 036 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](https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance) scope that can be used to reference this finding in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#ar-identifiers). The locally defined *UUID* of the `finding` can be used to reference the data item locally or globally (e.g., in an imported 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.", 037 useName = "uuid", 038 required = true, 039 typeAdapter = UuidAdapter.class 040 ) 041 private UUID _uuid; 042 043 /** 044 * "The title for this finding." 045 */ 046 @BoundField( 047 formalName = "Finding Title", 048 description = "The title for this finding.", 049 useName = "title", 050 minOccurs = 1 051 ) 052 @BoundFieldValue( 053 typeAdapter = MarkupLineAdapter.class 054 ) 055 private MarkupLine _title; 056 057 /** 058 * "A human-readable description of this finding." 059 */ 060 @BoundField( 061 formalName = "Finding Description", 062 description = "A human-readable description of this finding.", 063 useName = "description", 064 minOccurs = 1 065 ) 066 @BoundFieldValue( 067 typeAdapter = MarkupMultilineAdapter.class 068 ) 069 private MarkupMultiline _description; 070 071 @BoundAssembly( 072 formalName = "Property", 073 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.", 074 useName = "prop", 075 maxOccurs = -1 076 ) 077 @GroupAs( 078 name = "props", 079 inJson = JsonGroupAsBehavior.LIST 080 ) 081 private List<Property> _props; 082 083 @BoundAssembly( 084 formalName = "Link", 085 description = "A reference to a local or remote resource, that has a specific relation to the containing object.", 086 useName = "link", 087 maxOccurs = -1 088 ) 089 @GroupAs( 090 name = "links", 091 inJson = JsonGroupAsBehavior.LIST 092 ) 093 private List<Link> _links; 094 095 @BoundAssembly( 096 formalName = "Origin", 097 description = "Identifies the source of the finding, such as a tool, interviewed person, or activity.", 098 useName = "origin", 099 maxOccurs = -1, 100 remarks = "Used to identify the individual and/or tool generated this finding." 101 ) 102 @GroupAs( 103 name = "origins", 104 inJson = JsonGroupAsBehavior.LIST 105 ) 106 private List<Origin> _origins; 107 108 @BoundAssembly( 109 formalName = "Objective Status", 110 description = "Captures an assessor's conclusions regarding the degree to which an objective is satisfied.", 111 useName = "target", 112 minOccurs = 1 113 ) 114 private FindingTarget _target; 115 116 /** 117 * "A <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented\">machine-oriented</a> identifier reference to the implementation statement in the SSP to which this finding is related." 118 */ 119 @BoundField( 120 formalName = "Implementation Statement UUID", 121 description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented) identifier reference to the implementation statement in the SSP to which this finding is related.", 122 useName = "implementation-statement-uuid" 123 ) 124 @BoundFieldValue( 125 typeAdapter = UuidAdapter.class 126 ) 127 private UUID _implementationStatementUuid; 128 129 /** 130 * "Relates the finding to a set of referenced observations that were used to determine the finding." 131 */ 132 @BoundAssembly( 133 formalName = "Related Observation", 134 description = "Relates the finding to a set of referenced observations that were used to determine the finding.", 135 useName = "related-observation", 136 maxOccurs = -1 137 ) 138 @GroupAs( 139 name = "related-observations", 140 inJson = JsonGroupAsBehavior.LIST 141 ) 142 private List<RelatedObservation> _relatedObservations; 143 144 /** 145 * "Relates the finding to a set of referenced risks that were used to determine the finding." 146 */ 147 @BoundAssembly( 148 formalName = "Associated Risk", 149 description = "Relates the finding to a set of referenced risks that were used to determine the finding.", 150 useName = "associated-risk", 151 maxOccurs = -1 152 ) 153 @GroupAs( 154 name = "related-risks", 155 inJson = JsonGroupAsBehavior.LIST 156 ) 157 private List<AssociatedRisk> _relatedRisks; 158 159 @BoundField( 160 formalName = "Remarks", 161 description = "Additional commentary about the containing object.", 162 useName = "remarks" 163 ) 164 @BoundFieldValue( 165 typeAdapter = MarkupMultilineAdapter.class 166 ) 167 private MarkupMultiline _remarks; 168 169 public Finding() { 170 } 171 172 public UUID getUuid() { 173 return _uuid; 174 } 175 176 public void setUuid(UUID value) { 177 _uuid = value; 178 } 179 180 public MarkupLine getTitle() { 181 return _title; 182 } 183 184 public void setTitle(MarkupLine value) { 185 _title = value; 186 } 187 188 public MarkupMultiline getDescription() { 189 return _description; 190 } 191 192 public void setDescription(MarkupMultiline value) { 193 _description = value; 194 } 195 196 public List<Property> getProps() { 197 return _props; 198 } 199 200 public void setProps(List<Property> value) { 201 _props = value; 202 } 203 204 /** 205 * Add a new {@link Property} item to the underlying collection. 206 * @param item the item to add 207 * @return {@code true} 208 */ 209 public boolean addProp(Property item) { 210 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 211 if (_props == null) { 212 _props = new LinkedList<>(); 213 } 214 return _props.add(value); 215 } 216 217 /** 218 * Remove the first matching {@link Property} item from the underlying collection. 219 * @param item the item to remove 220 * @return {@code true} if the item was removed or {@code false} otherwise 221 */ 222 public boolean removeProp(Property item) { 223 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 224 return _props == null ? false : _props.remove(value); 225 } 226 227 public List<Link> getLinks() { 228 return _links; 229 } 230 231 public void setLinks(List<Link> value) { 232 _links = value; 233 } 234 235 /** 236 * Add a new {@link Link} item to the underlying collection. 237 * @param item the item to add 238 * @return {@code true} 239 */ 240 public boolean addLink(Link item) { 241 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 242 if (_links == null) { 243 _links = new LinkedList<>(); 244 } 245 return _links.add(value); 246 } 247 248 /** 249 * Remove the first matching {@link Link} item from the underlying collection. 250 * @param item the item to remove 251 * @return {@code true} if the item was removed or {@code false} otherwise 252 */ 253 public boolean removeLink(Link item) { 254 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 255 return _links == null ? false : _links.remove(value); 256 } 257 258 public List<Origin> getOrigins() { 259 return _origins; 260 } 261 262 public void setOrigins(List<Origin> value) { 263 _origins = value; 264 } 265 266 /** 267 * Add a new {@link Origin} item to the underlying collection. 268 * @param item the item to add 269 * @return {@code true} 270 */ 271 public boolean addOrigin(Origin item) { 272 Origin value = ObjectUtils.requireNonNull(item,"item cannot be null"); 273 if (_origins == null) { 274 _origins = new LinkedList<>(); 275 } 276 return _origins.add(value); 277 } 278 279 /** 280 * Remove the first matching {@link Origin} item from the underlying collection. 281 * @param item the item to remove 282 * @return {@code true} if the item was removed or {@code false} otherwise 283 */ 284 public boolean removeOrigin(Origin item) { 285 Origin value = ObjectUtils.requireNonNull(item,"item cannot be null"); 286 return _origins == null ? false : _origins.remove(value); 287 } 288 289 public FindingTarget getTarget() { 290 return _target; 291 } 292 293 public void setTarget(FindingTarget value) { 294 _target = value; 295 } 296 297 public UUID getImplementationStatementUuid() { 298 return _implementationStatementUuid; 299 } 300 301 public void setImplementationStatementUuid(UUID value) { 302 _implementationStatementUuid = value; 303 } 304 305 public List<RelatedObservation> getRelatedObservations() { 306 return _relatedObservations; 307 } 308 309 public void setRelatedObservations(List<RelatedObservation> value) { 310 _relatedObservations = value; 311 } 312 313 /** 314 * Add a new {@link RelatedObservation} item to the underlying collection. 315 * @param item the item to add 316 * @return {@code true} 317 */ 318 public boolean addRelatedObservation(RelatedObservation item) { 319 RelatedObservation value = ObjectUtils.requireNonNull(item,"item cannot be null"); 320 if (_relatedObservations == null) { 321 _relatedObservations = new LinkedList<>(); 322 } 323 return _relatedObservations.add(value); 324 } 325 326 /** 327 * Remove the first matching {@link RelatedObservation} item from the underlying collection. 328 * @param item the item to remove 329 * @return {@code true} if the item was removed or {@code false} otherwise 330 */ 331 public boolean removeRelatedObservation(RelatedObservation item) { 332 RelatedObservation value = ObjectUtils.requireNonNull(item,"item cannot be null"); 333 return _relatedObservations == null ? false : _relatedObservations.remove(value); 334 } 335 336 public List<AssociatedRisk> getRelatedRisks() { 337 return _relatedRisks; 338 } 339 340 public void setRelatedRisks(List<AssociatedRisk> value) { 341 _relatedRisks = value; 342 } 343 344 /** 345 * Add a new {@link AssociatedRisk} item to the underlying collection. 346 * @param item the item to add 347 * @return {@code true} 348 */ 349 public boolean addAssociatedRisk(AssociatedRisk item) { 350 AssociatedRisk value = ObjectUtils.requireNonNull(item,"item cannot be null"); 351 if (_relatedRisks == null) { 352 _relatedRisks = new LinkedList<>(); 353 } 354 return _relatedRisks.add(value); 355 } 356 357 /** 358 * Remove the first matching {@link AssociatedRisk} item from the underlying collection. 359 * @param item the item to remove 360 * @return {@code true} if the item was removed or {@code false} otherwise 361 */ 362 public boolean removeAssociatedRisk(AssociatedRisk item) { 363 AssociatedRisk value = ObjectUtils.requireNonNull(item,"item cannot be null"); 364 return _relatedRisks == null ? false : _relatedRisks.remove(value); 365 } 366 367 public MarkupMultiline getRemarks() { 368 return _remarks; 369 } 370 371 public void setRemarks(MarkupMultiline value) { 372 _remarks = value; 373 } 374 375 @Override 376 public String toString() { 377 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString(); 378 } 379 380 /** 381 * Relates the finding to a set of referenced risks that were used to determine the finding. 382 */ 383 @MetaschemaAssembly( 384 formalName = "Associated Risk", 385 description = "Relates the finding to a set of referenced risks that were used to determine the finding.", 386 name = "associated-risk", 387 metaschema = OscalAssessmentCommonMetaschema.class 388 ) 389 public static class AssociatedRisk { 390 @BoundFlag( 391 formalName = "Risk Universally Unique Identifier Reference", 392 description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented) identifier reference to a risk defined in the list of risks.", 393 useName = "risk-uuid", 394 required = true, 395 typeAdapter = UuidAdapter.class 396 ) 397 private UUID _riskUuid; 398 399 public AssociatedRisk() { 400 } 401 402 public UUID getRiskUuid() { 403 return _riskUuid; 404 } 405 406 public void setRiskUuid(UUID value) { 407 _riskUuid = value; 408 } 409 410 @Override 411 public String toString() { 412 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString(); 413 } 414 } 415 416 /** 417 * Relates the finding to a set of referenced observations that were used to determine the finding. 418 */ 419 @MetaschemaAssembly( 420 formalName = "Related Observation", 421 description = "Relates the finding to a set of referenced observations that were used to determine the finding.", 422 name = "related-observation", 423 metaschema = OscalAssessmentCommonMetaschema.class 424 ) 425 public static class RelatedObservation { 426 @BoundFlag( 427 formalName = "Observation Universally Unique Identifier Reference", 428 description = "A [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented) identifier reference to an observation defined in the list of observations.", 429 useName = "observation-uuid", 430 required = true, 431 typeAdapter = UuidAdapter.class 432 ) 433 private UUID _observationUuid; 434 435 public RelatedObservation() { 436 } 437 438 public UUID getObservationUuid() { 439 return _observationUuid; 440 } 441 442 public void setObservationUuid(UUID value) { 443 _observationUuid = value; 444 } 445 446 @Override 447 public String toString() { 448 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString(); 449 } 450 } 451}