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.catalog;
28
29 import gov.nist.secauto.metaschema.binding.io.IDeserializationHandler;
30 import gov.nist.secauto.metaschema.model.common.datatype.markup.MarkupLine;
31 import gov.nist.secauto.metaschema.model.common.util.CollectionUtil;
32 import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
33 import gov.nist.secauto.oscal.lib.model.Control;
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.Parameter;
37 import gov.nist.secauto.oscal.lib.model.Property;
38
39 import java.util.LinkedList;
40 import java.util.List;
41 import java.util.Objects;
42 import java.util.stream.Stream;
43
44 import edu.umd.cs.findbugs.annotations.NonNull;
45
46 public abstract class AbstractControl
47 implements IDeserializationHandler, IControl {
48 private Control parent;
49
50 @Override
51 public Control getParentControl() {
52 return parent;
53 }
54
55 @Override
56 public void setParentControl(Control parent) {
57 this.parent = parent;
58 }
59
60 @Override
61 public void beforeDeserialize(Object parent) {
62
63 }
64
65 @Override
66 public void afterDeserialize(Object parent) {
67 if (parent instanceof Control) {
68 setParentControl((Control) parent);
69 }
70 }
71
72 @NonNull
73 @Override
74 public Stream<String> getReferencedParameterIds() {
75
76
77 Stream<String> insertIds = CollectionUtil.listOrEmpty(getParts()).stream()
78
79 .flatMap(part -> Stream.concat(Stream.of(part), part.getPartsRecursively()))
80
81 .flatMap(part -> part.getInserts(insert -> "param".equals(insert.getType().toString())))
82
83 .map(insert -> insert.getIdReference().toString())
84 .flatMap(ObjectUtils::filterNull);
85
86
87 Stream<String> parameterIds = CollectionUtil.listOrEmpty(getParams()).stream()
88 .flatMap(ObjectUtils::filterNull)
89 .flatMap(param -> param.getParameterReferences());
90
91 return ObjectUtils.notNull(
92 Stream.concat(insertIds, parameterIds).distinct());
93 }
94
95 @NonNull
96 public static Builder builder(@NonNull String id) {
97 return new Builder(id);
98 }
99
100 public static class Builder {
101 @NonNull
102 private final String id;
103
104 private String clazz;
105 private MarkupLine title;
106 private final List<Parameter> params = new LinkedList<>();
107 private final List<Property> props = new LinkedList<>();
108 private final List<Link> links = new LinkedList<>();
109 private final List<ControlPart> parts = new LinkedList<>();
110 private final List<Control> controls = new LinkedList<>();
111
112 public Builder(@NonNull String id) {
113 this.id = Objects.requireNonNull(id, "id");
114 }
115
116 @NonNull
117 public Builder clazz(@NonNull String value) {
118 this.clazz = Objects.requireNonNull(value);
119 return this;
120 }
121
122 @NonNull
123 public Builder title(@NonNull String markdown) {
124 this.title = MarkupLine.fromMarkdown(Objects.requireNonNull(markdown));
125 return this;
126 }
127
128 @NonNull
129 public Builder title(@NonNull MarkupLine value) {
130 this.title = Objects.requireNonNull(value);
131 return this;
132 }
133
134 @NonNull
135 public Builder param(@NonNull Parameter value) {
136 this.params.add(Objects.requireNonNull(value));
137 return this;
138 }
139
140 @NonNull
141 public Builder prop(@NonNull Property value) {
142 this.props.add(Objects.requireNonNull(value));
143 return this;
144 }
145
146 @NonNull
147 public Builder link(@NonNull Link value) {
148 this.links.add(Objects.requireNonNull(value));
149 return this;
150 }
151
152 @NonNull
153 public Builder part(@NonNull ControlPart value) {
154 this.parts.add(Objects.requireNonNull(value));
155 return this;
156 }
157
158 @NonNull
159 public Builder control(@NonNull Control value) {
160 this.controls.add(Objects.requireNonNull(value));
161 return this;
162 }
163
164 @NonNull
165 public Control build() {
166 Control retval = new Control();
167 retval.setId(id);
168
169 if (title == null) {
170 throw new IllegalStateException("a title must be provided");
171 }
172 retval.setTitle(title);
173
174 if (clazz != null) {
175 retval.setClazz(clazz);
176 }
177 if (!params.isEmpty()) {
178 retval.setParams(params);
179 }
180 if (!props.isEmpty()) {
181 retval.setProps(props);
182 }
183 if (!links.isEmpty()) {
184 retval.setLinks(links);
185 }
186 if (!parts.isEmpty()) {
187 retval.setParts(parts);
188 }
189 if (!controls.isEmpty()) {
190 controls.forEach(control -> control.setParentControl(retval));
191 retval.setControls(controls);
192 }
193
194 return retval;
195 }
196 }
197 }