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}