001package gov.nist.secauto.oscal.lib.model;
002
003import gov.nist.secauto.metaschema.core.datatype.adapter.StringAdapter;
004import gov.nist.secauto.metaschema.core.datatype.adapter.TokenAdapter;
005import gov.nist.secauto.metaschema.core.datatype.adapter.UriAdapter;
006import gov.nist.secauto.metaschema.core.datatype.adapter.UuidAdapter;
007import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
008import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultilineAdapter;
009import gov.nist.secauto.metaschema.core.model.IBoundObject;
010import gov.nist.secauto.metaschema.core.model.IMetaschemaData;
011import gov.nist.secauto.metaschema.core.model.JsonGroupAsBehavior;
012import gov.nist.secauto.metaschema.core.model.constraint.IConstraint;
013import gov.nist.secauto.metaschema.core.util.ObjectUtils;
014import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValue;
015import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValues;
016import gov.nist.secauto.metaschema.databind.model.annotations.BoundAssembly;
017import gov.nist.secauto.metaschema.databind.model.annotations.BoundField;
018import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag;
019import gov.nist.secauto.metaschema.databind.model.annotations.GroupAs;
020import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly;
021import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints;
022import java.lang.Override;
023import java.lang.String;
024import java.net.URI;
025import java.util.LinkedList;
026import java.util.List;
027import java.util.UUID;
028import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
029import org.apache.commons.lang3.builder.ToStringStyle;
030
031/**
032 * A relationship-based mapping between a source and target set consisting of members (i.e., controls, control statements) from the respective source and target.
033 */
034@MetaschemaAssembly(
035    formalName = "Mapping Entry",
036    description = "A relationship-based mapping between a source and target set consisting of members (i.e., controls, control statements) from the respective source and target.",
037    name = "map",
038    moduleClass = OscalMappingCommonModule.class
039)
040public class MappingEntry implements IBoundObject {
041  private final IMetaschemaData __metaschemaData;
042
043  /**
044   * "The unique identifier for the mapping entry."
045   */
046  @BoundFlag(
047      formalName = "Mapping Entry Identifier",
048      description = "The unique identifier for the mapping entry.",
049      name = "uuid",
050      required = true,
051      typeAdapter = UuidAdapter.class
052  )
053  private UUID _uuid;
054
055  /**
056   * "A namespace qualifying the relationship's value. This allows different organizations to associate distinct semantics for relationships with the same name."
057   */
058  @BoundFlag(
059      formalName = "Relationship Value Namespace",
060      description = "A namespace qualifying the relationship's value. This allows different organizations to associate distinct semantics for relationships with the same name.",
061      name = "ns",
062      defaultValue = "http://csrc.nist.gov/ns/oscal",
063      typeAdapter = UriAdapter.class,
064      remarks = "This value must be an [absolute URI](https://pages.nist.gov/OSCAL/concepts/uri-use/#absolute-uri) that serves as a [naming system identifier](https://pages.nist.gov/OSCAL/concepts/uri-use/#use-as-a-naming-system-identifier).\n"
065              + "\n"
066              + "When a `ns` is not provided, its value should be assumed to be ` http://csrc.nist.gov/ns/oscal` and the name should be a name defined by the associated OSCAL model."
067  )
068  private URI _ns;
069
070  /**
071   * "The method used for relating controls within the mapping. The supported methods are aligned with the <a href=\"https://doi.org/10.6028/NIST.IR.8477\">NIST Interagency Report (IR) 8477</a>, Section 4.3 Set Theory Relationship Mapping."
072   */
073  @BoundFlag(
074      formalName = "Matching",
075      description = "The method used for relating controls within the mapping. The supported methods are aligned with the [NIST Interagency Report (IR) 8477](https://doi.org/10.6028/NIST.IR.8477), Section 4.3 Set Theory Relationship Mapping.",
076      name = "matching-rationale",
077      typeAdapter = StringAdapter.class,
078      valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, values = {@AllowedValue(value = "syntactic", description = "Syntactic: How similar is the *wording* that expresses the two concepts. This is a word-for-word analysis of the relationship, not an interpretation of the language."), @AllowedValue(value = "semantic", description = "Semantic: How similar are the *meanings* of the two concepts? This involves some interpretation of each concept’s language."), @AllowedValue(value = "functional", description = "Functional: How similar are the *results* of executing the two concepts? This involves understanding what will happen if the two concepts are implemented, performed, or otherwise executed.")}))
079  )
080  private String _matchingRationale;
081
082  @BoundField(
083      formalName = "Mapping Entry Relationship",
084      description = "The relationship type for the mapping entry, which describes the relationship between the effective requirements of the specified source and target sets in the context of the `matching-rationale` method globaly defined in the `provenance` unless overwritten locally in the ` map`. The `relationship` type and the `matching-rationale` must be used together. However, more than one `matching-rationale` method may apply to a `source` and `target` pair.",
085      useName = "relationship",
086      remarks = "For example, consider the CSF 1.1's PR.AC-1, \"Identities and credentials are issued, managed, verified, revoked, and audited for authorized devices, users and processes\", and the Privacy Framework's PR.AC-P1, \"Identities and credentials are issued, managed, verified, and devices.\"\n"
087              + "\n"
088              + "These two requirements have identical wording except for \"users\" versus \"individuals\" and the order of the last few words. With a \\`matching-rationale\\` of syntactic, the relationship type would beintersects with because the two overlap, but each includes content that the other does not. However, with a rationale of semantic, the relationship type would be equal if \"users\" and \"individuals\" have the same meaning in their respective sources, subset if \"users\" was a subset of \"individuals,\" and so on.\n"
089              + "\n"
090              + "When establishing relationships, mapping SHOULD be done at the control statement level where possible. This approach allows for a more accurate relationship.",
091      minOccurs = 1,
092      typeAdapter = TokenAdapter.class,
093      valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, target = ".[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]", values = {@AllowedValue(value = "equivalent-to", description = "The `source` and `target` requirements are similar, although not necessarily identical. The words may differ, but both mapped sets convey similar information with the same effective meaning. This relationship may be reversed, since \\`A equivalent-to B\\` also means that \\`B equivalent-to A\\`. This relationship is less suitable for a *syntactic* `matching-rationale` ."), @AllowedValue(value = "equal-to", description = "The `source` and `target` requirements are the same. Differences in capitalization, spelling, and grammar can be ignored, if these differences do not change the meaning. This relationship may be reversed, since \\`A equal-to B\\` also means that \\`B equal-to A\\`."), @AllowedValue(value = "subset-of", description = "The `source` requirements are a subset of ` target` requirements. In other words, `target` contains all `source`requirements and aditional others. This relationship may be reversed as a \\`superset-of\\`, since \\`A subset-of B\\` also means that \\`B superset-of A\\`."), @AllowedValue(value = "superset-of", description = "The `source` requirements are a superset of `target` requirements. In other words, ` source` contains all `target`requirements and aditional others. This relationship may be reversed as a \\`subset-of\\`, since \\`A superset-of B\\` also means that \\`B subset-of A\\`."), @AllowedValue(value = "intersects-with", description = "The `source` and `target` requirements have some overlap, but each includes content that the other does not. This relationship may be reversed, since \\`A intersects-with B\\` also means that \\`B intersects-with A\\`. A mapping at statement level could result on `relationships` mapping that allows for more inference than using this relationship type."), @AllowedValue(value = "no-relationship", description = "The `source` and `target` requirements are not related; their content does not overlap. This relation is introduced not with the intention to support exhaustiv mapping of all requirements and statements that have no overlap, but rather to support edge cases such is the need to tailor a ` relationship` in the context of a component or system to better align with the implementation and configuration of the respective component or system. Also, this `relationship` is provided in support of the [NIST IR 8477](https://doi.org/10.6028/NIST.IR.8477).")}))
094  )
095  private String _relationship;
096
097  @BoundAssembly(
098      formalName = "Mapping Entry Item (source or target)",
099      description = "A specific edge within a source or target that is the subject of a mapping.",
100      useName = "source",
101      minOccurs = 1,
102      maxOccurs = -1,
103      groupAs = @GroupAs(name = "sources", inJson = JsonGroupAsBehavior.LIST)
104  )
105  private List<MappingItem> _sources;
106
107  @BoundAssembly(
108      formalName = "Mapping Entry Item (source or target)",
109      description = "A specific edge within a source or target that is the subject of a mapping.",
110      useName = "target",
111      minOccurs = 1,
112      maxOccurs = -1,
113      groupAs = @GroupAs(name = "targets", inJson = JsonGroupAsBehavior.LIST)
114  )
115  private List<MappingItem> _targets;
116
117  @BoundAssembly(
118      formalName = "Relationship Qualifier",
119      description = "Describes requirements, incompatibilities and gaps that are identified between a target and source in a mapping item.",
120      useName = "qualifier",
121      maxOccurs = -1,
122      groupAs = @GroupAs(name = "qualifiers", inJson = JsonGroupAsBehavior.LIST)
123  )
124  private List<QualifierItem> _qualifiers;
125
126  @BoundField(
127      formalName = "Confidence Score",
128      description = "This records either a string category or a decimal value from 0-1 representing a percentage. Both of these values describe an estimation of the author's confidence that this mapping is correct and accurate.",
129      useName = "confidence-score"
130  )
131  private ConfidenceScore _confidenceScore;
132
133  @BoundField(
134      formalName = "Coverage",
135      description = "A decimal value from 0-1, representing the percentage coverage of the targets by the sources.",
136      useName = "coverage"
137  )
138  private Coverage _coverage;
139
140  @BoundAssembly(
141      formalName = "Property",
142      description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
143      useName = "prop",
144      maxOccurs = -1,
145      groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST)
146  )
147  private List<Property> _props;
148
149  @BoundAssembly(
150      formalName = "Link",
151      description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
152      useName = "link",
153      maxOccurs = -1,
154      groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST)
155  )
156  private List<Link> _links;
157
158  @BoundField(
159      formalName = "Remarks",
160      description = "Additional commentary about the containing object.",
161      useName = "remarks",
162      typeAdapter = MarkupMultilineAdapter.class
163  )
164  private MarkupMultiline _remarks;
165
166  public MappingEntry() {
167    this(null);
168  }
169
170  public MappingEntry(IMetaschemaData data) {
171    this.__metaschemaData = data;
172  }
173
174  @Override
175  public IMetaschemaData getMetaschemaData() {
176    return __metaschemaData;
177  }
178
179  public UUID getUuid() {
180    return _uuid;
181  }
182
183  public void setUuid(UUID value) {
184    _uuid = value;
185  }
186
187  public URI getNs() {
188    return _ns;
189  }
190
191  public void setNs(URI value) {
192    _ns = value;
193  }
194
195  public String getMatchingRationale() {
196    return _matchingRationale;
197  }
198
199  public void setMatchingRationale(String value) {
200    _matchingRationale = value;
201  }
202
203  public String getRelationship() {
204    return _relationship;
205  }
206
207  public void setRelationship(String value) {
208    _relationship = value;
209  }
210
211  public List<MappingItem> getSources() {
212    return _sources;
213  }
214
215  public void setSources(List<MappingItem> value) {
216    _sources = value;
217  }
218
219  /**
220   * Add a new {@link MappingItem} item to the underlying collection.
221   * @param item the item to add
222   * @return {@code true}
223   */
224  public boolean addSource(MappingItem item) {
225    MappingItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
226    if (_sources == null) {
227      _sources = new LinkedList<>();
228    }
229    return _sources.add(value);
230  }
231
232  /**
233   * Remove the first matching {@link MappingItem} item from the underlying collection.
234   * @param item the item to remove
235   * @return {@code true} if the item was removed or {@code false} otherwise
236   */
237  public boolean removeSource(MappingItem item) {
238    MappingItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
239    return _sources != null && _sources.remove(value);
240  }
241
242  public List<MappingItem> getTargets() {
243    return _targets;
244  }
245
246  public void setTargets(List<MappingItem> value) {
247    _targets = value;
248  }
249
250  /**
251   * Add a new {@link MappingItem} item to the underlying collection.
252   * @param item the item to add
253   * @return {@code true}
254   */
255  public boolean addTarget(MappingItem item) {
256    MappingItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
257    if (_targets == null) {
258      _targets = new LinkedList<>();
259    }
260    return _targets.add(value);
261  }
262
263  /**
264   * Remove the first matching {@link MappingItem} item from the underlying collection.
265   * @param item the item to remove
266   * @return {@code true} if the item was removed or {@code false} otherwise
267   */
268  public boolean removeTarget(MappingItem item) {
269    MappingItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
270    return _targets != null && _targets.remove(value);
271  }
272
273  public List<QualifierItem> getQualifiers() {
274    return _qualifiers;
275  }
276
277  public void setQualifiers(List<QualifierItem> value) {
278    _qualifiers = value;
279  }
280
281  /**
282   * Add a new {@link QualifierItem} item to the underlying collection.
283   * @param item the item to add
284   * @return {@code true}
285   */
286  public boolean addQualifier(QualifierItem item) {
287    QualifierItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
288    if (_qualifiers == null) {
289      _qualifiers = new LinkedList<>();
290    }
291    return _qualifiers.add(value);
292  }
293
294  /**
295   * Remove the first matching {@link QualifierItem} item from the underlying collection.
296   * @param item the item to remove
297   * @return {@code true} if the item was removed or {@code false} otherwise
298   */
299  public boolean removeQualifier(QualifierItem item) {
300    QualifierItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
301    return _qualifiers != null && _qualifiers.remove(value);
302  }
303
304  public ConfidenceScore getConfidenceScore() {
305    return _confidenceScore;
306  }
307
308  public void setConfidenceScore(ConfidenceScore value) {
309    _confidenceScore = value;
310  }
311
312  public Coverage getCoverage() {
313    return _coverage;
314  }
315
316  public void setCoverage(Coverage value) {
317    _coverage = value;
318  }
319
320  public List<Property> getProps() {
321    return _props;
322  }
323
324  public void setProps(List<Property> value) {
325    _props = value;
326  }
327
328  /**
329   * Add a new {@link Property} item to the underlying collection.
330   * @param item the item to add
331   * @return {@code true}
332   */
333  public boolean addProp(Property item) {
334    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
335    if (_props == null) {
336      _props = new LinkedList<>();
337    }
338    return _props.add(value);
339  }
340
341  /**
342   * Remove the first matching {@link Property} item from the underlying collection.
343   * @param item the item to remove
344   * @return {@code true} if the item was removed or {@code false} otherwise
345   */
346  public boolean removeProp(Property item) {
347    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
348    return _props != null && _props.remove(value);
349  }
350
351  public List<Link> getLinks() {
352    return _links;
353  }
354
355  public void setLinks(List<Link> value) {
356    _links = value;
357  }
358
359  /**
360   * Add a new {@link Link} item to the underlying collection.
361   * @param item the item to add
362   * @return {@code true}
363   */
364  public boolean addLink(Link item) {
365    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
366    if (_links == null) {
367      _links = new LinkedList<>();
368    }
369    return _links.add(value);
370  }
371
372  /**
373   * Remove the first matching {@link Link} item from the underlying collection.
374   * @param item the item to remove
375   * @return {@code true} if the item was removed or {@code false} otherwise
376   */
377  public boolean removeLink(Link item) {
378    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
379    return _links != null && _links.remove(value);
380  }
381
382  public MarkupMultiline getRemarks() {
383    return _remarks;
384  }
385
386  public void setRemarks(MarkupMultiline value) {
387    _remarks = value;
388  }
389
390  @Override
391  public String toString() {
392    return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString();
393  }
394}