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