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.AssemblyConstraints;
6 import gov.nist.secauto.metaschema.binding.model.annotations.BoundAssembly;
7 import gov.nist.secauto.metaschema.binding.model.annotations.BoundField;
8 import gov.nist.secauto.metaschema.binding.model.annotations.BoundFieldValue;
9 import gov.nist.secauto.metaschema.binding.model.annotations.BoundFlag;
10 import gov.nist.secauto.metaschema.binding.model.annotations.Expect;
11 import gov.nist.secauto.metaschema.binding.model.annotations.GroupAs;
12 import gov.nist.secauto.metaschema.binding.model.annotations.HasCardinality;
13 import gov.nist.secauto.metaschema.binding.model.annotations.Index;
14 import gov.nist.secauto.metaschema.binding.model.annotations.IsUnique;
15 import gov.nist.secauto.metaschema.binding.model.annotations.KeyField;
16 import gov.nist.secauto.metaschema.binding.model.annotations.Matches;
17 import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaAssembly;
18 import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaField;
19 import gov.nist.secauto.metaschema.binding.model.annotations.MetaschemaFieldValue;
20 import gov.nist.secauto.metaschema.binding.model.annotations.ValueConstraints;
21 import gov.nist.secauto.metaschema.model.common.JsonGroupAsBehavior;
22 import gov.nist.secauto.metaschema.model.common.constraint.IConstraint;
23 import gov.nist.secauto.metaschema.model.common.datatype.adapter.Base64Adapter;
24 import gov.nist.secauto.metaschema.model.common.datatype.adapter.DateTimeWithTZAdapter;
25 import gov.nist.secauto.metaschema.model.common.datatype.adapter.StringAdapter;
26 import gov.nist.secauto.metaschema.model.common.datatype.adapter.TokenAdapter;
27 import gov.nist.secauto.metaschema.model.common.datatype.adapter.UriReferenceAdapter;
28 import gov.nist.secauto.metaschema.model.common.datatype.adapter.UuidAdapter;
29 import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine;
30 import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLineAdapter;
31 import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultiline;
32 import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupMultilineAdapter;
33 import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
34 import gov.nist.secauto.oscal.lib.model.metadata.AbstractBackMatter;
35 import java.lang.Override;
36 import java.lang.String;
37 import java.net.URI;
38 import java.nio.ByteBuffer;
39 import java.util.LinkedList;
40 import java.util.List;
41 import java.util.UUID;
42 import org.apache.commons.lang3.builder.MultilineRecursiveToStringStyle;
43 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
44
45
46
47
48 @MetaschemaAssembly(
49 formalName = "Back matter",
50 description = "A collection of resources that may be referenced from within the OSCAL document instance.",
51 name = "back-matter",
52 metaschema = OscalMetadataMetaschema.class,
53 remarks = "Provides a collection of identified `resource` objects that can be referenced by a `link` with a `rel` value of \"reference\" and an `href` value that is a fragment \"#\" followed by a reference to a reference's `uuid`. Other specialized link \"rel\" values also use this pattern when indicated in that context of use."
54 )
55 @AssemblyConstraints(
56 index = @Index(level = IConstraint.Level.ERROR, target = "resource", name = "index-back-matter-resource", keyFields = @KeyField(target = "@uuid"))
57 )
58 public class BackMatter extends AbstractBackMatter {
59
60
61
62 @BoundAssembly(
63 formalName = "Resource",
64 description = "A resource associated with content in the containing document instance. A resource may be directly included in the document using base64 encoding or may point to one or more equivalent internet resources.",
65 useName = "resource",
66 maxOccurs = -1,
67 remarks = "A resource can be used in two ways. 1) it may point to an specific retrievable network resource using a `rlink`, or 2) it may be included as an attachment using a `base64`. A resource may contain multiple `rlink` and `base64` entries that represent alternative download locations (rlink) and attachments (base64) for the same resource.\n"
68 + "\n"
69 + "Both rlink and base64 allow for a `media-type` to be specified, which is used to distinguish between different representations of the same resource (e.g., Microsoft Word, PDF). When multiple `rlink` and `base64` items are included for a given resource, all items must contain equivalent information. This allows the document consumer to choose a preferred item to process based on a the selected item's `media-type`. This is extremely important when the items represent OSCAL content that is represented in alternate formats (i.e., XML, JSON, YAML), allowing the same OSCAL data to be processed from any of the available formats indicated by the items.\n"
70 + "\n"
71 + "When a resource includes a citation, then the `title` and `citation` properties must both be included."
72 )
73 @GroupAs(
74 name = "resources",
75 inJson = JsonGroupAsBehavior.LIST
76 )
77 private List<Resource> _resources;
78
79 public BackMatter() {
80 }
81
82 public List<Resource> getResources() {
83 return _resources;
84 }
85
86 public void setResources(List<Resource> value) {
87 _resources = value;
88 }
89
90
91
92
93
94
95 public boolean addResource(Resource item) {
96 Resource value = ObjectUtils.requireNonNull(item,"item cannot be null");
97 if (_resources == null) {
98 _resources = new LinkedList<>();
99 }
100 return _resources.add(value);
101 }
102
103
104
105
106
107
108 public boolean removeResource(Resource item) {
109 Resource value = ObjectUtils.requireNonNull(item,"item cannot be null");
110 return _resources == null ? false : _resources.remove(value);
111 }
112
113 @Override
114 public String toString() {
115 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
116 }
117
118
119
120
121 @MetaschemaAssembly(
122 formalName = "Resource",
123 description = "A resource associated with content in the containing document instance. A resource may be directly included in the document using base64 encoding or may point to one or more equivalent internet resources.",
124 name = "resource",
125 metaschema = OscalMetadataMetaschema.class,
126 remarks = "A resource can be used in two ways. 1) it may point to an specific retrievable network resource using a `rlink`, or 2) it may be included as an attachment using a `base64`. A resource may contain multiple `rlink` and `base64` entries that represent alternative download locations (rlink) and attachments (base64) for the same resource.\n"
127 + "\n"
128 + "Both rlink and base64 allow for a `media-type` to be specified, which is used to distinguish between different representations of the same resource (e.g., Microsoft Word, PDF). When multiple `rlink` and `base64` items are included for a given resource, all items must contain equivalent information. This allows the document consumer to choose a preferred item to process based on a the selected item's `media-type`. This is extremely important when the items represent OSCAL content that is represented in alternate formats (i.e., XML, JSON, YAML), allowing the same OSCAL data to be processed from any of the available formats indicated by the items.\n"
129 + "\n"
130 + "When a resource includes a citation, then the `title` and `citation` properties must both be included."
131 )
132 @ValueConstraints(
133 allowedValues = {
134 @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal')]/@name", values = {@AllowedValue(value = "type", description = "Identifies the type of resource represented. The most specific appropriate type value SHOULD be used."), @AllowedValue(value = "version", description = "For resources representing a published document, this represents the version number of that document."), @AllowedValue(value = "published", description = "For resources representing a published document, this represents the publication date of that document.")}),
135 @AllowedValues(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='type']/@value", values = {@AllowedValue(value = "logo", description = "Indicates the resource is an organization's logo."), @AllowedValue(value = "image", description = "Indicates the resource represents an image."), @AllowedValue(value = "screen-shot", description = "Indicates the resource represents an image of screen content."), @AllowedValue(value = "law", description = "Indicates the resource represents an applicable law."), @AllowedValue(value = "regulation", description = "Indicates the resource represents an applicable regulation."), @AllowedValue(value = "standard", description = "Indicates the resource represents an applicable standard."), @AllowedValue(value = "external-guidance", description = "Indicates the resource represents applicable guidance."), @AllowedValue(value = "acronyms", description = "Indicates the resource provides a list of relevant acronyms."), @AllowedValue(value = "citation", description = "Indicates the resource cites relevant information."), @AllowedValue(value = "policy", description = "Indicates the resource is a policy."), @AllowedValue(value = "procedure", description = "Indicates the resource is a procedure."), @AllowedValue(value = "system-guide", description = "Indicates the resource is guidance document related to the subject system of an SSP."), @AllowedValue(value = "users-guide", description = "Indicates the resource is guidance document a user's guide or administrator's guide."), @AllowedValue(value = "administrators-guide", description = "Indicates the resource is guidance document a administrator's guide."), @AllowedValue(value = "rules-of-behavior", description = "Indicates the resource represents rules of behavior content."), @AllowedValue(value = "plan", description = "Indicates the resource represents a plan."), @AllowedValue(value = "artifact", description = "Indicates the resource represents an artifact, such as may be reviewed by an assessor."), @AllowedValue(value = "evidence", description = "Indicates the resource represents evidence, such as to support an assessment finding."), @AllowedValue(value = "tool-output", description = "Indicates the resource represents output from a tool."), @AllowedValue(value = "raw-data", description = "Indicates the resource represents machine data, which may require a tool or analysis for interpretation or presentation."), @AllowedValue(value = "interview-notes", description = "Indicates the resource represents notes from an interview, such as may be collected during an assessment."), @AllowedValue(value = "questionnaire", description = "Indicates the resource is a set of questions, possibly with responses."), @AllowedValue(value = "report", description = "Indicates the resource is a report."), @AllowedValue(value = "agreement", description = "Indicates the resource is a formal agreement between two or more parties.")})
136 },
137 matches = @Matches(level = IConstraint.Level.ERROR, target = "prop[has-oscal-namespace('http://csrc.nist.gov/ns/oscal') and @name='published']/@value", typeAdapter = DateTimeWithTZAdapter.class),
138 expect = @Expect(level = IConstraint.Level.ERROR, target = ".[citation]", test = "title")
139 )
140 @AssemblyConstraints(
141 isUnique = {
142 @IsUnique(id = "unique-resource-rlink-href", level = IConstraint.Level.ERROR, target = "rlink", keyFields = {@KeyField(target = "@href"), @KeyField(target = "@media-type")}),
143 @IsUnique(id = "unique-resource-base64-filename", level = IConstraint.Level.ERROR, target = "base64", keyFields = @KeyField(target = "@filename"))
144 },
145 hasCardinality = @HasCardinality(level = IConstraint.Level.WARNING, target = "rlink|base64", minOccurs = 1)
146 )
147 public static class Resource {
148 @BoundFlag(
149 formalName = "Resource Universally Unique Identifier",
150 description = "A unique identifier for a resource.",
151 useName = "uuid",
152 required = true,
153 typeAdapter = UuidAdapter.class
154 )
155 private UUID _uuid;
156
157
158
159
160 @BoundField(
161 formalName = "Resource Title",
162 description = "An optional name given to the resource, which may be used by a tool for display and navigation.",
163 useName = "title"
164 )
165 @BoundFieldValue(
166 typeAdapter = MarkupLineAdapter.class
167 )
168 private MarkupLine _title;
169
170
171
172
173 @BoundField(
174 formalName = "Resource Description",
175 description = "An optional short summary of the resource used to indicate the purpose of the resource.",
176 useName = "description"
177 )
178 @BoundFieldValue(
179 typeAdapter = MarkupMultilineAdapter.class
180 )
181 private MarkupMultiline _description;
182
183 @BoundAssembly(
184 formalName = "Property",
185 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
186 useName = "prop",
187 maxOccurs = -1
188 )
189 @GroupAs(
190 name = "props",
191 inJson = JsonGroupAsBehavior.LIST
192 )
193 private List<Property> _props;
194
195 @BoundField(
196 formalName = "Document Identifier",
197 description = "A document identifier qualified by an identifier `scheme`.",
198 useName = "document-id",
199 maxOccurs = -1
200 )
201 @GroupAs(
202 name = "document-ids",
203 inJson = JsonGroupAsBehavior.LIST
204 )
205 private List<DocumentId> _documentIds;
206
207
208
209
210 @BoundAssembly(
211 formalName = "Citation",
212 description = "An optional citation consisting of end note text using structured markup.",
213 useName = "citation"
214 )
215 private Citation _citation;
216
217
218
219
220 @BoundAssembly(
221 formalName = "Resource link",
222 description = "A URL-based pointer to an external resource with an optional hash for verification and change detection.",
223 useName = "rlink",
224 maxOccurs = -1,
225 remarks = "Multiple `rlink` objects can be included for a resource. In such a case, all provided `rlink` items are intended to be equivalent in content, but may differ in structure or format.\n"
226 + "\n"
227 + "A `media-type` is used to identify the format of a given rlink, and can be used to differentiate items in a collection of rlinks. The `media-type` provides a hint to the OSCAL document consumer about the structure of the resource referenced by the `rlink`."
228 )
229 @GroupAs(
230 name = "rlinks",
231 inJson = JsonGroupAsBehavior.LIST
232 )
233 private List<Rlink> _rlinks;
234
235
236
237
238 @BoundField(
239 formalName = "Base64",
240 description = "A resource encoded using the Base64 alphabet defined by [RFC 2045](https://www.rfc-editor.org/rfc/rfc2045.html).",
241 useName = "base64"
242 )
243 private Base64 _base64;
244
245 @BoundField(
246 formalName = "Remarks",
247 description = "Additional commentary about the containing object.",
248 useName = "remarks"
249 )
250 @BoundFieldValue(
251 typeAdapter = MarkupMultilineAdapter.class
252 )
253 private MarkupMultiline _remarks;
254
255 public Resource() {
256 }
257
258 public UUID getUuid() {
259 return _uuid;
260 }
261
262 public void setUuid(UUID value) {
263 _uuid = value;
264 }
265
266 public MarkupLine getTitle() {
267 return _title;
268 }
269
270 public void setTitle(MarkupLine value) {
271 _title = value;
272 }
273
274 public MarkupMultiline getDescription() {
275 return _description;
276 }
277
278 public void setDescription(MarkupMultiline value) {
279 _description = value;
280 }
281
282 public List<Property> getProps() {
283 return _props;
284 }
285
286 public void setProps(List<Property> value) {
287 _props = value;
288 }
289
290
291
292
293
294
295 public boolean addProp(Property item) {
296 Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
297 if (_props == null) {
298 _props = new LinkedList<>();
299 }
300 return _props.add(value);
301 }
302
303
304
305
306
307
308 public boolean removeProp(Property item) {
309 Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
310 return _props == null ? false : _props.remove(value);
311 }
312
313 public List<DocumentId> getDocumentIds() {
314 return _documentIds;
315 }
316
317 public void setDocumentIds(List<DocumentId> value) {
318 _documentIds = value;
319 }
320
321
322
323
324
325
326 public boolean addDocumentId(DocumentId item) {
327 DocumentId value = ObjectUtils.requireNonNull(item,"item cannot be null");
328 if (_documentIds == null) {
329 _documentIds = new LinkedList<>();
330 }
331 return _documentIds.add(value);
332 }
333
334
335
336
337
338
339 public boolean removeDocumentId(DocumentId item) {
340 DocumentId value = ObjectUtils.requireNonNull(item,"item cannot be null");
341 return _documentIds == null ? false : _documentIds.remove(value);
342 }
343
344 public Citation getCitation() {
345 return _citation;
346 }
347
348 public void setCitation(Citation value) {
349 _citation = value;
350 }
351
352 public List<Rlink> getRlinks() {
353 return _rlinks;
354 }
355
356 public void setRlinks(List<Rlink> value) {
357 _rlinks = value;
358 }
359
360
361
362
363
364
365 public boolean addRlink(Rlink item) {
366 Rlink value = ObjectUtils.requireNonNull(item,"item cannot be null");
367 if (_rlinks == null) {
368 _rlinks = new LinkedList<>();
369 }
370 return _rlinks.add(value);
371 }
372
373
374
375
376
377
378 public boolean removeRlink(Rlink item) {
379 Rlink value = ObjectUtils.requireNonNull(item,"item cannot be null");
380 return _rlinks == null ? false : _rlinks.remove(value);
381 }
382
383 public Base64 getBase64() {
384 return _base64;
385 }
386
387 public void setBase64(Base64 value) {
388 _base64 = value;
389 }
390
391 public MarkupMultiline getRemarks() {
392 return _remarks;
393 }
394
395 public void setRemarks(MarkupMultiline value) {
396 _remarks = value;
397 }
398
399 @Override
400 public String toString() {
401 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
402 }
403
404
405
406
407 @MetaschemaAssembly(
408 formalName = "Citation",
409 description = "An optional citation consisting of end note text using structured markup.",
410 name = "citation",
411 metaschema = OscalMetadataMetaschema.class
412 )
413 public static class Citation {
414
415
416
417 @BoundField(
418 formalName = "Citation Text",
419 description = "A line of citation text.",
420 useName = "text",
421 minOccurs = 1
422 )
423 @BoundFieldValue(
424 typeAdapter = MarkupLineAdapter.class
425 )
426 private MarkupLine _text;
427
428 @BoundAssembly(
429 formalName = "Property",
430 description = "An attribute, characteristic, or quality of the containing object expressed as a namespace qualified name/value pair.",
431 useName = "prop",
432 maxOccurs = -1
433 )
434 @GroupAs(
435 name = "props",
436 inJson = JsonGroupAsBehavior.LIST
437 )
438 private List<Property> _props;
439
440 @BoundAssembly(
441 formalName = "Link",
442 description = "A reference to a local or remote resource, that has a specific relation to the containing object.",
443 useName = "link",
444 maxOccurs = -1
445 )
446 @GroupAs(
447 name = "links",
448 inJson = JsonGroupAsBehavior.LIST
449 )
450 private List<Link> _links;
451
452 public Citation() {
453 }
454
455 public MarkupLine getText() {
456 return _text;
457 }
458
459 public void setText(MarkupLine value) {
460 _text = value;
461 }
462
463 public List<Property> getProps() {
464 return _props;
465 }
466
467 public void setProps(List<Property> value) {
468 _props = value;
469 }
470
471
472
473
474
475
476 public boolean addProp(Property item) {
477 Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
478 if (_props == null) {
479 _props = new LinkedList<>();
480 }
481 return _props.add(value);
482 }
483
484
485
486
487
488
489 public boolean removeProp(Property item) {
490 Property value = ObjectUtils.requireNonNull(item,"item cannot be null");
491 return _props == null ? false : _props.remove(value);
492 }
493
494 public List<Link> getLinks() {
495 return _links;
496 }
497
498 public void setLinks(List<Link> value) {
499 _links = value;
500 }
501
502
503
504
505
506
507 public boolean addLink(Link item) {
508 Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
509 if (_links == null) {
510 _links = new LinkedList<>();
511 }
512 return _links.add(value);
513 }
514
515
516
517
518
519
520 public boolean removeLink(Link item) {
521 Link value = ObjectUtils.requireNonNull(item,"item cannot be null");
522 return _links == null ? false : _links.remove(value);
523 }
524
525 @Override
526 public String toString() {
527 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
528 }
529 }
530
531
532
533
534 @MetaschemaField(
535 formalName = "Base64",
536 description = "A resource encoded using the Base64 alphabet defined by [RFC 2045](https://www.rfc-editor.org/rfc/rfc2045.html).",
537 name = "base64",
538 metaschema = OscalMetadataMetaschema.class,
539 isCollapsible = false
540 )
541 public static class Base64 {
542 @MetaschemaFieldValue(
543 valueKeyName = "value",
544 typeAdapter = Base64Adapter.class
545 )
546 private ByteBuffer _value;
547
548 @BoundFlag(
549 formalName = "File Name",
550 description = "Name of the file before it was encoded as Base64 to be embedded in a `resource`. This is the name that will be assigned to the file when the file is decoded.",
551 useName = "filename",
552 typeAdapter = TokenAdapter.class
553 )
554 private String _filename;
555
556 @BoundFlag(
557 formalName = "Media Type",
558 description = "A label that indicates the nature of a resource, as a data serialization or format.",
559 useName = "media-type",
560 typeAdapter = StringAdapter.class
561 )
562 private String _mediaType;
563
564 public Base64() {
565 }
566
567 public ByteBuffer getValue() {
568 return _value;
569 }
570
571 public void setValue(ByteBuffer value) {
572 _value = value;
573 }
574
575 public String getFilename() {
576 return _filename;
577 }
578
579 public void setFilename(String value) {
580 _filename = value;
581 }
582
583 public String getMediaType() {
584 return _mediaType;
585 }
586
587 public void setMediaType(String value) {
588 _mediaType = value;
589 }
590
591 @Override
592 public String toString() {
593 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
594 }
595 }
596
597
598
599
600 @MetaschemaAssembly(
601 formalName = "Resource link",
602 description = "A URL-based pointer to an external resource with an optional hash for verification and change detection.",
603 name = "rlink",
604 metaschema = OscalMetadataMetaschema.class,
605 remarks = "Multiple `rlink` objects can be included for a resource. In such a case, all provided `rlink` items are intended to be equivalent in content, but may differ in structure or format.\n"
606 + "\n"
607 + "A `media-type` is used to identify the format of a given rlink, and can be used to differentiate items in a collection of rlinks. The `media-type` provides a hint to the OSCAL document consumer about the structure of the resource referenced by the `rlink`."
608 )
609 public static class Rlink {
610 @BoundFlag(
611 formalName = "Hypertext Reference",
612 description = "A resolvable URL pointing to the referenced resource.",
613 useName = "href",
614 required = true,
615 typeAdapter = UriReferenceAdapter.class,
616 remarks = "This value may be either:\n"
617 + "\n"
618 + "1. an [absolute URI](https://pages.nist.gov/OSCAL/concepts/uri-use/#absolute-uri) that points to a network resolvable resource,\n"
619 + "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"
620 )
621 private URI _href;
622
623 @BoundFlag(
624 formalName = "Media Type",
625 description = "A label that indicates the nature of a resource, as a data serialization or format.",
626 useName = "media-type",
627 typeAdapter = StringAdapter.class
628 )
629 private String _mediaType;
630
631
632
633
634 @BoundField(
635 formalName = "Hash",
636 description = "A hash of the resource identified by `href`, which can be used to verify the resource was not changed since it was hashed.",
637 useName = "hash",
638 maxOccurs = -1,
639 remarks = "The `hash` value can be used to confirm that the resource referenced by the `href` is the same resources that was hashed by retrieving the resource, calculating a hash, and comparing the result to this value."
640 )
641 @GroupAs(
642 name = "hashes",
643 inJson = JsonGroupAsBehavior.LIST
644 )
645 private List<Hash> _hashes;
646
647 public Rlink() {
648 }
649
650 public URI getHref() {
651 return _href;
652 }
653
654 public void setHref(URI value) {
655 _href = value;
656 }
657
658 public String getMediaType() {
659 return _mediaType;
660 }
661
662 public void setMediaType(String value) {
663 _mediaType = value;
664 }
665
666 public List<Hash> getHashes() {
667 return _hashes;
668 }
669
670 public void setHashes(List<Hash> value) {
671 _hashes = value;
672 }
673
674
675
676
677
678
679 public boolean addHash(Hash item) {
680 Hash value = ObjectUtils.requireNonNull(item,"item cannot be null");
681 if (_hashes == null) {
682 _hashes = new LinkedList<>();
683 }
684 return _hashes.add(value);
685 }
686
687
688
689
690
691
692 public boolean removeHash(Hash item) {
693 Hash value = ObjectUtils.requireNonNull(item,"item cannot be null");
694 return _hashes == null ? false : _hashes.remove(value);
695 }
696
697 @Override
698 public String toString() {
699 return new ReflectionToStringBuilder(this, MultilineRecursiveToStringStyle.MULTI_LINE_STYLE).toString();
700 }
701 }
702 }
703 }