001package gov.nist.secauto.oscal.lib.model; 002 003import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter; 004import gov.nist.secauto.metaschema.core.model.IBoundObject; 005import gov.nist.secauto.metaschema.core.model.IMetaschemaData; 006import gov.nist.secauto.metaschema.core.model.constraint.IConstraint; 007import gov.nist.secauto.metaschema.core.util.ObjectUtils; 008import gov.nist.secauto.metaschema.databind.model.annotations.AssemblyConstraints; 009import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly; 010import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag; 011import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs; 012import gov.nist.secauto.metaschema.databind.model.annotations.Index; 013import gov.nist.secauto.metaschema.databind.model.annotations.IsUnique; 014import gov.nist.secauto.metaschema.databind.model.annotations.KeyField; 015import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly; 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.ReflectionToStringBuilder; 022import org.apache.commons.lang3.builder.ToStringStyle; 023 024/** 025 * A collection of relationship-based control and/or control statement mappings. 026 */ 027@MetaschemaAssembly( 028 formalName = "Mapping Collection", 029 description = "A collection of relationship-based control and/or control statement mappings.", 030 name = "mapping-collection", 031 moduleClass = OscalMappingModule.class, 032 rootName = "mapping-collection", 033 remarks = "A mapping collection affirmatively declares the relationships that exist between sets of controls and/or control statements in a source and target. It is expected that inferences can be made based on what is mapped; however, no inferences should be made based on what is not mapped, since it is impossible to quantify how complete or granular a given mapping is.", 034 modelConstraints = @AssemblyConstraints(index = {@Index(id = "oscal-mapping-collection-index-metadata-scoped-role-id", formalName = "In-Scope Role Identifiers", description = "An index of role identifiers that are in-scope for the mapping-collection model.", level = IConstraint.Level.ERROR, target = "metadata/role", name = "index-imports-metadata-role-id", keyFields = @KeyField(target = "@id")), @Index(id = "oscal-mapping-collection-index-metadata-scoped-location-uuid", level = IConstraint.Level.ERROR, target = "metadata/location", name = "index-imports-metadata-location-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-mapping-collection-index-metadata-scoped-party-uuid", level = IConstraint.Level.ERROR, target = "metadata/party", name = "index-imports-metadata-party-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-mapping-collection-index-metadata-scoped-party-organization-uuid", level = IConstraint.Level.ERROR, target = "metadata/party[@type='organization']", name = "index-imports-metadata-party-organization-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-mapping-collection-index-metadata-scoped-property-uuid", level = IConstraint.Level.ERROR, target = ".//prop[@uuid]", name = "index-imports-metadata-property-uuid", keyFields = @KeyField(target = "@uuid"))}, unique = {@IsUnique(id = "oscal-unique-document-id", formalName = "Unique Document Identifier", description = "Ensure all document identifiers have a unique combination of @scheme and value.", level = IConstraint.Level.ERROR, target = "document-id", keyFields = {@KeyField(target = "@scheme"), @KeyField}), @IsUnique(id = "oscal-unique-property-in-context-location", formalName = "Unique Properties", description = "Ensure all properties are unique for a given location using a unique combination of @ns, @name, @class. @group. and @value.", level = IConstraint.Level.ERROR, target = ".//prop", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@name"), @KeyField(target = "@ns"), @KeyField(target = "@class"), @KeyField(target = "@group"), @KeyField(target = "@value")}), @IsUnique(id = "oscal-unique-link-in-context-location", formalName = "Unique Links", description = "Ensure all links are unique for a given location using a unique combination of @href, @rel, and @media-type.", level = IConstraint.Level.ERROR, target = ".//link", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@href"), @KeyField(target = "@rel"), @KeyField(target = "@media-type"), @KeyField(target = "@resource-fragment")}), @IsUnique(id = "oscal-unique-responsibility-in-context-location", formalName = "Unique Responsibilities", description = "Ensure all responsible-roles and responsible-parties are unique for a given location using a unique combination of @role-id and the combination of @party-uuid values.", level = IConstraint.Level.ERROR, target = ".//(responsible-party|responsible-role)", keyFields = {@KeyField(target = "path(..)"), @KeyField(target = "@role-id"), @KeyField(target = "@party-uuid")}, remarks = "Since `responsible-party` and `responsible-role` associate multiple `party-uuid` entries with a single `role-id`, each role-id must be referenced only once.")}) 035) 036public class MappingCollection implements IBoundObject { 037 private final IMetaschemaData __metaschemaData; 038 039 /** 040 * "A globally unique identifier with cross-instance scope for this catalog instance. This UUID should be changed when this document is revised." 041 */ 042 @BoundFlag( 043 formalName = "Mapping Collection Universally Unique Identifier", 044 description = "A globally unique identifier with cross-instance scope for this catalog instance. This UUID should be changed when this document is revised.", 045 name = "uuid", 046 required = true, 047 typeAdapter = UuidAdapter.class 048 ) 049 private UUID _uuid; 050 051 @BoundAssembly( 052 formalName = "Document Metadata", 053 description = "Provides information about the containing document, and defines concepts that are shared across the document.", 054 useName = "metadata", 055 minOccurs = 1 056 ) 057 private Metadata _metadata; 058 059 @BoundAssembly( 060 formalName = "Mapping Provenance", 061 description = "Describes requirements, incompatibilities and gaps that are identified between a target and source in a mapping item.", 062 useName = "provenance", 063 minOccurs = 1 064 ) 065 private MappingProvenance _provenance; 066 067 @BoundAssembly( 068 formalName = "Control Mapping", 069 description = "A mapping between two target resources.", 070 useName = "mapping", 071 minOccurs = 1, 072 maxOccurs = -1, 073 groupAs = @GroupAs(name = "mappings") 074 ) 075 private List<Mapping> _mappings; 076 077 @BoundAssembly( 078 formalName = "Back matter", 079 description = "A collection of resources that may be referenced from within the OSCAL document instance.", 080 useName = "back-matter", 081 remarks = "Back matter including references and resources." 082 ) 083 private BackMatter _backMatter; 084 085 public MappingCollection() { 086 this(null); 087 } 088 089 public MappingCollection(IMetaschemaData data) { 090 this.__metaschemaData = data; 091 } 092 093 @Override 094 public IMetaschemaData getMetaschemaData() { 095 return __metaschemaData; 096 } 097 098 public UUID getUuid() { 099 return _uuid; 100 } 101 102 public void setUuid(UUID value) { 103 _uuid = value; 104 } 105 106 public Metadata getMetadata() { 107 return _metadata; 108 } 109 110 public void setMetadata(Metadata value) { 111 _metadata = value; 112 } 113 114 public MappingProvenance getProvenance() { 115 return _provenance; 116 } 117 118 public void setProvenance(MappingProvenance value) { 119 _provenance = value; 120 } 121 122 public List<Mapping> getMappings() { 123 return _mappings; 124 } 125 126 public void setMappings(List<Mapping> value) { 127 _mappings = value; 128 } 129 130 /** 131 * Add a new {@link Mapping} item to the underlying collection. 132 * @param item the item to add 133 * @return {@code true} 134 */ 135 public boolean addMapping(Mapping item) { 136 Mapping value = ObjectUtils.requireNonNull(item,"item cannot be null"); 137 if (_mappings == null) { 138 _mappings = new LinkedList<>(); 139 } 140 return _mappings.add(value); 141 } 142 143 /** 144 * Remove the first matching {@link Mapping} item from the underlying collection. 145 * @param item the item to remove 146 * @return {@code true} if the item was removed or {@code false} otherwise 147 */ 148 public boolean removeMapping(Mapping item) { 149 Mapping value = ObjectUtils.requireNonNull(item,"item cannot be null"); 150 return _mappings != null && _mappings.remove(value); 151 } 152 153 public BackMatter getBackMatter() { 154 return _backMatter; 155 } 156 157 public void setBackMatter(BackMatter value) { 158 _backMatter = value; 159 } 160 161 @Override 162 public String toString() { 163 return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString(); 164 } 165}