001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.oscal.lib.profile.resolver.selection; 007 008import gov.nist.secauto.metaschema.core.util.ObjectUtils; 009import gov.nist.secauto.oscal.lib.model.Catalog; 010import gov.nist.secauto.oscal.lib.model.CatalogGroup; 011import gov.nist.secauto.oscal.lib.model.Control; 012import gov.nist.secauto.oscal.lib.model.Parameter; 013 014import org.apache.logging.log4j.LogManager; 015import org.apache.logging.log4j.Logger; 016 017import java.util.Collection; 018import java.util.Collections; 019import java.util.HashSet; 020import java.util.LinkedHashSet; 021import java.util.List; 022import java.util.Set; 023 024import edu.umd.cs.findbugs.annotations.NonNull; 025import nl.talsmasoftware.lazy4j.Lazy; 026 027public class DefaultResult implements IResult { 028 private static final Logger LOGGER = LogManager.getLogger(DefaultResult.class); 029 030 @NonNull 031 private final Lazy<Set<Control>> promotedControls = ObjectUtils.notNull(Lazy.lazy(LinkedHashSet::new)); 032 @NonNull 033 private final Lazy<Set<Parameter>> promotedParameters = ObjectUtils.notNull(Lazy.lazy(LinkedHashSet::new)); 034 @NonNull 035 private final Lazy<Set<CatalogGroup>> removedGroups = ObjectUtils.notNull(Lazy.lazy(HashSet::new)); 036 @NonNull 037 private final Lazy<Set<Control>> removedControls = ObjectUtils.notNull(Lazy.lazy(HashSet::new)); 038 @NonNull 039 private final Lazy<Set<Parameter>> removedParameters = ObjectUtils.notNull(Lazy.lazy(HashSet::new)); 040 041 @SuppressWarnings("null") 042 @NonNull 043 protected Collection<Parameter> getPromotedParameters() { 044 return promotedParameters.getIfAvailable().orElse(Collections.emptySet()); 045 } 046 047 @SuppressWarnings("null") 048 @NonNull 049 protected Collection<Control> getPromotedControls() { 050 return promotedControls.getIfAvailable().orElse(Collections.emptySet()); 051 } 052 053 @SuppressWarnings("null") 054 @NonNull 055 protected Collection<CatalogGroup> getRemovedGroups() { 056 return removedGroups.getIfAvailable().orElse(Collections.emptySet()); 057 } 058 059 @SuppressWarnings("null") 060 @NonNull 061 protected Collection<Control> getRemovedControls() { 062 return removedControls.getIfAvailable().orElse(Collections.emptySet()); 063 } 064 065 @SuppressWarnings("null") 066 @NonNull 067 protected Collection<Parameter> getRemovedParameters() { 068 return removedParameters.getIfAvailable().orElse(Collections.emptySet()); 069 } 070 071 @Override 072 public void promoteParameter(@NonNull Parameter param) { 073 if (LOGGER.isDebugEnabled()) { 074 LOGGER.atDebug().log("promoting parameter '{}'", param.getId()); 075 } 076 promotedParameters.get().add(param); 077 } 078 079 @Override 080 public void promoteControl(@NonNull Control control) { 081 if (LOGGER.isDebugEnabled()) { 082 LOGGER.atDebug().log("promoting control '{}'", control.getId()); 083 } 084 // promote 085 promotedControls.get().add(control); 086 } 087 088 @Override 089 public void applyTo(@NonNull Catalog parent) { 090 applyRemovesTo(parent); 091 getPromotedParameters().forEach(param -> parent.addParam(ObjectUtils.notNull(param))); 092 getPromotedControls().forEach(control -> { 093 assert control != null; 094 // add promoted control 095 parent.addControl(control); 096 control.setParentControl(null); 097 }); 098 } 099 100 @Override 101 public void applyTo(@NonNull CatalogGroup parent) { 102 applyRemovesTo(parent); 103 getPromotedControls().forEach(control -> { 104 assert control != null; 105 parent.addControl(control); 106 control.setParentControl(null); 107 }); 108 getPromotedParameters().forEach(param -> parent.addParam(ObjectUtils.notNull(param))); 109 } 110 111 @Override 112 public void applyTo(@NonNull Control parent) { 113 applyRemovesTo(parent); 114 getPromotedControls().forEach(control -> { 115 assert control != null; 116 parent.addControl(control); 117 control.setParentControl(null); 118 }); 119 getPromotedParameters().forEach(param -> parent.addParam(ObjectUtils.notNull(param))); 120 } 121 122 public void applyRemovesTo(Catalog parent) { 123 removeItems(parent.getGroups(), getRemovedGroups()); 124 removeItems(parent.getControls(), getRemovedControls()); 125 removeItems(parent.getParams(), getRemovedParameters()); 126 } 127 128 public void applyRemovesTo(CatalogGroup parent) { 129 removeItems(parent.getGroups(), getRemovedGroups()); 130 removeItems(parent.getControls(), getRemovedControls()); 131 removeItems(parent.getParams(), getRemovedParameters()); 132 } 133 134 public void applyRemovesTo(Control parent) { 135 removeItems(parent.getControls(), getRemovedControls()); 136 removeItems(parent.getParams(), getRemovedParameters()); 137 } 138 139 public DefaultResult append(@NonNull DefaultResult that) { 140 lazyAppend(promotedControls, that.promotedControls); 141 lazyAppend(promotedParameters, that.promotedParameters); 142 lazyAppend(removedGroups, that.removedGroups); 143 lazyAppend(removedControls, that.removedControls); 144 lazyAppend(removedParameters, that.removedParameters); 145 return this; 146 } 147 148 public DefaultResult appendPromoted(@NonNull DefaultResult that) { 149 lazyAppend(promotedControls, that.promotedControls); 150 lazyAppend(promotedParameters, that.promotedParameters); 151 return this; 152 } 153 154 protected static <T> void lazyAppend(@NonNull Lazy<Set<T>> self, @NonNull Lazy<Set<T>> other) { 155 if (other.isAvailable()) { 156 Set<T> otherSet = other.get(); 157 if (!otherSet.isEmpty()) { 158 self.get().addAll(otherSet); 159 } 160 } 161 } 162 163 protected static <T> void removeItems(List<T> list, @NonNull Collection<T> itemsToDelete) { 164 itemsToDelete.forEach(item -> { 165 if (!list.remove(item)) { 166 LOGGER.atError().log("item didn't exist in list"); 167 } 168 }); 169 } 170 171 public void removeGroup(CatalogGroup group) { 172 if (LOGGER.isDebugEnabled()) { 173 LOGGER.atDebug().log("Requesting removal of group '{}'.", group.getId()); 174 } 175 removedGroups.get().add(group); 176 } 177 178 public void removeControl(Control control) { 179 if (LOGGER.isDebugEnabled()) { 180 LOGGER.atDebug().log("Requesting removal of control '{}'.", control.getId()); 181 } 182 removedControls.get().add(control); 183 } 184 185 public void removeParameter(Parameter parameter) { 186 if (LOGGER.isDebugEnabled()) { 187 LOGGER.atDebug().log("Requesting removal of parameter '{}'.", parameter.getId()); 188 } 189 removedParameters.get().add(parameter); 190 } 191}