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