/* * 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.view.impl.utility; import java.util.Arrays; import java.util.Set; import org.deidentifier.arx.ARXLattice.ARXNode; import org.deidentifier.arx.ARXLattice.Anonymity; import org.deidentifier.arx.ARXResult; import org.deidentifier.arx.criteria.AverageReidentificationRisk; import org.deidentifier.arx.criteria.BasicBLikeness; import org.deidentifier.arx.criteria.DDisclosurePrivacy; import org.deidentifier.arx.criteria.DPresence; import org.deidentifier.arx.criteria.DistinctLDiversity; import org.deidentifier.arx.criteria.EDDifferentialPrivacy; import org.deidentifier.arx.criteria.EnhancedBLikeness; import org.deidentifier.arx.criteria.EntropyLDiversity; import org.deidentifier.arx.criteria.EqualDistanceTCloseness; import org.deidentifier.arx.criteria.HierarchicalDistanceTCloseness; import org.deidentifier.arx.criteria.KAnonymity; import org.deidentifier.arx.criteria.KMap; import org.deidentifier.arx.criteria.OrderedDistanceTCloseness; import org.deidentifier.arx.criteria.PopulationUniqueness; import org.deidentifier.arx.criteria.PrivacyCriterion; import org.deidentifier.arx.criteria.ProfitabilityJournalist; import org.deidentifier.arx.criteria.ProfitabilityJournalistNoAttack; import org.deidentifier.arx.criteria.ProfitabilityProsecutor; import org.deidentifier.arx.criteria.ProfitabilityProsecutorNoAttack; import org.deidentifier.arx.criteria.RecursiveCLDiversity; import org.deidentifier.arx.criteria.RiskBasedCriterion; import org.deidentifier.arx.criteria.SampleUniqueness; import org.deidentifier.arx.gui.Controller; import org.deidentifier.arx.gui.model.ModelEvent.ModelPart; import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.SWTUtil; import org.deidentifier.arx.gui.view.impl.common.ClipboardHandlerTree; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisData; import org.deidentifier.arx.metric.v2.QualityMetadata; import org.eclipse.jface.viewers.ILabelProviderListener; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeColumn; /** * This view displays basic properties about output data. * * @author Fabian Prasser */ public class ViewPropertiesOutput extends ViewProperties { /** * A content provider. * * @author Fabian Prasser */ private class OutputContentProvider implements ITreeContentProvider { @Override public void dispose() { // Nothing to do } @Override public Object[] getChildren(final Object arg0) { return ((Property) arg0).children.toArray(); } @Override public Object[] getElements(final Object arg0) { return roots.toArray(); } @Override public Object getParent(final Object arg0) { return ((Property) arg0).parent; } @Override public boolean hasChildren(final Object arg0) { return !((Property) arg0).children.isEmpty(); } @Override public void inputChanged(final Viewer arg0, final Object arg1, final Object arg2) { // Nothing to do } } /** * A content provider. * * @author Fabian Prasser */ private class OutputLabelProvider implements ITableLabelProvider { @Override public void addListener(final ILabelProviderListener listener) { // Nothing to do } @Override public void dispose() { // Nothing to do } @Override public Image getColumnImage(final Object element, final int columnIndex) { return null; } @Override public String getColumnText(final Object element, final int columnIndex) { switch (columnIndex) { case 0: return ((Property) element).property; case 1: return ((Property) element).values[0]; } return null; } @Override public boolean isLabelProperty(final Object element, final String property) { return false; } @Override public void removeListener(final ILabelProviderListener listener) { // Nothing to do } } /** * Constructor. * * @param parent * @param controller */ public ViewPropertiesOutput(final Composite parent, final Controller controller) { super(parent, controller, ModelPart.OUTPUT, ModelPart.INPUT); create(parent); reset(); } /** * Returns the view type * @return */ public LayoutUtility.ViewUtilityType getType() { return LayoutUtility.ViewUtilityType.PROPERTIES; } /** * Creates the view. * * @param root */ private void create(final Composite root) { root.setLayout(new FillLayout()); final Tree tree = new Tree(root, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION); tree.setHeaderVisible(true); treeViewer = new TreeViewer(tree); tree.setMenu(new ClipboardHandlerTree(treeViewer).getMenu()); final TreeColumn column1 = new TreeColumn(tree, SWT.LEFT); tree.setLinesVisible(true); column1.setAlignment(SWT.LEFT); column1.setText(Resources.getMessage("PropertiesView.1")); //$NON-NLS-1$ column1.setWidth(160); final TreeColumn column2 = new TreeColumn(tree, SWT.RIGHT); column2.setAlignment(SWT.LEFT); column2.setText(Resources.getMessage("PropertiesView.2")); //$NON-NLS-1$ column2.setWidth(100); treeViewer.setContentProvider(new OutputContentProvider()); treeViewer.setLabelProvider(new OutputLabelProvider()); treeViewer.setInput(roots); treeViewer.expandAll(); } /** * Update the view. * @param part */ protected void doUpdate(ModelPart part) { AnalysisData context = getContext().getData(); if (context == null || context.config == null || context.handle == null) { reset(); return; } // We don't need to update in many cases if (part == ModelPart.ATTRIBUTE_TYPE || part == ModelPart.METRIC || part == ModelPart.ATTRIBUTE_WEIGHT || part == ModelPart.GS_FACTOR || part == ModelPart.MAX_OUTLIERS || part == ModelPart.DATA_TYPE || part == ModelPart.COST_BENEFIT_MODEL) { return; } // Disable redrawing root.setRedraw(false); // Obtain data ARXResult result = model.getResult(); ARXNode node = model.getSelectedNode(); // Clear roots.clear(); // Print score if (node.getHighestScore().getValue().equals( node.getLowestScore().getValue())) { final String infoloss = node.getLowestScore().toString() + " [" + SWTUtil.getPrettyString(asRelativeValue(node.getLowestScore(), result)) + "%]"; //$NON-NLS-1$ //$NON-NLS-2$ Property score = new Property(Resources.getMessage("PropertiesView.46"), new String[] { infoloss }); //$NON-NLS-1$ // Print metadata if (node.isChecked()) { for (QualityMetadata<?> metadata : node.getLowestScore().getMetadata()) { new Property(score, metadata.getParameter(), new String[] { SWTUtil.getPrettyString(metadata.getValue()) }); } } } // Print basic info on neighboring nodes new Property(Resources.getMessage("PropertiesView.48"), new String[] { String.valueOf(node.getSuccessors().length) }); //$NON-NLS-1$ new Property(Resources.getMessage("PropertiesView.49"), new String[] { String.valueOf(node.getPredecessors().length) }); //$NON-NLS-1$ new Property(Resources.getMessage("PropertiesView.50"), new String[] { Arrays.toString(node.getTransformation()) }); //$NON-NLS-1$ // If the node is anonymous if (node.getAnonymity() == Anonymity.ANONYMOUS) { // Print info about d-presence if (context.config.containsCriterion(DPresence.class)) { DPresence criterion = context.config.getCriterion(DPresence.class); // Only if its not an auto-generated criterion if (!(criterion.getDMin()==0d && criterion.getDMax()==1d)){ Property n = new Property(Resources.getMessage("PropertiesView.92"), new String[] { Resources.getMessage("PropertiesView.93") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.94"), new String[] { SWTUtil.getPrettyString(criterion.getDMin())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.95"), new String[] { SWTUtil.getPrettyString(criterion.getDMax())}); //$NON-NLS-1$ } } // Print info about k-anonymity if (context.config.containsCriterion(KAnonymity.class)) { KAnonymity criterion = context.config.getCriterion(KAnonymity.class); Property n = new Property(Resources.getMessage("PropertiesView.51"), new String[] { Resources.getMessage("PropertiesView.52") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.53"), new String[] { SWTUtil.getPrettyString(criterion.getK())}); //$NON-NLS-1$ } // Print info about k-map if (context.config.containsCriterion(KMap.class)) { KMap criterion = context.config.getCriterion(KMap.class); Property n = new Property(Resources.getMessage("PropertiesView.51"), new String[] { Resources.getMessage("PropertiesView.132") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.53"), new String[] { SWTUtil.getPrettyString(criterion.getK())}); //$NON-NLS-1$ if (!criterion.isAccurate()) { new Property(n, Resources.getMessage("PropertiesView.146"), new String[] { SWTUtil.getPrettyString(criterion.getDerivedK()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.133"), new String[] { SWTUtil.getPrettyString(((KMap)criterion).getPopulationModel().getPopulationSize())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.147"), new String[] { SWTUtil.getPrettyString(criterion.getSignificanceLevel()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.148"), new String[] { SWTUtil.getPrettyString(criterion.getType1Error()) }); //$NON-NLS-1$ } } // Print info about game-theoretic privacy if (context.config.containsCriterion(ProfitabilityProsecutor.class) || context.config.containsCriterion(ProfitabilityJournalist.class) || context.config.containsCriterion(ProfitabilityProsecutorNoAttack.class) || context.config.containsCriterion(ProfitabilityJournalistNoAttack.class)) { Property n = new Property(Resources.getMessage("PropertiesView.51"), new String[] { Resources.getMessage("PropertiesView.134") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.135"), new String[] { SWTUtil.getPrettyString(context.config.getPublisherBenefit())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.136"), new String[] { SWTUtil.getPrettyString(context.config.getPublisherLoss())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.137"), new String[] { SWTUtil.getPrettyString(context.config.getAdversaryGain())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.138"), new String[] { SWTUtil.getPrettyString(context.config.getAdversaryCost())}); //$NON-NLS-1$ if (context.config.containsCriterion(ProfitabilityJournalist.class) || context.config.containsCriterion(ProfitabilityJournalistNoAttack.class)) { new Property(n, Resources.getMessage("PropertiesView.139"), new String[] { Resources.getMessage("PropertiesView.161") }); //$NON-NLS-1$ //$NON-NLS-2$ } else if (context.config.containsCriterion(ProfitabilityProsecutor.class) || context.config.containsCriterion(ProfitabilityProsecutorNoAttack.class)) { new Property(n, Resources.getMessage("PropertiesView.139"), new String[] { Resources.getMessage("PropertiesView.160") }); //$NON-NLS-1$ //$NON-NLS-2$ } if (context.config.containsCriterion(ProfitabilityJournalistNoAttack.class)) { ProfitabilityJournalistNoAttack model = context.config.getCriterion(ProfitabilityJournalistNoAttack.class); new Property(n, Resources.getMessage("PropertiesView.162"), new String[] { SWTUtil.getPrettyString(model.getK()) }); //$NON-NLS-1$ } else if (context.config.containsCriterion(ProfitabilityProsecutorNoAttack.class)) { ProfitabilityProsecutorNoAttack model = context.config.getCriterion(ProfitabilityProsecutorNoAttack.class); new Property(n, Resources.getMessage("PropertiesView.162"), new String[] { SWTUtil.getPrettyString(model.getK()) }); //$NON-NLS-1$ } } // Print info about (e,d)-dp if (context.config.containsCriterion(EDDifferentialPrivacy.class)) { EDDifferentialPrivacy criterion = context.config.getCriterion(EDDifferentialPrivacy.class); Property n = new Property(Resources.getMessage("PropertiesView.51"), new String[] { Resources.getMessage("PropertiesView.141") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.142"), new String[] { SWTUtil.getPrettyString(criterion.getEpsilon())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.143"), new String[] { SWTUtil.getPrettyString(criterion.getDelta())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.144"), new String[] { SWTUtil.getPrettyString(criterion.getK())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.145"), new String[] { SWTUtil.getPrettyString(criterion.getBeta())}); //$NON-NLS-1$ } // Print info about l-diversity, t-closeness and d-disclosure privacy int index = 0; for (PrivacyCriterion c : context.config.getCriteria()) { if (c instanceof DistinctLDiversity){ DistinctLDiversity criterion = (DistinctLDiversity)c; Property n = new Property(Resources.getMessage("PropertiesView.57"), new String[] { Resources.getMessage("PropertiesView.58") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.59"), new String[] { SWTUtil.getPrettyString(criterion.getL()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ } else if (c instanceof EntropyLDiversity){ EntropyLDiversity criterion = (EntropyLDiversity)c; Property n = new Property(Resources.getMessage("PropertiesView.63"), new String[] { Resources.getMessage("PropertiesView.64") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.164"), new String[] { criterion.getEstimator().toString() }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.65"), new String[] { SWTUtil.getPrettyString(criterion.getL()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ } else if (c instanceof RecursiveCLDiversity){ RecursiveCLDiversity criterion = (RecursiveCLDiversity)c; Property n = new Property(Resources.getMessage("PropertiesView.69"), new String[] { Resources.getMessage("PropertiesView.70") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.71"), new String[] { SWTUtil.getPrettyString(criterion.getC()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.72"), new String[] { SWTUtil.getPrettyString(criterion.getL()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ } else if (c instanceof EqualDistanceTCloseness){ EqualDistanceTCloseness criterion = (EqualDistanceTCloseness)c; Property n = new Property(Resources.getMessage("PropertiesView.77"), new String[] { Resources.getMessage("PropertiesView.78") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.79"), new String[] { SWTUtil.getPrettyString(criterion.getT()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ } else if (c instanceof OrderedDistanceTCloseness){ OrderedDistanceTCloseness criterion = (OrderedDistanceTCloseness)c; Property n = new Property(Resources.getMessage("PropertiesView.77"), new String[] { Resources.getMessage("PropertiesView.163") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.79"), new String[] { SWTUtil.getPrettyString(criterion.getT()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ } else if (c instanceof HierarchicalDistanceTCloseness){ HierarchicalDistanceTCloseness criterion = (HierarchicalDistanceTCloseness)c; Property n = new Property(Resources.getMessage("PropertiesView.83"), new String[] { Resources.getMessage("PropertiesView.84") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.85"), new String[] { SWTUtil.getPrettyString(criterion.getT()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ final int height = context.config.getHierarchy(criterion.getAttribute()).getHierarchy()[0].length; new Property(n, "SE-"+(index++), new String[] { Resources.getMessage("PropertiesView.87") + String.valueOf(height) }); //$NON-NLS-1$ //$NON-NLS-2$ } else if (c instanceof DDisclosurePrivacy){ DDisclosurePrivacy criterion = (DDisclosurePrivacy)c; Property n = new Property(Resources.getMessage("PropertiesView.83"), new String[] { Resources.getMessage("PropertiesView.130") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.131"), new String[] { SWTUtil.getPrettyString(criterion.getD()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ } else if (c instanceof BasicBLikeness){ BasicBLikeness criterion = (BasicBLikeness)c; Property n = new Property(Resources.getMessage("PropertiesView.83"), new String[] { Resources.getMessage("PropertiesView.172") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.171"), new String[] { SWTUtil.getPrettyString(criterion.getB()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ } else if (c instanceof EnhancedBLikeness){ EnhancedBLikeness criterion = (EnhancedBLikeness)c; Property n = new Property(Resources.getMessage("PropertiesView.83"), new String[] { Resources.getMessage("PropertiesView.173") }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.171"), new String[] { SWTUtil.getPrettyString(criterion.getB()) }); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.100"), new String[] { criterion.getAttribute() }); //$NON-NLS-1$ } } // Print info about risk-based criteria Set<RiskBasedCriterion> criteria = context.config.getCriteria(RiskBasedCriterion.class); for (RiskBasedCriterion criterion : criteria) { String type = ""; //$NON-NLS-1$ if (criterion instanceof AverageReidentificationRisk) { type = Resources.getMessage("PropertiesView.123"); //$NON-NLS-1$ } else if (criterion instanceof PopulationUniqueness) { type = Resources.getMessage("PropertiesView.125"); //$NON-NLS-1$ } else if (criterion instanceof SampleUniqueness) { type = Resources.getMessage("PropertiesView.124"); //$NON-NLS-1$ } Property n = new Property(Resources.getMessage("PropertiesView.51"), new String[] { type }); //$NON-NLS-1$ //$NON-NLS-2$ new Property(n, Resources.getMessage("PropertiesView.120"), new String[] { SWTUtil.getPrettyString(criterion.getRiskThreshold())}); //$NON-NLS-1$ if (criterion instanceof PopulationUniqueness) { new Property(n, Resources.getMessage("PropertiesView.133"), new String[] { SWTUtil.getPrettyString(((PopulationUniqueness)criterion).getPopulationModel().getPopulationSize())}); //$NON-NLS-1$ new Property(n, Resources.getMessage("PropertiesView.122"), new String[] { ((PopulationUniqueness)criterion).getStatisticalModel().toString()}); //$NON-NLS-1$ } } } else { new Property(Resources.getMessage("PropertiesView.90"), new String[] { Resources.getMessage("PropertiesView.91") }); //$NON-NLS-1$ //$NON-NLS-2$ } // Initialize refresh(); // Redraw root.setRedraw(true); } }