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
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
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 }