Metadata.java

package gov.nist.secauto.oscal.lib.model;

import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValue;
import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValues;
import gov.nist.secauto.metaschema.binding.model.annotations.AssemblyConstraints;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundField;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue;
import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag;
import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs;
import gov.nist.secauto.metaschema.binding.model.annotations.HasCardinality;
import gov.nist.secauto.metaschema.binding.model.annotations.Index;
import gov.nist.secauto.metaschema.binding.model.annotations.IndexHasKey;
import gov.nist.secauto.metaschema.binding.model.annotations.IsUnique;
import gov.nist.secauto.metaschema.binding.model.annotations.KeyField;
import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly;
import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaField;
import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaFieldValue;
import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints;
import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior;
import gov.nist.secauto.metaschema.model.common.XmlGroupAsBehavior;
import gov.nist.secauto.metaschema.model.common.constraint.IConstraint;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.DateTimeWithTZAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.EmailAddressAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.StringAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.TokenAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.UriAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.adapter.UuidAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultiline;
import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter;
import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
import gov.nist.secauto.oscal.lib.model.metadata.AbstractMetadata;
import java.lang.Override;
import java.lang.String;
import java.net.URI;
import java.time.ZonedDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;

/**
 * Provides information about the containing document, and defines concepts that are shared across the document.
 */
@MetaschemaAssembly(
    formalName = "Document Metadata",
    description = "Provides information about the containing document, and defines concepts that are shared across the document.",
    name = "metadata",
    metaschema = OscalMetadataMetaschema.class,
    remarks = "All OSCAL documents use the same metadata structure, that provides a consistent way of expressing OSCAL document metadata across all OSCAL models. The metadata section also includes declarations of individual objects (i.e., roles, location, parties) that may be referenced within and across linked OSCAL documents.\n"
            + "\n"
            + "The metadata in an OSCAL document has few required fields, representing only the bare minimum data needed to differentiate one instance from another. Tools and users creating OSCAL documents may choose to use any of the optional fields, as well as extension mechanisms (e.g., properties, links) to go beyond this minimum to suit their use cases.\n"
            + "\n"
            + "A publisher of OSCAL content can use the `published`, `last-modified`, and `version` fields to establish information about an individual in a sequence of successive revisions of a given OSCAL-based publication. The metadata for a previous revision can be represented as a `revision` within this object. Links may also be provided using the `predecessor-version` and `successor-version` link relations to provide for direct access to the related resource. These relations can be provided as a link child of this object or as `link` within a given `revision`.\n"
            + "\n"
            + "A `responsible-party` entry in this context refers to roles and parties that have responsibility relative to the production, review, publication, and use of the containing document."
)
@ValueConstraints(
    allowedValues = {
        @AllowedValues(id = "allowed-metadata-responsibe-party-role-ids", level = IConstraint.Level.ERROR, target = "responsible-party/@role-id", allowOthers = true, values = {@AllowedValue(value = "creator", description = "Indicates the person or organization that created this content."), @AllowedValue(value = "prepared-by", description = "Indicates the person or organization that prepared this content."), @AllowedValue(value = "prepared-for", description = "Indicates the person or organization for which this content was created."), @AllowedValue(value = "content-approver", description = "Indicates the person or organization responsible for all content represented in the \"document\"."), @AllowedValue(value = "contact", description = "Indicates the person or organization to contact for questions or support related to this content.")}),
        @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = @AllowedValue(value = "keywords", description = "The value identifies a comma-seperated listing of keywords associated with this content. These keywords may be used as search terms for indexing and other applications.")),
        @AllowedValues(level = IConstraint.Level.ERROR, target = "link/@rel", allowOthers = true, values = {@AllowedValue(value = "canonical", description = "The link identifies the authoritative location for this resource. Defined by [RFC 6596](https://tools.ietf.org/html/rfc6596)."), @AllowedValue(value = "alternate", description = "The link identifies an alternative location or format for this resource. Defined by [the HTML Living Standard](https://html.spec.whatwg.org/multipage/links.html#linkTypes)"), @AllowedValue(value = "latest-version", description = "This link identifies a resource containing the latest version in the version history. Defined by [RFC 5829](https://tools.ietf.org/html/rfc5829)."), @AllowedValue(value = "predecessor-version", description = "This link identifies a resource containing the predecessor version in the version history. Defined by [RFC 5829](https://tools.ietf.org/html/rfc5829)."), @AllowedValue(value = "successor-version", description = "This link identifies a resource containing the predecessor version in the version history. Defined by [RFC 5829](https://tools.ietf.org/html/rfc5829).")})
    }
)
@AssemblyConstraints(
    index = {
        @Index(id = "index-metadata-roles", level = IConstraint.Level.ERROR, target = "role", name = "index-metadata-role-ids", keyFields = @KeyField(target = "@id")),
        @Index(id = "index-metadata-property-uuid", level = IConstraint.Level.ERROR, target = ".//prop", name = "index-metadata-property-uuid", keyFields = @KeyField(target = "@uuid")),
        @Index(id = "index-metadata-role-id", level = IConstraint.Level.ERROR, target = "role", name = "index-metadata-role-id", keyFields = @KeyField(target = "@id")),
        @Index(id = "index-metadata-location-uuid", level = IConstraint.Level.ERROR, target = "location", name = "index-metadata-location-uuid", keyFields = @KeyField(target = "@uuid")),
        @Index(id = "index-metadata-party-uuid", level = IConstraint.Level.ERROR, target = "party", name = "index-metadata-party-uuid", keyFields = @KeyField(target = "@uuid")),
        @Index(id = "index-metadata-party-organizations-uuid", level = IConstraint.Level.ERROR, target = "party[@type='organization']", name = "index-metadata-party-organizations-uuid", keyFields = @KeyField(target = "@uuid"))
    },
    isUnique = {
        @IsUnique(id = "unique-metadata-doc-id", level = IConstraint.Level.ERROR, target = "document-id", keyFields = {@KeyField(target = "@scheme"), @KeyField}),
        @IsUnique(id = "unique-metadata-property", level = IConstraint.Level.ERROR, target = "prop", keyFields = {@KeyField(target = "@name"), @KeyField(target = "@ns"), @KeyField(target = "@class"), @KeyField(target = "@group"), @KeyField(target = "@value")}),
        @IsUnique(id = "unique-metadata-link", level = IConstraint.Level.ERROR, target = "link", keyFields = {@KeyField(target = "@href"), @KeyField(target = "@rel"), @KeyField(target = "@media-type")}),
        @IsUnique(id = "unique-metadata-responsible-party", level = IConstraint.Level.ERROR, target = "responsible-party", keyFields = @KeyField(target = "@role-id"), remarks = "Since `responsible-party` associates multiple `party-uuid` entries with a single `role-id`, each role-id must be referenced only once."),
        @IsUnique(level = IConstraint.Level.ERROR, target = "document-id", keyFields = {@KeyField(target = "@scheme"), @KeyField}, remarks = "The combination of `scheme` and the field value must be unique.")
    }
)
public class Metadata extends AbstractMetadata {
  /**
   * "A name given to the document, which may be used by a tool for display and navigation."
   */
  @BoundField(
      formalName = "Document Title",
      description = "A name given to the document, which may be used by a tool for display and navigation.",
      useName = "title",
      minOccurs = 1
  )
  @BoundFieldValue(
      typeAdapter = MarkupLineAdapter.class
  )
  private MarkupLine _title;

