001package gov.nist.secauto.oscal.lib.model;
002
003import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValue;
004import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValues;
005import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly;
006import gov.nist.secauto.metaschema.binding.model.annotations.BoundField;
007import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue;
008import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag;
009import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs;
010import gov.nist.secauto.metaschema.binding.model.annotations.IndexHasKey;
011import gov.nist.secauto.metaschema.binding.model.annotations.KeyField;
012import gov.nist.secauto.metaschema.binding.model.annotations.Matches;
013import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly;
014import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints;
015import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior;
016import gov.nist.secauto.metaschema.model.common.constraint.IConstraint;
017import gov.nist.secauto.metaschema.model.common.datatype.adapter.UriAdapter;
018import gov.nist.secauto.metaschema.model.common.datatype.adapter.UriReferenceAdapter;
019import gov.nist.secauto.metaschema.model.common.datatype.adapter.UuidAdapter;
020import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine;
021import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter;
022import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultiline;
023import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter;
024import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
025import java.lang.Override;
026import java.lang.String;
027import java.util.LinkedList;
028import java.util.List;
029import java.util.UUID;
030import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle;
031import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
032
033/**
034 * A graphic that provides a visual representation the system, or some aspect of it.
035 */
036@MetaschemaAssembly(
037    formalName = "Diagram",
038    description = "A graphic that provides a visual representation the system, or some aspect of it.",
039    name = "diagram",
040    metaschema = OscalSspMetaschema.class,
041    remarks = "A diagram must include a `link` with a rel value of \"diagram\", who's href references a remote URI or an internal reference within this document containing the diagram."
042)
043@ValueConstraints(
044    allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, target = "link/@rel", allowOthers = true, values = @AllowedValue(value = "diagram", description = "A reference to the diagram image.")),
045    indexHasKey = @IndexHasKey(level = IConstraint.Level.ERROR, target = "link[@rel='diagram' and starts-with(@href,'#')]", indexName = "index-back-matter-resource", keyFields = @KeyField(target = "@href", pattern = "#(.*)")),
046    matches = {
047        @Matches(level = IConstraint.Level.ERROR, target = "link[@rel='diagram']/@href[starts-with(.,'#')]", typeAdapter = UriReferenceAdapter.class),
048        @Matches(level = IConstraint.Level.ERROR, target = "link[@rel='diagram']/@href[not(starts-with(.,'#'))]", typeAdapter = UriAdapter.class)
049    }
050)
051public class Diagram {
052  @BoundFlag(
053      formalName = "Diagram ID",
054      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 diagram elsewhere in [this or other OSCAL instances](https://pages.nist.gov/OSCAL/concepts/identifier-use/#ssp-identifiers). The locally defined *UUID* of the `diagram` 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 subject across revisions of the document.",
055      useName = "uuid",
056      required = true,
057      typeAdapter = UuidAdapter.class
058  )
059  private UUID _uuid;
060
061  /**
062   * "A summary of the diagram."
063   */
064  @BoundField(
065      formalName = "Diagram Description",
066      description = "A summary of the diagram.",
067      useName = "description",
068      remarks = "This description is intended to be used as alternate text to support compliance with requirements from [Section 508 of the United States Workforce Rehabilitation Act of 1973](https://www.section508.gov/manage/laws-and-policies)."
069  )
070  @BoundFieldValue(
071      typeAdapter = MarkupMultilineAdapter.class
072  )
073  private MarkupMultiline _description;
074
075  @BoundAssembly(
076      formalName = "Property",
077      description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
078      useName = "prop",
079      maxOccurs = -1
080  )
081  @GroupAs(
082      name = "props",
083      inJson = JsonGroupAsBehavior.LIST
084  )
085  private List<Property> _props;
086
087  @BoundAssembly(
088      formalName = "Link",
089      description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
090      useName = "link",
091      maxOccurs = -1
092  )
093  @GroupAs(
094      name = "links",
095      inJson = JsonGroupAsBehavior.LIST
096  )
097  private List<Link> _links;
098
099  /**
100   * "A brief caption to annotate the diagram."
101   */
102  @BoundField(
103      formalName = "Caption",
104      description = "A brief caption to annotate the diagram.",
105      useName = "caption"
106  )
107  @BoundFieldValue(
108      typeAdapter = MarkupLineAdapter.class
109  )
110  private MarkupLine _caption;
111
112  @BoundField(
113      formalName = "Remarks",
114      description = "Additional commentary about the containing object.",
115      useName = "remarks"
116  )
117  @BoundFieldValue(
118      typeAdapter = MarkupMultilineAdapter.class
119  )
120  private MarkupMultiline _remarks;
121
122  public Diagram() {
123  }
124
125  public UUID getUuid() {
126    return _uuid;
127  }
128
129  public void setUuid(UUID value) {
130    _uuid = value;
131  }
132
133  public MarkupMultiline getDescription() {
134    return _description;
135  }
136
137  public void setDescription(MarkupMultiline value) {
138    _description = value;
139  }
140
141  public List<Property> getProps() {
142    return _props;
143  }
144
145  public void setProps(List<Property> value) {
146    _props = value;
147  }
148
149  /**
150   * Add a new {@link Property} item to the underlying collection.
151   * @param item the item to add
152   * @return {@code true}
153   */
154  public boolean addProp(Property item) {
155    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
156    if (_props == null) {
157      _props = new LinkedList<>();
158    }
159    return _props.add(value);
160  }
161
162  /**
163   * Remove the first matching {@link Property} item from the underlying collection.
164   * @param item the item to remove
165   * @return {@code true} if the item was removed or {@code false} otherwise
166   */
167  public boolean removeProp(Property item) {
168    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
169    return _props == null ? false : _props.remove(value);
170  }
171
172  public List<Link> getLinks() {
173    return _links;
174  }
175
176  public void setLinks(List<Link> value) {
177    _links = value;
178  }
179
180  /**
181   * Add a new {@link Link} item to the underlying collection.
182   * @param item the item to add
183   * @return {@code true}
184   */
185  public boolean addLink(Link item) {
186    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
187    if (_links == null) {
188      _links = new LinkedList<>();
189    }
190    return _links.add(value);
191  }
192
193  /**
194   * Remove the first matching {@link Link} item from the underlying collection.
195   * @param item the item to remove
196   * @return {@code true} if the item was removed or {@code false} otherwise
197   */
198  public boolean removeLink(Link item) {
199    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
200    return _links == null ? false : _links.remove(value);
201  }
202
203  public MarkupLine getCaption() {
204    return _caption;
205  }
206
207  public void setCaption(MarkupLine value) {
208    _caption = value;
209  }
210
211  public MarkupMultiline getRemarks() {
212    return _remarks;
213  }
214
215  public void setRemarks(MarkupMultiline value) {
216    _remarks = value;
217  }
218
219  @Override
220  public String toString() {
221    return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
222  }
223}