/* * 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.risk; import org.deidentifier.arx.gui.Controller; import org.deidentifier.arx.gui.model.ModelEvent; import org.deidentifier.arx.gui.model.ModelEvent.ModelPart; import org.deidentifier.arx.gui.model.ModelRisk.ViewRiskType; import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.SWTUtil; import org.deidentifier.arx.gui.view.impl.common.ClipboardHandlerTable; import org.deidentifier.arx.gui.view.impl.common.ComponentStatusLabelProgressProvider; import org.deidentifier.arx.gui.view.impl.common.async.Analysis; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisContext; import org.deidentifier.arx.gui.view.impl.common.async.AnalysisManager; import org.deidentifier.arx.risk.RiskEstimateBuilderInterruptible; import org.deidentifier.arx.risk.RiskModelPopulationUniqueness; import org.deidentifier.arx.risk.RiskModelPopulationUniqueness.PopulationUniquenessModel; import org.deidentifier.arx.risk.RiskModelSampleRisks; import org.deidentifier.arx.risk.RiskModelSampleUniqueness; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.swt.widgets.TableItem; import de.linearbits.swt.table.DynamicTable; import de.linearbits.swt.table.DynamicTableColumn; /** * This view displays basic risk estimates. * * @author Fabian Prasser */ public class ViewRisksReIdentificationTable extends ViewRisks<AnalysisContextRisk> { /** View */ private Composite root; /** View */ private DynamicTable table; /** Internal stuff. */ private AnalysisManager manager; /** * Creates a new instance. * * @param parent * @param controller * @param target * @param reset */ public ViewRisksReIdentificationTable(final Composite parent, final Controller controller, final ModelPart target, final ModelPart reset) { super(parent, controller, target, reset); controller.addListener(ModelPart.ATTRIBUTE_TYPE, this); controller.addListener(ModelPart.POPULATION_MODEL, this); this.manager = new AnalysisManager(parent.getDisplay()); } @Override public void update(ModelEvent event) { super.update(event); if (event.part == ModelPart.ATTRIBUTE_TYPE || event.part == ModelPart.POPULATION_MODEL) { triggerUpdate(); } } /** * Creates a table item * @param label * @param value */ private void createItem(String label, double value) { TableItem item = new TableItem(table, SWT.NONE); item.setText(0, label); item.setData("1", value); } /** * Creates a table item * @param label * @param value */ private void createItem(String label, PopulationUniquenessModel value) { TableItem item = new TableItem(table, SWT.NONE); item.setText(0, label); item.setText(1, value == null ? "N/A" : value.toString()); //$NON-NLS-1$ } /** * Creates a table item * @param label * @param value */ private void createItem(String label, String value) { TableItem item = new TableItem(table, SWT.NONE); item.setText(0, label); item.setText(1, value); } @Override protected Control createControl(Composite parent) { this.root = new Composite(parent, SWT.NONE); this.root.setLayout(SWTUtil.createGridLayout(1)); table = SWTUtil.createTableDynamic(root, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.FULL_SELECTION); table.setHeaderVisible(true); table.setLinesVisible(true); table.setMenu(new ClipboardHandlerTable(table).getMenu()); table.setLayoutData(SWTUtil.createFillGridData()); DynamicTableColumn c = new DynamicTableColumn(table, SWT.LEFT); c.setWidth("50%", "100px"); //$NON-NLS-1$ //$NON-NLS-2$ c.setText(Resources.getMessage("RiskAnalysis.6")); //$NON-NLS-1$ c = new DynamicTableColumn(table, SWT.LEFT); SWTUtil.createColumnWithBarCharts(table, c); c.setWidth("50%", "100px"); //$NON-NLS-1$ //$NON-NLS-2$ c.setText(Resources.getMessage("RiskAnalysis.7")); //$NON-NLS-1$ for (final TableColumn col : table.getColumns()) { col.pack(); } SWTUtil.createGenericTooltip(table); return root; } @Override protected AnalysisContextRisk createViewConfig(AnalysisContext context) { return new AnalysisContextRisk(context); } @Override protected void doReset() { if (this.manager != null) { this.manager.stop(); } table.setRedraw(false); for (final TableItem i : table.getItems()) { i.dispose(); } table.setRedraw(true); setStatusEmpty(); } @Override protected void doUpdate(final AnalysisContextRisk context) { // Enable/disable final RiskEstimateBuilderInterruptible builder = getBuilder(context); if (!this.isEnabled() || builder == null) { if (manager != null) { manager.stop(); } this.setStatusEmpty(); return; } // Create an analysis Analysis analysis = new Analysis(){ private boolean stopped = false; private double lowestRisk; private double fractionOfTuplesAffectedByLowestRisk; private double averageRisk; private double highestRisk; private double fractionOfTuplesAffectedByHighestRisk; private double estimatedProsecutorRisk; private double estimatedJournalistRisk; private double estimatedMarketerRisk; private double fractionOfUniqueTuples; private double fractionOfUniqueTuplesDankar; private PopulationUniquenessModel populationModel; @Override public int getProgress() { return 0; } @Override public void onError() { setStatusEmpty(); } @Override public void onFinish() { if (stopped || !isEnabled()) { return; } table.setRedraw(false); for (final TableItem i : table.getItems()) { i.dispose(); } createItem(Resources.getMessage("RiskAnalysis.14"), lowestRisk); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.17"), fractionOfTuplesAffectedByLowestRisk); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.8"), averageRisk); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.9"), highestRisk); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.10"), fractionOfTuplesAffectedByHighestRisk); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.40"), estimatedProsecutorRisk); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.41"), estimatedJournalistRisk); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.42"), estimatedMarketerRisk); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.11"), fractionOfUniqueTuples); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.12"), fractionOfUniqueTuplesDankar); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.18"), populationModel); //$NON-NLS-1$ createItem(Resources.getMessage("RiskAnalysis.25"), getQuasiIdentifiers(context)); //$NON-NLS-1$ table.setRedraw(true); table.layout(); setStatusDone(); } @Override public void onInterrupt() { if (!isEnabled() || !isValid()) { setStatusEmpty(); } else { setStatusWorking(); } } @Override public void run() throws InterruptedException { // Timestamp long time = System.currentTimeMillis(); // Perform work RiskModelSampleRisks samReidModel = builder.getSampleBasedReidentificationRisk(); RiskModelSampleUniqueness samUniqueModel = builder.getSampleBasedUniquenessRisk(); RiskModelPopulationUniqueness popUniqueModel = builder.getPopulationBasedUniquenessRisk(); lowestRisk = samReidModel.getLowestRisk(); fractionOfTuplesAffectedByLowestRisk = samReidModel.getFractionOfTuplesAffectedByLowestRisk(); averageRisk = samReidModel.getAverageRisk(); highestRisk = samReidModel.getHighestRisk(); fractionOfTuplesAffectedByHighestRisk = samReidModel.getFractionOfTuplesAffectedByHighestRisk(); estimatedProsecutorRisk = samReidModel.getEstimatedProsecutorRisk(); estimatedJournalistRisk = samReidModel.getEstimatedJournalistRisk(); estimatedMarketerRisk = samReidModel.getEstimatedMarketerRisk(); fractionOfUniqueTuples = samUniqueModel.getFractionOfUniqueTuples(); fractionOfUniqueTuplesDankar = popUniqueModel.getFractionOfUniqueTuplesDankar(); populationModel = popUniqueModel.getPopulationUniquenessModel(); // Our users are patient while (System.currentTimeMillis() - time < MINIMAL_WORKING_TIME && !stopped){ Thread.sleep(10); } } @Override public void stop() { if (builder != null) builder.interrupt(); this.stopped = true; } }; this.manager.start(analysis); } @Override protected ComponentStatusLabelProgressProvider getProgressProvider() { return null; } @Override protected ViewRiskType getViewType() { return ViewRiskType.OVERVIEW; } /** * Is an analysis running */ protected boolean isRunning() { return manager != null && manager.isRunning(); } }