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 promotedControls.get().add(control); 085 } 086 087 @Override 088 public void applyTo(@NonNull Catalog parent) { 089 applyRemovesTo(parent); 090 getPromotedParameters().forEach(param -> parent.addParam(ObjectUtils.notNull(param))); 091 getPromotedControls().forEach(control -> { 092 assert control != null; 093 parent.addControl(control); 094 control.setParentControl(null); 095 }); 096 } 097 098 @Override 099 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}