/*
* 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.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.deidentifier.arx.ARXAnonymizer;
import org.deidentifier.arx.ARXConfiguration;
import org.deidentifier.arx.ARXLattice.ARXNode;
import org.deidentifier.arx.ARXPopulationModel;
import org.deidentifier.arx.ARXResult;
import org.deidentifier.arx.AttributeType;
import org.deidentifier.arx.AttributeType.Hierarchy;
import org.deidentifier.arx.AttributeType.MicroAggregationFunction;
import org.deidentifier.arx.DataDefinition;
import org.deidentifier.arx.DataHandle;
import org.deidentifier.arx.DataSubset;
import org.deidentifier.arx.aggregates.HierarchyBuilder;
import org.deidentifier.arx.criteria.Inclusion;
import org.deidentifier.arx.criteria.PrivacyCriterion;
import org.deidentifier.arx.gui.resources.Resources;
import org.deidentifier.arx.io.CSVSyntax;
import org.deidentifier.arx.metric.MetricConfiguration;
import org.deidentifier.arx.metric.MetricDescription;
/**
* This class implements a large portion of the model used by the GUI.
*
* @author Fabian Prasser
* @author James Gaupp
*/
public class Model implements Serializable {
/**
* The currently selected perspective
* @author Fabian Prasser
*/
public static enum Perspective {
CONFIGURATION,
EXPLORATION,
ANALYSIS,
RISK
}
/** SVUID. */
private static final long serialVersionUID = -7669920657919151279L;
/* *****************************************
* TRANSIENT VARIABLES
*******************************************/
/** The current anonymizer, if any. */
private transient ARXAnonymizer anonymizer = null;
/** The current output data. */
private transient DataHandle output = null;
/** The currently displayed transformation. */
private transient ARXNode outputNode = null;
/** The path to the project file. */
private transient String path = null;
/** The current result. */
private transient ARXResult result = null;
/** The currently selected node. */
private transient ARXNode selectedNode = null;
/** The clip board. */
private transient ModelClipboard clipboard = null;
/** The perspective */
private transient Perspective perspective = Perspective.CONFIGURATION;
/* *****************************************
* PARAMETERS AND THRESHOLDS
*******************************************/
/** Anonymization parameter. */
private double snapshotSizeDataset = 0.2d;
/** Anonymization parameter. */
private double snapshotSizeSnapshot = 0.8d;
/** Anonymization parameter. */
private int historySize = 200;
/** Threshold. */
private int maximalSizeForComplexOperations = 5000000;
/** Threshold. */
private int initialNodesInViewer = 100;
/** Threshold. */
private int maxNodesInViewer = 700;
/* *****************************************
* PROJECT METADATA
******************************************/
/** The project description. */
private String description;
/** The size of the input file. */
private long inputBytes = 0L; //$NON-NLS-1$
/** Is the project file modified. */
private boolean modified = false;
/** The project name. */
private String name = null;
/** Left for backwards compatibility only! */
private char separator = ';'; //$NON-NLS-1$
/** The projects CSV syntax */
private CSVSyntax csvSyntax;
/** Execution time of last anonymization. */
private long time;
/** Locale. */
// TODO: This is only a quick-fix. A locale should be definable for each data type individually.
private Locale locale = null;
/** The audit trail*/
private List<ModelAuditTrailEntry> auditTrail = new ArrayList<ModelAuditTrailEntry>();
/* *****************************************
* DEBUGGING
******************************************/
/** Is the debugging mode enabled. */
private boolean debugEnabled = false;
/* *****************************************
* VISUALIZATIONS
******************************************/
/** Indices of groups in the current output view. */
private int[] groups;
/** Label. */
private String optimalNodeAsString;
/** Label. */
private String outputNodeAsString;
/** Current selection. */
private String selectedAttribute = null;
/** Enable/disable. */
private Boolean showVisualization = true;
/** Last two selections. */
private String[] pair = new String[] { null, null };
/* *****************************************
* SUBSET MANAGEMENT
******************************************/
/** Query. */
private String query = ""; //$NON-NLS-1$
/** Origin of current subset. */
private String subsetOrigin = "All"; //$NON-NLS-1$
/* *****************************************
* SUB-MODELS
******************************************/
/** The current input configuration. */
private ModelConfiguration inputConfig = new ModelConfiguration();
/** A filter describing which transformations are currently selected. */
private ModelNodeFilter nodeFilter = null;
/** Configuration of the data view. */
private ModelViewConfig viewConfig = new ModelViewConfig();
/** The current output configuration. */
private ModelConfiguration outputConfig = null;
/** The current risk model. */
private ModelRisk riskModel = null;
/* *****************************************
* PRIVACY CRITERIA
* *****************************************/
/** Model for a specific privacy criterion. */
private ModelDPresenceCriterion dPresenceModel = new ModelDPresenceCriterion();
/** Model for a specific privacy criterion. */
private ModelKMapCriterion kMapModel = new ModelKMapCriterion();
/** Model for a specific privacy criterion. */
private ModelKAnonymityCriterion kAnonymityModel = new ModelKAnonymityCriterion();
/** Model for a specific privacy criterion. */
private Map<String, ModelLDiversityCriterion> lDiversityModel = new HashMap<String, ModelLDiversityCriterion>();
/** Model for a specific privacy criterion. */
private Map<String, ModelTClosenessCriterion> tClosenessModel = new HashMap<String, ModelTClosenessCriterion>();
/** Model for a specific privacy criterion. */
private Set<ModelRiskBasedCriterion> riskBasedModel = new HashSet<ModelRiskBasedCriterion>();
/** Model for a specific privacy criterion. */
private ModelDifferentialPrivacyCriterion differentialPrivacyModel = new ModelDifferentialPrivacyCriterion();
/** Model for a specific privacy criterion. */
private Map<String, ModelDDisclosurePrivacyCriterion> dDisclosurePrivacyModel = new HashMap<String, ModelDDisclosurePrivacyCriterion>();
/** Model for a specific privacy criterion. */
private ModelProfitabilityCriterion stackelbergPrivacyModel = new ModelProfitabilityCriterion();
/** Model for a specific privacy criterion. */
private Map<String, ModelBLikenessCriterion> bLikenessModel = new HashMap<String, ModelBLikenessCriterion>();
/* *****************************************
* UTILITY ANALYSIS
******************************************/
/** Configuration. */
private MetricConfiguration metricConfig = null;
/** Description. */
private MetricDescription metricDescription = null;
/** Summary statistics */
private Boolean useListwiseDeletion = true;
/** Utility estimation during anonymization */
private Boolean useFunctionalHierarchies = true;
/* *****************************************
* RISK ANALYSIS
******************************************/
/** Selected quasi identifiers*/
private Set<String> selectedQuasiIdentifiers = null;
/* *****************************************
* LOCAL RECODING
******************************************/
/** The local recoding model */
private ModelLocalRecoding localRecodingModel = new ModelLocalRecoding();
/* *****************************************
* Data Mining
*******************************************/
/** Selected attributes */
private Set<String> selectedFeatures = null;
/** Selected attributes */
private Set<String> selectedClasses = null;
/** Model */
private ModelClassification classificationModel = new ModelClassification();
/**
* Creates a new instance.
*
* @param name
* @param description
* @param locale
*/
public Model(final String name, final String description, Locale locale) {
this.name = name;
this.description = description;
this.locale = locale;
setModified();
}
/**
* Adds an entry to the audit trail
* @param entry
*/
public void addAuditTrailEntry(ModelAuditTrailEntry entry) {
this.getAuditTrail().add(entry);
this.setModified();
}
/**
* Creates an anonymizer for the current config.
*
* @return
*/
public ARXAnonymizer createAnonymizer() {
// Initialize anonymizer
this.anonymizer = new ARXAnonymizer();
this.anonymizer.setHistorySize(getHistorySize());
this.anonymizer.setMaximumSnapshotSizeDataset(getSnapshotSizeDataset());
this.anonymizer.setMaximumSnapshotSizeSnapshot(getSnapshotSizeSnapshot());
// Add all criteria
this.createConfig();
// Return the anonymizer
return anonymizer;
}
/**
* Replaces the output config with a clone of the input config.
*/
public void createClonedConfig() {
// Clone the config
outputConfig = inputConfig.clone();
this.setModified();
}
/**
* Creates an ARXConfiguration.
*/
public void createConfig() {
ModelConfiguration config = getInputConfig();
DataDefinition definition = getInputDefinition();
// Initialize the config
config.removeAllCriteria();
if (definition == null) return;
// Initialize the metric
config.setMetric(this.getMetricDescription().createInstance(this.getMetricConfiguration()));
// Initialize definition
for (String attr : definition.getQuasiIdentifyingAttributes()) {
// Reset
definition.resetAttributeType(attr);
definition.resetHierarchy(attr);
definition.resetHierarchyBuilder(attr);
definition.resetMaximumGeneralization(attr);
definition.resetMicroAggregationFunction(attr);
definition.resetMinimumGeneralization(attr);
// This increases the precision of the Loss utility measure
if (this.getUseFunctionalHierarchies() && config.getHierarchyBuilder(attr) != null) {
definition.setHierarchy(attr, config.getHierarchyBuilder(attr));
} else {
definition.setHierarchy(attr, (HierarchyBuilder<?>)null);
}
// Set hierarchy
Hierarchy hierarchy = config.getHierarchy(attr);
if (hierarchy != null && hierarchy.getHierarchy() != null) {
definition.setHierarchy(attr, hierarchy);
}
// Set attribute type
definition.setAttributeType(attr, AttributeType.QUASI_IDENTIFYING_ATTRIBUTE);
if (config.getTransformationMode(attr) == ModelTransformationMode.MICRO_AGGREGATION) {
// Prepare for microaggregation
MicroAggregationFunction function = config.getMicroAggregationFunction(attr).createInstance(config.getMicroAggregationIgnoreMissingData(attr));
definition.setMicroAggregationFunction(attr, function);
} else {
// Prepare for generalization
definition.setMicroAggregationFunction(attr, null);
Integer min = config.getMinimumGeneralization(attr);
Integer max = config.getMaximumGeneralization(attr);
if (min != null) {
definition.setMinimumGeneralization(attr, min);
}
if (max != null) {
definition.setMaximumGeneralization(attr, max);
}
}
}
if (this.differentialPrivacyModel != null &&
this.differentialPrivacyModel.isEnabled()) {
config.addCriterion(this.differentialPrivacyModel.getCriterion(this));
}
if (this.kAnonymityModel != null &&
this.kAnonymityModel.isEnabled()) {
config.addCriterion(this.kAnonymityModel.getCriterion(this));
}
if (this.kMapModel != null &&
this.kMapModel.isEnabled()) {
config.addCriterion(this.kMapModel.getCriterion(this));
}
if (this.dPresenceModel != null &&
this.dPresenceModel.isEnabled()) {
config.addCriterion(this.dPresenceModel.getCriterion(this));
}
if (this.stackelbergPrivacyModel != null &&
this.stackelbergPrivacyModel.isEnabled()) {
config.addCriterion(this.stackelbergPrivacyModel.getCriterion(this));
}
for (Entry<String, ModelLDiversityCriterion> entry : this.lDiversityModel.entrySet()){
if (entry.getValue() != null &&
entry.getValue().isEnabled()) {
config.addCriterion(entry.getValue().getCriterion(this));
}
}
for (Entry<String, ModelTClosenessCriterion> entry : this.tClosenessModel.entrySet()){
if (entry.getValue() != null &&
entry.getValue().isEnabled()) {
if (entry.getValue().getVariant()==1){ // EMD with hierarchy
if (config.getHierarchy(entry.getValue().getAttribute())==null){
config.setHierarchy(entry.getValue().getAttribute(), Hierarchy.create());
}
}
PrivacyCriterion criterion = entry.getValue().getCriterion(this);
config.addCriterion(criterion);
}
}
for (Entry<String, ModelDDisclosurePrivacyCriterion> entry : this.dDisclosurePrivacyModel.entrySet()){
if (entry.getValue() != null &&
entry.getValue().isEnabled()) {
config.addCriterion(entry.getValue().getCriterion(this));
}
}
for (Entry<String, ModelBLikenessCriterion> entry : this.bLikenessModel.entrySet()){
if (entry.getValue() != null &&
entry.getValue().isEnabled()) {
config.addCriterion(entry.getValue().getCriterion(this));
}
}
for (ModelRiskBasedCriterion entry : this.riskBasedModel){
if (entry != null && entry.isEnabled()) {
PrivacyCriterion criterion = entry.getCriterion(this);
config.addCriterion(criterion);
}
}
// If a subset has been defined
if (config.getInput() != null && config.getResearchSubset() != null &&
config.getResearchSubset().size() != config.getInput().getHandle().getNumRows()) {
// Configure it, if not done already
boolean subsetDefined = false;
for (PrivacyCriterion c : config.getCriteria()) {
// (e,d)-DP will return false at this point,
// but consistency will be checked by ARXConfiguration.initialize(...)
subsetDefined |= c.isSubsetAvailable();
}
// Add, if missing
if (!subsetDefined) {
DataSubset subset = DataSubset.create(config.getInput(), config.getResearchSubset());
config.addCriterion(new Inclusion(subset));
}
}
}
/**
* Creates an ARXConfiguration for the subset.
*
* @return
*/
public ARXConfiguration createSubsetConfig() {
// Create a temporary config
ARXConfiguration config = ARXConfiguration.create();
// Add an enclosure criterion
DataSubset subset = DataSubset.create(getInputConfig().getInput(),
getInputConfig().getResearchSubset());
config.addPrivacyModel(new Inclusion(subset));
// Return the config
return config;
}
/**
* Returns the current anonymizer.
*
* @return
*/
public ARXAnonymizer getAnonymizer() {
return anonymizer;
}
/**
* Returns the last two selected attributes.
*
* @return
*/
public String[] getAttributePair() {
if (pair == null) pair = new String[] { null, null };
return pair;
}
/**
* Returns the audit trail
* @return
*/
public List<ModelAuditTrailEntry> getAuditTrail() {
if (this.auditTrail == null) {
this.auditTrail = new ArrayList<ModelAuditTrailEntry>();
}
return auditTrail;
}
/**
* Returns the classification model
* @return
*/
public ModelClassification getClassificationModel() {
if (this.classificationModel == null) {
this.classificationModel = new ModelClassification();
}
return this.classificationModel;
}
/**
* Returns the clipboard.
*
* @return
*/
public ModelClipboard getClipboard(){
if (clipboard==null){
clipboard = new ModelClipboard();
}
return clipboard;
}
/**
* Gets the csv config model.
* @return
*/
public CSVSyntax getCSVSyntax() {
if (csvSyntax == null) {
csvSyntax = new CSVSyntax();
csvSyntax.setDelimiter(separator);
}
return csvSyntax;
}
/**
* Returns the d-disclosure privacy model.
*
* @return
*/
public Map<String, ModelDDisclosurePrivacyCriterion> getDDisclosurePrivacyModel() {
if (this.dDisclosurePrivacyModel == null) {
this.dDisclosurePrivacyModel = new HashMap<String, ModelDDisclosurePrivacyCriterion>();
DataHandle handle = inputConfig.getInput().getHandle();
for (int col = 0; col < handle.getNumColumns(); col++) {
String attribute = handle.getAttributeName(col);
dDisclosurePrivacyModel.put(attribute, new ModelDDisclosurePrivacyCriterion(attribute));
}
}
return dDisclosurePrivacyModel;
}
/**
* Returns the b-Likeness privacy model.
*
* @return
*/
public Map<String, ModelBLikenessCriterion> getBLikenessModel() {
if (this.bLikenessModel == null) {
this.bLikenessModel = new HashMap<String, ModelBLikenessCriterion>();
DataHandle handle = inputConfig.getInput().getHandle();
for (int col = 0; col < handle.getNumColumns(); col++) {
String attribute = handle.getAttributeName(col);
bLikenessModel.put(attribute, new ModelBLikenessCriterion(attribute));
}
}
return bLikenessModel;
}
/**
* Returns the project description.
*
* @return
*/
public String getDescription() {
return description;
}
/**
* Returns the (e,d)-DP model.
*
* @return
*/
public ModelDifferentialPrivacyCriterion getDifferentialPrivacyModel() {
if (this.differentialPrivacyModel == null) {
this.differentialPrivacyModel = new ModelDifferentialPrivacyCriterion();
}
return differentialPrivacyModel;
}
/**
* Returns the d-presence model.
*
* @return
*/
public ModelDPresenceCriterion getDPresenceModel() {
return dPresenceModel;
}
/**
* Returns a list of indices of all equivalence classes.
*
* @return
*/
public int[] getGroups() {
// TODO: Refactor to colors[groups[row]]
return this.groups;
}
/**
* Returns the according parameter.
*
* @return
*/
public int getHistorySize() {
return historySize;
}
/**
* Returns an upper bound on the number of nodes that will initially
* be displayed in the lattice viewer.
*
* @return
*/
public int getInitialNodesInViewer() {
return initialNodesInViewer;
}
/**
* Returns the size in bytes of the input file.
*
* @return
*/
public long getInputBytes() {
return inputBytes;
}
/**
* Returns the input configuration.
*
* @return
*/
public ModelConfiguration getInputConfig() {
return inputConfig;
}
/**
* Returns the input definition.
*
* @return
*/
public DataDefinition getInputDefinition(){
if (inputConfig==null) return null;
else if (inputConfig.getInput()==null) return null;
else return inputConfig.getInput().getDefinition();
}
/**
* Returns the input population model
* @return
*/
public ARXPopulationModel getInputPopulationModel() {
return getRiskModel().getPopulationModel();
}
/**
* Returns the k-anonymity model.
*
* @return
*/
public ModelKAnonymityCriterion getKAnonymityModel() {
return kAnonymityModel;
}
/**
* Returns the k-map model.
*
* @return
*/
public ModelKMapCriterion getKMapModel() {
if (kMapModel == null) {
kMapModel = new ModelKMapCriterion();
}
return kMapModel;
}
/**
* Returns the l-diversity model.
*
* @return
*/
public Map<String, ModelLDiversityCriterion> getLDiversityModel() {
if (this.lDiversityModel == null) {
this.lDiversityModel = new HashMap<String, ModelLDiversityCriterion>();
}
return lDiversityModel;
}
/**
* Returns the project locale.
*
* @return
*/
public Locale getLocale() {
if (this.locale == null) {
return Locale.getDefault();
} else {
return locale;
}
}
/**
* Returns the model for local recoding
* @return
*/
public ModelLocalRecoding getLocalRecodingModel() {
if (this.localRecodingModel == null) {
this.localRecodingModel = new ModelLocalRecoding();
}
return localRecodingModel;
}
/**
* When a dataset has more records than this threshold,
* visualization of statistics will be disabled.
*
* @return
*/
public int getMaximalSizeForComplexOperations(){
return this.maximalSizeForComplexOperations;
}
/**
* Returns the maximal size of a sub-lattice that will be displayed
* by the viewer.
*
* @return
*/
public int getMaxNodesInViewer() {
return maxNodesInViewer;
}
/**
* Returns the configuration of the metric.
*
* @return
*/
public MetricConfiguration getMetricConfiguration() {
if (this.metricConfig == null) {
if (this.inputConfig == null || this.inputConfig.getMetric() == null) {
this.metricConfig = ARXConfiguration.create().getQualityModel().getConfiguration();
} else {
this.metricConfig = this.inputConfig.getMetric().getConfiguration();
}
}
return this.metricConfig;
}
/**
* Returns a description of the metric.
*
* @return
*/
public MetricDescription getMetricDescription() {
if (this.metricDescription == null) {
if (this.inputConfig == null || this.inputConfig.getMetric() == null) {
this.metricDescription = ARXConfiguration.create().getQualityModel().getDescription();
} else {
this.metricDescription = this.inputConfig.getMetric().getDescription();
}
}
return this.metricDescription;
}
/**
* Returns the name of this project.
*
* @return
*/
public String getName() {
return name;
}
/**
* Returns the current filter.
*
* @return
*/
public ModelNodeFilter getNodeFilter() {
return nodeFilter;
}
/**
* Returns a string representation of the current optimum.
*
* @return
*/
public String getOptimalNodeAsString() {
return optimalNodeAsString;
}
/**
* @return the output
*/
public DataHandle getOutput() {
return output;
}
/**
* Returns the output config.
*
* @return
*/
public ModelConfiguration getOutputConfig() {
return outputConfig;
}
/**
* Returns the output definition.
*
* @return
*/
public DataDefinition getOutputDefinition(){
if (this.output == null) return null;
else return this.output.getDefinition();
}
/**
* Returns the currently applied transformation.
*
* @return
*/
public ARXNode getOutputNode() {
return outputNode;
}
/**
* Returns a string representation of the currently applied transformation.
*
* @return
*/
public String getOutputNodeAsString() {
return outputNodeAsString;
}
/**
* Returns the output population model, if any. Null otherwise.
* @return
*/
public ARXPopulationModel getOutputPopulationModel() {
ModelConfiguration config = getOutputConfig();
if (config != null) {
for (PrivacyCriterion c : config.getCriteria()) {
if (c.getPopulationModel() != null) {
return c.getPopulationModel();
}
}
}
return null;
}
/**
* Returns the path of the project.
*
* @return
*/
public String getPath() {
return path;
}
/**
* @return the perspective
*/
public Perspective getPerspective() {
if (perspective == null) {
perspective = Perspective.CONFIGURATION;
}
return perspective;
}
/**
* Returns the current query.
*
* @return
*/
public String getQuery() {
return query;
}
/**
* Returns the current result.
*
* @return the result
*/
public ARXResult getResult() {
return result;
}
/**
* Returns the risk-based model.
*
* @return
*/
public Set<ModelRiskBasedCriterion> getRiskBasedModel() {
if (this.riskBasedModel == null) {
this.riskBasedModel = new HashSet<ModelRiskBasedCriterion>();
this.riskBasedModel.add(new ModelRiskBasedCriterion(ModelRiskBasedCriterion.VARIANT_AVERAGE_RISK));
this.riskBasedModel.add(new ModelRiskBasedCriterion(ModelRiskBasedCriterion.VARIANT_SAMPLE_UNIQUES));
this.riskBasedModel.add(new ModelRiskBasedCriterion(ModelRiskBasedCriterion.VARIANT_POPULATION_UNIQUES_DANKAR));
}
return riskBasedModel;
}
/**
* Returns the risk model
* @return the risk model
*/
public ModelRisk getRiskModel() {
if (this.riskModel == null) {
this.riskModel = new ModelRisk();
}
return riskModel;
}
/**
* Returns the currently selected attribute.
*
* @return
*/
public String getSelectedAttribute() {
return selectedAttribute;
}
/**
* Returns the selected features
* @return
*/
public Set<String> getSelectedClasses() {
if (this.selectedClasses == null) {
// Add attributes
if (this.getInputConfig() != null && this.getInputConfig().getInput() != null) {
DataHandle handle = this.getInputConfig().getInput().getHandle();
this.selectedClasses = new HashSet<String>();
for (int i = 0; i < handle.getNumColumns(); i++) {
this.selectedClasses.add(handle.getAttributeName(i));
}
} else {
// Return empty set
return new HashSet<String>();
}
}
return this.selectedClasses;
}
/**
* Returns the selected features
* @return
*/
public Set<String> getSelectedFeatures() {
if (this.selectedFeatures == null) {
// Add attributes
if (this.getInputConfig() != null && this.getInputConfig().getInput() != null) {
DataHandle handle = this.getInputConfig().getInput().getHandle();
this.selectedFeatures = new HashSet<String>();
for (int i = 0; i < handle.getNumColumns(); i++) {
this.selectedFeatures.add(handle.getAttributeName(i));
}
} else {
// Return empty set
return new HashSet<String>();
}
}
return this.selectedFeatures;
}
/**
* Returns the selected transformation.
*
* @return
*/
public ARXNode getSelectedNode() {
return selectedNode;
}
/**
* Returns a set of quasi identifiers selected for risk analysis
* @return
*/
public Set<String> getSelectedQuasiIdentifiers() {
if (this.selectedQuasiIdentifiers == null) {
// Add qis or other attributes
if (this.getInputConfig() != null && this.getInputConfig().getInput() != null) {
DataHandle handle = this.getInputConfig().getInput().getHandle();
this.selectedQuasiIdentifiers = new HashSet<String>();
Set<String> qis = this.getInputDefinition().getQuasiIdentifyingAttributes();
// Add standard attributes
if (qis.isEmpty()) {
int max = handle.getNumColumns();
max = Math.min(max, getRiskModel().getMaxQiSize());
for (int i=0; i<max; i++) {
this.selectedQuasiIdentifiers.add(handle.getAttributeName(i));
}
// Add QIs
} else {
int max = qis.size();
max = Math.min(max, getRiskModel().getMaxQiSize());
for (int i = 0; i < handle.getNumColumns() && selectedQuasiIdentifiers.size() <= max; i++) {
String attr = handle.getAttributeName(i);
if (qis.contains(attr)) {
this.selectedQuasiIdentifiers.add(attr);
}
}
}
} else {
// Return empty set
return new HashSet<String>();
}
}
return this.selectedQuasiIdentifiers;
}
/**
* Returns the separator.
*
* @return
*/
public char getSeparator() {
return separator;
}
/**
* Returns the according parameter.
*
* @return
*/
public double getSnapshotSizeDataset() {
return snapshotSizeDataset;
}
/**
* Returns the according parameter.
*
* @return
*/
public double getSnapshotSizeSnapshot() {
return snapshotSizeSnapshot;
}
/**
* Returns the configuration object for the stackelberg privacy model
* @return
*/
public ModelProfitabilityCriterion getStackelbergModel() {
if (this.stackelbergPrivacyModel == null) {
this.stackelbergPrivacyModel = new ModelProfitabilityCriterion();
}
return stackelbergPrivacyModel;
}
/**
* Returns the origin of the subset.
*
* @return
*/
public String getSubsetOrigin(){
return this.subsetOrigin;
}
/**
* Returns the t-closeness model.
*
* @return
*/
public Map<String, ModelTClosenessCriterion> getTClosenessModel() {
if (this.tClosenessModel == null) {
this.tClosenessModel = new HashMap<String, ModelTClosenessCriterion>();
}
return tClosenessModel;
}
/**
* Returns the execution time of the last anonymization process.
*
* @return
*/
public long getTime() {
return time;
}
/**
* Returns whether functional hierarchies should be used
* @return
*/
public Boolean getUseFunctionalHierarchies() {
// Backwards compatibility
if (useFunctionalHierarchies == null) {
useFunctionalHierarchies = true;
}
return useFunctionalHierarchies;
}
/**
* Returns whether list-wise deletion is used for summary statistics
* @return
*/
public Boolean getUseListwiseDeletion() {
// Backwards compatibility
if (useListwiseDeletion == null) {
useListwiseDeletion = true;
}
return useListwiseDeletion;
}
/**
* Returns the view configuration.
*
* @return
*/
public ModelViewConfig getViewConfig() {
return this.viewConfig;
}
/**
* Returns whether debugging is enabled.
*
* @return
*/
public boolean isDebugEnabled() {
return debugEnabled;
}
/**
* Returns whether this project is modified.
*
* @return
*/
public boolean isModified() {
if (inputConfig.isModified()) { return true; }
if (getRiskModel().isModified()) { return true; }
if (getClassificationModel().isModified()) { return true; }
if ((outputConfig != null) && outputConfig.isModified()) { return true; }
if ((clipboard != null) && clipboard.isModified()) { return true; }
return modified;
}
/**
* Returns whether a quasi-identifier is selected.
*
* @return
*/
public boolean isQuasiIdentifierSelected() {
return (getInputDefinition().getAttributeType(getSelectedAttribute()) == AttributeType.QUASI_IDENTIFYING_ATTRIBUTE);
}
/**
* Returns whether a sensitive attribute is selected.
*
* @return
*/
public boolean isSensitiveAttributeSelected() {
return (getInputDefinition().getAttributeType(getSelectedAttribute()) == AttributeType.SENSITIVE_ATTRIBUTE);
}
/**
* Returns whether visualization is enabled.
*
* @return
*/
public boolean isVisualizationEnabled(){
if (this.showVisualization == null) {
return true;
} else {
return this.showVisualization;
}
}
/**
* Resets the model.
*/
public void reset() {
this.resetCriteria();
this.resetAttributePair();
this.inputConfig = new ModelConfiguration();
this.outputConfig = null;
this.output = null;
this.result = null;
if (auditTrail != null) auditTrail.clear();
this.selectedQuasiIdentifiers = null;
this.selectedFeatures = null;
this.selectedClasses = null;
this.subsetOrigin = Resources.getMessage("Model.0"); //$NON-NLS-1$
this.groups = null;
this.classificationModel = new ModelClassification();
}
/**
* Returns the last two selected attributes.
*/
public void resetAttributePair() {
if (pair == null)
pair = new String[] { null, null };
pair[0] = null;
pair[1] = null;
}
/**
* Resets the configuration of the privacy criteria.
*/
public void resetCriteria() {
if (inputConfig==null || inputConfig.getInput()==null) return;
differentialPrivacyModel = new ModelDifferentialPrivacyCriterion();
kAnonymityModel = new ModelKAnonymityCriterion();
stackelbergPrivacyModel = new ModelProfitabilityCriterion();
dPresenceModel = new ModelDPresenceCriterion();
kMapModel = new ModelKMapCriterion();
lDiversityModel.clear();
tClosenessModel.clear();
riskBasedModel.clear();
dDisclosurePrivacyModel.clear();
DataHandle handle = inputConfig.getInput().getHandle();
for (int col = 0; col < handle.getNumColumns(); col++) {
String attribute = handle.getAttributeName(col);
lDiversityModel.put(attribute, new ModelLDiversityCriterion(attribute));
tClosenessModel.put(attribute, new ModelTClosenessCriterion(attribute));
dDisclosurePrivacyModel.put(attribute, new ModelDDisclosurePrivacyCriterion(attribute));
bLikenessModel.put(attribute, new ModelBLikenessCriterion(attribute));
}
riskBasedModel.add(new ModelRiskBasedCriterion(ModelRiskBasedCriterion.VARIANT_AVERAGE_RISK));
riskBasedModel.add(new ModelRiskBasedCriterion(ModelRiskBasedCriterion.VARIANT_SAMPLE_UNIQUES));
riskBasedModel.add(new ModelRiskBasedCriterion(ModelRiskBasedCriterion.VARIANT_POPULATION_UNIQUES_DANKAR));
}
/**
* Sets the anonymizer.
*
* @param anonymizer
*/
public void setAnonymizer(final ARXAnonymizer anonymizer) {
setModified();
this.anonymizer = anonymizer;
}
/**
* Enables debugging.
*
* @param value
*/
public void setDebugEnabled(boolean value){
this.debugEnabled = value;
this.setModified();
}
/**
* Sets the project description.
*
* @param description
*/
public void setDescription(final String description) {
this.description = description;
setModified();
}
/**
* Sets the indices of equivalence classes.
*
* @param groups
*/
public void setGroups(int[] groups) {
this.groups = groups;
}
/**
* Sets the according parameter.
*
* @param historySize
*/
public void setHistorySize(final int historySize) {
this.historySize = historySize;
setModified();
}
/**
* Sets the according parameter.
*
* @param val
*/
public void setInitialNodesInViewer(final int val) {
initialNodesInViewer = val;
setModified();
}
/**
* Sets the size of the input in bytes.
*
* @param inputBytes
*/
public void setInputBytes(final long inputBytes) {
setModified();
this.inputBytes = inputBytes;
}
/**
* Sets the input config.
*
* @param config
*/
public void setInputConfig(final ModelConfiguration config) {
this.inputConfig = config;
}
/**
* Sets the project locale.
*
* @param locale Null for default locale
*/
public void setLocale(Locale locale) {
this.locale = locale;
this.setModified();
}
/**
* Sets the according parameter.
*
* @param numberOfRows
*/
public void setMaximalSizeForComplexOperations(int numberOfRows) {
this.maximalSizeForComplexOperations = numberOfRows;
this.setModified();
}
/**
* Sets the according parameter.
*
* @param maxNodesInViewer
*/
public void setMaxNodesInViewer(final int maxNodesInViewer) {
this.maxNodesInViewer = maxNodesInViewer;
setModified();
}
/**
* Sets the description of the metric.
*
* @param description
*/
public void setMetricDescription(MetricDescription description) {
this.metricDescription = description;
}
/**
* Marks this project as modified.
*/
public void setModified() {
modified = true;
}
/**
* Sets the project name.
*
* @param name
*/
public void setName(final String name) {
this.name = name;
setModified();
}
/**
* Sets a filter.
*
* @param filter
*/
public void setNodeFilter(final ModelNodeFilter filter) {
nodeFilter = filter;
setModified();
}
/**
* Sets the current output.
*
* @param output
* @param node
*/
public void setOutput(final DataHandle output, final ARXNode node) {
this.output = output;
this.outputNode = node;
if (node != null) {
outputNodeAsString = Arrays.toString(node.getTransformation());
} else {
outputNodeAsString = null;
}
setModified();
}
/**
* Sets the output config.
*
* @param config
*/
public void setOutputConfig(final ModelConfiguration config) {
outputConfig = config;
}
/**
* Sets the project path.
*
* @param path
*/
public void setPath(final String path) {
this.path = path;
}
/**
* @param perspective the perspective to set
*/
public void setPerspective(Perspective perspective) {
this.perspective = perspective;
}
/**
* Sets the query.
*
* @param query
*/
public void setQuery(String query){
this.query = query;
setModified();
}
/**
* Sets the result.
*
* @param result
*/
public void setResult(final ARXResult result) {
this.result = result;
if ((result != null) && (result.getGlobalOptimum() != null)) {
optimalNodeAsString = Arrays.toString(result.getGlobalOptimum()
.getTransformation());
}
setModified();
}
/**
* Marks this project as saved.
*/
public void setSaved() {
modified = false;
}
/**
* Sets the selected attribute.
*
* @param attribute
*/
public void setSelectedAttribute(final String attribute) {
selectedAttribute = attribute;
// Track last two selected attributes
if (pair == null)
pair = new String[] { null, null };
if (pair[0] == null) {
pair[0] = attribute;
pair[1] = null;
} else if (pair[1] == null) {
pair[1] = attribute;
} else {
pair[0] = pair[1];
pair[1] = attribute;
}
setModified();
}
/**
* Sets a set of selected attributes
* @param set
*/
public void setSelectedClasses(Set<String> set) {
this.selectedClasses = set;
this.setModified();
}
/**
* Sets a set of selected attributes
* @param set
*/
public void setSelectedFeatures(Set<String> set) {
this.selectedFeatures = set;
this.setModified();
}
/**
* Sets the selected node.
*
* @param node
*/
public void setSelectedNode(final ARXNode node) {
selectedNode = node;
setModified();
}
/**
* Sets a set of quasi identifiers selected for risk analysis
* @param set
*/
public void setSelectedQuasiIdentifiers(Set<String> set) {
this.selectedQuasiIdentifiers = set;
this.setModified();
}
/**
*
*
* @param snapshotSize
*/
public void setSnapshotSizeDataset(final double snapshotSize) {
snapshotSizeDataset = snapshotSize;
setModified();
}
/**
* Sets the according parameter.
*
* @param snapshotSize
*/
public void setSnapshotSizeSnapshot(final double snapshotSize) {
setModified();
snapshotSizeSnapshot = snapshotSize;
}
/**
* Sets how the subset was defined.
*/
public void setSubsetManual(){
if (!this.subsetOrigin.endsWith(Resources.getMessage("Model.1"))) { //$NON-NLS-1$
this.subsetOrigin += Resources.getMessage("Model.2"); //$NON-NLS-1$
}
}
/**
* Sets how the subset was defined.
*
* @param origin
*/
public void setSubsetOrigin(String origin){
this.subsetOrigin = origin;
}
/**
* Sets the execution time of the last anonymization process.
*
* @param time
*/
public void setTime(final long time) {
this.time = time;
}
/**
* Marks this model as unmodified.
*/
public void setUnmodified() {
modified = false;
inputConfig.setUnmodified();
getRiskModel().setUnmodified();
if (outputConfig != null) {
outputConfig.setUnmodified();
}
if (clipboard != null) {
clipboard.setUnmodified();
}
getClassificationModel().setUnmodified();
}
/**
* Sets whether funtional hierarchies should be used during anonymization to esimtate utility
* @param useFunctionalHierarchies
*/
public void setUseFunctionalHierarchies(boolean useFunctionalHierarchies) {
this.useFunctionalHierarchies = useFunctionalHierarchies;
}
/**
* Sets whether list-wise deletion should be used for summary statistics
* @param useListwiseDeletion
*/
public void setUseListwiseDeletion(boolean useListwiseDeletion) {
this.useListwiseDeletion = useListwiseDeletion;
}
/**
* Sets the view configuration.
*
* @param viewConfig
*/
public void setViewConfig(ModelViewConfig viewConfig) {
this.viewConfig = viewConfig;
}
/**
* Sets visualization as enabled/disabled.
*
* @param value
*/
public void setVisualizationEnabled(boolean value){
this.showVisualization = value;
this.setModified();
}
}