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.JsonGroupAsBehavior;
007import gov.nist.secauto.metaschema.core.model.constraint.IConstraint;
008import gov.nist.secauto.metaschema.core.util.ObjectUtils;
009import gov.nist.secauto.metaschema.databind.model.annotations.AssemblyConstraints;
010import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly;
011import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag;
012import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs;
013import gov.nist.secauto.metaschema.databind.model.annotations.Index;
014import gov.nist.secauto.metaschema.databind.model.annotations.IsUnique;
015import gov.nist.secauto.metaschema.databind.model.annotations.KeyField;
016import gov.nist.secauto.metaschema.databind.model.annotations.Let;
017import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly;
018import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints;
019import java.lang.Override;
020import java.lang.String;
021import java.util.LinkedList;
022import java.util.List;
023import java.util.UUID;
024import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
025import org.apache.commons.lang3.builder.ToStringStyle;
026
027/**
028 * A collection of component descriptions, which may optionally be grouped by capability.
029 */
030@MetaschemaAssembly(
031    formalName = "Component Definition",
032    description = "A collection of component descriptions, which may optionally be grouped by capability.",
033    name = "component-definition",
034    moduleClass = OscalComponentDefinitionModule.class,
035    rootName = "component-definition",
036    valueConstraints = @ValueConstraints(lets = @Let(name = "all-imports", target = "import-component-definition ! recurse-depth('doc(resolve-uri(Q{http://csrc.nist.gov/ns/oscal/1.0}resolve-reference(@href)))/component-definition')")),
037    modelConstraints = @AssemblyConstraints(index = {@Index(level = IConstraint.Level.ERROR, target = "component", name = "index-system-component-uuid", keyFields = @KeyField(target = "@uuid"), remarks = "Since multiple `component` entries can be provided, each component must have a unique `uuid`."), @Index(id = "oscal-component-definition-index-metadata-scoped-role-id", formalName = "In-Scope Role Identifiers", description = "An index of role identifiers that are in-scope for the component-definition model. Roles are collected from imported component-definition. For a given role @id, a locally declared role takes precedence over a role that is imported, the role that was last imported.", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/role ! map:entry(@id,.))?*", name = "index-imports-metadata-role-id", keyFields = @KeyField(target = "@id")), @Index(id = "oscal-component-definition-index-metadata-scoped-location-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/location ! map:entry(@uuid,.))?*", name = "index-imports-metadata-location-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-component-definition-index-metadata-scoped-party-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/party ! map:entry(@uuid,.))?*", name = "index-imports-metadata-party-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-component-definition-index-metadata-scoped-party-organization-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports/metadata/party[@type='organization'] ! map:entry(@uuid,.))?*", name = "index-imports-metadata-party-organization-uuid", keyFields = @KeyField(target = "@uuid")), @Index(id = "oscal-component-definition-index-metadata-scoped-property-uuid", level = IConstraint.Level.ERROR, target = "map:merge($all-imports//prop[@uuid] ! map:entry(@uuid,.))?*", name = "index-imports-metadata-property-uuid", keyFields = @KeyField(target = "@uuid"))}, unique = {@IsUnique(id = "unique-component-definition-capability", level = IConstraint.Level.ERROR, target = "capability", keyFields = @KeyField(target = "@uuid"), remarks = "A given `component` must not be referenced more than once within the same `capability`."), @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")}), @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.")})
038)
039public class ComponentDefinition implements IBoundObject {
040  private final IMetaschemaData __metaschemaData;
041
042  /**
043   * "Provides a globally unique means to identify a given component definition instance."
044   */
045  @BoundFlag(
046      formalName = "Component Definition Universally Unique Identifier",
047      description = "Provides a globally unique means to identify a given component definition instance.",
048      name = "uuid",
049      required = true,
050      typeAdapter = UuidAdapter.class
051  )
052  private UUID _uuid;
053
054  @BoundAssembly(
055      formalName = "Document Metadata",
056      description = "Provides information about the containing document, and defines concepts that are shared across the document.",
057      useName = "metadata",
058      minOccurs = 1
059  )
060  private Metadata _metadata;
061
062  @BoundAssembly(
063      formalName = "Import Component Definition",
064      description = "Loads a component definition from another resource.",
065      useName = "import-component-definition",
066      maxOccurs = -1,
067      groupAs = @GroupAs(name = "import-component-definitions", inJson = JsonGroupAsBehavior.LIST)
068  )
069  private List<ImportComponentDefinition> _importComponentDefinitions;
070
071  @BoundAssembly(
072      formalName = "Component",
073      description = "A defined component that can be part of an implemented system.",
074      useName = "component",
075      maxOccurs = -1,
076      groupAs = @GroupAs(name = "components", inJson = JsonGroupAsBehavior.LIST)
077  )
078  private List<DefinedComponent> _components;
079
080  @BoundAssembly(
081      formalName = "Capability",
082      description = "A grouping of other components and/or capabilities.",
083      useName = "capability",
084      maxOccurs = -1,
085      groupAs = @GroupAs(name = "capabilities", inJson = JsonGroupAsBehavior.LIST)
086  )
087  private List<Capability> _capabilities;
088
089  @BoundAssembly(
090      formalName = "Back matter",
091      description = "A collection of resources that may be referenced from within the OSCAL document instance.",
092      useName = "back-matter"
093  )
094  private BackMatter _backMatter;
095
096  public ComponentDefinition() {
097    this(null);
098  }
099
100  public ComponentDefinition(IMetaschemaData data) {
101    this.__metaschemaData = data;
102  }
103
104  @Override
105  public IMetaschemaData getMetaschemaData() {
106    return __metaschemaData;
107  }
108
109  public UUID getUuid() {
110    return _uuid;
111  }
112
113  public void setUuid(UUID value) {
114    _uuid = value;
115  }
116
117  public Metadata getMetadata() {
118    return _metadata;
119  }
120
121  public void setMetadata(Metadata value) {
122    _metadata = value;
123  }
124
125  public List<ImportComponentDefinition> getImportComponentDefinitions() {
126    return _importComponentDefinitions;
127  }
128
129  public void setImportComponentDefinitions(List<ImportComponentDefinition> value) {
130    _importComponentDefinitions = value;
131  }
132
133  /**
134   * Add a new {@link ImportComponentDefinition} item to the underlying collection.
135   * @param item the item to add
136   * @return {@code true}
137   */
138  public boolean addImportComponentDefinition(ImportComponentDefinition item) {
139    ImportComponentDefinition value = ObjectUtils.requireNonNull(item,"item cannot be null");
140    if (_importComponentDefinitions == null) {
141      _importComponentDefinitions = new LinkedList<>();
142    }
143    return _importComponentDefinitions.add(value);
144  }
145
146  /**
147   * Remove the first matching {@link ImportComponentDefinition} item from the underlying collection.
148   * @param item the item to remove
149   * @return {@code true} if the item was removed or {@code false} otherwise
150   */
151  public boolean removeImportComponentDefinition(ImportComponentDefinition item) {
152    ImportComponentDefinition value = ObjectUtils.requireNonNull(item,"item cannot be null");
153    return _importComponentDefinitions != null && _importComponentDefinitions.remove(value);
154  }
155
156  public List<DefinedComponent> getComponents() {
157    return _components;
158  }
159
160  public void setComponents(List<DefinedComponent> value) {
161    _components = value;
162  }
163
164  /**
165   * Add a new {@link DefinedComponent} item to the underlying collection.
166   * @param item the item to add
167   * @return {@code true}
168   */
169  public boolean addComponent(DefinedComponent item) {
170    DefinedComponent value = ObjectUtils.requireNonNull(item,"item cannot be null");
171    if (_components == null) {
172      _components = new LinkedList<>();
173    }
174    return _components.add(value);
175  }
176
177  /**
178   * Remove the first matching {@link DefinedComponent} item from the underlying collection.
179   * @param item the item to remove
180   * @return {@code true} if the item was removed or {@code false} otherwise
181   */
182  public boolean removeComponent(DefinedComponent item) {
183    DefinedComponent value = ObjectUtils.requireNonNull(item,"item cannot be null");
184    return _components != null && _components.remove(value);
185  }
186
187  public List<Capability> getCapabilities() {
188    return _capabilities;
189  }
190
191  public void setCapabilities(List<Capability> value) {
192    _capabilities = value;
193  }
194
195  /**
196   * Add a new {@link Capability} item to the underlying collection.
197   * @param item the item to add
198   * @return {@code true}
199   */
200  public boolean addCapability(Capability item) {
201    Capability value = ObjectUtils.requireNonNull(item,"item cannot be null");
202    if (_capabilities == null) {
203      _capabilities = new LinkedList<>();
204    }
205    return _capabilities.add(value);
206  }
207
208  /**
209   * Remove the first matching {@link Capability} item from the underlying collection.
210   * @param item the item to remove
211   * @return {@code true} if the item was removed or {@code false} otherwise
212   */
213  public boolean removeCapability(Capability item) {
214    Capability value = ObjectUtils.requireNonNull(item,"item cannot be null");
215    return _capabilities != null && _capabilities.remove(value);
216  }
217
218  public BackMatter getBackMatter() {
219    return _backMatter;
220  }
221
222  public void setBackMatter(BackMatter value) {
223    _backMatter = value;
224  }
225
226  @Override
227  public String toString() {
228    return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString();
229  }
230}