001// Generated from: ../../../../../../../../oscal/src/metaschema/oscal_mapping-common_metaschema.xml
002// Do not edit - changes will be lost when regenerated.
003package dev.metaschema.oscal.lib.model;
004
005import dev.metaschema.core.datatype.adapter.StringAdapter;
006import dev.metaschema.core.datatype.adapter.TokenAdapter;
007import dev.metaschema.core.datatype.adapter.UriAdapter;
008import dev.metaschema.core.datatype.adapter.UuidAdapter;
009import dev.metaschema.core.datatype.markup.MarkupMultiline;
010import dev.metaschema.core.datatype.markup.MarkupMultilineAdapter;
011import dev.metaschema.core.model.IBoundObject;
012import dev.metaschema.core.model.IMetaschemaData;
013import dev.metaschema.core.model.JsonGroupAsBehavior;
014import dev.metaschema.core.model.constraint.IConstraint;
015import dev.metaschema.core.util.ObjectUtils;
016import dev.metaschema.databind.model.annotations.AllowedValue;
017import dev.metaschema.databind.model.annotations.AllowedValues;
018import dev.metaschema.databind.model.annotations.BoundAssembly;
019import dev.metaschema.databind.model.annotations.BoundField;
020import dev.metaschema.databind.model.annotations.BoundFlag;
021import dev.metaschema.databind.model.annotations.GroupAs;
022import dev.metaschema.databind.model.annotations.MetaschemaAssembly;
023import dev.metaschema.databind.model.annotations.ValueConstraints;
024import edu.umd.cs.findbugs.annotations.NonNull;
025import edu.umd.cs.findbugs.annotations.Nullable;
026import java.net.URI;
027import java.util.LinkedList;
028import java.util.List;
029import java.util.UUID;
030import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
031import org.apache.commons.lang3.builder.ToStringStyle;
032
033/**
034 * A relationship-based mapping between a source and target set consisting of members (i.e., controls, control statements) from the respective source and target.
035 */
036@MetaschemaAssembly(
037    formalName = "Mapping Entry",
038    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.",
039    name = "map",
040    moduleClass = OscalMappingCommonModule.class
041)
042public class MappingEntry implements IBoundObject {
043  private final IMetaschemaData __metaschemaData;
044
045  /**
046   * The unique identifier for the mapping entry.
047   */
048  @BoundFlag(
049      formalName = "Mapping Entry Identifier",
050      description = "The unique identifier for the mapping entry.",
051      name = "uuid",
052      required = true,
053      typeAdapter = UuidAdapter.class
054  )
055  private UUID _uuid;
056
057  /**
058   * A namespace qualifying the relationship's value. This allows different organizations to associate distinct semantics for relationships with the same name.
059   */
060  @BoundFlag(
061      formalName = "Relationship Value Namespace",
062      description = "A namespace qualifying the relationship's value. This allows different organizations to associate distinct semantics for relationships with the same name.",
063      name = "ns",
064      defaultValue = "http://csrc.nist.gov/ns/oscal",
065      typeAdapter = UriAdapter.class,
066      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"
067              + "\n"
068              + "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."
069  )
070  private URI _ns;
071
072  /**
073   * 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.
074   */
075  @BoundFlag(
076      formalName = "Matching",
077      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.",
078      name = "matching-rationale",
079      typeAdapter = StringAdapter.class,
080      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.")}))
081  )
082  private String _matchingRationale;
083
084  /**
085   * 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 <code>matching-rationale</code> method globaly defined in the <code>provenance</code> unless overwritten locally in the <code> map</code>. The <code>relationship</code> type and the <code>matching-rationale</code> must be used together. However, more than one <code>matching-rationale</code> method may apply to a <code>source</code> and <code>target</code> pair.
086   */
087  @BoundField(
088      formalName = "Mapping Entry Relationship",
089      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.",
090      useName = "relationship",
091      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"
092              + "\n"
093              + "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"
094              + "\n"
095              + "When establishing relationships, mapping SHOULD be done at the control statement level where possible. This approach allows for a more accurate relationship.",
096      minOccurs = 1,
097      typeAdapter = TokenAdapter.class,
098      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).")}))
099  )
100  private String _relationship;
101
102  /**
103   * A specific edge within a source or target that is the subject of a mapping.
104   */
105  @BoundAssembly(
106      formalName = "Mapping Entry Item (source or target)",
107      description = "A specific edge within a source or target that is the subject of a mapping.",
108      useName = "source",
109      minOccurs = 1,
110      maxOccurs = -1,
111      groupAs = @GroupAs(name = "sources", inJson = JsonGroupAsBehavior.LIST)
112  )
113  private List<MappingItem> _sources;
114
115  /**
116   * A specific edge within a source or target that is the subject of a mapping.
117   */
118  @BoundAssembly(
119      formalName = "Mapping Entry Item (source or target)",
120      description = "A specific edge within a source or target that is the subject of a mapping.",
121      useName = "target",
122      minOccurs = 1,
123      maxOccurs = -1,
124      groupAs = @GroupAs(name = "targets", inJson = JsonGroupAsBehavior.LIST)
125  )
126  private List<MappingItem> _targets;
127
128  /**
129   * Describes requirements, incompatibilities and gaps that are identified between a target and source in a mapping item.
130   */
131  @BoundAssembly(
132      formalName = "Relationship Qualifier",
133      description = "Describes requirements, incompatibilities and gaps that are identified between a target and source in a mapping item.",
134      useName = "qualifier",
135      maxOccurs = -1,
136      groupAs = @GroupAs(name = "qualifiers", inJson = JsonGroupAsBehavior.LIST)
137  )
138  private List<QualifierItem> _qualifiers;
139
140  /**
141   * 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.
142   */
143  @BoundField(
144      formalName = "Confidence Score",
145      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.",
146      useName = "confidence-score"
147  )
148  private ConfidenceScore _confidenceScore;
149
150  /**
151   * A decimal value from 0-1, representing the percentage coverage of the targets by the sources.
152   */
153  @BoundField(
154      formalName = "Coverage",
155      description = "A decimal value from 0-1, representing the percentage coverage of the targets by the sources.",
156      useName = "coverage"
157  )
158  private Coverage _coverage;
159
160  /**
161   * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.
162   */
163  @BoundAssembly(
164      formalName = "Property",
165      description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
166      useName = "prop",
167      maxOccurs = -1,
168      groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST)
169  )
170  private List<Property> _props;
171
172  /**
173   * A reference to a local or remote resource, that has a specific relation to the containing object.
174   */
175  @BoundAssembly(
176      formalName = "Link",
177      description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
178      useName = "link",
179      maxOccurs = -1,
180      groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST)
181  )
182  private List<Link> _links;
183
184  /**
185   * Additional commentary about the containing object.
186   */
187  @BoundField(
188      formalName = "Remarks",
189      description = "Additional commentary about the containing object.",
190      useName = "remarks",
191      typeAdapter = MarkupMultilineAdapter.class
192  )
193  private MarkupMultiline _remarks;
194
195  /**
196   * Constructs a new {@code dev.metaschema.oscal.lib.model.MappingEntry} instance with no metadata.
197   */
198  public MappingEntry() {
199    this(null);
200  }
201
202  /**
203   * Constructs a new {@code dev.metaschema.oscal.lib.model.MappingEntry} instance with the specified metadata.
204   *
205   * @param data
206   *           the metaschema data, or {@code null} if none
207   */
208  public MappingEntry(IMetaschemaData data) {
209    this.__metaschemaData = data;
210  }
211
212  @Override
213  public IMetaschemaData getMetaschemaData() {
214    return __metaschemaData;
215  }
216
217  /**
218   * Get the "{@literal Mapping Entry Identifier}".
219   *
220   * <p>
221   * The unique identifier for the mapping entry.
222   *
223   * @return the uuid value
224   */
225  @NonNull
226  public UUID getUuid() {
227    return _uuid;
228  }
229
230  /**
231   * Set the "{@literal Mapping Entry Identifier}".
232   *
233   * <p>
234   * The unique identifier for the mapping entry.
235   *
236   * @param value
237   *           the uuid value to set
238   */
239  public void setUuid(@NonNull UUID value) {
240    _uuid = value;
241  }
242
243  /**
244   * Get the "{@literal Relationship Value Namespace}".
245   *
246   * <p>
247   * A namespace qualifying the relationship's value. This allows different organizations to associate distinct semantics for relationships with the same name.
248   *
249   * @return the ns value, or {@code null} if not set
250   */
251  @Nullable
252  public URI getNs() {
253    return _ns;
254  }
255
256  /**
257   * Set the "{@literal Relationship Value Namespace}".
258   *
259   * <p>
260   * A namespace qualifying the relationship's value. This allows different organizations to associate distinct semantics for relationships with the same name.
261   *
262   * @param value
263   *           the ns value to set, or {@code null} to clear
264   */
265  public void setNs(@Nullable URI value) {
266    _ns = value;
267  }
268
269  /**
270   * Get the "{@literal Matching}".
271   *
272   * <p>
273   * 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.
274   *
275   * @return the matching-rationale value, or {@code null} if not set
276   */
277  @Nullable
278  public String getMatchingRationale() {
279    return _matchingRationale;
280  }
281
282  /**
283   * Set the "{@literal Matching}".
284   *
285   * <p>
286   * 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.
287   *
288   * @param value
289   *           the matching-rationale value to set, or {@code null} to clear
290   */
291  public void setMatchingRationale(@Nullable String value) {
292    _matchingRationale = value;
293  }
294
295  /**
296   * Get the "{@literal Mapping Entry Relationship}".
297   *
298   * <p>
299   * 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 <code>matching-rationale</code> method globaly defined in the <code>provenance</code> unless overwritten locally in the <code> map</code>. The <code>relationship</code> type and the <code>matching-rationale</code> must be used together. However, more than one <code>matching-rationale</code> method may apply to a <code>source</code> and <code>target</code> pair.
300   *
301   * @return the relationship value
302   */
303  @NonNull
304  public String getRelationship() {
305    return _relationship;
306  }
307
308  /**
309   * Set the "{@literal Mapping Entry Relationship}".
310   *
311   * <p>
312   * 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 <code>matching-rationale</code> method globaly defined in the <code>provenance</code> unless overwritten locally in the <code> map</code>. The <code>relationship</code> type and the <code>matching-rationale</code> must be used together. However, more than one <code>matching-rationale</code> method may apply to a <code>source</code> and <code>target</code> pair.
313   *
314   * @param value
315   *           the relationship value to set
316   */
317  public void setRelationship(@NonNull String value) {
318    _relationship = value;
319  }
320
321  /**
322   * Get the "{@literal Mapping Entry Item (source or target)}".
323   *
324   * <p>
325   * A specific edge within a source or target that is the subject of a mapping.
326   *
327   * @return the source value
328   */
329  @NonNull
330  public List<MappingItem> getSources() {
331    if (_sources == null) {
332      _sources = new LinkedList<>();
333    }
334    return ObjectUtils.notNull(_sources);
335  }
336
337  /**
338   * Set the "{@literal Mapping Entry Item (source or target)}".
339   *
340   * <p>
341   * A specific edge within a source or target that is the subject of a mapping.
342   *
343   * @param value
344   *           the source value to set
345   */
346  public void setSources(@NonNull List<MappingItem> value) {
347    _sources = value;
348  }
349
350  /**
351   * Add a new {@link MappingItem} item to the underlying collection.
352   * @param item the item to add
353   * @return {@code true}
354   */
355  public boolean addSource(MappingItem item) {
356    MappingItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
357    if (_sources == null) {
358      _sources = new LinkedList<>();
359    }
360    return _sources.add(value);
361  }
362
363  /**
364   * Remove the first matching {@link MappingItem} item from the underlying collection.
365   * @param item the item to remove
366   * @return {@code true} if the item was removed or {@code false} otherwise
367   */
368  public boolean removeSource(MappingItem item) {
369    MappingItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
370    return _sources != null && _sources.remove(value);
371  }
372
373  /**
374   * Get the "{@literal Mapping Entry Item (source or target)}".
375   *
376   * <p>
377   * A specific edge within a source or target that is the subject of a mapping.
378   *
379   * @return the target value
380   */
381  @NonNull
382  public List<MappingItem> getTargets() {
383    if (_targets == null) {
384      _targets = new LinkedList<>();
385    }
386    return ObjectUtils.notNull(_targets);
387  }
388
389  /**
390   * Set the "{@literal Mapping Entry Item (source or target)}".
391   *
392   * <p>
393   * A specific edge within a source or target that is the subject of a mapping.
394   *
395   * @param value
396   *           the target value to set
397   */
398  public void setTargets(@NonNull List<MappingItem> value) {
399    _targets = value;
400  }
401
402  /**
403   * Add a new {@link MappingItem} item to the underlying collection.
404   * @param item the item to add
405   * @return {@code true}
406   */
407  public boolean addTarget(MappingItem item) {
408    MappingItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
409    if (_targets == null) {
410      _targets = new LinkedList<>();
411    }
412    return _targets.add(value);
413  }
414
415  /**
416   * Remove the first matching {@link MappingItem} item from the underlying collection.
417   * @param item the item to remove
418   * @return {@code true} if the item was removed or {@code false} otherwise
419   */
420  public boolean removeTarget(MappingItem item) {
421    MappingItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
422    return _targets != null && _targets.remove(value);
423  }
424
425  /**
426   * Get the "{@literal Relationship Qualifier}".
427   *
428   * <p>
429   * Describes requirements, incompatibilities and gaps that are identified between a target and source in a mapping item.
430   *
431   * @return the qualifier value
432   */
433  @NonNull
434  public List<QualifierItem> getQualifiers() {
435    if (_qualifiers == null) {
436      _qualifiers = new LinkedList<>();
437    }
438    return ObjectUtils.notNull(_qualifiers);
439  }
440
441  /**
442   * Set the "{@literal Relationship Qualifier}".
443   *
444   * <p>
445   * Describes requirements, incompatibilities and gaps that are identified between a target and source in a mapping item.
446   *
447   * @param value
448   *           the qualifier value to set
449   */
450  public void setQualifiers(@NonNull List<QualifierItem> value) {
451    _qualifiers = value;
452  }
453
454  /**
455   * Add a new {@link QualifierItem} item to the underlying collection.
456   * @param item the item to add
457   * @return {@code true}
458   */
459  public boolean addQualifier(QualifierItem item) {
460    QualifierItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
461    if (_qualifiers == null) {
462      _qualifiers = new LinkedList<>();
463    }
464    return _qualifiers.add(value);
465  }
466
467  /**
468   * Remove the first matching {@link QualifierItem} item from the underlying collection.
469   * @param item the item to remove
470   * @return {@code true} if the item was removed or {@code false} otherwise
471   */
472  public boolean removeQualifier(QualifierItem item) {
473    QualifierItem value = ObjectUtils.requireNonNull(item,"item cannot be null");
474    return _qualifiers != null && _qualifiers.remove(value);
475  }
476
477  /**
478   * Get the "{@literal Confidence Score}".
479   *
480   * <p>
481   * 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.
482   *
483   * @return the confidence-score value, or {@code null} if not set
484   */
485  @Nullable
486  public ConfidenceScore getConfidenceScore() {
487    return _confidenceScore;
488  }
489
490  /**
491   * Set the "{@literal Confidence Score}".
492   *
493   * <p>
494   * 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.
495   *
496   * @param value
497   *           the confidence-score value to set, or {@code null} to clear
498   */
499  public void setConfidenceScore(@Nullable ConfidenceScore value) {
500    _confidenceScore = value;
501  }
502
503  /**
504   * Get the "{@literal Coverage}".
505   *
506   * <p>
507   * A decimal value from 0-1, representing the percentage coverage of the targets by the sources.
508   *
509   * @return the coverage value, or {@code null} if not set
510   */
511  @Nullable
512  public Coverage getCoverage() {
513    return _coverage;
514  }
515
516  /**
517   * Set the "{@literal Coverage}".
518   *
519   * <p>
520   * A decimal value from 0-1, representing the percentage coverage of the targets by the sources.
521   *
522   * @param value
523   *           the coverage value to set, or {@code null} to clear
524   */
525  public void setCoverage(@Nullable Coverage value) {
526    _coverage = value;
527  }
528
529  /**
530   * Get the "{@literal Property}".
531   *
532   * <p>
533   * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.
534   *
535   * @return the prop value
536   */
537  @NonNull
538  public List<Property> getProps() {
539    if (_props == null) {
540      _props = new LinkedList<>();
541    }
542    return ObjectUtils.notNull(_props);
543  }
544
545  /**
546   * Set the "{@literal Property}".
547   *
548   * <p>
549   * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.
550   *
551   * @param value
552   *           the prop value to set
553   */
554  public void setProps(@NonNull List<Property> value) {
555    _props = value;
556  }
557
558  /**
559   * Add a new {@link Property} item to the underlying collection.
560   * @param item the item to add
561   * @return {@code true}
562   */
563  public boolean addProp(Property item) {
564    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
565    if (_props == null) {
566      _props = new LinkedList<>();
567    }
568    return _props.add(value);
569  }
570
571  /**
572   * Remove the first matching {@link Property} item from the underlying collection.
573   * @param item the item to remove
574   * @return {@code true} if the item was removed or {@code false} otherwise
575   */
576  public boolean removeProp(Property item) {
577    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
578    return _props != null && _props.remove(value);
579  }
580
581  /**
582   * Get the "{@literal Link}".
583   *
584   * <p>
585   * A reference to a local or remote resource, that has a specific relation to the containing object.
586   *
587   * @return the link value
588   */
589  @NonNull
590  public List<Link> getLinks() {
591    if (_links == null) {
592      _links = new LinkedList<>();
593    }
594    return ObjectUtils.notNull(_links);
595  }
596
597  /**
598   * Set the "{@literal Link}".
599   *
600   * <p>
601   * A reference to a local or remote resource, that has a specific relation to the containing object.
602   *
603   * @param value
604   *           the link value to set
605   */
606  public void setLinks(@NonNull List<Link> value) {
607    _links = value;
608  }
609
610  /**
611   * Add a new {@link Link} item to the underlying collection.
612   * @param item the item to add
613   * @return {@code true}
614   */
615  public boolean addLink(Link item) {
616    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
617    if (_links == null) {
618      _links = new LinkedList<>();
619    }
620    return _links.add(value);
621  }
622
623  /**
624   * Remove the first matching {@link Link} item from the underlying collection.
625   * @param item the item to remove
626   * @return {@code true} if the item was removed or {@code false} otherwise
627   */
628  public boolean removeLink(Link item) {
629    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
630    return _links != null && _links.remove(value);
631  }
632
633  /**
634   * Get the "{@literal Remarks}".
635   *
636   * <p>
637   * Additional commentary about the containing object.
638   *
639   * @return the remarks value, or {@code null} if not set
640   */
641  @Nullable
642  public MarkupMultiline getRemarks() {
643    return _remarks;
644  }
645
646  /**
647   * Set the "{@literal Remarks}".
648   *
649   * <p>
650   * Additional commentary about the containing object.
651   *
652   * @param value
653   *           the remarks value to set, or {@code null} to clear
654   */
655  public void setRemarks(@Nullable MarkupMultiline value) {
656    _remarks = value;
657  }
658
659  @Override
660  public String toString() {
661    return ObjectUtils.notNull(new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString());
662  }
663}