  @BoundField(
      formalName = "Publication Timestamp",
      description = "The date and time the document was last made available.",
      useName = "published"
  )
  @BoundFieldValue(
      typeAdapter = DateTimeWithTZAdapter.class
  )
  private ZonedDateTime _published;

  @BoundField(
      formalName = "Last Modified Timestamp",
      description = "The date and time the document was last stored for later retrieval.",
      useName = "last-modified",
      minOccurs = 1
  )
  @BoundFieldValue(
      typeAdapter = DateTimeWithTZAdapter.class
  )
  private ZonedDateTime _lastModified;

  @BoundField(
      formalName = "Document Version",
      description = "Used to distinguish a specific revision of an OSCAL document from other previous and future versions.",
      useName = "version",
      minOccurs = 1
  )
  private String _version;

  @BoundField(
      formalName = "OSCAL Version",
      description = "The OSCAL model version the document was authored against and will conform to as valid.",
      useName = "oscal-version",
      minOccurs = 1
  )
  private String _oscalVersion;

  /**
   * "An entry in a sequential list of revisions to the containing document, expected to be in reverse chronological order (i.e. latest first)."
   */
  @BoundAssembly(
      formalName = "Revision History Entry",
      description = "An entry in a sequential list of revisions to the containing document, expected to be in reverse chronological order (i.e. latest first).",
      useName = "revision",
      maxOccurs = -1,
      remarks = "While `published`, `last-modified`, and `oscal-version` are not required, values for these entries should be provided if the information is known. A `link` with a `rel` of \"source\" should be provided if the information is known."
  )
  @GroupAs(
      name = "revisions",
      inJson = JsonGroupAsBehavior.LIST,
      inXml = XmlGroupAsBehavior.GROUPED
  )
  private List<Revision> _revisions;

