/* * ARX: Powerful Data Anonymization * Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.deidentifier.arx.gui.model; import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.deidentifier.arx.ARXConfiguration; import org.deidentifier.arx.AttributeType; import org.deidentifier.arx.AttributeType.Hierarchy; import org.deidentifier.arx.AttributeType.MicroAggregationFunctionDescription; import org.deidentifier.arx.Data; import org.deidentifier.arx.DataSubset; import org.deidentifier.arx.RowSet; import org.deidentifier.arx.aggregates.HierarchyBuilder; import org.deidentifier.arx.criteria.PrivacyCriterion; import org.deidentifier.arx.metric.Metric; /** * This class represents an input or output configuration. * * @author Fabian Prasser */ public class ModelConfiguration implements Serializable, Cloneable { /** SVUID. */ private static final long serialVersionUID = -2887699232096897527L; /** Minimum generalization. */ private Map<String, Integer> min = new HashMap<String, Integer>(); /** Maximum generalization. */ private Map<String, Integer> max = new HashMap<String, Integer>(); /** Input data. */ private transient Data input = null; /** Associated ARXConfiguration. */ private ARXConfiguration config = ARXConfiguration.create(); /** Is this model modified. */ private boolean modified = false; /** The associated hierarchies. */ private Map<String, Hierarchy> hierarchies = new HashMap<String, Hierarchy>(); /** The associated microaggregation functions. */ private Map<String, MicroAggregationFunctionDescription> microAggregationFunctions = new HashMap<String, MicroAggregationFunctionDescription>(); /** The associated handling of null values. */ private Map<String, Boolean> microAggregationIgnoreMissingData = new HashMap<String, Boolean>(); /** The associated mode */ private Map<String, ModelTransformationMode> transformationModes = new HashMap<String, ModelTransformationMode>(); /** The associated research subset. */ private RowSet researchSubset = null; /** The suppression weight. */ private Double suppressionWeight = null; /** Hierarchy builder. */ private Map<String, HierarchyBuilder<?>> hierarchyBuilders = null; /** * Delegates to an instance of ARXConfiguration. * * @param c * @return */ public ARXConfiguration addCriterion(PrivacyCriterion c) { setModified(); return config.addPrivacyModel(c); } @Override public ModelConfiguration clone() { final ModelConfiguration c = new ModelConfiguration(); c.input = input; c.min = new HashMap<String, Integer>(min); c.max = new HashMap<String, Integer>(max); c.config = config.clone(); c.hierarchies = new HashMap<String, Hierarchy>(hierarchies); // Clone subset boolean found = false; for (PrivacyCriterion pc : this.getCriteria()) { if (pc.isSubsetAvailable()) { DataSubset subset = pc.getDataSubset(); if (subset != null) { c.researchSubset = subset.getSet(); found = true; break; } } } if (!found) { c.researchSubset = this.researchSubset.clone(); } c.suppressionWeight = this.suppressionWeight; c.microAggregationFunctions = new HashMap<String, MicroAggregationFunctionDescription>(microAggregationFunctions); c.microAggregationIgnoreMissingData = new HashMap<String, Boolean>(microAggregationIgnoreMissingData); c.transformationModes = new HashMap<String, ModelTransformationMode>(transformationModes); return c; } /** * Delegates to an instance of ARXConfiguration. * * @param clazz * @return */ public boolean containsCriterion(Class<? extends PrivacyCriterion> clazz) { return config.isPrivacyModelSpecified(clazz); } /** * @return the adversaryCost */ public double getAdversaryCost() { return this.config.getCostBenefitConfiguration().getAdversaryCost(); } /** * @return the adversaryGain */ public double getAdversaryGain() { return this.config.getCostBenefitConfiguration().getAdversaryGain(); } /** * Delegates to an instance of ARXConfiguration. * * @return */ public double getAllowedOutliers() { return config.getMaxOutliers(); } /** * Returns the associated attribute weight. * * @param attribute * @return */ public double getAttributeWeight(String attribute) { return config.getAttributeWeight(attribute); } /** * Returns all weights. * * @return */ public Map<String, Double> getAttributeWeights() { return config.getAttributeWeights(); } /** * Returns the current config. * * @return */ public ARXConfiguration getConfig() { return config; } /** * Delegates to an instance of ARXConfiguration. * * @return */ public Set<PrivacyCriterion> getCriteria() { return config.getPrivacyModels(); } /** * Delegates to an instance of ARXConfiguration. * * @param <T> * @param clazz * @return */ public <T extends PrivacyCriterion> Set<T> getCriteria(Class<T> clazz) { return config.getPrivacyModels(clazz); } /** * Delegates to an instance of ARXConfiguration. * * @param <T> * @param clazz * @return */ public <T extends PrivacyCriterion> T getCriterion(Class<T> clazz) { return config.getPrivacyModel(clazz); } /** * @return * @see org.deidentifier.arx.ARXConfiguration#getHeuristicSearchThreshold() */ public int getHeuristicSearchThreshold() { return config.getHeuristicSearchThreshold(); } /** * @return * @see org.deidentifier.arx.ARXConfiguration#getHeuristicSearchTimeLimit() */ public int getHeuristicSearchTimeLimit() { return config.getHeuristicSearchTimeLimit(); } /** * Returns the set of all assigned hierarchies. * * @return */ public Map<String, Hierarchy> getHierarchies() { return this.hierarchies; } /** * Returns the assigned hierarchy, if any. Else null. * * @param attribute * @return */ public Hierarchy getHierarchy(String attribute) { return this.hierarchies.get(attribute); } /** * Returns the according builder. * * @param attr * @return */ public HierarchyBuilder<?> getHierarchyBuilder(String attr) { if (hierarchyBuilders == null) return null; else return hierarchyBuilders.get(attr); } /** * @return the input */ public Data getInput() { return input; } /** * Maximum generalization. * * @param attribute * @return */ public Integer getMaximumGeneralization(String attribute) { if (this.max == null) { return null; } return this.max.get(attribute); } /** * Delegates to an instance of ARXConfiguration. * * @return */ public Metric<?> getMetric() { return config.getQualityModel(); } /** * Returns the microaggregation function. * * @param attribute * @return */ public MicroAggregationFunctionDescription getMicroAggregationFunction(String attribute) { if (this.microAggregationFunctions == null) { this.microAggregationFunctions = new HashMap<String, MicroAggregationFunctionDescription>(); } return this.microAggregationFunctions.get(attribute); } /** * Returns the associated handling of missing data * @param attribute * @return */ public Boolean getMicroAggregationIgnoreMissingData(String attribute) { if (this.microAggregationIgnoreMissingData == null) { this.microAggregationIgnoreMissingData = new HashMap<String, Boolean>(); } Boolean ignore = this.microAggregationIgnoreMissingData.get(attribute); if (ignore == null) { return true; } else { return ignore; } } /** * Minimum generalization. * * @param attribute * @return */ public Integer getMinimumGeneralization(String attribute) { if (this.min == null) { return null; } return this.min.get(attribute); } /** * @return the publisherBenefit */ public double getPublisherBenefit() { return this.config.getCostBenefitConfiguration().getPublisherBenefit(); } /** * @return the publisherLoss */ public double getPublisherLoss() { return this.config.getCostBenefitConfiguration().getPublisherLoss(); } /** * Returns the current research subset. * * @return */ public RowSet getResearchSubset() { return researchSubset; } /** * Returns the suppression/generalization weight, that will be respected by * the NDS metric. * * @return */ public double getSuppressionWeight() { // For backwards compatibility if (this.suppressionWeight == null) { this.suppressionWeight = 0.5d; } return suppressionWeight; } /** * Returns the transformation mode for the given attribute. Returns ModelTransformationMode.GENERALIZATION * if no entry was found, for backwards compatibility * @param attribute * @return */ public ModelTransformationMode getTransformationMode(String attribute) { if (this.transformationModes == null) { this.transformationModes = new HashMap<String, ModelTransformationMode>(); } ModelTransformationMode result = this.transformationModes.get(attribute); if (result != null) { return result; } else { return ModelTransformationMode.GENERALIZATION; } } /** * @param type * @return * @see org.deidentifier.arx.ARXConfiguration#isAttributeTypeSuppressed(org.deidentifier.arx.AttributeType) */ public boolean isAttributeTypeSuppressed(AttributeType type) { return config.isAttributeTypeSuppressed(type); } /** * @return * @see org.deidentifier.arx.ARXConfiguration#isUseHeuristicSearchForSampleBasedCriteria() */ public boolean isHeuristicForSampleBasedCriteria() { return config.isUseHeuristicSearchForSampleBasedCriteria(); } /** * @return * @see org.deidentifier.arx.ARXConfiguration#isHeuristicSearchEnabled() */ public boolean isHeuristicSearchEnabled() { return config.isHeuristicSearchEnabled(); } /** * Has the config been modified. * * @return */ public boolean isModified() { return modified; } /** * Delegates to an instance of ARXConfiguration. * * @return */ public boolean isPracticalMonotonicity() { return config.isPracticalMonotonicity(); } /** * @return * @see org.deidentifier.arx.ARXConfiguration#isSuppressionAlwaysEnabled() */ public boolean isSuppressionAlwaysEnabled() { return config.isSuppressionAlwaysEnabled(); } /** * Returns whether microaggregation will be considered by utility measures * @return */ public boolean isUtilityBasedMicroaggregation() { return config.isUtilityBasedMicroaggregation(); } /** * Returns whether microaggregation will be considered using the mean squared error * @return */ public boolean isUtilityBasedMicroaggregationUseMeanSquaredError() { return config.isUtilityBasedMicroaggregationUseMeanSquaredError(); } /** * Removes all criteria. */ public void removeAllCriteria() { this.getCriteria().clear(); } /** * Delegates to an instance of ARXConfiguration. * * @param <T> * @param c * @return */ public <T extends PrivacyCriterion> boolean removeCriterion(PrivacyCriterion c) { setModified(); return config.removeCriterion(c); } /** * Removes a hierarchy. * * @param attribute */ public void removeHierarchy(String attribute) { this.hierarchies.remove(attribute); this.setModified(); } /** * Removes the builder for the given attribute. * * @param attr */ public void removeHierarchyBuilder(String attr) { if (hierarchyBuilders == null) return; setModified(); hierarchyBuilders.remove(attr); } /** * @param adversaryCost the adversaryCost to set */ public void setAdversaryCost(double adversaryCost) { if (this.getAdversaryCost() != adversaryCost) { this.setModified(); } this.config.getCostBenefitConfiguration().setAdversaryCost(adversaryCost); } /** * @param adversaryGain the adversaryGain to set */ public void setAdversaryGain(double adversaryGain) { if (this.getAdversaryGain() != adversaryGain) { this.setModified(); } this.config.getCostBenefitConfiguration().setAdversaryGain(adversaryGain); } /** * Delegates to an instance of ARXConfiguration. * * @param supp */ public void setAllowedOutliers(double supp) { setModified(); config.setMaxOutliers(supp); } /** * @param type * @param enabled * @see org.deidentifier.arx.ARXConfiguration#setAttributeTypeSuppressed(org.deidentifier.arx.AttributeType, boolean) */ public void setAttributeTypeSuppressed(AttributeType type, boolean enabled) { setModified(); config.setAttributeTypeSuppressed(type, enabled); } /** * Sets the according attribute weight. * * @param attribute * @param weight */ public void setAttributeWeight(String attribute, Double weight) { setModified(); config.setAttributeWeight(attribute, weight); } /** * @param value * @see org.deidentifier.arx.ARXConfiguration#setUseHeuristicSearchForSampleBasedCriteria(boolean) */ public void setHeuristicForSampleBasedCriteria(boolean value) { config.setUseHeuristicSearchForSampleBasedCriteria(value); } /** * @param heuristicSearchEnabled * @see org.deidentifier.arx.ARXConfiguration#setHeuristicSearchEnabled(boolean) */ public void setHeuristicSearchEnabled(boolean heuristicSearchEnabled) { config.setHeuristicSearchEnabled(heuristicSearchEnabled); } /** * @param numberOfTransformations * @see org.deidentifier.arx.ARXConfiguration#setHeuristicSearchThreshold(int) */ public void setHeuristicSearchThreshold(int numberOfTransformations) { config.setHeuristicSearchThreshold(numberOfTransformations); } /** * @param timeInMillis * @see org.deidentifier.arx.ARXConfiguration#setHeuristicSearchTimeLimit(int) */ public void setHeuristicSearchTimeLimit(int timeInMillis) { config.setHeuristicSearchTimeLimit(timeInMillis); } /** * Assigns a hierarchy. * * @param attribute * @param hierarchy */ public void setHierarchy(String attribute, Hierarchy hierarchy) { this.hierarchies.put(attribute, hierarchy); this.setModified(); } /** * Sets the given hierarchy builder. * * @param attr * @param builder */ public void setHierarchyBuilder(String attr, HierarchyBuilder<?> builder) { if (hierarchyBuilders == null) { hierarchyBuilders = new HashMap<String, HierarchyBuilder<?>>(); } setModified(); hierarchyBuilders.put(attr, builder); } /** * @param data * the input to set */ public void setInput(final Data data) { input = data; setModified(); } /** * Maximum generalization. * * @param attribute * @param max */ public void setMaximumGeneralization(String attribute, Integer max) { if (this.max == null) { this.max = new HashMap<String, Integer>(); } setModified(); this.max.put(attribute, max); } /** * Delegates to an instance of ARXConfiguration. * * @param metric */ public void setMetric(Metric<?> metric) { setModified(); config.setQualityModel(metric); } /** * Assigns a microaggregation function. * * @param attribute * @param microaggregation */ public void setMicroAggregationFunction(String attribute, MicroAggregationFunctionDescription microaggregation) { if (this.microAggregationFunctions == null) { this.microAggregationFunctions = new HashMap<String, MicroAggregationFunctionDescription>(); } this.microAggregationFunctions.put(attribute, microaggregation); this.setModified(); } /** * Determines whether or not to ignore missing data * * @param attribute * @param ignoreNullValues */ public void setMicroAggregationIgnoreMissingData(String attribute, boolean ignoreMissingData) { if (this.microAggregationIgnoreMissingData == null) { this.microAggregationIgnoreMissingData = new HashMap<String, Boolean>(); } this.microAggregationIgnoreMissingData.put(attribute, ignoreMissingData); this.setModified(); } /** * Minimum generalization. * * @param attribute * @param min */ public void setMinimumGeneralization(String attribute, Integer min) { if (this.min == null) { this.min = new HashMap<String, Integer>(); } setModified(); this.min.put(attribute, min); } /** * Delegates to an instance of ARXConfiguration. * * @param assumeMonotonicity */ public void setPracticalMonotonicity(boolean assumeMonotonicity) { setModified(); config.setPracticalMonotonicity(assumeMonotonicity); } /** * @param publisherBenefit the publisherBenefit to set */ public void setPublisherBenefit(double publisherBenefit) { if (this.getPublisherBenefit() != publisherBenefit) { this.setModified(); } this.config.getCostBenefitConfiguration().setPublisherBenefit(publisherBenefit); } /** * @param publisherLoss the publisherLoss to set */ public void setPublisherLoss(double publisherLoss) { if (this.getPublisherLoss() != publisherLoss) { this.setModified(); } this.config.getCostBenefitConfiguration().setPublisherLoss(publisherLoss); } /** * Sets the current research subset. * * @param subset */ public void setResearchSubset(RowSet subset) { setModified(); this.researchSubset = subset; } /** * @param enabled * @see org.deidentifier.arx.ARXConfiguration#setSuppressionAlwaysEnabled(boolean) */ public void setSuppressionAlwaysEnabled(boolean enabled) { setModified(); config.setSuppressionAlwaysEnabled(enabled); } /** * Sets the suppression/generalization weight, that will be respected by * the NDS metric. * * @param suppressionWeight */ public void setSuppressionWeight(double suppressionWeight) { setModified(); this.suppressionWeight = suppressionWeight; } /** * Sets the transformation mode * @param attribute * @param mode */ public void setTransformationMode(String attribute, ModelTransformationMode mode) { if (this.transformationModes == null) { this.transformationModes = new HashMap<String, ModelTransformationMode>(); } this.transformationModes.put(attribute, mode); setModified(); } /** * Sets the config unmodified. */ public void setUnmodified() { this.modified = false; } /** * Sets whether microaggregation will be considered by utility measures * @return */ public void setUseUtilityBasedMicroaggregation(boolean value) { setModified(); config.setUtilityBasedMicroaggregation(value); } /** * Sets whether microaggregation will be considered using the mean squared error * @return */ public void setUseUtilityBasedMicroaggregationMeanSquaredError(boolean value) { setModified(); config.setUtilityBasedMicroaggregationUseMeanSquaredError(value); } /** * Mark as modified. */ private void setModified() { modified = true; } }