View Javadoc
1   package gov.nist.secauto.oscal.lib.model;
2   
3   import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValue;
4   import gov.nist.secauto.metaschema.binding.model.annotations.AllowedValues;
5   import gov.nist.secauto.metaschema.binding.model.annotations.BoundField;
6   import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue;
7   import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag;
8   import gov.nist.secauto.metaschema.binding.model.annotations.Expect;
9   import gov.nist.secauto.metaschema.binding.model.annotations.IndexHasKey;
10  import gov.nist.secauto.metaschema.binding.model.annotations.KeyField;
11  import gov.nist.secauto.metaschema.binding.model.annotations.Matches;
12  import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly;
13  import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints;
14  import gov.nist.secauto.metaschema.model.common.constraint.IConstraint;
15  import gov.nist.secauto.metaschema.model.common.datatype.adapter.StringAdapter;
16  import gov.nist.secauto.metaschema.model.common.datatype.adapter.TokenAdapter;
17  import gov.nist.secauto.metaschema.model.common.datatype.adapter.UriAdapter;
18  import gov.nist.secauto.metaschema.model.common.datatype.adapter.UriReferenceAdapter;
19  import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine;
20  import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter;
21  import gov.nist.secauto.oscal.lib.model.metadata.AbstractLink;
22  import java.lang.Override;
23  import java.lang.String;
24  import java.net.URI;
25  import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle;
26  import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
27  
28  /**
29   * A reference to a local or remote resource, that has a specific relation to the containing object.
30   */
31  @MetaschemaAssembly(
32      formalName = "Link",
33      description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
34      name = "link",
35      metaschema = OscalMetadataMetaschema.class,
36      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"
37              + "\n"
38              + "The OSCAL `link` is a roughly based on the HTML [link element](https://www.w3.org/TR/html401/struct/links.html#edef-LINK)."
39  )
40  @ValueConstraints(
41      indexHasKey = @IndexHasKey(level = IConstraint.Level.ERROR, target = ".[@rel=('reference') and starts-with(@href,'#')]", indexName = "index-back-matter-resource", keyFields = @KeyField(target = "@href", pattern = "#(.*)")),
42      matches = {
43          @Matches(level = IConstraint.Level.ERROR, target = ".[@rel=('reference') and starts-with(@href,'#')]/@href", typeAdapter = UriReferenceAdapter.class),
44          @Matches(level = IConstraint.Level.ERROR, target = ".[@rel=('reference') and not(starts-with(@href,'#'))]/@href", typeAdapter = UriAdapter.class),
45          @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.")
46      },
47      expect = @Expect(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.")
48  )
49  public class Link extends AbstractLink {
50    @BoundFlag(
51        formalName = "Hypertext Reference",
52        description = "A resolvable URL reference to a resource.",
53        useName = "href",
54        required = true,
55        typeAdapter = UriReferenceAdapter.class,
56        remarks = "This value may be one of:\n"
57                + "\n"
58                + "1. an [absolute URI](https://pages.nist.gov/OSCAL/concepts/uri-use/#absolute-uri) that points to a network resolvable resource,\n"
59                + "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"
60                + "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."
61    )
62    private URI _href;
63  
64    @BoundFlag(
65        formalName = "Link Relation Type",
66        description = "Describes the type of relationship provided by the link's hypertext reference. This can be an indicator of the link's purpose.",
67        useName = "rel",
68        typeAdapter = TokenAdapter.class
69    )
70    @ValueConstraints(
71        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."))
72    )
73    private String _rel;
74  
75    @BoundFlag(
76        formalName = "Link Media Type",
77        description = "A label that indicates the nature of a resource, as a data serialization or format.",
78        useName = "media-type",
79        typeAdapter = StringAdapter.class,
80        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."
81    )
82    private String _mediaType;
83  
84    @BoundFlag(
85        formalName = "Resource Fragment",
86        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).",
87        useName = "resource-fragment",
88        typeAdapter = StringAdapter.class
89    )
90    private String _resourceFragment;
91  
92    /**
93     * "A textual label to associate with the link, which may be used for presentation in a tool."
94     */
95    @BoundField(
96        formalName = "Link Text",
97        description = "A textual label to associate with the link, which may be used for presentation in a tool.",
98        useName = "text"
99    )
100   @BoundFieldValue(
101       typeAdapter = MarkupLineAdapter.class
102   )
103   private MarkupLine _text;
104 
105   public Link() {
106   }
107 
108   public URI getHref() {
109     return _href;
110   }
111 
112   public void setHref(URI value) {
113     _href = value;
114   }
115 
116   public String getRel() {
117     return _rel;
118   }
119 
120   public void setRel(String value) {
121     _rel = value;
122   }
123 
124   public String getMediaType() {
125     return _mediaType;
126   }
127 
128   public void setMediaType(String value) {
129     _mediaType = value;
130   }
131 
132   public String getResourceFragment() {
133     return _resourceFragment;
134   }
135 
136   public void setResourceFragment(String value) {
137     _resourceFragment = value;
138   }
139 
140   public MarkupLine getText() {
141     return _text;
142   }
143 
144   public void setText(MarkupLine value) {
145     _text = value;
146   }
147 
148   @Override
149   public String toString() {
150     return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
151   }
152 }