001package gov.nist.secauto.oscal.lib.model; 002 003import gov.nist.secauto.metaschema.core.datatype.adapter.StringAdapter; 004import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter; 005import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline; 006import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultilineAdapter; 007import gov.nist.secauto.metaschema.core.model.IBoundObject; 008import gov.nist.secauto.metaschema.core.model.IMetaschemaData; 009import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior; 010import gov.nist.secauto.metaschema.core.model.constraint.IConstraint; 011import gov.nist.secauto.metaschema.core.util.ObjectUtils; 012import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValue; 013import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValues; 014import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly; 015import gov.nist.secauto.metaschema.databind.model.annotations.BoundField; 016import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag; 017import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; 018import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly; 019import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints; 020import java.lang.Override; 021import java.lang.String; 022import java.util.LinkedList; 023import java.util.List; 024import java.util.UUID; 025import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 026import org.apache.commons.lang3.builder.ToStringStyle; 027 028/** 029 * A mapping between two target resources. 030 */ 031@MetaschemaAssembly( 032 formalName = "Control Mapping", 033 description = "A mapping between two target resources.", 034 name = "mapping", 035 moduleClass = OscalMappingCommonModule.class 036) 037public class Mapping implements IBoundObject { 038 private final IMetaschemaData __metaschemaData; 039 040 /** 041 * "A <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented\">machine-oriented</a>, <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#globally-unique\">globally unique</a> identifier with <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#cross-instance\">cross-instance</a> scope that can be used to reference this mapping definition elsewhere in this or other OSCAL instances. The locally defined <em>UUID</em> of the <code> mapping</code> can be used to reference the data item locally or globally (e.g., in an imported OSCAL instance). This UUID should be assigned <a href=\"https://pages.nist.gov/OSCAL/concepts/identifier-use/#consistency\">per-subject</a>, which means it should be consistently used to identify the same mapping across revisions of the document." 042 */ 043 @BoundFlag( 044 formalName = "Mapping Universally Unique Identifier", 045 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 mapping definition elsewhere in this or other OSCAL instances. The locally defined *UUID* of the ` mapping` 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 mapping across revisions of the document.", 046 name = "uuid", 047 required = true, 048 typeAdapter = UuidAdapter.class 049 ) 050 private UUID _uuid; 051 052 /** 053 * "The method used to complete the overall mapping." 054 */ 055 @BoundFlag( 056 formalName = "Method", 057 description = "The method used to complete the overall mapping.", 058 name = "method", 059 typeAdapter = StringAdapter.class, 060 valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, values = {@AllowedValue(value = "human", description = "Human"), @AllowedValue(value = "automation", description = "Automation"), @AllowedValue(value = "hybrid", description = "Hybrid")})) 061 ) 062 private String _method; 063 064 /** 065 * "The method used for relating controls within the mapping. The supported methods are aligned with the <a href=\"https://doi.org/10.6028/NIST.IR.8477\">NIST Interagency Report (IR) 8477</a>, Section 4.3 Set Theory Relationship Mapping." 066 */ 067 @BoundFlag( 068 formalName = "Matching", 069 description = "The method used for relating controls within the mapping. The supported methods are aligned with the [NIST Interagency Report (IR) 8477](https://doi.org/10.6028/NIST.IR.8477), Section 4.3 Set Theory Relationship Mapping.", 070 name = "matching-rationale", 071 typeAdapter = StringAdapter.class, 072 valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, values = {@AllowedValue(value = "syntactic", description = "Syntactic: How similar is the *wording* that expresses the two concepts. This is a word-for-word analysis of the relationship, not an interpretation of the language."), @AllowedValue(value = "semantic", description = "Semantic: How similar are the *meanings* of the two concepts? This involves some interpretation of each concept’s language."), @AllowedValue(value = "functional", description = "Functional: How similar are the *results* of executing the two concepts? This involves understanding what will happen if the two concepts are implemented, performed, or otherwise executed.")})) 073 ) 074 private String _matchingRationale; 075 076 /** 077 * "The current status of this mapping document." 078 */ 079 @BoundFlag( 080 formalName = "Status", 081 description = "The current status of this mapping document.", 082 name = "status", 083 typeAdapter = StringAdapter.class, 084 valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, values = {@AllowedValue(value = "complete", description = "Complete"), @AllowedValue(value = "not-complete", description = "Not Complete"), @AllowedValue(value = "draft", description = "Draft"), @AllowedValue(value = "deprecated", description = "Deprecated"), @AllowedValue(value = "superseded", description = "Superseded")})) 085 ) 086 private String _status; 087 088 @BoundAssembly( 089 formalName = "Mapped Resource Reference", 090 description = "A reference to a resource that is either the source or the target of a mapping.", 091 useName = "source-resource", 092 minOccurs = 1 093 ) 094 private MappingResourceReference _sourceResource; 095 096 @BoundAssembly( 097 formalName = "Mapped Resource Reference", 098 description = "A reference to a resource that is either the source or the target of a mapping.", 099 useName = "target-resource", 100 minOccurs = 1 101 ) 102 private MappingResourceReference _targetResource; 103 104 @BoundAssembly( 105 formalName = "Mapping Entry", 106 description = "A relationship-based mapping between a source and target set consisting of members (i.e., controls, control statements) from the respective source and target.", 107 useName = "map", 108 minOccurs = 1, 109 maxOccurs = -1, 110 groupAs = @GroupAs(name = "maps", inJson = JsonGroupAsBehavior.LIST) 111 ) 112 private List<MappingEntry> _maps; 113 114 @BoundAssembly( 115 formalName = "Property", 116 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.", 117 useName = "prop", 118 maxOccurs = -1, 119 groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST) 120 ) 121 private List<Property> _props; 122 123 @BoundAssembly( 124 formalName = "Link", 125 description = "A reference to a local or remote resource, that has a specific relation to the containing object.", 126 useName = "link", 127 maxOccurs = -1, 128 groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST) 129 ) 130 private List<Link> _links; 131 132 @BoundField( 133 formalName = "Remarks", 134 description = "Additional commentary about the containing object.", 135 useName = "remarks", 136 typeAdapter = MarkupMultilineAdapter.class 137 ) 138 private MarkupMultiline _remarks; 139 140 @BoundField( 141 formalName = "Mapping Description", 142 description = "Description of the context and intended use of the mapping set.", 143 useName = "mapping-description", 144 typeAdapter = MarkupMultilineAdapter.class 145 ) 146 private MarkupMultiline _mappingDescription; 147 148 @BoundAssembly( 149 formalName = "Gap Summary", 150 description = "A *by-id* collection of all controls that were not mapped at all in this ` mapping-collection`. If a control is partially mapped, the parts of the control are not mappable, the gap and discrepancies should be documented in the ` relationship-gal`.", 151 useName = "source-gap-summary" 152 ) 153 private GapSummary _sourceGapSummary; 154 155 @BoundAssembly( 156 formalName = "Gap Summary", 157 description = "A *by-id* collection of all controls that were not mapped at all in this ` mapping-collection`. If a control is partially mapped, the parts of the control are not mappable, the gap and discrepancies should be documented in the ` relationship-gal`.", 158 useName = "target-gap-summary" 159 ) 160 private GapSummary _targetGapSummary; 161 162 @BoundField( 163 formalName = "Confidence Score", 164 description = "This records either a string category or a decimal value from 0-1 representing a percentage. Both of these values describe an estimation of the author's confidence that this mapping is correct and accurate.", 165 useName = "confidence-score" 166 ) 167 private ConfidenceScore _confidenceScore; 168 169 @BoundField( 170 formalName = "Coverage", 171 description = "A decimal value from 0-1, representing the percentage coverage of the targets by the sources.", 172 useName = "coverage" 173 ) 174 private Coverage _coverage; 175 176 public Mapping() { 177 this(null); 178 } 179 180 public Mapping(IMetaschemaData data) { 181 this.__metaschemaData = data; 182 } 183 184 @Override 185 public IMetaschemaData getMetaschemaData() { 186 return __metaschemaData; 187 } 188 189 public UUID getUuid() { 190 return _uuid; 191 } 192 193 public void setUuid(UUID value) { 194 _uuid = value; 195 } 196 197 public String getMethod() { 198 return _method; 199 } 200 201 public void setMethod(String value) { 202 _method = value; 203 } 204 205 public String getMatchingRationale() { 206 return _matchingRationale; 207 } 208 209 public void setMatchingRationale(String value) { 210 _matchingRationale = value; 211 } 212 213 public String getStatus() { 214 return _status; 215 } 216 217 public void setStatus(String value) { 218 _status = value; 219 } 220 221 public MappingResourceReference getSourceResource() { 222 return _sourceResource; 223 } 224 225 public void setSourceResource(MappingResourceReference value) { 226 _sourceResource = value; 227 } 228 229 public MappingResourceReference getTargetResource() { 230 return _targetResource; 231 } 232 233 public void setTargetResource(MappingResourceReference value) { 234 _targetResource = value; 235 } 236 237 public List<MappingEntry> getMaps() { 238 return _maps; 239 } 240 241 public void setMaps(List<MappingEntry> value) { 242 _maps = value; 243 } 244 245 /** 246 * Add a new {@link MappingEntry} item to the underlying collection. 247 * @param item the item to add 248 * @return {@code true} 249 */ 250 public boolean addMap(MappingEntry item) { 251 MappingEntry value = ObjectUtils.requireNonNull(item,"item cannot be null"); 252 if (_maps == null) { 253 _maps = new LinkedList<>(); 254 } 255 return _maps.add(value); 256 } 257 258 /** 259 * Remove the first matching {@link MappingEntry} item from the underlying collection. 260 * @param item the item to remove 261 * @return {@code true} if the item was removed or {@code false} otherwise 262 */ 263 public boolean removeMap(MappingEntry item) { 264 MappingEntry value = ObjectUtils.requireNonNull(item,"item cannot be null"); 265 return _maps != null && _maps.remove(value); 266 } 267 268 public List<Property> getProps() { 269 return _props; 270 } 271 272 public void setProps(List<Property> value) { 273 _props = value; 274 } 275 276 /** 277 * Add a new {@link Property} item to the underlying collection. 278 * @param item the item to add 279 * @return {@code true} 280 */ 281 public boolean addProp(Property item) { 282 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 283 if (_props == null) { 284 _props = new LinkedList<>(); 285 } 286 return _props.add(value); 287 } 288 289 /** 290 * Remove the first matching {@link Property} item from the underlying collection. 291 * @param item the item to remove 292 * @return {@code true} if the item was removed or {@code false} otherwise 293 */ 294 public boolean removeProp(Property item) { 295 Property value = ObjectUtils.requireNonNull(item,"item cannot be null"); 296 return _props != null && _props.remove(value); 297 } 298 299 public List<Link> getLinks() { 300 return _links; 301 } 302 303 public void setLinks(List<Link> value) { 304 _links = value; 305 } 306 307 /** 308 * Add a new {@link Link} item to the underlying collection. 309 * @param item the item to add 310 * @return {@code true} 311 */ 312 public boolean addLink(Link item) { 313 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 314 if (_links == null) { 315 _links = new LinkedList<>(); 316 } 317 return _links.add(value); 318 } 319 320 /** 321 * Remove the first matching {@link Link} item from the underlying collection. 322 * @param item the item to remove 323 * @return {@code true} if the item was removed or {@code false} otherwise 324 */ 325 public boolean removeLink(Link item) { 326 Link value = ObjectUtils.requireNonNull(item,"item cannot be null"); 327 return _links != null && _links.remove(value); 328 } 329 330 public MarkupMultiline getRemarks() { 331 return _remarks; 332 } 333 334 public void setRemarks(MarkupMultiline value) { 335 _remarks = value; 336 } 337 338 public MarkupMultiline getMappingDescription() { 339 return _mappingDescription; 340 } 341 342 public void setMappingDescription(MarkupMultiline value) { 343 _mappingDescription = value; 344 } 345 346 public GapSummary getSourceGapSummary() { 347 return _sourceGapSummary; 348 } 349 350 public void setSourceGapSummary(GapSummary value) { 351 _sourceGapSummary = value; 352 } 353 354 public GapSummary getTargetGapSummary() { 355 return _targetGapSummary; 356 } 357 358 public void setTargetGapSummary(GapSummary value) { 359 _targetGapSummary = value; 360 } 361 362 public ConfidenceScore getConfidenceScore() { 363 return _confidenceScore; 364 } 365 366 public void setConfidenceScore(ConfidenceScore value) { 367 _confidenceScore = value; 368 } 369 370 public Coverage getCoverage() { 371 return _coverage; 372 } 373 374 public void setCoverage(Coverage value) { 375 _coverage = value; 376 } 377 378 @Override 379 public String toString() { 380 return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString(); 381 } 382}