  @BoundField(
      formalName = "Document Identifier",
      description = "A document identifier qualified by an identifier `scheme`.",
      useName = "document-id",
      maxOccurs = -1
  )
  @GroupAs(
      name = "document-ids",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<DocumentId> _documentIds;

  @BoundAssembly(
      formalName = "Property",
      description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
      useName = "prop",
      maxOccurs = -1
  )
  @GroupAs(
      name = "props",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Property> _props;

  @BoundAssembly(
      formalName = "Link",
      description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
      useName = "link",
      maxOccurs = -1
  )
  @GroupAs(
      name = "links",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Link> _links;

  /**
   * "Defines a function, which might be assigned to a party in a specific situation."
   */
  @BoundAssembly(
      formalName = "Role",
      description = "Defines a function, which might be assigned to a party in a specific situation.",
      useName = "role",
      maxOccurs = -1,
      remarks = "Permissible values to be determined closer to the application (e.g. by a receiving authority).\n"
              + "\n"
              + "OSCAL has defined a set of standardized roles for consistent use in OSCAL documents. This allows tools consuming OSCAL content to infer specific semantics when these roles are used. These roles are documented in the specific contexts of their use (e.g., responsible-party, responsible-role). When using such a role, it is necessary to define these roles in this list, which will then allow such a role to be referenced."
  )
  @GroupAs(
      name = "roles",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Role> _roles;

  /**
   * "A physical point of presence, which may be associated with people, organizations, or other concepts within the current or linked OSCAL document."
   */
  @BoundAssembly(
      formalName = "Location",
      description = "A physical point of presence, which may be associated with people, organizations, or other concepts within the current or linked OSCAL document.",
      useName = "location",
      maxOccurs = -1,
      remarks = "An address might be sensitive in nature. In such cases a title, mailing address, email-address, and/or phone number may be used instead."
  )
  @GroupAs(
      name = "locations",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Location> _locations;

  /**
   * "An organization or person, which may be associated with roles or other concepts within the current or linked OSCAL document."
   */
  @BoundAssembly(
      formalName = "Party",
      description = "An organization or person, which may be associated with roles or other concepts within the current or linked OSCAL document.",
      useName = "party",
      maxOccurs = -1,
      remarks = "A party can be optionally associated with either an address or a location. While providing a meaningful location for a party is desired, there are some cases where it might not be possible to provide an exact location or even any location."
  )
  @GroupAs(
      name = "parties",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Party> _parties;

  @BoundAssembly(
      formalName = "Responsible Party",
      description = "A reference to a set of persons and/or organizations that have responsibility for performing the referenced role in the context of the containing object.",
      useName = "responsible-party",
      maxOccurs = -1
  )
  @GroupAs(
      name = "responsible-parties",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<ResponsibleParty> _responsibleParties;

  @BoundAssembly(
      formalName = "Action",
      description = "An action applied by a role within a given party to the content.",
      useName = "action",
      maxOccurs = -1
  )
  @GroupAs(
      name = "actions",
      inJson = JsonGroupAsBehavior.LIST
  )
  private List<Action> _actions;

  @BoundField(
      formalName = "Remarks",
      description = "Additional commentary about the containing object.",
      useName = "remarks"
  )
  @BoundFieldValue(
      typeAdapter = MarkupMultilineAdapter.class
  )
  private MarkupMultiline _remarks;

  public Metadata() {
  }

  public MarkupLine getTitle() {
    return _title;
  }

  public void setTitle(MarkupLine value) {
    _title = value;
  }

  public ZonedDateTime getPublished() {
    return _published;
  }

  public void setPublished(ZonedDateTime value) {
    _published = value;
  }

  public ZonedDateTime getLastModified() {
    return _lastModified;
  }

  public void setLastModified(ZonedDateTime value) {
    _lastModified = value;
  }

  public String getVersion() {
    return _version;
  }

  public void setVersion(String value) {
    _version = value;
  }

  public String getOscalVersion() {
    return _oscalVersion;
  }

  public void setOscalVersion(String value) {
    _oscalVersion = value;
  }

  public List<Revision> getRevisions() {
    return _revisions;
  }

  public void setRevisions(List<Revision> value) {
    _revisions = value;
  }

  /**
   * Add a new {@link Revision} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addRevision(Revision item) {
    Revision value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_revisions == null) {
      _revisions = new LinkedList<>();
    }
    return _revisions.add(value);
  }

  /**
   * Remove the first matching {@link Revision} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeRevision(Revision item) {
    Revision value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _revisions == null ? false : _revisions.remove(value);
  }

  public List<DocumentId> getDocumentIds() {
    return _documentIds;
  }

  public void setDocumentIds(List<DocumentId> value) {
    _documentIds = value;
  }

  /**
   * Add a new {@link DocumentId} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addDocumentId(DocumentId item) {
    DocumentId value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_documentIds == null) {
      _documentIds = new LinkedList<>();
    }
    return _documentIds.add(value);
  }

  /**
   * Remove the first matching {@link DocumentId} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeDocumentId(DocumentId item) {
    DocumentId value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _documentIds == null ? false : _documentIds.remove(value);
  }

  public List<Property> getProps() {
    return _props;
  }

  public void setProps(List<Property> value) {
    _props = value;
  }

  /**
   * Add a new {@link Property} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addProp(Property item) {
    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_props == null) {
      _props = new LinkedList<>();
    }
    return _props.add(value);
  }

  /**
   * Remove the first matching {@link Property} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeProp(Property item) {
    Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _props == null ? false : _props.remove(value);
  }

  public List<Link> getLinks() {
    return _links;
  }

  public void setLinks(List<Link> value) {
    _links = value;
  }

  /**
   * Add a new {@link Link} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addLink(Link item) {
    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_links == null) {
      _links = new LinkedList<>();
    }
    return _links.add(value);
  }

  /**
   * Remove the first matching {@link Link} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeLink(Link item) {
    Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _links == null ? false : _links.remove(value);
  }

  public List<Role> getRoles() {
    return _roles;
  }

  public void setRoles(List<Role> value) {
    _roles = value;
  }

  /**
   * Add a new {@link Role} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addRole(Role item) {
    Role value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_roles == null) {
      _roles = new LinkedList<>();
    }
    return _roles.add(value);
  }

  /**
   * Remove the first matching {@link Role} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeRole(Role item) {
    Role value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _roles == null ? false : _roles.remove(value);
  }

  public List<Location> getLocations() {
    return _locations;
  }

  public void setLocations(List<Location> value) {
    _locations = value;
  }

  /**
   * Add a new {@link Location} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addLocation(Location item) {
    Location value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_locations == null) {
      _locations = new LinkedList<>();
    }
    return _locations.add(value);
  }

  /**
   * Remove the first matching {@link Location} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeLocation(Location item) {
    Location value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _locations == null ? false : _locations.remove(value);
  }

  public List<Party> getParties() {
    return _parties;
  }

  public void setParties(List<Party> value) {
    _parties = value;
  }

  /**
   * Add a new {@link Party} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addParty(Party item) {
    Party value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_parties == null) {
      _parties = new LinkedList<>();
    }
    return _parties.add(value);
  }

  /**
   * Remove the first matching {@link Party} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeParty(Party item) {
    Party value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _parties == null ? false : _parties.remove(value);
  }

  public List<ResponsibleParty> getResponsibleParties() {
    return _responsibleParties;
  }

  public void setResponsibleParties(List<ResponsibleParty> value) {
    _responsibleParties = value;
  }

  /**
   * Add a new {@link ResponsibleParty} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addResponsibleParty(ResponsibleParty item) {
    ResponsibleParty value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_responsibleParties == null) {
      _responsibleParties = new LinkedList<>();
    }
    return _responsibleParties.add(value);
  }

  /**
   * Remove the first matching {@link ResponsibleParty} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeResponsibleParty(ResponsibleParty item) {
    ResponsibleParty value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _responsibleParties == null ? false : _responsibleParties.remove(value);
  }

  public List<Action> getActions() {
    return _actions;
  }

  public void setActions(List<Action> value) {
    _actions = value;
  }

  /**
   * Add a new {@link Action} item to the underlying collection.
   * @param item the item to add
   * @return {@code true}
   */
  public boolean addAction(Action item) {
    Action value = ObjectUtils.requireNonNull(item,"item cannot be null");
    if (_actions == null) {
      _actions = new LinkedList<>();
    }
    return _actions.add(value);
  }

  /**
   * Remove the first matching {@link Action} item from the underlying collection.
   * @param item the item to remove
   * @return {@code true} if the item was removed or {@code false} otherwise
   */
  public boolean removeAction(Action item) {
    Action value = ObjectUtils.requireNonNull(item,"item cannot be null");
    return _actions == null ? false : _actions.remove(value);
  }

  public MarkupMultiline getRemarks() {
    return _remarks;
  }

  public void setRemarks(MarkupMultiline value) {
    _remarks = value;
  }

  @Override
  public String toString() {
    return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
  }

  /**
   * An entry in a sequential list of revisions to the containing document, expected to be in reverse chronological order (i.e. latest first).
   */
  @MetaschemaAssembly(
      formalName = "Revision History Entry",
      description = "An entry in a sequential list of revisions to the containing document, expected to be in reverse chronological order (i.e. latest first).",
      name = "revision",
      metaschema = OscalMetadataMetaschema.class,
      remarks = "While `published`, `last-modified`, and `oscal-version` are not required, values for these entries should be provided if the information is known. A `link` with a `rel` of \"source\" should be provided if the information is known."
  )
  @ValueConstraints(
      allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, target = "link/@rel", allowOthers = true, values = {@AllowedValue(value = "canonical", description = "The link identifies the authoritative location for this resource. Defined by [RFC 6596](https://tools.ietf.org/html/rfc6596)."), @AllowedValue(value = "alternate", description = "The link identifies an alternative location or format for this resource. Defined by [the HTML Living Standard](https://html.spec.whatwg.org/multipage/links.html#linkTypes)"), @AllowedValue(value = "predecessor-version", description = "This link identifies a resource containing the predecessor version in the version history. Defined by [RFC 5829](https://tools.ietf.org/html/rfc5829)."), @AllowedValue(value = "successor-version", description = "This link identifies a resource containing the predecessor version in the version history. Defined by [RFC 5829](https://tools.ietf.org/html/rfc5829)."), @AllowedValue(value = "version-history", description = "This link identifies a resource containing the version history of this document. Defined by [RFC 5829](https://tools.ietf.org/html/rfc5829).")})
  )
  public static class Revision {
    /**
     * "A name given to the document revision, which may be used by a tool for display and navigation."
     */
    @BoundField(
        formalName = "Document Title",
        description = "A name given to the document revision, which may be used by a tool for display and navigation.",
        useName = "title"
    )
    @BoundFieldValue(
        typeAdapter = MarkupLineAdapter.class
    )
    private MarkupLine _title;

    @BoundField(
        formalName = "Publication Timestamp",
        description = "The date and time the document was last made available.",
        useName = "published"
    )
    @BoundFieldValue(
        typeAdapter = DateTimeWithTZAdapter.class
    )
    private ZonedDateTime _published;

    @BoundField(
        formalName = "Last Modified Timestamp",
        description = "The date and time the document was last stored for later retrieval.",
        useName = "last-modified"
    )
    @BoundFieldValue(
        typeAdapter = DateTimeWithTZAdapter.class
    )
    private ZonedDateTime _lastModified;

    @BoundField(
        formalName = "Document Version",
        description = "Used to distinguish a specific revision of an OSCAL document from other previous and future versions.",
        useName = "version",
        minOccurs = 1
    )
    private String _version;

    @BoundField(
        formalName = "OSCAL Version",
        description = "The OSCAL model version the document was authored against and will conform to as valid.",
        useName = "oscal-version"
    )
    private String _oscalVersion;

    @BoundAssembly(
        formalName = "Property",
        description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
        useName = "prop",
        maxOccurs = -1
    )
    @GroupAs(
        name = "props",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Property> _props;

    @BoundAssembly(
        formalName = "Link",
        description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
        useName = "link",
        maxOccurs = -1
    )
    @GroupAs(
        name = "links",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Link> _links;

    @BoundField(
        formalName = "Remarks",
        description = "Additional commentary about the containing object.",
        useName = "remarks"
    )
    @BoundFieldValue(
        typeAdapter = MarkupMultilineAdapter.class
    )
    private MarkupMultiline _remarks;

    public Revision() {
    }

    public MarkupLine getTitle() {
      return _title;
    }

    public void setTitle(MarkupLine value) {
      _title = value;
    }

    public ZonedDateTime getPublished() {
      return _published;
    }

    public void setPublished(ZonedDateTime value) {
      _published = value;
    }

    public ZonedDateTime getLastModified() {
      return _lastModified;
    }

    public void setLastModified(ZonedDateTime value) {
      _lastModified = value;
    }

    public String getVersion() {
      return _version;
    }

    public void setVersion(String value) {
      _version = value;
    }

    public String getOscalVersion() {
      return _oscalVersion;
    }

    public void setOscalVersion(String value) {
      _oscalVersion = value;
    }

    public List<Property> getProps() {
      return _props;
    }

    public void setProps(List<Property> value) {
      _props = value;
    }

    /**
     * Add a new {@link Property} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_props == null) {
        _props = new LinkedList<>();
      }
      return _props.add(value);
    }

    /**
     * Remove the first matching {@link Property} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _props == null ? false : _props.remove(value);
    }

    public List<Link> getLinks() {
      return _links;
    }

    public void setLinks(List<Link> value) {
      _links = value;
    }

    /**
     * Add a new {@link Link} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_links == null) {
        _links = new LinkedList<>();
      }
      return _links.add(value);
    }

    /**
     * Remove the first matching {@link Link} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _links == null ? false : _links.remove(value);
    }

    public MarkupMultiline getRemarks() {
      return _remarks;
    }

    public void setRemarks(MarkupMultiline value) {
      _remarks = value;
    }

    @Override
    public String toString() {
      return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
    }
  }

  /**
   * An organization or person, which may be associated with roles or other concepts within the current or linked OSCAL document.
   */
  @MetaschemaAssembly(
      formalName = "Party",
      description = "An organization or person, which may be associated with roles or other concepts within the current or linked OSCAL document.",
      name = "party",
      metaschema = OscalMetadataMetaschema.class,
      remarks = "A party can be optionally associated with either an address or a location. While providing a meaningful location for a party is desired, there are some cases where it might not be possible to provide an exact location or even any location."
  )
  @ValueConstraints(
      allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "mail-stop", description = "A mail stop associated with the party."), @AllowedValue(value = "office", description = "The name or number of the party's office."), @AllowedValue(value = "job-title", description = "The formal job title of a person.")})
  )
  public static class Party {
    @BoundFlag(
        formalName = "Party Universally Unique Identifier",
        description = "A unique identifier for the party.",
        useName = "uuid",
        required = true,
        typeAdapter = UuidAdapter.class
    )
    private UUID _uuid;

    @BoundFlag(
        formalName = "Party Type",
        description = "A category describing the kind of party the object describes.",
        useName = "type",
        required = true,
        typeAdapter = StringAdapter.class
    )
    @ValueConstraints(
        allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, values = {@AllowedValue(value = "person", description = "A human being regarded as an individual."), @AllowedValue(value = "organization", description = "An organized group of one or more `person` individuals with a specific purpose.")})
    )
    private String _type;

    /**
     * "The full name of the party. This is typically the legal name associated with the party."
     */
    @BoundField(
        formalName = "Party Name",
        description = "The full name of the party. This is typically the legal name associated with the party.",
        useName = "name"
    )
    private String _name;

    /**
     * "A short common name, abbreviation, or acronym for the party."
     */
    @BoundField(
        formalName = "Party Short Name",
        description = "A short common name, abbreviation, or acronym for the party.",
        useName = "short-name"
    )
    private String _shortName;

    /**
     * "An identifier for a person or organization using a designated scheme. e.g. an Open Researcher and Contributor ID (ORCID)."
     */
    @BoundField(
        formalName = "Party External Identifier",
        description = "An identifier for a person or organization using a designated scheme. e.g. an Open Researcher and Contributor ID (ORCID).",
        useName = "external-id",
        maxOccurs = -1
    )
    @GroupAs(
        name = "external-ids",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<ExternalId> _externalIds;

    @BoundAssembly(
        formalName = "Property",
        description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
        useName = "prop",
        maxOccurs = -1
    )
    @GroupAs(
        name = "props",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Property> _props;

    @BoundAssembly(
        formalName = "Link",
        description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
        useName = "link",
        maxOccurs = -1
    )
    @GroupAs(
        name = "links",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Link> _links;

    @BoundField(
        formalName = "Email Address",
        description = "An email address as defined by [RFC 5322 Section 3.4.1](https://tools.ietf.org/html/rfc5322#section-3.4.1).",
        useName = "email-address",
        maxOccurs = -1,
        remarks = "This is a contact email associated with the party."
    )
    @BoundFieldValue(
        typeAdapter = EmailAddressAdapter.class
    )
    @GroupAs(
        name = "email-addresses",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<String> _emailAddresses;

    @BoundField(
        formalName = "Telephone Number",
        description = "A telephone service number as defined by [ITU-T E.164](https://www.itu.int/rec/T-REC-E.164-201011-I/en).",
        useName = "telephone-number",
        maxOccurs = -1,
        remarks = "A phone number used to contact the party."
    )
    @GroupAs(
        name = "telephone-numbers",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<TelephoneNumber> _telephoneNumbers;

    @BoundAssembly(
        formalName = "Address",
        description = "A postal address for the location.",
        useName = "address",
        maxOccurs = -1
    )
    @GroupAs(
        name = "addresses",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Address> _addresses;

    @BoundField(
        formalName = "Location Universally Unique Identifier Reference",
        description = "Reference to a location by UUID.",
        useName = "location-uuid",
        maxOccurs = -1
    )
    @BoundFieldValue(
        typeAdapter = UuidAdapter.class
    )
    @ValueConstraints(
        indexHasKey = @IndexHasKey(level = IConstraint.Level.ERROR, indexName = "index-metadata-location-uuid", keyFields = @KeyField)
    )
    @GroupAs(
        name = "location-uuids",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<UUID> _locationUuids;

    /**
     * "A reference to another <code>party</code> by UUID, typically an organization, that this subject is associated with."
     */
    @BoundField(
        formalName = "Organizational Affiliation",
        description = "A reference to another `party` by UUID, typically an organization, that this subject is associated with.",
        useName = "member-of-organization",
        maxOccurs = -1,
        remarks = "Since the reference target of an organizational affiliation must be another `party` (whether further qualified as person or organization) as inidcated by its `uuid`. As a [machine-oriented](https://pages.nist.gov/OSCAL/concepts/identifier-use/#machine-oriented) identifier with uniqueness across document and trans-document scope, this `uuid` value is sufficient to reference the data item locally or globally across related documents, e.g., in an imported OSCAL instance.\n"
                + "\n"
                + "Parties of both the `person` or `organization` type can be associated with an organization using the `member-of-organization`."
    )
    @BoundFieldValue(
        typeAdapter = UuidAdapter.class
    )
    @ValueConstraints(
        indexHasKey = @IndexHasKey(level = IConstraint.Level.ERROR, indexName = "index-metadata-party-organizations-uuid", keyFields = @KeyField)
    )
    @GroupAs(
        name = "member-of-organizations",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<UUID> _memberOfOrganizations;

    @BoundField(
        formalName = "Remarks",
        description = "Additional commentary about the containing object.",
        useName = "remarks"
    )
    @BoundFieldValue(
        typeAdapter = MarkupMultilineAdapter.class
    )
    private MarkupMultiline _remarks;

    public Party() {
    }

    public UUID getUuid() {
      return _uuid;
    }

    public void setUuid(UUID value) {
      _uuid = value;
    }

    public String getType() {
      return _type;
    }

    public void setType(String value) {
      _type = value;
    }

    public String getName() {
      return _name;
    }

    public void setName(String value) {
      _name = value;
    }

    public String getShortName() {
      return _shortName;
    }

    public void setShortName(String value) {
      _shortName = value;
    }

    public List<ExternalId> getExternalIds() {
      return _externalIds;
    }

    public void setExternalIds(List<ExternalId> value) {
      _externalIds = value;
    }

    /**
     * Add a new {@link ExternalId} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addExternalId(ExternalId item) {
      ExternalId value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_externalIds == null) {
        _externalIds = new LinkedList<>();
      }
      return _externalIds.add(value);
    }

    /**
     * Remove the first matching {@link ExternalId} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeExternalId(ExternalId item) {
      ExternalId value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _externalIds == null ? false : _externalIds.remove(value);
    }

    public List<Property> getProps() {
      return _props;
    }

    public void setProps(List<Property> value) {
      _props = value;
    }

    /**
     * Add a new {@link Property} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_props == null) {
        _props = new LinkedList<>();
      }
      return _props.add(value);
    }

    /**
     * Remove the first matching {@link Property} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _props == null ? false : _props.remove(value);
    }

    public List<Link> getLinks() {
      return _links;
    }

    public void setLinks(List<Link> value) {
      _links = value;
    }

    /**
     * Add a new {@link Link} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_links == null) {
        _links = new LinkedList<>();
      }
      return _links.add(value);
    }

    /**
     * Remove the first matching {@link Link} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _links == null ? false : _links.remove(value);
    }

    public List<String> getEmailAddresses() {
      return _emailAddresses;
    }

    public void setEmailAddresses(List<String> value) {
      _emailAddresses = value;
    }

    /**
     * Add a new {@link String} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addEmailAddress(String item) {
      String value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_emailAddresses == null) {
        _emailAddresses = new LinkedList<>();
      }
      return _emailAddresses.add(value);
    }

    /**
     * Remove the first matching {@link String} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeEmailAddress(String item) {
      String value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _emailAddresses == null ? false : _emailAddresses.remove(value);
    }

    public List<TelephoneNumber> getTelephoneNumbers() {
      return _telephoneNumbers;
    }

    public void setTelephoneNumbers(List<TelephoneNumber> value) {
      _telephoneNumbers = value;
    }

    /**
     * Add a new {@link TelephoneNumber} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addTelephoneNumber(TelephoneNumber item) {
      TelephoneNumber value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_telephoneNumbers == null) {
        _telephoneNumbers = new LinkedList<>();
      }
      return _telephoneNumbers.add(value);
    }

    /**
     * Remove the first matching {@link TelephoneNumber} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeTelephoneNumber(TelephoneNumber item) {
      TelephoneNumber value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _telephoneNumbers == null ? false : _telephoneNumbers.remove(value);
    }

    public List<Address> getAddresses() {
      return _addresses;
    }

    public void setAddresses(List<Address> value) {
      _addresses = value;
    }

    /**
     * Add a new {@link Address} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addAddress(Address item) {
      Address value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_addresses == null) {
        _addresses = new LinkedList<>();
      }
      return _addresses.add(value);
    }

    /**
     * Remove the first matching {@link Address} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeAddress(Address item) {
      Address value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _addresses == null ? false : _addresses.remove(value);
    }

    public List<UUID> getLocationUuids() {
      return _locationUuids;
    }

    public void setLocationUuids(List<UUID> value) {
      _locationUuids = value;
    }

    /**
     * Add a new {@link UUID} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addLocationUuid(UUID item) {
      UUID value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_locationUuids == null) {
        _locationUuids = new LinkedList<>();
      }
      return _locationUuids.add(value);
    }

    /**
     * Remove the first matching {@link UUID} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeLocationUuid(UUID item) {
      UUID value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _locationUuids == null ? false : _locationUuids.remove(value);
    }

    public List<UUID> getMemberOfOrganizations() {
      return _memberOfOrganizations;
    }

    public void setMemberOfOrganizations(List<UUID> value) {
      _memberOfOrganizations = value;
    }

    /**
     * Add a new {@link UUID} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addMemberOfOrganization(UUID item) {
      UUID value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_memberOfOrganizations == null) {
        _memberOfOrganizations = new LinkedList<>();
      }
      return _memberOfOrganizations.add(value);
    }

    /**
     * Remove the first matching {@link UUID} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeMemberOfOrganization(UUID item) {
      UUID value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _memberOfOrganizations == null ? false : _memberOfOrganizations.remove(value);
    }

    public MarkupMultiline getRemarks() {
      return _remarks;
    }

    public void setRemarks(MarkupMultiline value) {
      _remarks = value;
    }

    @Override
    public String toString() {
      return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
    }

    /**
     * An identifier for a person or organization using a designated scheme. e.g. an Open Researcher and Contributor ID (ORCID).
     */
    @MetaschemaField(
        formalName = "Party External Identifier",
        description = "An identifier for a person or organization using a designated scheme. e.g. an Open Researcher and Contributor ID (ORCID).",
        name = "external-id",
        metaschema = OscalMetadataMetaschema.class,
        isCollapsible = false
    )
    public static class ExternalId {
      @MetaschemaFieldValue(
          valueKeyName = "id"
      )
      private String _value;

      @BoundFlag(
          formalName = "External Identifier Schema",
          description = "Indicates the type of external identifier.",
          useName = "scheme",
          required = true,
          typeAdapter = UriAdapter.class,
          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)."
      )
      @ValueConstraints(
          allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, allowOthers = true, values = @AllowedValue(value = "http://orcid.org/", description = "The identifier is Open Researcher and Contributor ID (ORCID)."))
      )
      private URI _scheme;

      public ExternalId() {
      }

      public String getValue() {
        return _value;
      }

      public void setValue(String value) {
        _value = value;
      }

      public URI getScheme() {
        return _scheme;
      }

      public void setScheme(URI value) {
        _scheme = value;
      }

      @Override
      public String toString() {
        return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
      }
    }
  }

  /**
   * Defines a function, which might be assigned to a party in a specific situation.
   */
  @MetaschemaAssembly(
      formalName = "Role",
      description = "Defines a function, which might be assigned to a party in a specific situation.",
      name = "role",
      metaschema = OscalMetadataMetaschema.class,
      remarks = "Permissible values to be determined closer to the application (e.g. by a receiving authority).\n"
              + "\n"
              + "OSCAL has defined a set of standardized roles for consistent use in OSCAL documents. This allows tools consuming OSCAL content to infer specific semantics when these roles are used. These roles are documented in the specific contexts of their use (e.g., responsible-party, responsible-role). When using such a role, it is necessary to define these roles in this list, which will then allow such a role to be referenced."
  )
  public static class Role {
    @BoundFlag(
        formalName = "Role Identifier",
        description = "A unique identifier for the role.",
        useName = "id",
        required = true,
        typeAdapter = TokenAdapter.class
    )
    private String _id;

    /**
     * "A name given to the role, which may be used by a tool for display and navigation."
     */
    @BoundField(
        formalName = "Role Title",
        description = "A name given to the role, which may be used by a tool for display and navigation.",
        useName = "title",
        minOccurs = 1
    )
    @BoundFieldValue(
        typeAdapter = MarkupLineAdapter.class
    )
    private MarkupLine _title;

    /**
     * "A short common name, abbreviation, or acronym for the role."
     */
    @BoundField(
        formalName = "Role Short Name",
        description = "A short common name, abbreviation, or acronym for the role.",
        useName = "short-name"
    )
    private String _shortName;

    /**
     * "A summary of the role's purpose and associated responsibilities."
     */
    @BoundField(
        formalName = "Role Description",
        description = "A summary of the role's purpose and associated responsibilities.",
        useName = "description"
    )
    @BoundFieldValue(
        typeAdapter = MarkupMultilineAdapter.class
    )
    private MarkupMultiline _description;

    @BoundAssembly(
        formalName = "Property",
        description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
        useName = "prop",
        maxOccurs = -1
    )
    @GroupAs(
        name = "props",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Property> _props;

    @BoundAssembly(
        formalName = "Link",
        description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
        useName = "link",
        maxOccurs = -1
    )
    @GroupAs(
        name = "links",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Link> _links;

    @BoundField(
        formalName = "Remarks",
        description = "Additional commentary about the containing object.",
        useName = "remarks"
    )
    @BoundFieldValue(
        typeAdapter = MarkupMultilineAdapter.class
    )
    private MarkupMultiline _remarks;

    public Role() {
    }

    public String getId() {
      return _id;
    }

    public void setId(String value) {
      _id = value;
    }

    public MarkupLine getTitle() {
      return _title;
    }

    public void setTitle(MarkupLine value) {
      _title = value;
    }

    public String getShortName() {
      return _shortName;
    }

    public void setShortName(String value) {
      _shortName = value;
    }

    public MarkupMultiline getDescription() {
      return _description;
    }

    public void setDescription(MarkupMultiline value) {
      _description = value;
    }

    public List<Property> getProps() {
      return _props;
    }

    public void setProps(List<Property> value) {
      _props = value;
    }

    /**
     * Add a new {@link Property} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_props == null) {
        _props = new LinkedList<>();
      }
      return _props.add(value);
    }

    /**
     * Remove the first matching {@link Property} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _props == null ? false : _props.remove(value);
    }

    public List<Link> getLinks() {
      return _links;
    }

    public void setLinks(List<Link> value) {
      _links = value;
    }

    /**
     * Add a new {@link Link} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_links == null) {
        _links = new LinkedList<>();
      }
      return _links.add(value);
    }

    /**
     * Remove the first matching {@link Link} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _links == null ? false : _links.remove(value);
    }

    public MarkupMultiline getRemarks() {
      return _remarks;
    }

    public void setRemarks(MarkupMultiline value) {
      _remarks = value;
    }

    @Override
    public String toString() {
      return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
    }
  }

  /**
   * A physical point of presence, which may be associated with people, organizations, or other concepts within the current or linked OSCAL document.
   */
  @MetaschemaAssembly(
      formalName = "Location",
      description = "A physical point of presence, which may be associated with people, organizations, or other concepts within the current or linked OSCAL document.",
      name = "location",
      metaschema = OscalMetadataMetaschema.class,
      remarks = "An address might be sensitive in nature. In such cases a title, mailing address, email-address, and/or phone number may be used instead."
  )
  @ValueConstraints(
      allowedValues = {
          @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = @AllowedValue(value = "type", description = "Characterizes the kind of location.")),
          @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='type']/@value", values = @AllowedValue(value = "data-center", description = "A location that contains computing assets. A `class` can be used to indicate the sub-type of data-center as *primary* or *alternate*.")),
          @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='type' and @value='data-center']/@class", values = {@AllowedValue(value = "primary", description = "The location is a data-center used for normal operations."), @AllowedValue(value = "alternate", description = "The location is a data-center used for fail-over or backup operations.")})
      }
  )
  @AssemblyConstraints(
      hasCardinality = {
          @HasCardinality(level = IConstraint.Level.WARNING, target = "address", minOccurs = 1),
          @HasCardinality(level = IConstraint.Level.ERROR, target = "title|address|email-address|telephone-number", minOccurs = 1)
      }
  )
  public static class Location {
    @BoundFlag(
        formalName = "Location Universally Unique Identifier",
        description = "A unique ID for the location, for reference.",
        useName = "uuid",
        required = true,
        typeAdapter = UuidAdapter.class
    )
    private UUID _uuid;

    /**
     * "A name given to the location, which may be used by a tool for display and navigation."
     */
    @BoundField(
        formalName = "Location Title",
        description = "A name given to the location, which may be used by a tool for display and navigation.",
        useName = "title"
    )
    @BoundFieldValue(
        typeAdapter = MarkupLineAdapter.class
    )
    private MarkupLine _title;

    @BoundAssembly(
        formalName = "Address",
        description = "A postal address for the location.",
        useName = "address",
        remarks = "The physical address of the location, which will provided for physical locations. Virtual locations can omit this data item."
    )
    private Address _address;

    @BoundField(
        formalName = "Email Address",
        description = "An email address as defined by [RFC 5322 Section 3.4.1](https://tools.ietf.org/html/rfc5322#section-3.4.1).",
        useName = "email-address",
        maxOccurs = -1,
        remarks = "A contact email associated with the location."
    )
    @BoundFieldValue(
        typeAdapter = EmailAddressAdapter.class
    )
    @GroupAs(
        name = "email-addresses",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<String> _emailAddresses;

    @BoundField(
        formalName = "Telephone Number",
        description = "A telephone service number as defined by [ITU-T E.164](https://www.itu.int/rec/T-REC-E.164-201011-I/en).",
        useName = "telephone-number",
        maxOccurs = -1,
        remarks = "A phone number used to contact the location."
    )
    @GroupAs(
        name = "telephone-numbers",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<TelephoneNumber> _telephoneNumbers;

    /**
     * "The uniform resource locator (URL) for a web site or other resource associated with the location."
     */
    @BoundField(
        formalName = "Location URL",
        description = "The uniform resource locator (URL) for a web site or other resource associated with the location.",
        useName = "url",
        maxOccurs = -1,
        remarks = "This data field is deprecated in favor of using a link with an appropriate relationship."
    )
    @BoundFieldValue(
        typeAdapter = UriAdapter.class
    )
    @GroupAs(
        name = "urls",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<URI> _urls;

    @BoundAssembly(
        formalName = "Property",
        description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
        useName = "prop",
        maxOccurs = -1
    )
    @GroupAs(
        name = "props",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Property> _props;

    @BoundAssembly(
        formalName = "Link",
        description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
        useName = "link",
        maxOccurs = -1
    )
    @GroupAs(
        name = "links",
        inJson = JsonGroupAsBehavior.LIST
    )
    private List<Link> _links;

    @BoundField(
        formalName = "Remarks",
        description = "Additional commentary about the containing object.",
        useName = "remarks"
    )
    @BoundFieldValue(
        typeAdapter = MarkupMultilineAdapter.class
    )
    private MarkupMultiline _remarks;

    public Location() {
    }

    public UUID getUuid() {
      return _uuid;
    }

    public void setUuid(UUID value) {
      _uuid = value;
    }

    public MarkupLine getTitle() {
      return _title;
    }

    public void setTitle(MarkupLine value) {
      _title = value;
    }

    public Address getAddress() {
      return _address;
    }

    public void setAddress(Address value) {
      _address = value;
    }

    public List<String> getEmailAddresses() {
      return _emailAddresses;
    }

    public void setEmailAddresses(List<String> value) {
      _emailAddresses = value;
    }

    /**
     * Add a new {@link String} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addEmailAddress(String item) {
      String value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_emailAddresses == null) {
        _emailAddresses = new LinkedList<>();
      }
      return _emailAddresses.add(value);
    }

    /**
     * Remove the first matching {@link String} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeEmailAddress(String item) {
      String value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _emailAddresses == null ? false : _emailAddresses.remove(value);
    }

    public List<TelephoneNumber> getTelephoneNumbers() {
      return _telephoneNumbers;
    }

    public void setTelephoneNumbers(List<TelephoneNumber> value) {
      _telephoneNumbers = value;
    }

    /**
     * Add a new {@link TelephoneNumber} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addTelephoneNumber(TelephoneNumber item) {
      TelephoneNumber value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_telephoneNumbers == null) {
        _telephoneNumbers = new LinkedList<>();
      }
      return _telephoneNumbers.add(value);
    }

    /**
     * Remove the first matching {@link TelephoneNumber} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeTelephoneNumber(TelephoneNumber item) {
      TelephoneNumber value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _telephoneNumbers == null ? false : _telephoneNumbers.remove(value);
    }

    public List<URI> getUrls() {
      return _urls;
    }

    public void setUrls(List<URI> value) {
      _urls = value;
    }

    /**
     * Add a new {@link URI} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addUrl(URI item) {
      URI value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_urls == null) {
        _urls = new LinkedList<>();
      }
      return _urls.add(value);
    }

    /**
     * Remove the first matching {@link URI} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeUrl(URI item) {
      URI value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _urls == null ? false : _urls.remove(value);
    }

    public List<Property> getProps() {
      return _props;
    }

    public void setProps(List<Property> value) {
      _props = value;
    }

    /**
     * Add a new {@link Property} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_props == null) {
        _props = new LinkedList<>();
      }
      return _props.add(value);
    }

    /**
     * Remove the first matching {@link Property} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeProp(Property item) {
      Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _props == null ? false : _props.remove(value);
    }

    public List<Link> getLinks() {
      return _links;
    }

    public void setLinks(List<Link> value) {
      _links = value;
    }

    /**
     * Add a new {@link Link} item to the underlying collection.
     * @param item the item to add
     * @return {@code true}
     */
    public boolean addLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      if (_links == null) {
        _links = new LinkedList<>();
      }
      return _links.add(value);
    }

    /**
     * Remove the first matching {@link Link} item from the underlying collection.
     * @param item the item to remove
     * @return {@code true} if the item was removed or {@code false} otherwise
     */
    public boolean removeLink(Link item) {
      Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
      return _links == null ? false : _links.remove(value);
    }

    public MarkupMultiline getRemarks() {
      return _remarks;
    }

    public void setRemarks(MarkupMultiline value) {
      _remarks = value;
    }

    @Override
    public String toString() {
      return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
    }
  }
}