001package gov.nist.secauto.oscal.lib.model;
002
003import gov.nist.secauto.metaschema.core.datatype.adapter.StringAdapter;
004import gov.nist.secauto.metaschema.core.datatype.adapter.TokenAdapter;
005import gov.nist.secauto.metaschema.core.datatype.adapter.UriAdapter;
006import gov.nist.secauto.metaschema.core.datatype.adapter.UriReferenceAdapter;
007import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
008import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLineAdapter;
009import gov.nist.secauto.metaschema.core.model.IBoundObject;
010import gov.nist.secauto.metaschema.core.model.IMetaschemaData;
011import gov.nist.secauto.metaschema.core.model.constraint.IConstraint;
012import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValue;
013import gov.nist.secauto.metaschema.databind.model.annotations.AllowedValues;
014import gov.nist.secauto.metaschema.databind.model.annotations.BoundField;
015import gov.nist.secauto.metaschema.databind.model.annotations.BoundFlag;
016import gov.nist.secauto.metaschema.databind.model.annotations.Expect;
017import gov.nist.secauto.metaschema.databind.model.annotations.IndexHasKey;
018import gov.nist.secauto.metaschema.databind.model.annotations.KeyField;
019import gov.nist.secauto.metaschema.databind.model.annotations.Matches;
020import gov.nist.secauto.metaschema.databind.model.annotations.MetaschemaAssembly;
021import gov.nist.secauto.metaschema.databind.model.annotations.ValueConstraints;
022import gov.nist.secauto.oscal.lib.model.metadata.AbstractLink;
023import java.lang.Override;
024import java.lang.String;
025import java.net.URI;
026import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
027import org.apache.commons.lang3.builder.ToStringStyle;
028
029/**
030 * A reference to a local or remote resource, that has a specific relation to the containing object.
031 */
032@MetaschemaAssembly(
033    formalName = "Link",
034    description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
035    name = "link",
036    moduleClass = OscalMetadataModule.class,
037    remarks = "To provide a cryptographic hash for a remote target resource, a local reference to a back matter `resource` is needed. The resource allows one or more hash values to be provided using the `rlink/hash` object.\n"
038            + "\n"
039            + "The OSCAL `link` is a roughly based on the HTML [link element](https://www.w3.org/TR/html401/struct/links.html#edef-LINK).",
040    valueConstraints = @ValueConstraints(indexHasKey = @IndexHasKey(level = IConstraint.Level.ERROR, target = ".[@rel=('reference') and starts-with(@href,'#')]", indexName = "index-back-matter-resource", keyFields = @KeyField(target = "@href", pattern = "#(.*)")), matches = {@Matches(level = IConstraint.Level.ERROR, target = ".[@rel=('reference') and starts-with(@href,'#')]/@href", typeAdapter = UriReferenceAdapter.class), @Matches(level = IConstraint.Level.ERROR, target = ".[@rel=('reference') and not(starts-with(@href,'#'))]/@href", typeAdapter = UriAdapter.class), @Matches(level = IConstraint.Level.ERROR, target = "@resource-fragment", pattern = "(?:[0-9a-zA-Z-._~/?!$&'()*+,;=:@]|%[0-9A-F][0-9A-F])+", remarks = "This pattern is based on the fragment Augmented Backus-Naur form (ABNF) syntax provided in \\[RFC3986 section 3.5\\](https://www.rfc-editor.org/rfc/rfc3986#section-3.5). Uppercase alpha hex digits are required, which is the preferred normalized form defined in RFC3986.")}, expect = @Expect(description = "A local reference SHOULD NOT have a media-type.", level = IConstraint.Level.ERROR, target = ".[starts-with(@href,'#')]", test = "not(exists(@media-type))", remarks = "Since both `link` and `back-matter/resource` both allow specification of a `media-type`, the `media-type` on `link` may conflict with the any `media-type` entries on a resource's `rlink` or `base64` objects. This constraint prevents this from occurring."))
041)
042public class Link extends AbstractLink implements IBoundObject {
043  private final IMetaschemaData __metaschemaData;
044
045  /**
046   * "A resolvable URL reference to a resource."
047   */
048  @BoundFlag(
049      formalName = "Hypertext Reference",
050      description = "A resolvable URL reference to a resource.",
051      name = "href",
052      required = true,
053      typeAdapter = UriReferenceAdapter.class,
054      remarks = "This value may be one of:\n"
055              + "\n"
056              + "1. an [absolute URI](https://pages.nist.gov/OSCAL/concepts/uri-use/#absolute-uri) that points to a network resolvable resource,\n"
057              + "2. a [relative reference](https://pages.nist.gov/OSCAL/concepts/uri-use/#relative-reference) pointing to a network resolvable resource whose base URI is the URI of the containing document, or\n"
058              + "3. a bare URI fragment (i.e., \\`#uuid\\`) pointing to an OSCAL object by the objects identifier (e.g., id, uuid) in this or an imported document (see [linking to another OSCAL object](https://pages.nist.gov/OSCAL/concepts/uri-use/#linking-to-another-oscal-object)). The specific object type will differ based on the link relationship type."
059  )
060  private URI _href;
061
062  /**
063   * "Describes the type of relationship provided by the link's hypertext reference. This can be an indicator of the link's purpose."
064   */
065  @BoundFlag(
066      formalName = "Link Relation Type",
067      description = "Describes the type of relationship provided by the link's hypertext reference. This can be an indicator of the link's purpose.",
068      name = "rel",
069      typeAdapter = TokenAdapter.class,
070      valueConstraints = @ValueConstraints(allowedValues = @AllowedValues(level = IConstraint.Level.ERROR, allowOthers = true, values = @AllowedValue(value = "reference", description = "A generalized reference to a network resource (relative or absolute) or to a `back-matter` resource by UUID expressed as a bare URI fragment.")))
071  )
072  private String _rel;
073
074  /**
075   * "A label that indicates the nature of a resource, as a data serialization or format."
076   */
077  @BoundFlag(
078      formalName = "Link Media Type",
079      description = "A label that indicates the nature of a resource, as a data serialization or format.",
080      name = "media-type",
081      typeAdapter = StringAdapter.class,
082      remarks = "The `media-type` provides a hint about the content model of the referenced resource. A valid entry from the [IANA Media Types registry](https://www.iana.org/assignments/media-types/media-types.xhtml) SHOULD be used."
083  )
084  private String _mediaType;
085
086  /**
087   * "In case where the <code>href</code> points to a <code>back-matter/resource</code>, this value will indicate the URI <a href=\"https://www.rfc-editor.org/rfc/rfc3986#section-3.5\">fragment</a> to append to any <code>rlink</code> associated with the resource. This value MUST be <a href=\"https://www.rfc-editor.org/rfc/rfc3986#section-2.1\">URI encoded</a>."
088   */
089  @BoundFlag(
090      formalName = "Resource Fragment",
091      description = "In case where the `href` points to a `back-matter/resource`, this value will indicate the URI [fragment](https://www.rfc-editor.org/rfc/rfc3986#section-3.5) to append to any `rlink` associated with the resource. This value MUST be [URI encoded](https://www.rfc-editor.org/rfc/rfc3986#section-2.1).",
092      name = "resource-fragment",
093      typeAdapter = StringAdapter.class
094  )
095  private String _resourceFragment;
096
097  @BoundField(
098      formalName = "Link Text",
099      description = "A textual label to associate with the link, which may be used for presentation in a tool.",
100      useName = "text",
101      typeAdapter = MarkupLineAdapter.class
102  )
103  private MarkupLine _text;
104
105  public Link() {
106    this(null);
107  }
108
109  public Link(IMetaschemaData data) {
110    this.__metaschemaData = data;
111  }
112
113  @Override
114  public IMetaschemaData getMetaschemaData() {
115    return __metaschemaData;
116  }
117
118  public URI getHref() {
119    return _href;
120  }
121
122  public void setHref(URI value) {
123    _href = value;
124  }
125
126  public String getRel() {
127    return _rel;
128  }
129
130  public void setRel(String value) {
131    _rel = value;
132  }
133
134  public String getMediaType() {
135    return _mediaType;
136  }
137
138  public void setMediaType(String value) {
139    _mediaType = value;
140  }
141
142  public String getResourceFragment() {
143    return _resourceFragment;
144  }
145
146  public void setResourceFragment(String value) {
147    _resourceFragment = value;
148  }
149
150  public MarkupLine getText() {
151    return _text;
152  }
153
154  public void setText(MarkupLine value) {
155    _text = value;
156  }
157
158  @Override
159  public String toString() {
160    return new ReflectionToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).toString();
161  }
162}