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