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