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.profile.resolver.selection;
28
29 import gov.nist.secauto.metaschema.model.common.util.ObjectUtils;
30 import gov.nist.secauto.oscal.lib.model.Catalog;
31 import gov.nist.secauto.oscal.lib.model.CatalogGroup;
32 import gov.nist.secauto.oscal.lib.model.Control;
33 import gov.nist.secauto.oscal.lib.model.Parameter;
34
35 import org.apache.logging.log4j.LogManager;
36 import org.apache.logging.log4j.Logger;
37
38 import java.util.Collection;
39 import java.util.Collections;
40 import java.util.HashSet;
41 import java.util.LinkedHashSet;
42 import java.util.List;
43 import java.util.Set;
44
45 import edu.umd.cs.findbugs.annotations.NonNull;
46 import nl.talsmasoftware.lazy4j.Lazy;
47
48 public class DefaultResult implements IResult {
49 private static final Logger LOGGER = LogManager.getLogger(DefaultResult.class);
50
51 @NonNull
52 private final Lazy<Set<Control>> promotedControls = ObjectUtils.notNull(Lazy.lazy(LinkedHashSet::new));
53 @NonNull
54 private final Lazy<Set<Parameter>> promotedParameters = ObjectUtils.notNull(Lazy.lazy(LinkedHashSet::new));
55 @NonNull
56 private final Lazy<Set<CatalogGroup>> removedGroups = ObjectUtils.notNull(Lazy.lazy(HashSet::new));
57 @NonNull
58 private final Lazy<Set<Control>> removedControls = ObjectUtils.notNull(Lazy.lazy(HashSet::new));
59 @NonNull
60 private final Lazy<Set<Parameter>> removedParameters = ObjectUtils.notNull(Lazy.lazy(HashSet::new));
61
62 @SuppressWarnings("null")
63 @NonNull
64 protected Collection<Parameter> getPromotedParameters() {
65 return promotedParameters.getIfAvailable().orElse(Collections.emptySet());
66 }
67
68 @SuppressWarnings("null")
69 @NonNull
70 protected Collection<Control> getPromotedControls() {
71 return promotedControls.getIfAvailable().orElse(Collections.emptySet());
72 }
73
74 @SuppressWarnings("null")
75 @NonNull
76 protected Collection<CatalogGroup> getRemovedGroups() {
77 return removedGroups.getIfAvailable().orElse(Collections.emptySet());
78 }
79
80 @SuppressWarnings("null")
81 @NonNull
82 protected Collection<Control> getRemovedControls() {
83 return removedControls.getIfAvailable().orElse(Collections.emptySet());
84 }
85
86 @SuppressWarnings("null")
87 @NonNull
88 protected Collection<Parameter> getRemovedParameters() {
89 return removedParameters.getIfAvailable().orElse(Collections.emptySet());
90 }
91
92 @Override
93 public void promoteParameter(@NonNull Parameter param) {
94 if (LOGGER.isDebugEnabled()) {
95 LOGGER.atDebug().log("promoting parameter '{}'", param.getId());
96 }
97 promotedParameters.get().add(param);
98 }
99
100 @Override
101 public void promoteControl(@NonNull Control control) {
102 if (LOGGER.isDebugEnabled()) {
103 LOGGER.atDebug().log("promoting control '{}'", control.getId());
104 }
105 promotedControls.get().add(control);
106 }
107
108 @Override
109 public void applyTo(@NonNull Catalog parent) {
110 applyRemovesTo(parent);
111 getPromotedParameters().forEach(param -> parent.addParam(ObjectUtils.notNull(param)));
112 getPromotedControls().forEach(control -> {
113 assert control != null;
114 parent.addControl(control);
115 control.setParentControl(null);
116 });
117 }
118
119 @Override
120 public void applyTo(@NonNull CatalogGroup parent) {
121 applyRemovesTo(parent);
122 getPromotedControls().forEach(control -> {
123 assert control != null;
124 parent.addControl(control);
125 control.setParentControl(null);
126 });
127 getPromotedParameters().forEach(param -> parent.addParam(ObjectUtils.notNull(param)));
128 }
129
130 @Override
131 public void applyTo(@NonNull Control parent) {
132 applyRemovesTo(parent);
133 getPromotedControls().forEach(control -> {
134 assert control != null;
135 parent.addControl(control);
136 control.setParentControl(null);
137 });
138 getPromotedParameters().forEach(param -> parent.addParam(ObjectUtils.notNull(param)));
139 }
140
141 public void applyRemovesTo(Catalog parent) {
142 removeItems(parent.getGroups(), getRemovedGroups());
143 removeItems(parent.getControls(), getRemovedControls());
144 removeItems(parent.getParams(), getRemovedParameters());
145 }
146
147 public void applyRemovesTo(CatalogGroup parent) {
148 removeItems(parent.getGroups(), getRemovedGroups());
149 removeItems(parent.getControls(), getRemovedControls());
150 removeItems(parent.getParams(), getRemovedParameters());
151 }
152
153 public void applyRemovesTo(Control parent) {
154 removeItems(parent.getControls(), getRemovedControls());
155 removeItems(parent.getParams(), getRemovedParameters());
156 }
157
158 public DefaultResult append(@NonNull DefaultResult that) {
159 lazyAppend(promotedControls, that.promotedControls);
160 lazyAppend(promotedParameters, that.promotedParameters);
161 lazyAppend(removedGroups, that.removedGroups);
162 lazyAppend(removedControls, that.removedControls);
163 lazyAppend(removedParameters, that.removedParameters);
164 return this;
165 }
166
167 public DefaultResult appendPromoted(@NonNull DefaultResult that) {
168 lazyAppend(promotedControls, that.promotedControls);
169 lazyAppend(promotedParameters, that.promotedParameters);
170 return this;
171 }
172
173 protected static <T> void lazyAppend(@NonNull Lazy<Set<T>> self, @NonNull Lazy<Set<T>> other) {
174 if (other.isAvailable()) {
175 Set<T> otherSet = other.get();
176 if (!otherSet.isEmpty()) {
177 self.get().addAll(otherSet);
178 }
179 }
180 }
181
182 protected static <T> void removeItems(List<T> list, @NonNull Collection<T> itemsToDelete) {
183 itemsToDelete.forEach(item -> {
184 if (!list.remove(item)) {
185 LOGGER.atError().log("item didn't exist in list");
186 }
187 });
188 }
189
190 public void removeGroup(CatalogGroup group) {
191 if (LOGGER.isDebugEnabled()) {
192 LOGGER.atDebug().log("Requesting removal of group '{}'.", group.getId());
193 }
194 removedGroups.get().add(group);
195 }
196
197 public void removeControl(Control control) {
198 if (LOGGER.isDebugEnabled()) {
199 LOGGER.atDebug().log("Requesting removal of control '{}'.", control.getId());
200 }
201 removedControls.get().add(control);
202 }
203
204 public void removeParameter(Parameter parameter) {
205 if (LOGGER.isDebugEnabled()) {
206 LOGGER.atDebug().log("Requesting removal of parameter '{}'.", parameter.getId());
207 }
208 removedParameters.get().add(parameter);
209 }
210 }