1
2
3
4
5
6 package gov.nist.secauto.oscal.lib.model.control;
7
8 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupLine;
9 import gov.nist.secauto.metaschema.core.datatype.markup.MarkupMultiline;
10 import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.InsertAnchorExtension;
11 import gov.nist.secauto.metaschema.core.datatype.markup.flexmark.InsertAnchorExtension.InsertAnchorNode;
12 import gov.nist.secauto.metaschema.core.util.CollectionUtil;
13 import gov.nist.secauto.metaschema.core.util.ObjectUtils;
14 import gov.nist.secauto.oscal.lib.model.ControlPart;
15 import gov.nist.secauto.oscal.lib.model.Link;
16 import gov.nist.secauto.oscal.lib.model.Property;
17
18 import java.net.URI;
19 import java.util.LinkedList;
20 import java.util.List;
21 import java.util.Objects;
22 import java.util.function.Predicate;
23 import java.util.stream.Stream;
24
25 import edu.umd.cs.findbugs.annotations.NonNull;
26
27 public abstract class AbstractPart implements IPart {
28
29 @Override
30 @NonNull
31 public Stream<InsertAnchorExtension.InsertAnchorNode> getInserts(@NonNull Predicate<InsertAnchorNode> filter) {
32 MarkupMultiline prose = getProse();
33
34 @NonNull
35 Stream<InsertAnchorExtension.InsertAnchorNode> retval;
36 if (prose == null) {
37 retval = ObjectUtils.notNull(Stream.empty());
38 } else {
39 List<InsertAnchorExtension.InsertAnchorNode> result = prose.getInserts(filter);
40 retval = ObjectUtils.notNull(result.stream());
41 }
42 return retval;
43 }
44
45 public Stream<IPart> getPartsRecursively() {
46 return Stream.concat(
47 Stream.of(this),
48 CollectionUtil.listOrEmpty(getParts()).stream()
49 .flatMap(AbstractPart::getPartsRecursively));
50 }
51
52 @NonNull
53 public static Builder builder(@NonNull String name) {
54 return new Builder(name);
55 }
56
57 public static class Builder {
58 private String id;
59 @NonNull
60 private final String name;
61 private URI namespace;
62 private String clazz;
63 private MarkupMultiline prose;
64 private MarkupLine title;
65 private final List<Property> props = new LinkedList<>();
66 private final List<Link> links = new LinkedList<>();
67 private final List<ControlPart> parts = new LinkedList<>();
68
69 public Builder(@NonNull String name) {
70 this.name = Objects.requireNonNull(name);
71 }
72
73 @SuppressWarnings("PMD.ShortMethodName")
74 @NonNull
75 public Builder id(@NonNull String value) {
76 this.id = Objects.requireNonNull(value);
77 return this;
78 }
79
80 @NonNull
81 public Builder namespace(@NonNull URI value) {
82 this.namespace = Objects.requireNonNull(value);
83 return this;
84 }
85
86 @NonNull
87 public Builder clazz(@NonNull String value) {
88 this.clazz = Objects.requireNonNull(value);
89 return this;
90 }
91
92 @NonNull
93 public Builder title(@NonNull String markdown) {
94 return title(MarkupLine.fromMarkdown(Objects.requireNonNull(markdown)));
95 }
96
97 @NonNull
98 public Builder title(@NonNull MarkupLine value) {
99 this.title = Objects.requireNonNull(value);
100 return this;
101 }
102
103 @NonNull
104 public Builder prose(@NonNull String markdown) {
105 return prose(MarkupMultiline.fromMarkdown(Objects.requireNonNull(markdown)));
106 }
107
108 @NonNull
109 public Builder prose(@NonNull MarkupMultiline value) {
110 this.prose = Objects.requireNonNull(value);
111 return this;
112 }
113
114 @NonNull
115 public Builder prop(@NonNull Property value) {
116 this.props.add(Objects.requireNonNull(value));
117 return this;
118 }
119
120 @NonNull
121 public Builder link(@NonNull Link value) {
122 this.links.add(Objects.requireNonNull(value));
123 return this;
124 }
125
126 @NonNull
127 public Builder part(@NonNull ControlPart value) {
128 this.parts.add(Objects.requireNonNull(value));
129 return this;
130 }
131
132 @NonNull
133 public ControlPart build() {
134 ControlPart retval = new ControlPart();
135
136 retval.setName(name);
137
138 if (id != null) {
139 retval.setId(id);
140 }
141 if (namespace != null) {
142 retval.setNs(namespace);
143 }
144 if (clazz != null) {
145 retval.setClazz(clazz);
146 }
147 if (prose != null) {
148 retval.setProse(prose);
149 }
150 if (title != null) {
151 retval.setTitle(title);
152 }
153 if (!props.isEmpty()) {
154 retval.setProps(props);
155 }
156 if (!links.isEmpty()) {
157 retval.setLinks(links);
158 }
159 if (!parts.isEmpty()) {
160 retval.setParts(parts);
161 }
162 return retval;
163 }
164 }
165 }