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.AllowedValue;
010import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValues;
011import gov.nist.secauto.metaschema.databind.model.annotations.AssemblyConstraints;
012import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly;
013import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag;
014import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs;
015import gov.nist.secauto.metaschema.databind.model.annotations.Index;
016import gov.nist.secauto.metaschema.databind.model.annotations.IsUnique;
017import gov.nist.secauto.metaschema.databind.model.annotations.KeyField;
018import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly;
019import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints;
020import gov.nist.secauto.oscal.lib.model.control.catalog.AbstractCatalog;
021import java.lang.Override;
022import java.lang.String;
023import java.util.LinkedList;
024import java.util.List;
025import java.util.UUID;
026import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
027import org.apache.commons.lang3.builder.ToStringStyle;
028
029/**
030 * A structured, <a href="https://pages.nist.gov/OSCAL/concepts/terminology/#catalog">organized collection</a> of control information.
031 */
032@MetaschemaAssembly(
033    formalName = "Catalog",
034    description = "A structured, [organized collection](https://pages.nist.gov/OSCAL/concepts/terminology/#catalog) of control information.",
035    name = "catalog",
036    moduleClass = OscalCatalogModule.class,
037    rootName = "catalog",
038    remarks = "Catalogs may use one or more `group` objects to subdivide the control contents of a catalog.",
039    valueConstraints = @ValueConstraints(allowedValues = {@AllowedValues(level = IConstraint.Level.ERROR, target = "metadata/prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "resolution-tool", description = "The tool used to produce a resolved profile."), @AllowedValue(value = "source-profile-uuid", description = "The document-level `uuid` of the source profile from which the catalog was produced by [profile resolution](https://pages.nist.gov/OSCAL/concepts/processing/profile-resolution/).")}), @AllowedValues(level = IConstraint.Level.ERROR, target = "metadata/link/@rel", allowOthers = true, values = {@AllowedValue(value = "source-profile", description = "The profile from which the catalog was produced by [profile resolution](https://pages.nist.gov/OSCAL/concepts/processing/profile-resolution/)."), @AllowedValue(value = "source-profile-uuid", description = "The document-level `uuid` of the profile from which the catalog was produced by [profile resolution](https://pages.nist.gov/OSCAL/concepts/processing/profile-resolution/).")})}),
040    modelConstraints = @AssemblyConstraints(index = {@Index(level = IConstraint.Level.ERROR, target = "//part", name = "catalog-parts", keyFields = @KeyField(target = "@id")), @Index(level = IConstraint.Level.ERROR, target = "//prop", name = "catalog-props", keyFields = @KeyField(target = "@uuid")), @Index(level = IConstraint.Level.ERROR, target = "//(control|group|part)", name = "catalog-groups-controls-parts", keyFields = @KeyField(target = "@id")), @Index(level = IConstraint.Level.ERROR, target = "//control", name = "catalog-controls", keyFields = @KeyField(target = "@id")), @Index(level = IConstraint.Level.ERROR, target = "//param", name = "catalog-params", keyFields = @KeyField(target = "@id")), @Index(level = IConstraint.Level.ERROR, target = "//group", name = "catalog-groups", keyFields = @KeyField(target = "@id")), @Index(id = "oscal-catalog-index-metadata-scoped-metadata-role-id", formalName = "In-Scope Role Identifiers", description = "An index of role identifiers that are in-scope for the catalog model.", level = IConstraint.Level.ERROR, target = "metadata/role", name = "index-imports-metadata-role-id", keyFields = @KeyField(target = "@id")), @Index(id = "oscal-catalog-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-catalog-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-catalog-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-catalog-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")}), @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.")})
041)
042public class Catalog extends AbstractCatalog implements IBoundObject {
043  private final IMetaschemaData __metaschemaData;
044
045  /**
046   * "Provides a globally unique means to identify a given catalog instance."
047   */
048  @BoundFlag(
049      formalName = "Catalog Universally Unique Identifier",
050      description = "Provides a globally unique means to identify a given catalog instance.",
051      name = "uuid",
052      required = true,
053      typeAdapter = UuidAdapter.class
054  )
055  private UUID _uuid;
056
057  @BoundAssembly(
058      formalName = "Document Metadata",
059      description = "Provides information about the containing document, and defines concepts that are shared across the document.",
060      useName = "metadata",
061      minOccurs = 1
062  )
063  private Metadata _metadata;
064
065  @BoundAssembly(
066      formalName = "Parameter",
067      description = "Parameters provide a mechanism for the dynamic assignment of value(s) in a control.",
068      useName = "param",
069      maxOccurs = -1,
070      groupAs = @GroupAs(name = "params", inJson = JsonGroupAsBehavior.LIST)
071  )
072  private List<Parameter> _params;
073
074  @BoundAssembly(
075      formalName = "Control",
076      description = "A [structured object](https://pages.nist.gov/OSCAL/concepts/terminology/#control) representing a requirement or guideline, which when implemented will reduce an aspect of risk related to an information system and its information.",
077      useName = "control",
078      maxOccurs = -1,
079      groupAs = @GroupAs(name = "controls", inJson = JsonGroupAsBehavior.LIST)
080  )
081  private List<Control> _controls;
082
083  @BoundAssembly(
084      formalName = "Control Group",
085      description = "A group of controls, or of groups of controls.",
086      useName = "group",
087      maxOccurs = -1,
088      groupAs = @GroupAs(name = "groups", inJson = JsonGroupAsBehavior.LIST)
089  )
090  private List<CatalogGroup> _groups;
091
092  @BoundAssembly(
093      formalName = "Back matter",
094      description = "A collection of resources that may be referenced from within the OSCAL document instance.",
095      useName = "back-matter",
096      remarks = "Back matter including references and resources."
097  )
098  private BackMatter _backMatter;
099
100  public Catalog() {
101    this(null);
102  }
103
104  public Catalog(IMetaschemaData data) {
105    this.__metaschemaData = data;
106  }
107
108  @Override
109  public IMetaschemaData getMetaschemaData() {
110    return __metaschemaData;
111  }
112
113  public UUID getUuid() {
114    return _uuid;
115  }
116
117  public void setUuid(UUID value) {
118    _uuid = value;
119  }
120
121  public Metadata getMetadata() {
122    return _metadata;
123  }
124
125  public void setMetadata(Metadata value) {
126    _metadata = value;
127  }
128
129  public List<Parameter> getParams() {
130    return _params;
131  }
132
133  public void setParams(List<Parameter> value) {
134    _params = value;
135  }
136
137  /**
138   * Add a new {@link Parameter} item to the underlying collection.
139   * @param item the item to add
140   * @return {@code true}
141   */
142  public boolean addParam(Parameter item) {
143    Parameter value = ObjectUtils.requireNonNull(item,"item cannot be null");
144    if (_params == null) {
145      _params = new LinkedList<>();
146    }
147    return _params.add(value);
148  }
149
150  /**
151   * Remove the first matching {@link Parameter} item from the underlying collection.
152   * @param item the item to remove
153   * @return {@code true} if the item was removed or {@code false} otherwise
154   */
155  public boolean removeParam(Parameter item) {
156    Parameter value = ObjectUtils.requireNonNull(item,"item cannot be null");
157    return _params != null && _params.remove(value);
158  }
159
160  public List<Control> getControls() {
161    return _controls;
162  }
163
164  public void setControls(List<Control> value) {
165    _controls = value;
166  }
167
168  /**
169   * Add a new {@link Control} item to the underlying collection.
170   * @param item the item to add
171   * @return {@code true}
172   */
173  public boolean addControl(Control item) {
174    Control value = ObjectUtils.requireNonNull(item,"item cannot be null");
175    if (_controls == null) {
176      _controls = new LinkedList<>();
177    }
178    return _controls.add(value);
179  }
180
181  /**
182   * Remove the first matching {@link Control} item from the underlying collection.
183   * @param item the item to remove
184   * @return {@code true} if the item was removed or {@code false} otherwise
185   */
186  public boolean removeControl(Control item) {
187    Control value = ObjectUtils.requireNonNull(item,"item cannot be null");
188    return _controls != null && _controls.remove(value);
189  }
190
191  public List<CatalogGroup> getGroups() {
192    return _groups;
193  }
194
195  public void setGroups(List<CatalogGroup> value) {
196    _groups = value;
197  }
198
199  /**
200   * Add a new {@link CatalogGroup} item to the underlying collection.
201   * @param item the item to add
202   * @return {@code true}
203   */
204  public boolean addGroup(CatalogGroup item) {
205    CatalogGroup value = ObjectUtils.requireNonNull(item,"item cannot be null");
206    if (_groups == null) {
207      _groups = new LinkedList<>();
208    }
209    return _groups.add(value);
210  }
211
212  /**
213   * Remove the first matching {@link CatalogGroup} item from the underlying collection.
214   * @param item the item to remove
215   * @return {@code true} if the item was removed or {@code false} otherwise
216   */
217  public boolean removeGroup(CatalogGroup item) {
218    CatalogGroup value = ObjectUtils.requireNonNull(item,"item cannot be null");
219    return _groups != null && _groups.remove(value);
220  }
221
222  public BackMatter getBackMatter() {
223    return _backMatter;
224  }
225
226  public void setBackMatter(BackMatter value) {
227    _backMatter = value;
228  }
229
230  @Override
231  public String toString() {
232    return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString();
233  }
234}