001// Generated from: ../../../../../../../../oscal/src/metaschema/oscal_control-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.TokenAdapter;
006import dev.metaschema.core.datatype.adapter.UriAdapter;
007import dev.metaschema.core.datatype.markup.MarkupLine;
008import dev.metaschema.core.datatype.markup.MarkupLineAdapter;
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 dev.metaschema.oscal.lib.model.control.AbstractPart;
025import edu.umd.cs.findbugs.annotations.NonNull;
026import edu.umd.cs.findbugs.annotations.Nullable;
027import java.net.URI;
028import java.util.LinkedList;
029import java.util.List;
030import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
031import org.apache.commons.lang3.builder.ToStringStyle;
032
033/**
034 * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.
035 */
036@MetaschemaAssembly(
037    formalName = "Part",
038    description = "An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.",
039    name = "part",
040    moduleClass = OscalControlCommonModule.class,
041    remarks = "A `part` provides for logical partitioning of prose, and can be thought of as a grouping structure (e.g., section). A `part` can have child parts allowing for arbitrary nesting of prose content (e.g., statement hierarchy). A `part` can contain `prop` objects that allow for enriching prose text with structured name/value information.\n"
042            + "\n"
043            + "A `part` can be assigned an optional `id`, which allows references to this part from within a catalog, or within an instance of another OSCAL model that has a need to reference the part. Examples of where part referencing is used in OSCAL include:\n"
044            + "\n"
045            + "- Referencing a part by id to tailor (make modifications to) a control statement in a profile.\n"
046            + "- Referencing a control statement represented by a part in a system security plan implemented-requirement where a statement-level response is desired.\n"
047            + "\n"
048            + "Use of `part` and `prop` provides for a wide degree of extensibility within the OSCAL catalog model. The optional `ns` provides a means to qualify a part's `name`, allowing for organization-specific vocabularies to be defined with clear semantics. Any organization that extends OSCAL in this way should consistently assign a `ns` value that represents the organization, making a given namespace qualified `name` unique to that organization. This allows the combination of `ns` and `name` to always be unique and unambiguous, even when mixed with extensions from other organizations. Each organization is responsible for governance of their own extensions, and is strongly encouraged to publish their extensions as standards to their user community. If no `ns` is provided, the name is expected to be in the \"OSCAL\" namespace.\n"
049            + "\n"
050            + "To ensure a `ns` is unique to an organization and naming conflicts are avoided, a URI containing a DNS or other globally defined organization name should be used. For example, if FedRAMP and DoD both extend OSCAL, FedRAMP will use the `ns` `http://fedramp.gov/ns/oscal`, while DoD might use the `ns` `https://defense.gov` for any organization specific `name`.\n"
051            + "\n"
052            + "Tools that process OSCAL content are not required to interpret unrecognized OSCAL extensions; however, OSCAL compliant tools should not modify or remove unrecognized extensions, unless there is a compelling reason to do so, such as data sensitivity.",
053    valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(id = "oscal-part-prop-name", level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "label", description = "A human-readable label for the parent context, which may be rendered in place of the actual identifier for some use cases."), @AllowedValue(value = "sort-id", description = "An alternative identifier, whose value is easily sortable among other such values in the document."), @AllowedValue(value = "alt-identifier", description = "An alternate or aliased identifier for the parent context.")}))
054)
055public class ControlPart extends AbstractPart implements IBoundObject {
056  private final IMetaschemaData __metaschemaData;
057
058  /**
059   * A unique identifier for the part.
060   */
061  @BoundFlag(
062      formalName = "Part Identifier",
063      description = "A unique identifier for the part.",
064      name = "id",
065      typeAdapter = TokenAdapter.class,
066      remarks = "While a part is not required to have an id, it is often desirable for an identifier to be provided, which allows the part to be referenced elsewhere in OSCAL document instances. For this reason, it is RECOMMENDED to provide a part identifier."
067  )
068  private String _id;
069
070  /**
071   * A textual label that uniquely identifies the part's semantic type, which exists in a value space qualified by the <code>ns</code>.
072   */
073  @BoundFlag(
074      formalName = "Part Name",
075      description = "A textual label that uniquely identifies the part's semantic type, which exists in a value space qualified by the `ns`.",
076      name = "name",
077      required = true,
078      typeAdapter = TokenAdapter.class
079  )
080  private String _name;
081
082  /**
083   * An optional namespace qualifying the part's <code>name</code>. This allows different organizations to associate distinct semantics with the same name.
084   */
085  @BoundFlag(
086      formalName = "Part Namespace",
087      description = "An optional namespace qualifying the part's `name`. This allows different organizations to associate distinct semantics with the same name.",
088      name = "ns",
089      defaultValue = "http://csrc.nist.gov/ns/oscal",
090      typeAdapter = UriAdapter.class,
091      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"
092              + "\n"
093              + "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."
094  )
095  private URI _ns;
096
097  /**
098   * An optional textual providing a sub-type or characterization of the part's <code>name</code>, or a category to which the part belongs.
099   */
100  @BoundFlag(
101      formalName = "Part Class",
102      description = "An optional textual providing a sub-type or characterization of the part's `name`, or a category to which the part belongs.",
103      name = "class",
104      typeAdapter = TokenAdapter.class,
105      remarks = "One use of this flag is to distinguish or discriminate between the semantics of multiple parts of the same control with the same `name` and `ns` (since even within a given namespace it can be useful to overload a name).\n"
106              + "\n"
107              + "A `class` can be used in validation rules to express extra constraints over named items of a specific `class` value.\n"
108              + "\n"
109              + "A `class` can also be used in an OSCAL profile as a means to target an alteration to control content."
110  )
111  private String _clazz;
112
113  /**
114   * An optional name given to the part, which may be used by a tool for display and navigation.
115   */
116  @BoundField(
117      formalName = "Part Title",
118      description = "An optional name given to the part, which may be used by a tool for display and navigation.",
119      useName = "title",
120      typeAdapter = MarkupLineAdapter.class
121  )
122  private MarkupLine _title;
123
124  /**
125   * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.
126   */
127  @BoundAssembly(
128      formalName = "Property",
129      description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
130      useName = "prop",
131      maxOccurs = -1,
132      groupAs = @GroupAs(name = "props", inJson = JsonGroupAsBehavior.LIST)
133  )
134  private List<Property> _props;
135
136  /**
137   * Permits multiple paragraphs, lists, tables etc.
138   */
139  @BoundField(
140      formalName = "Part Text",
141      description = "Permits multiple paragraphs, lists, tables etc.",
142      useName = "prose",
143      inXmlWrapped = false,
144      typeAdapter = MarkupMultilineAdapter.class
145  )
146  private MarkupMultiline _prose;
147
148  /**
149   * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.
150   */
151  @BoundAssembly(
152      formalName = "Part",
153      description = "An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.",
154      useName = "part",
155      maxOccurs = -1,
156      groupAs = @GroupAs(name = "parts", inJson = JsonGroupAsBehavior.LIST)
157  )
158  private List<ControlPart> _parts;
159
160  /**
161   * A reference to a local or remote resource, that has a specific relation to the containing object.
162   */
163  @BoundAssembly(
164      formalName = "Link",
165      description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
166      useName = "link",
167      maxOccurs = -1,
168      groupAs = @GroupAs(name = "links", inJson = JsonGroupAsBehavior.LIST)
169  )
170  private List<Link> _links;
171
172  /**
173   * Constructs a new {@code dev.metaschema.oscal.lib.model.ControlPart} instance with no metadata.
174   */
175  public ControlPart() {
176    this(null);
177  }
178
179  /**
180   * Constructs a new {@code dev.metaschema.oscal.lib.model.ControlPart} instance with the specified metadata.
181   *
182   * @param data
183   *           the metaschema data, or {@code null} if none
184   */
185  public ControlPart(IMetaschemaData data) {
186    this.__metaschemaData = data;
187  }
188
189  @Override
190  public IMetaschemaData getMetaschemaData() {
191    return __metaschemaData;
192  }
193
194  /**
195   * Get the "{@literal Part Identifier}".
196   *
197   * <p>
198   * A unique identifier for the part.
199   *
200   * @return the id value, or {@code null} if not set
201   */
202  @Nullable
203  public String getId() {
204    return _id;
205  }
206
207  /**
208   * Set the "{@literal Part Identifier}".
209   *
210   * <p>
211   * A unique identifier for the part.
212   *
213   * @param value
214   *           the id value to set, or {@code null} to clear
215   */
216  public void setId(@Nullable String value) {
217    _id = value;
218  }
219
220  /**
221   * Get the "{@literal Part Name}".
222   *
223   * <p>
224   * A textual label that uniquely identifies the part's semantic type, which exists in a value space qualified by the <code>ns</code>.
225   *
226   * @return the name value
227   */
228  @NonNull
229  public String getName() {
230    return _name;
231  }
232
233  /**
234   * Set the "{@literal Part Name}".
235   *
236   * <p>
237   * A textual label that uniquely identifies the part's semantic type, which exists in a value space qualified by the <code>ns</code>.
238   *
239   * @param value
240   *           the name value to set
241   */
242  public void setName(@NonNull String value) {
243    _name = value;
244  }
245
246  /**
247   * Get the "{@literal Part Namespace}".
248   *
249   * <p>
250   * An optional namespace qualifying the part's <code>name</code>. This allows different organizations to associate distinct semantics with the same name.
251   *
252   * @return the ns value, or {@code null} if not set
253   */
254  @Nullable
255  public URI getNs() {
256    return _ns;
257  }
258
259  /**
260   * Set the "{@literal Part Namespace}".
261   *
262   * <p>
263   * An optional namespace qualifying the part's <code>name</code>. This allows different organizations to associate distinct semantics with the same name.
264   *
265   * @param value
266   *           the ns value to set, or {@code null} to clear
267   */
268  public void setNs(@Nullable URI value) {
269    _ns = value;
270  }
271
272  /**
273   * Get the "{@literal Part Class}".
274   *
275   * <p>
276   * An optional textual providing a sub-type or characterization of the part's <code>name</code>, or a category to which the part belongs.
277   *
278   * @return the class value, or {@code null} if not set
279   */
280  @Nullable
281  public String getClazz() {
282    return _clazz;
283  }
284
285  /**
286   * Set the "{@literal Part Class}".
287   *
288   * <p>
289   * An optional textual providing a sub-type or characterization of the part's <code>name</code>, or a category to which the part belongs.
290   *
291   * @param value
292   *           the class value to set, or {@code null} to clear
293   */
294  public void setClazz(@Nullable String value) {
295    _clazz = value;
296  }
297
298  /**
299   * Get the "{@literal Part Title}".
300   *
301   * <p>
302   * An optional name given to the part, which may be used by a tool for display and navigation.
303   *
304   * @return the title value, or {@code null} if not set
305   */
306  @Nullable
307  public MarkupLine getTitle() {
308    return _title;
309  }
310
311  /**
312   * Set the "{@literal Part Title}".
313   *
314   * <p>
315   * An optional name given to the part, which may be used by a tool for display and navigation.
316   *
317   * @param value
318   *           the title value to set, or {@code null} to clear
319   */
320  public void setTitle(@Nullable MarkupLine value) {
321    _title = value;
322  }
323
324  /**
325   * Get the "{@literal Property}".
326   *
327   * <p>
328   * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.
329   *
330   * @return the prop value
331   */
332  @NonNull
333  public List<Property> getProps() {
334    if (_props == null) {
335      _props = new LinkedList<>();
336    }
337    return ObjectUtils.notNull(_props);
338  }
339
340  /**
341   * Set the "{@literal Property}".
342   *
343   * <p>
344   * An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.
345   *
346   * @param value
347   *           the prop value to set
348   */
349  public void setProps(@NonNull List<Property> value) {
350    _props = value;
351  }
352
353  /**
354   * Add a new {@link Property} item to the underlying collection.
355   * @param item the item to add
356   * @return {@code true}
357   */
358  public boolean addProp(Property item) {
359    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
360    if (_props == null) {
361      _props = new LinkedList<>();
362    }
363    return _props.add(value);
364  }
365
366  /**
367   * Remove the first matching {@link Property} item from the underlying collection.
368   * @param item the item to remove
369   * @return {@code true} if the item was removed or {@code false} otherwise
370   */
371  public boolean removeProp(Property item) {
372    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
373    return _props != null && _props.remove(value);
374  }
375
376  /**
377   * Get the "{@literal Part Text}".
378   *
379   * <p>
380   * Permits multiple paragraphs, lists, tables etc.
381   *
382   * @return the prose value, or {@code null} if not set
383   */
384  @Nullable
385  public MarkupMultiline getProse() {
386    return _prose;
387  }
388
389  /**
390   * Set the "{@literal Part Text}".
391   *
392   * <p>
393   * Permits multiple paragraphs, lists, tables etc.
394   *
395   * @param value
396   *           the prose value to set, or {@code null} to clear
397   */
398  public void setProse(@Nullable MarkupMultiline value) {
399    _prose = value;
400  }
401
402  /**
403   * Get the "{@literal Part}".
404   *
405   * <p>
406   * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.
407   *
408   * @return the part value
409   */
410  @NonNull
411  public List<ControlPart> getParts() {
412    if (_parts == null) {
413      _parts = new LinkedList<>();
414    }
415    return ObjectUtils.notNull(_parts);
416  }
417
418  /**
419   * Set the "{@literal Part}".
420   *
421   * <p>
422   * An annotated, markup-based textual element of a control's or catalog group's definition, or a child of another part.
423   *
424   * @param value
425   *           the part value to set
426   */
427  public void setParts(@NonNull List<ControlPart> value) {
428    _parts = value;
429  }
430
431  /**
432   * Add a new {@link ControlPart} item to the underlying collection.
433   * @param item the item to add
434   * @return {@code true}
435   */
436  public boolean addPart(ControlPart item) {
437    ControlPart value = ObjectUtils.requireNonNull(item,"item cannot be null");
438    if (_parts == null) {
439      _parts = new LinkedList<>();
440    }
441    return _parts.add(value);
442  }
443
444  /**
445   * Remove the first matching {@link ControlPart} item from the underlying collection.
446   * @param item the item to remove
447   * @return {@code true} if the item was removed or {@code false} otherwise
448   */
449  public boolean removePart(ControlPart item) {
450    ControlPart value = ObjectUtils.requireNonNull(item,"item cannot be null");
451    return _parts != null && _parts.remove(value);
452  }
453
454  /**
455   * Get the "{@literal Link}".
456   *
457   * <p>
458   * A reference to a local or remote resource, that has a specific relation to the containing object.
459   *
460   * @return the link value
461   */
462  @NonNull
463  public List<Link> getLinks() {
464    if (_links == null) {
465      _links = new LinkedList<>();
466    }
467    return ObjectUtils.notNull(_links);
468  }
469
470  /**
471   * Set the "{@literal Link}".
472   *
473   * <p>
474   * A reference to a local or remote resource, that has a specific relation to the containing object.
475   *
476   * @param value
477   *           the link value to set
478   */
479  public void setLinks(@NonNull List<Link> value) {
480    _links = value;
481  }
482
483  /**
484   * Add a new {@link Link} item to the underlying collection.
485   * @param item the item to add
486   * @return {@code true}
487   */
488  public boolean addLink(Link item) {
489    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
490    if (_links == null) {
491      _links = new LinkedList<>();
492    }
493    return _links.add(value);
494  }
495
496  /**
497   * Remove the first matching {@link Link} item from the underlying collection.
498   * @param item the item to remove
499   * @return {@code true} if the item was removed or {@code false} otherwise
500   */
501  public boolean removeLink(Link item) {
502    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
503    return _links != null && _links.remove(value);
504  }
505
506  @Override
507  public String toString() {
508    return ObjectUtils.notNull(new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString());
509  }
510}