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