From d9489b5c721829880d279126edefe15b736a9a08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 00:16:11 +0100 Subject: [PATCH 01/22] add checklist wizard --- .../org/deidentifier/arx/gui/Controller.java | 91 ++------ .../resources/checklist_khaled_el_emam.txt | 38 +++ .../arx/gui/resources/messages.properties | 66 +++--- .../arx/gui/view/impl/MainWindow.java | 157 +++++++------ .../sharingwizard/AnswerRadioGroup.java | 54 +++++ .../wizard/sharingwizard/ChecklistDialog.java | 168 ++++++++++++++ .../wizard/sharingwizard/ChecklistWizard.java | 58 +++++ .../wizard/sharingwizard/EvaluationPage.java | 217 ++++++++++++++++++ .../wizard/sharingwizard/SectionPage.java | 146 ++++++++++++ .../wizard/sharingwizard/WeightField.java | 117 ++++++++++ .../sharingwizard/checklist/Checklist.java | 138 +++++++++++ .../wizard/sharingwizard/checklist/Item.java | 51 ++++ .../sharingwizard/checklist/Question.java | 51 ++++ .../sharingwizard/checklist/Section.java | 67 ++++++ .../checklist/WeightConfiguration.java | 119 ++++++++++ .../evaluation/MonitorVisualization.java | 72 ++++++ .../evaluation/StackVisualization.java | 124 ++++++++++ .../evaluation/Visualization.java | 36 +++ .../evaluation/resources/bullet_green.png | Bin 0 -> 295 bytes .../evaluation/resources/bullet_red.png | Bin 0 -> 287 bytes 20 files changed, 1586 insertions(+), 184 deletions(-) create mode 100644 src/gui/org/deidentifier/arx/gui/resources/checklist_khaled_el_emam.txt create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/resources/bullet_green.png create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/resources/bullet_red.png diff --git a/src/gui/org/deidentifier/arx/gui/Controller.java b/src/gui/org/deidentifier/arx/gui/Controller.java index fb1e80df0c..846372504e 100644 --- a/src/gui/org/deidentifier/arx/gui/Controller.java +++ b/src/gui/org/deidentifier/arx/gui/Controller.java @@ -1,6 +1,6 @@ /* * ARX: Powerful Data Anonymization - * Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors + * Copyright 2012 - 2016 Fabian Prasser, Florian Kohlmayer and contributors * Copyright 2014 Karol Babioch * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,7 +18,6 @@ package org.deidentifier.arx.gui; -import java.awt.Desktop; import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -82,7 +81,6 @@ import org.deidentifier.arx.gui.view.impl.wizard.ImportWizard; import org.deidentifier.arx.gui.worker.Worker; import org.deidentifier.arx.gui.worker.WorkerAnonymize; -import org.deidentifier.arx.gui.worker.WorkerCreateCertificate; import org.deidentifier.arx.gui.worker.WorkerExport; import org.deidentifier.arx.gui.worker.WorkerImport; import org.deidentifier.arx.gui.worker.WorkerLoad; @@ -956,72 +954,6 @@ public void actionMenuEditSettings() { } } - /** - * Creates and displays a certificate - */ - public void actionMenuFileCreateCertificate() { - - if (model == null) { - main.showInfoDialog(main.getShell(), - Resources.getMessage("Controller.30"), //$NON-NLS-1$ - Resources.getMessage("Controller.31")); //$NON-NLS-1$ - return; - } else if (model.getOutput() == null) { - main.showInfoDialog(main.getShell(), - Resources.getMessage("Controller.32"), //$NON-NLS-1$ - Resources.getMessage("Controller.33")); //$NON-NLS-1$ - return; - } - - // Check node - if (model.getOutputNode().getAnonymity() != Anonymity.ANONYMOUS) { - if (!main.showQuestionDialog(main.getShell(), - Resources.getMessage("Controller.34"), //$NON-NLS-1$ - Resources.getMessage("Controller.156"))) //$NON-NLS-1$ - { - return; - } - } - - // Ask for file - String file = main.showSaveFileDialog(main.getShell(), "*.pdf"); //$NON-NLS-1$ - if (file == null) { - return; - } - if (!file.endsWith(".pdf")) { //$NON-NLS-1$ - file = file + ".pdf"; //$NON-NLS-1$ - } - - // Export - final WorkerCreateCertificate worker = new WorkerCreateCertificate(file, - model.getCSVSyntax(), - model.getInputConfig().getInput().getHandle(), - model.getOutputDefinition(), - model.getOutputConfig().getConfig(), - model.getResult(), - model.getOutputNode(), - model.getOutput(), - model); - - main.showProgressDialog(Resources.getMessage("Controller.154"), worker); //$NON-NLS-1$ - - if (worker.getError() != null) { - main.showErrorDialog(main.getShell(), - Resources.getMessage("Controller.155"), //$NON-NLS-1$ - worker.getError()); - return; - } - - // Open - if (Desktop.isDesktopSupported()) { - try { - Desktop.getDesktop().open(worker.getResult()); - } catch (Exception e) { - // Drop silently - } - } - } - /** * File->exit. */ @@ -1350,6 +1282,13 @@ public void actionMenuFileSaveAs() { public void actionMenuHelpAbout() { main.showAboutDialog(); } + + /** + * Shows the "about" dialog. + */ + public void actionMenuHelpChecklistWizard() { + main.showChecklistWizard(); + } /** * Shows the "debug" dialog. @@ -1581,7 +1520,7 @@ public String actionShowFormatInputDialog(final Shell shell, return main.showFormatInputDialog(shell, title, text, null, locale, type, Arrays.asList(values)); } - + /** * Shows a dialog for selecting a format string for a data type. * @@ -1604,7 +1543,7 @@ public String actionShowFormatInputDialog(final Shell shell, return main.showFormatInputDialog(shell, title, text, preselected, locale, type, values); } - + /** * Shows a help dialog. * @@ -1624,6 +1563,7 @@ public void actionShowHelpDialog(String id) { public void actionShowInfoDialog(final Shell shell, final String header, final String text) { main.showInfoDialog(shell, header, text); } + /** * Shows an input dialog. * @@ -1639,7 +1579,6 @@ public String actionShowInputDialog(final Shell shell, final String initial) { return main.showInputDialog(shell, header, text, initial); } - /** * Shows an input dialog. * @@ -1726,6 +1665,7 @@ public boolean actionShowQuestionDialog(final Shell shell, final String text) { return main.showQuestionDialog(shell, header, text); } + /** * Shows a question dialog. * @@ -1737,7 +1677,6 @@ public boolean actionShowQuestionDialog(final String header, final String text) { return main.showQuestionDialog(this.main.getShell(), header, text); } - /** * Internal method for showing a "save file" dialog. * @@ -1748,7 +1687,7 @@ public boolean actionShowQuestionDialog(final String header, public String actionShowSaveFileDialog(final Shell shell, String filter) { return main.showSaveFileDialog(shell, filter); } - + /** * Includes all tuples in the research subset. */ @@ -1887,7 +1826,7 @@ public String isValid(String arg0) { model.setSubsetOrigin(Resources.getMessage("Controller.133")); //$NON-NLS-1$ update(new ModelEvent(this, ModelPart.RESEARCH_SUBSET, subset.getSet())); } - + /** * Registers a listener at the controller. * @@ -1900,7 +1839,7 @@ public void addListener(final ModelPart target, final IView listener) { } listeners.get(target).add(listener); } - + @Override public void dispose() { for (final Set listeners : getListeners().values()) { diff --git a/src/gui/org/deidentifier/arx/gui/resources/checklist_khaled_el_emam.txt b/src/gui/org/deidentifier/arx/gui/resources/checklist_khaled_el_emam.txt new file mode 100644 index 0000000000..baa09a09e8 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/resources/checklist_khaled_el_emam.txt @@ -0,0 +1,38 @@ +#mitigating: Mitigating Controls + sharing-forbids: The data sharing agreement forbids the recipient from disclosing the database to third parties + sharing-enforceable: The data sharing agreement is enforceable in all jurisdictions where the recipient will use the data + sharing-audits: The data sharing agreement will allow surprise audits of the recipient's record management system and practices + sharing-dblimits: The data sharing agreement imposes strong limits linking the database with other administrative or clinical data sources + privacy-policy: The recipient has a written privacy policy + privacy-on-site: There is a person responsible for privacy at the recipient's site + staff-confidential: All members of the team on the recipient site have signed a confidentiality agreement as a condition of them having access to the disclosed database + recipient-assessment: A threat and risk assessment has been completed on the recipient + security-documentation: Strong security procedures for the collection, transmission, storage and disposal of personal information, and access to it, have been documented + staff-trained: IT & database staff are sufficiently trained in the requirements for protecting personal information + system-backlog: Systems are designed so that access and changes to personal information can be audited by date and user authentication + system-full-control: User accounts, access rights and security authorizations are fully controlled by a system or record management process + breach-protocol: The recipient has an adequate breach notification protocol in place and their staff are trained in its implementation + physically-secure: Computer systems are housed in a physically secure environment + physically-privatearea: There is no public access to areas where computers holding the data will be + data-destruction: The data will be destroyed once its purpose has been accomplished (e.g., the study has been published or other funding agency data retention period expires) + staff-restricted: Access rights are only provided to users on a ‘need to know’ basis consistent with the stated purpose for which the data was collected + +#motives: Motives and Capacity + criminal-value: The disclosed database has potential commercial or criminal value + re-identify-motive: There is a likely motive for the recipient to try to re-identify the disclosed database + re-identify-expertise: The recipient has the technical expertise to attempt to re-identify the disclosed database + re-identify-resources: The recipient has the financial resources to attempt to re-identify the disclosed database + recipient-wants-harm: The recipient may want to harm or embarrass the data custodian + recipient-only-choice: If the recipient does have a possible motive to attempt re-identification, they can not achieve their objectives through other means apart from re-identification + +#privacy: Invasion-of-Privacy + highly-detailed: The personal information is highly detailed + large-database: The database is large / many people would be affected if there was a breach + sensitive-data: The information is of a highly sensitive personal nature + sensitive-context: The information comes from a sensitive context (for example, data about individuals participating in a youth employment program are less sensitive than a similar list containing names and addresses of Hepatitis C and HIV compensation victims) + no-promise: There is no commitment or promise not to disclose to any third party or institution + no-guarantee: The information wasn't compiled or obtained under guarantees that preclude some or all types of disclosure + no-expectation: The information wasn't unsolicited, given freely and voluntarily with little expectation of it being maintained in total confidence + injury-risk: Disclosure of the information carries a probability of causing measurable injury (e.g., identity theft, fraud, etc) + foreign-laws-risk: There is a risk in terms of the possible application of foreign laws + injury-serious: The potential injury to the patients in case of an inappropriate disclosure is grave or serious \ No newline at end of file diff --git a/src/gui/org/deidentifier/arx/gui/resources/messages.properties b/src/gui/org/deidentifier/arx/gui/resources/messages.properties index eed9c38bc4..2efd790322 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/messages.properties +++ b/src/gui/org/deidentifier/arx/gui/resources/messages.properties @@ -149,9 +149,6 @@ Controller.150=Not available Controller.151=Top/bottom coding is only available for variables with ratio or interval scale. Controller.152=Top/bottom coding Controller.153=An unexpected format error occurred. -Controller.154=Creating certificate -Controller.155=Cannot create certificate: -Controller.156=The data that you are about to create a certificate for does not fulfill all privacy models. Proceed? HierarchyWizard.0=Hierarchy wizard HierarchyWizard.1=Load... HierarchyWizard.11=Error saving hierarchy specification @@ -265,6 +262,7 @@ MainMenu.21=Anonymize MainMenu.23=Create hierarchy... MainMenu.25=Settings... MainMenu.27=Help +MainMenu.28=Checklist wizard... MainMenu.29=About MainMenu.3=New project... MainMenu.30=Find/replace... @@ -283,7 +281,6 @@ MainMenu.9=Save project as... MainMenu.40=Heuristic anonymization MainMenu.41=Create empty hierarchy MainMenu.42=Create top/bottom coding rule... -MainMenu.43=Create certificate... MainToolBar.1=Solution space\n MainToolBar.11=Open project... MainToolBar.12=\ - Pruned transformations: @@ -308,10 +305,10 @@ MainToolBar.31=S: MainToolBar.32=A: MainToolBar.33=L: MainToolBar.34=\n - Transformations with unknown properties: -MainToolBar.35=\n - Transformations with known score: +MainToolBar.35=\n - Transformations with information loss available: MainToolBar.36=\nSolution MainToolBar.37=\n - Transformation: -MainToolBar.38=\n - Score: +MainToolBar.38=\n - Information loss: MainToolBar.39=\n - Global optimum: MainToolBar.4=Applied: MainToolBar.42=Copy @@ -406,10 +403,10 @@ ModelCriterion.0=k-Anonymity ModelCriterion.1=-Anonymity ModelCriterion.2=-Differential privacy ModelCriterion.3=(e,d)-Differential privacy -ModelCriterion.4=Profitability +ModelCriterion.4=Game-theoretic privacy ModelCriterion.5=prosecutor ModelCriterion.6=journalist -ModelCriterion.7=No-attack profitability +ModelCriterion.7=No-attack game-theoretic privacy ProjectDialog.0=ARX Anonymization Tool ProjectDialog.1=New Project ProjectDialog.3=OK @@ -435,7 +432,7 @@ PropertiesView.40=IS- PropertiesView.41=Suppressed records PropertiesView.42=Equivalence classes PropertiesView.43=Suppressed classes -PropertiesView.46=Score +PropertiesView.46=Information loss PropertiesView.48=Successors PropertiesView.49=Predecessors PropertiesView.5=Data type @@ -491,7 +488,7 @@ PropertiesView.130=d-Disclosure privacy PropertiesView.131=d PropertiesView.132=k-map PropertiesView.133=Population size -PropertiesView.134=Profitability +PropertiesView.134=Game-theoretic privacy PropertiesView.135=Publisher's benefit PropertiesView.136=Publisher's loss PropertiesView.137=Adverary's gain @@ -578,7 +575,7 @@ PropertiesView.157=Precomputed PropertiesView.158=Considers microaggregation PropertiesView.159=Yes PropertiesView.170=No -Resources.0=3.6.0 +Resources.0=3.5.0 SeparatorDialog.10=An internal error happened: SeparatorDialog.11=Error SeparatorDialog.12=An internal error happened: @@ -601,7 +598,7 @@ StatisticsView.9=Classification accuracy StatisticsView.10=Classification accuracy WorkerAnonymize.0=Anonymizing WorkerAnonymize.1=Task interrupted\! -WorkerAnonymize.2=Calculating score +WorkerAnonymize.2=Determining information loss WorkerAnonymize.3=Encoding result data WorkerExport.0=Exporting data WorkerImport.0=Importing data @@ -630,7 +627,7 @@ AboutDialog.10=limitations under the License.\n AboutDialog.12=ARX Data Anonymization Tool AboutDialog.13=About AboutDialog.15=OK -AboutDialog.16=(c) Copyright 2012-2017 Fabian Prasser, Florian Kohlmayer and contributors +AboutDialog.16=(c) Copyright 2012-2016 Fabian Prasser, Florian Kohlmayer and contributors AboutDialog.18={firstname.lastname}@gmail.com AboutDialog.2=You may obtain a copy of the License at\n AboutDialog.21=Version: @@ -687,7 +684,7 @@ HierarchyView.9=Insert column HierarchyView.20=Remove functional hierarchy HierarchyView.21=This action will remove the underlying functional representation of the current hierarchy. Proceed? HierarchyView.22=Top/bottom coding -LatticeView.1=Score: +LatticeView.1=Information loss: LatticeView.10=Apply transformation LatticeView.11=Expand transformation LatticeView.7=The selected subset of the solution space is\ntoo large to be displayed (%d transformations).\nThe current maximum is %d.\nYou can change this in the settings. @@ -695,8 +692,8 @@ LatticeView.9=Add to clipboard ListView.1=Transformation ListView.10=Unknown ListView.2=Anonymity -ListView.3=Min. score -ListView.4=Max. score +ListView.3=Min. info. loss +ListView.4=Max. info. loss ListView.7=Unknown NodeClipboardView.0=Clipboard NodeClipboardView.1=Edit comment @@ -708,15 +705,15 @@ NodeClipboardView.6=Transformation NodeClipboardView.7=Comment NodeClipboardView.8=Move up NodeClipboardView.9=Move down -NodeClipboardView.10=Sort by score +NodeClipboardView.10=Sort by information loss NodeClipboardView.11=Copy NodeFilterView.10=Show NodeFilterView.11=Hide NodeFilterView.12=Unknown: NodeFilterView.13=Show NodeFilterView.14=Hide -NodeFilterView.15=Min. score: -NodeFilterView.16=Max. score: +NodeFilterView.15=Min. info. loss: +NodeFilterView.16=Max. info. loss: NodeFilterView.3=Filter NodeFilterView.4=Quasi-identifier: NodeFilterView.5=Visible levels @@ -726,7 +723,7 @@ NodeFilterView.8=Hide NodeFilterView.9=Not anonymous: NodeFilterView.20=Generalization: NodeFilterView.21=Classification: -NodeFilterView.22=Score: +NodeFilterView.22=Information loss: NodePropertiesView.0=Properties NodePropertiesView.10=Predecessors NodePropertiesView.12=Transformation @@ -734,17 +731,17 @@ NodePropertiesView.14=Checked NodePropertiesView.16=Property NodePropertiesView.17=Value NodePropertiesView.18=Anonymous -NodePropertiesView.19=Min. score +NodePropertiesView.19=Min. info. loss NodePropertiesView.2=Anonymous NodePropertiesView.22=Unknown -NodePropertiesView.23=Max. score +NodePropertiesView.23=Max. info. loss NodePropertiesView.26=Unknown NodePropertiesView.27=Successors NodePropertiesView.28=Predecessors NodePropertiesView.29=Transformation NodePropertiesView.30=Checked -NodePropertiesView.4=Min. score -NodePropertiesView.6=Max. score +NodePropertiesView.4=Min. info. loss +NodePropertiesView.6=Max. info. loss NodePropertiesView.8=Successors CriterionDefinitionView.0=Height CriterionDefinitionView.1=Precision @@ -812,16 +809,13 @@ CriterionDefinitionView.120=Attacker model: CriterionDefinitionView.121=Prosecutor CriterionDefinitionView.122=Journalist CriterionDefinitionView.123=Allow attack: -CriterionDefinitionView.124=Ignore -CriterionDefinitionView.125=Consider mean squared error -CriterionDefinitionView.126=Consider information loss -ViewCostBenefitModel.1=Publisher's benefit: -ViewCostBenefitModel.2=Publisher's loss: -ViewCostBenefitModel.3=Adverary's gain: -ViewCostBenefitModel.4=Adverary's cost: -ViewCostBenefitModel.0=... -ViewCostBenefitModel.5=Update amount -ViewCostBenefitModel.6=Please enter a number >= 0 +ViewFinancialModel.1=Publisher's benefit: +ViewFinancialModel.2=Publisher's loss: +ViewFinancialModel.3=Adverary's gain: +ViewFinancialModel.4=Adverary's cost: +ViewFinancialModel.0=... +ViewFinancialModel.5=Update amount +ViewFinancialModel.6=Please enter a number >= 0 CriterionDefinitionView.102=EMD with ordered distance CriterionDefinitionView.110=Grassberger-entropy-l-diversity CriterionSelectionDialog.0=Please select a privacy model from which the settings will be transfered @@ -834,7 +828,7 @@ CriterionSelectionDialog.6=Please select a privacy model which will be applied t CriterionSelectionDialog.7=Add a new privacy model CriterionSelectionDialog.8=Please select a privacy model to edit CriterionSelectionDialog.9=Edit a privacy model -CriterionSelectionDialog.10=Costs and benefits +CriterionSelectionDialog.10=Financial setup SubsetDefinitionView.0=Sample extraction SubsetDefinitionView.1=Select none SubsetDefinitionView.2=Select all @@ -1140,7 +1134,7 @@ ViewAttributeDefinition.8=Default ViewClipboard.0=Remove ViewClipboard.1=Move up ViewClipboard.2=Move down -ViewClipboard.3=Sort by score +ViewClipboard.3=Sort by information loss ViewCodingModel.0=Suppression ViewCodingModel.1=Generalization ViewCodingModel.2=Reset diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java index ded99a57fb..eb1cb8b416 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java @@ -1,6 +1,6 @@ /* * ARX: Powerful Data Anonymization - * Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors + * Copyright 2012 - 2016 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. @@ -65,6 +65,9 @@ import org.deidentifier.arx.gui.view.impl.risk.LayoutRisks; import org.deidentifier.arx.gui.view.impl.utility.LayoutUtility; import org.deidentifier.arx.gui.worker.Worker; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.ChecklistWizard; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.ChecklistDialog; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; @@ -83,6 +86,7 @@ import org.eclipse.swt.widgets.Monitor; import org.eclipse.swt.widgets.Shell; + /** * This class implements the global application window. * @@ -267,6 +271,15 @@ public void showAboutDialog() { dialog.open(); } + /** + * Shows the checklist wizard. + */ + public void showChecklistWizard() { + Checklist checklist = new Checklist(controller.getResources().getStream("checklist_khaled_el_emam.txt")); + final ChecklistDialog dialog = new ChecklistDialog(checklist, shell, controller, new ChecklistWizard(checklist, controller)); + dialog.open(); + } + /** * Shows a dialog for selecting privacy criteria. * @@ -719,28 +732,11 @@ public void update(final ModelEvent event) { } - /** - * Creates the global menu - * @return - */ - private List getMenu() { - - List menu = new ArrayList(); - - menu.add(getMenuFile()); - menu.add(getMenuEdit()); - menu.add(getMenuView()); - menu.add(getMenuHelp()); - - return menu; - } - - /** * Creates the edit menu * @return */ - private MainMenuItem getMenuEdit() { + private MainMenuItem getEditMenu() { List items = new ArrayList(); @@ -895,6 +891,75 @@ public boolean isEnabled(Model model) { }; } + + /** + * Creates the help menu + * @return + */ + private MainMenuItem getHelpMenu() { + + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.27"), //$NON-NLS-1$ + controller.getResources().getManagedImage("help.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuHelpHelp(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.28"), //$NON-NLS-1$ + controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuHelpChecklistWizard(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.29"), //$NON-NLS-1$ + controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuHelpAbout(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.32"), //$NON-NLS-1$ + controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuHelpDebug(); } + public boolean isEnabled(Model model) { + return model != null && model.isDebugEnabled(); + } + }); + + return new MainMenuGroup(Resources.getMessage("MainMenu.2"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } + + /** + * Creates the global menu + * @return + */ + private List getMenu() { + + List menu = new ArrayList(); + + menu.add(getMenuFile()); + menu.add(getEditMenu()); + menu.add(getViewMenu()); + menu.add(getHelpMenu()); + + return menu; + } + /** * Creates the file menu * @return @@ -951,15 +1016,6 @@ public boolean isEnabled(Model model) { } }); - items.add(new MainMenuItem(Resources.getMessage("MainMenu.43"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_create_certificate.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileCreateCertificate(); } - public boolean isEnabled(Model model) { - return model != null && model.getOutput() != null && model.getPerspective() == Perspective.ANALYSIS; - } - }); - items.add(new MainMenuSeparator()); items.add(new MainMenuItem(Resources.getMessage("MainMenu.15"), //$NON-NLS-1$ @@ -1002,50 +1058,7 @@ public boolean isEnabled(Model model) { * Creates the help menu * @return */ - private MainMenuItem getMenuHelp() { - - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.27"), //$NON-NLS-1$ - controller.getResources().getManagedImage("help.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuHelpHelp(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.29"), //$NON-NLS-1$ - controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuHelpAbout(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.32"), //$NON-NLS-1$ - controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuHelpDebug(); } - public boolean isEnabled(Model model) { - return model != null && model.isDebugEnabled(); - } - }); - - return new MainMenuGroup(Resources.getMessage("MainMenu.2"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } - - /** - * Creates the help menu - * @return - */ - private MainMenuItem getMenuView() { + private MainMenuItem getViewMenu() { List items = new ArrayList(); diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java new file mode 100644 index 0000000000..e28a6c95b9 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java @@ -0,0 +1,54 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.*; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.*; + +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question.*; + + +public class AnswerRadioGroup extends Composite { + private Button yesButton; + private Button noButton; + private Button n_aButton; + + private Question item; + + public AnswerRadioGroup(Composite parent, Question targetItem) { + super(parent,SWT.NONE); + this.item = targetItem; + this.setLayout(new FillLayout()); + Group group = new Group(this, SWT.SHADOW_IN); + group.setLayout(new RowLayout(SWT.HORIZONTAL)); + + SelectionListener selectionListener = new SelectionAdapter () { + public void widgetSelected(SelectionEvent event) { + Button button = ((Button) event.widget); + if(button == yesButton) { + item.answer = Answer.YES; + } else if(button == noButton) { + item.answer = Answer.NO; + } else { + item.answer = Answer.N_A; + } + }; + }; + + yesButton = new Button(group, SWT.RADIO); + yesButton.setText("Yes"); + yesButton.addSelectionListener(selectionListener); + + noButton = new Button(group, SWT.RADIO); + noButton.setText("No"); + noButton.addSelectionListener(selectionListener); + + n_aButton = new Button(group, SWT.RADIO); + n_aButton.setText("N/A"); + n_aButton.setSelection(true); + n_aButton.addSelectionListener(selectionListener); + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java new file mode 100644 index 0000000000..066615a086 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java @@ -0,0 +1,168 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.ProgressMonitorPart; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.WeightConfiguration; + + +public class ChecklistDialog extends WizardDialog { + private Button weightButton; + private Button loadButton; + private Button saveButton; + private Checklist checklist; + + private Controller controller; + + public ChecklistDialog(Checklist checklist, Shell parentShell, Controller controller, IWizard newWizard) { + super(parentShell, newWizard); + this.checklist = checklist; + this.controller = controller; + } + + protected void createButtonsForButtonBar(Composite parent) { + // this code creates the button on the left side (settings) + GridLayout layout = (GridLayout) parent.getLayout(); + layout.horizontalSpacing = 0; + + // adjust the parent to use the full width + GridData gridData = (GridData) parent.getLayoutData(); + gridData.grabExcessHorizontalSpace = true; + gridData.minimumWidth = 650; + gridData.horizontalAlignment = GridData.FILL; + + // add the settings button + layout.numColumns++; + + weightButton = new Button(parent, SWT.CHECK);//this.createButton(parent, 1000, "Settings", false); + weightButton.setText("Edit"); + + final ChecklistDialog reference = this; + + loadButton = new Button(parent, SWT.PUSH); + loadButton.setText("Load"); + loadButton.setVisible(false); + loadButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dialog = new FileDialog(loadButton.getShell(), SWT.OPEN); + dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); + dialog.setFilterPath("config/weights"); + String result = dialog.open(); + if(result != null) { + updateWeightConfig(result); + } + } + }); + layout.numColumns++; + + saveButton = new Button(parent, SWT.PUSH); + saveButton.setText("Save"); + saveButton.setVisible(false); + saveButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dialog = new FileDialog(saveButton.getShell(), SWT.SAVE); + String name = checklist.getWeightConfiguration().getName(); + if(name == "Last used") { + name = "last_used.txt"; + } + dialog.setFileName(name); + dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); + dialog.setFilterPath("config/weights"); + String result = dialog.open(); + if(result != null) { + WeightConfiguration wc = checklist.getWeightConfiguration(); + wc.save(result); + } + } + }); + layout.numColumns++; + + Listener listener = new Listener() { + public void handleEvent(Event event) { + reference.setWeightsEditable(weightButton.getSelection()); + } + }; + + weightButton.addListener(SWT.Selection, listener); + + + // add a placeholder label that uses the empty space + layout.numColumns++; + Label placeholder = new Label(parent, 1); + placeholder.setText(""); + placeholder.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + + + super.createButtonsForButtonBar(parent); + } + + protected void setWeightsEditable(boolean weightsEditable) { + loadButton.setVisible(weightsEditable); + saveButton.setVisible(weightsEditable); + System.out.println("Editable: "+weightsEditable); + IWizardPage pages[] = this.getWizard().getPages(); + for(IWizardPage page : pages) { + if(page instanceof SectionPage) { + SectionPage sectionPage = (SectionPage)page; + sectionPage.setWeightEditable(weightsEditable); + } + } + this.dialogArea.update(); + } + + + + protected void updateWeightConfig(String result) { + checklist.setWeightConfiguration(new WeightConfiguration(result)); + IWizard wizard = this.getWizard(); + if(wizard instanceof ChecklistWizard) { + ChecklistWizard casted = (ChecklistWizard)wizard; + casted.updateWeights(); + } + + //this.updateWeights(); + //this.updateBar(); + //this.updateWizard(); + } + + // remove progress monitor, taken from + // http://commercialjavaproducts.blogspot.de/2010/11/remove-progress-monitor-part-from-jface.html + + @Override + protected Control createDialogArea(Composite parent) { + Control ctrl = super.createDialogArea(parent); + getProgressMonitor(); + return ctrl; + } + + @Override + protected IProgressMonitor getProgressMonitor() { + ProgressMonitorPart monitor = (ProgressMonitorPart) super.getProgressMonitor(); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.heightHint = 0; + monitor.setLayoutData(gridData); + monitor.setVisible(false); + return monitor; + } + + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java new file mode 100644 index 0000000000..8073dc0fc7 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java @@ -0,0 +1,58 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; + +import org.eclipse.jface.wizard.Wizard; +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.*; + + +public class ChecklistWizard extends Wizard { + + protected SectionPage[] pages; + protected EvaluationPage evaluationPage; + private Checklist checklist; + private Controller controller; + + public ChecklistWizard(Checklist checklist, Controller controller) { + super(); + +// setNeedsProgressMonitor(true); + this.checklist = checklist; + this.controller = controller; + this.setWindowTitle("Checklist Wizard"); + } + + + @Override + public void addPages() { + + Section[] sections = checklist.getSections(); + pages = new SectionPage[sections.length]; + for(int i = 0; i < sections.length; i++) { + Section s = sections[i]; + SectionPage p = new SectionPage(s); + this.addPage(p); + pages[i] = p; + } + + evaluationPage = new EvaluationPage(checklist, controller); + this.addPage(evaluationPage); + } + + @Override + public boolean performFinish() { + // Print the result to the console + //this.pages = null; + //return false; + checklist.saveWeightDefaults(); + System.out.println(checklist); + return true; + } + + protected void updateWeights() { + for(SectionPage page : pages) { + page.updateWeights(); + } + evaluationPage.updateWeights(); + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java new file mode 100644 index 0000000000..53ba21f3a4 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java @@ -0,0 +1,217 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; + + + +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Device; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.swtchart.Chart; + +import java.awt.GridBagLayout; +import java.util.ArrayList; +import java.util.List; + +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.view.SWTUtil; +import org.deidentifier.arx.gui.view.impl.common.ComponentRiskMonitor; + +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.WeightConfiguration; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.MonitorVisualization; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.StackVisualization; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.Visualization; + +public class EvaluationPage extends WizardPage { + private Checklist checklist; + + private Label fileLabel; + private Composite topBar; + + private Visualization visualization; + private Composite rootComposite; + + private Controller controller; + + protected EvaluationPage(Checklist checklist, Controller controller) { + super("Evaluation"); + + this.checklist = checklist; + this.controller = controller; + this.setTitle("Risk Evaluation"); + this.setDescription("This is the risk evaluation based on your answers."); + } + + @Override + public void createControl(Composite parent) { + GridLayout layout = new GridLayout(); + layout.numColumns = 1; + layout.marginHeight = 0; + layout.marginTop = 0; + layout.marginBottom = 0; + layout.verticalSpacing = 0; + layout.makeColumnsEqualWidth = true; + + rootComposite = new Composite(parent, SWT.NO_BACKGROUND); + rootComposite.setLayout(layout); + GridData rootData = new GridData(); + rootData.grabExcessHorizontalSpace = true; + rootData.horizontalAlignment = GridData.FILL; + rootData.grabExcessVerticalSpace = true; + rootData.verticalAlignment = GridData.FILL; + rootComposite.setLayoutData(rootData); + + createTopBar(rootComposite, layout.numColumns); + + // rootComposite.setBackground(rootComposite.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + + this.showMonitorVisualization(); + // + //this.visualization = new StackVisualization(rootComposite, checklist); + + setControl(rootComposite); + } + + + private Composite createTopBar(Composite parent, int span) { + Composite c = new Composite(parent, SWT.NO_BACKGROUND); + + // c.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_CYAN)); + + GridData cData = new GridData(); + cData.horizontalSpan = span; + cData.horizontalAlignment = GridData.FILL; + c.setLayoutData(cData); + + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + c.setLayout(layout); + + + Label weightLabel = new Label(c, SWT.LEFT); + GridData weightData = new GridData(); + weightData.grabExcessHorizontalSpace = true; + weightLabel.setLayoutData(weightData); + weightLabel.setText("Visualization:"); + FontDescriptor boldDescriptor = FontDescriptor.createFrom(weightLabel.getFont()).setStyle(SWT.BOLD); + Font boldFont = boldDescriptor.createFont(weightLabel.getDisplay()); + weightLabel.setFont(boldFont); + fileLabel = weightLabel; + + final Combo visualizationDropDown = new Combo(c, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); + visualizationDropDown.add("Monitor"); + visualizationDropDown.add("Stacks"); + visualizationDropDown.setText("Monitor"); + visualizationDropDown.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + String selected = visualizationDropDown.getText(); + if(selected.equals("Stacks")) { + System.out.println("Select Stacks"); + showStacksVisualization(); + } else if(selected.equals("Monitor")) { + System.out.println("Select Monitor"); + showMonitorVisualization(); + } + } + }); + + /*Button load = new Button (c, SWT.PUSH); + load.setText("Load"); + load.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dialog = new FileDialog(load.getShell(), SWT.OPEN); + dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); + dialog.setFilterPath("config/weights"); + String result = dialog.open(); + if(result != null) { + updateWeightConfig(result); + } + } + }); + Button save = new Button (c, SWT.PUSH); + save.setText("Save"); + save.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dialog = new FileDialog(load.getShell(), SWT.SAVE); + String name = checklist.getWeightConfiguration().getName(); + if(name == "Last used") { + name = "last_used.txt"; + } + dialog.setFileName(name); + //dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); + dialog.setFilterPath("config/weights"); + String result = dialog.open(); + if(result != null) { + WeightConfiguration wc = checklist.getWeightConfiguration(); + wc.save(result); + updateBar(); + } + } + });*/ + + Label separator = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData sepData = new GridData(); + sepData.horizontalSpan = layout.numColumns; + sepData.grabExcessHorizontalSpace = true; + sepData.horizontalAlignment = GridData.FILL; + separator.setLayoutData(sepData); + + topBar = c; + return c; + } + + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + if(visible) { + this.updateWeights(); + } + } + + protected void updateWeights() { + visualization.updateWeights(); + } + + + private void showMonitorVisualization() { + setVisualization(new MonitorVisualization(rootComposite, controller, checklist)); + } + + private void showStacksVisualization() { + setVisualization(new StackVisualization(rootComposite, controller, checklist)); + } + + private void setVisualization(Visualization visualization) { + removeVisualization(); + this.visualization = visualization; + updateWeights(); + this.rootComposite.layout(); + } + + + + private void removeVisualization() { + if(this.visualization != null) { + this.visualization.dispose(); + } + } + + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java new file mode 100644 index 0000000000..7c8ced2b49 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java @@ -0,0 +1,146 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Spinner; +import org.eclipse.swt.widgets.Text; + +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question.Answer; + +public class SectionPage extends WizardPage { + private Section section; + private Composite container; + private boolean weightEditable; + private List weightFields; + + + public SectionPage(Section section) { + super(section.getTitle()); + + this.weightEditable = false; + this.section = section; + this.setTitle(section.getTitle()); + this.setDescription("Answer the following questions"); + } + + @Override + public void createControl(Composite parent) { + final Composite rootComposite = new Composite(parent, SWT.NONE); + //parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE)); + System.out.println("Data: " + parent.getLayoutData()); + + GridLayout rootGrid = new GridLayout(); + rootComposite.setLayout(rootGrid); + + final ScrolledComposite sc = new ScrolledComposite(rootComposite, SWT.BORDER | SWT.V_SCROLL); + GridData sgd = new GridData(GridData.FILL_BOTH); + sgd.grabExcessHorizontalSpace = true; + sgd.grabExcessVerticalSpace = true; + sgd.widthHint = 400;//SWT.DEFAULT; + sgd.heightHint = 300; + sc.setLayoutData(sgd); + + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + container = new Composite(sc, SWT.NULL); + GridLayout layout = new GridLayout(); + container.setLayout(layout); + layout.numColumns = 3; + layout.verticalSpacing = 12; + + createItems(); + + rootComposite.addListener(SWT.Resize, new Listener() { + int width = -1; + @Override + public void handleEvent(org.eclipse.swt.widgets.Event e) { + int newWidth = rootComposite.getSize().x; + if (newWidth != width) { + sc.setMinHeight(container.computeSize(newWidth, SWT.DEFAULT).y+40); + width = newWidth; + } + } + }); + + sc.setContent(container); + sc.setMinSize(container.computeSize(400, SWT.DEFAULT)); + sc.layout(); + + setControl(rootComposite); + } + + private void createItems() { + // add weight fields + this.weightFields = new ArrayList(); + this.weightFields.add(new WeightField(container, this.section, false)); + + Label label = new Label(container, SWT.NONE | SWT.WRAP); + label.setText(this.section.getTitle()); + // from http://eclipsesource.com/blogs/2014/02/10/swt-best-practices-changing-fonts/ + FontDescriptor boldDescriptor = FontDescriptor.createFrom(label.getFont()).setStyle(SWT.BOLD); + Font boldFont = boldDescriptor.createFont(label.getDisplay()); + label.setFont( boldFont ); + + GridData headerGridData = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); + headerGridData.verticalAlignment = GridData.CENTER; + headerGridData.grabExcessVerticalSpace = false; + headerGridData.horizontalSpan = 2; + label.setLayoutData(headerGridData); + + Question[] items = section.getItems(); + for(int i = 0; i < items.length; i++) { + Question itm = items[i]; + + this.weightFields.add(new WeightField(container, itm, false)); + + Label label1 = new Label(container, SWT.NONE | SWT.WRAP); + label1.setText(itm.getTitle()); + GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); + gd.verticalAlignment = GridData.CENTER; + gd.grabExcessVerticalSpace = false; + label1.setLayoutData(gd); + + new AnswerRadioGroup(container, itm); + } + } + + public void setWeightEditable(boolean editable) { + if(editable == this.weightEditable) { + return; + } + this.weightEditable = editable; + + // TODO iterate and set + for(WeightField w : this.weightFields) { + w.setEnabled(editable); + } + } + + protected void updateWeights() { + if(this.weightFields == null) { + return; + } + for(WeightField field : weightFields) { + field.updateText(); + } + } +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java new file mode 100644 index 0000000000..9d0ad5ed76 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java @@ -0,0 +1,117 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; + +import java.text.DecimalFormat; +import java.text.ParseException; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Text; + +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Item; + +public class WeightField { + private Item item; + private Text field; + private Combo dropdown; + private boolean disableUpdateQuestion; + + private boolean enabled; + + static final DecimalFormat df = new DecimalFormat("#.00"); + + public WeightField(Composite composite, Item item, boolean enabled) { + //this.field = new Text(composite, SWT.BORDER); + + dropdown = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); + dropdown.add("0.25"); + dropdown.add("0.50"); + dropdown.add("1.00"); + dropdown.add("1.50"); + dropdown.add("2.00"); + dropdown.add("3.00"); + dropdown.add("5.00"); + + this.item = item; + this.setEnabled(enabled); + + GridData gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER); + gridData.widthHint = 72; + dropdown.setLayoutData(gridData); + /*field.setLayoutData(gridData); + field.addListener (SWT.Verify, e -> { + String string = e.text; + char [] chars = new char [string.length ()]; + string.getChars (0, chars.length, chars, 0); + for (int i=0; i(); + + try { + + // hold a reference to the current section + Section currentSection = null; + + // read first line, then iterate over the lines + String line = bufferedReader.readLine(); + while (line != null) { + line = line.trim(); // get rid of leading/trailing whitespaces + if(line.length() == 0) { + // do nothing + } else if(line.startsWith("#") == true) { + // current line is a section + line = line.substring(1); + currentSection = Section.sectionFromLine(weightConfiguration, line); + sections.add(currentSection); + maximumWeight += Math.abs(currentSection.getWeight()); + } else { + // current line is an item + if(currentSection == null) { + System.out.println("Invalid syntax. Checklist item before section (section-lines start with #)"); + } + + // parse and add item + Question newItem = Question.itemFromLine(currentSection, line); + currentSection.addItem(newItem); + } + + // read next line + line = bufferedReader.readLine(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if(bufferedReader != null) { + try { + bufferedReader.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + public Section[] getSections() { + return (sections.toArray(new Section[sections.size()])); + } + + public double getMaximumWeight() { + return maximumWeight; + } + + public double getScore() { + if(maximumWeight == 0.0) { + System.out.println("This Checklist has a maximum weight of 0.0, it can't calculate a score: "+this); + return 0.0; + } + double result = 0.0; + for(Section s : sections) { + result += s.getWeight() * s.getScore(); + } + result /= maximumWeight; + return result; + } + + @Override + public String toString() { + return "Checklist [score="+this.getScore()+", sections=" + sections + "\n]"; + } + + public void saveWeightDefaults() { + this.weightConfiguration.saveLastUsed(); + } + + public WeightConfiguration getWeightConfiguration() { + return this.weightConfiguration; + } + + public void setWeightConfiguration(WeightConfiguration weightConfiguration) { + if(this.weightConfiguration == weightConfiguration) { + return; + } + + this.weightConfiguration = weightConfiguration; + this.maximumWeight = 0.0; + for(Section s : this.sections) { + s.setWeightConfiguration(weightConfiguration); + maximumWeight += Math.abs(s.getWeight()); + } + + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java new file mode 100644 index 0000000000..6467bdc122 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java @@ -0,0 +1,51 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; + + +public abstract class Item { + private WeightConfiguration weightConfiguration; + protected String identifier; + protected String title; + + public Item(String line) { + String components[] = line.split(":",2); + if(components.length != 2) { + System.err.println("Couldn't parse item! Original line: "+line); + return; + } + this.identifier = components[0].trim(); + this.title = components[1].trim(); + } + + protected WeightConfiguration getWeightConfiguration() { + return this.weightConfiguration; + } + + public void setWeightConfiguration(WeightConfiguration weightConfiguration) { + this.weightConfiguration = weightConfiguration; + updateWeights(); + } + + public void updateWeights() { + + } + + public double getWeight() { + if(weightConfiguration == null) { + return 1.0; + } + return weightConfiguration.weightForIdentifier(this.getIdentifier()); + } + + public void setWeight(double weight) { + weightConfiguration.setWeightForIdentifier(this.getIdentifier(), weight); + } + + public String getTitle() { + return title; + } + + public String getIdentifier() { + return identifier; + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java new file mode 100644 index 0000000000..ab0e4d223e --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java @@ -0,0 +1,51 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; + +public class Question extends Item { + private Section section; + public enum Answer { YES, NO, N_A } + + public Answer answer; + + public Question(Section section, String line) { + super(line); + this.section = section; + this.answer = Answer.N_A; + } + + public static Question itemFromLine(Section section, String line) { + line = line.trim(); + Question item = new Question(section, line); + return item; + } + + public String getIdentifier() { + return section.getIdentifier()+"."+identifier; + } + + public String getAnswerString() { + switch(answer) { + case YES: + return "YES"; + case NO: + return "NO"; + default: + return "N/A"; + } + } + + public double getScore() { + switch(answer) { + case YES: + return this.getWeight(); + case NO: + return -this.getWeight(); + default: + return 0.0; + } + } + + @Override + public String toString() { + return "\n\t\tQuestion [id=" + this.getIdentifier() + ", answer=" + this.getAnswerString() + ", weight=" + this.getWeight() + ", title=" + title + "]"; + } +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java new file mode 100644 index 0000000000..853a9e0af7 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java @@ -0,0 +1,67 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; + +import java.util.ArrayList; + +public class Section extends Item { + private ArrayList items; + private double maximumWeight = 0.0; + + + public Section(WeightConfiguration weightConfiguration, String line) { + super(line); + this.items = new ArrayList(); + setWeightConfiguration(weightConfiguration); + } + + public static Section sectionFromLine(WeightConfiguration weightConfiguration, String line) { + line = line.trim(); + Section section = new Section(weightConfiguration, line); + return section; + } + + public Question[] getItems() { + return items.toArray(new Question[items.size()]); + } + + public void addItem(Question item) { + item.setWeightConfiguration(this.getWeightConfiguration()); + items.add(item); + maximumWeight += Math.abs(item.getWeight()); + } + + public void updateWeights() { + super.updateWeights(); + + maximumWeight = 0.0; + for(Question item : items) { + item.setWeightConfiguration(this.getWeightConfiguration()); + maximumWeight += Math.abs(item.getWeight()); + } + } + + public double getMaximumWeight() { + return maximumWeight; + } + + public double getScore() { + if(maximumWeight == 0.0) { + System.out.println("This Section has a maximum weight of 0.0, it can't calculate a score: "+this); + return 0.0; + } + double result = 0.0; + for(Question q : items) { + result += q.getScore(); + } + if(this.getWeight() < 0.0) { + result = (result * (-1.0)); + } + result /= maximumWeight; + return result; + } + + @Override + public String toString() { + return "\n\tSection [id=" + this.getIdentifier() + ", title=" + this.getTitle() + ", weight=" + this.getWeight() + ", score="+ this.getScore() +", items=" + items + ", config="+this.getWeightConfiguration().getName()+"\n\t]"; + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java new file mode 100644 index 0000000000..972892ede3 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java @@ -0,0 +1,119 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +public class WeightConfiguration { + private String filename; + private String name; + private Map weights; + + private static final String lastUsedPath = "config/weights/last_used.txt"; + + public WeightConfiguration() { + this(lastUsedPath); + this.name = "Last used"; + } + + public WeightConfiguration(String filename) { + this.filename = filename; + weights = new HashMap(); + loadProperties(); + + updateName(); + + } + + private void updateName() { + Path p = Paths.get(filename); + this.name = p.getFileName().toString(); + } + + public double weightForIdentifier(String identifier) { + if(weights.containsKey(identifier) == false) { + return 1.0; + } + return weights.get(identifier); + } + + public void setWeightForIdentifier(String identifier, double weight) { + weights.put(identifier, weight); + } + + + private void loadProperties() { + Properties props = new Properties(); + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + + for(Entry entry : props.entrySet()) { + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + + double weight = Double.parseDouble(value); + weights.put(key, weight); + } + in.close(); + } catch (FileNotFoundException e) { + System.err.println("Couldn't open file: "+filename); + return; + } catch (IOException e) { + System.err.println("Couldn't parse file: "+filename); + return; + } + + } + + public String getName() { + return this.name; + } + + + public void saveLastUsed() { + save(lastUsedPath); + } + + + public void save() { + save(this.filename); + } + + + public void save(String filename) { + if(filename == null) { + System.out.println("No file specified to save to"); + return; + } + + Properties props = new Properties(); + for(Entry entry: weights.entrySet()) { + props.setProperty(entry.getKey(), Double.toString(entry.getValue())); + } + + FileOutputStream out; + try { + out = new FileOutputStream(filename); + props.store(out, null); + out.close(); + } catch (FileNotFoundException e) { + System.err.println("Couldn't open file: "+filename); + return; + } catch (IOException e) { + System.err.println("Couldn't store file: "+filename); + return; + } + + this.filename = filename; + updateName(); + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java new file mode 100644 index 0000000000..736b19755f --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java @@ -0,0 +1,72 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation; + +import java.util.ArrayList; +import java.util.List; + +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.view.SWTUtil; +import org.deidentifier.arx.gui.view.impl.common.ComponentRiskMonitor; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.*; + +public class MonitorVisualization extends Visualization { + private List monitors; + private ComponentRiskMonitor totalMonitor; + + public MonitorVisualization(Composite parent, Controller controller, Checklist checklist) { + super(parent, controller, checklist); + } + + protected void createVisualization() { + Section sections[] = this.checklist.getSections(); + monitors = new ArrayList(); + + //Composite rootComposite = new Composite(parent, SWT.NONE); + GridLayout layout = SWTUtil.createGridLayoutWithEqualWidth(sections.length); + layout.marginHeight = 0; + layout.marginTop = 0; + layout.marginBottom = 0; +// layout.verticalSpacing = 0; + layout.makeColumnsEqualWidth = true; + this.setLayout(layout); + + for(int i = 0; i < sections.length; i++) { + String title = sections[i].getTitle(); + + ComponentRiskMonitor riskMonitor = new ComponentRiskMonitor(this, this.controller, title, title); + riskMonitor.setLayoutData(SWTUtil.createFillGridData()); + riskMonitor.setRisk(0.5); + monitors.add(riskMonitor); + } + + totalMonitor = new ComponentRiskMonitor(this, this.controller, "Total", "Total"); + totalMonitor.setLayoutData(SWTUtil.createFillGridData()); + totalMonitor.setRisk(0.5); + + GridData gridData = new GridData(); + gridData.grabExcessVerticalSpace = true; + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + gridData.minimumHeight = 150; + gridData.horizontalSpan = layout.numColumns; + totalMonitor.setLayoutData(gridData); + } + + public void updateWeights() { + Section sections[] = checklist.getSections(); + for(int i = 0; i < sections.length; i++) { + Section s = sections[i]; + + ComponentRiskMonitor riskMonitor = monitors.get(i); + riskMonitor.setRisk((s.getScore() / 2.0) + 0.5); + // System.out.println("Setup"); + } + + totalMonitor.setRisk((checklist.getScore() / 2.0) + 0.5); + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java new file mode 100644 index 0000000000..610dda989e --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java @@ -0,0 +1,124 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.swtchart.*; +import org.swtchart.ISeries.*; +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; + +public class StackVisualization extends Visualization { + private Chart chart; + private IBarSeries positive; + private IBarSeries neutral; + private IBarSeries negative; + + public StackVisualization(Composite parent, Controller controller, Checklist checklist) { + super(parent, controller, checklist); + } + + protected void createVisualization() { + Section sections[] = this.checklist.getSections(); + String sectionNames[] = new String[sections.length]; + int idx = 0; + for(Section s : sections) { + sectionNames[idx] = s.getTitle(); + idx++; + } + + FillLayout fillLayout = new FillLayout(); + fillLayout.type = SWT.VERTICAL; + this.setLayout(fillLayout); + chart = new Chart(this, SWT.NONE); + chart.getTitle().setText("Weighted Answers"); + + double[] positiveSeries = { 0.1, 0, 0}; + double[] neutralSeries = { 0.1, 0, 0}; + double[] negativeSeries = { 0.1, 0, 0}; + + ISeriesSet seriesSet = chart.getSeriesSet(); + + positive = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, "Positive"); + positive.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_GREEN)); + positive.enableStack(true); + positive.setYSeries(positiveSeries); + + neutral = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, "Neutral"); + neutral.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_GRAY)); + neutral.enableStack(true); + neutral.setYSeries(neutralSeries); + + negative = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, "Negative"); + negative.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_RED)); + negative.enableStack(true); + negative.setYSeries(negativeSeries); + + IAxisSet axisSet = chart.getAxisSet(); + axisSet.adjustRange(); + + IAxis yAxis = axisSet.getYAxis(0); + yAxis.setRange(new Range(0.0, 1.05)); + yAxis.getTitle().setVisible(false); + + IAxis xAxis = axisSet.getXAxis(0); + xAxis.setCategorySeries(sectionNames); + xAxis.enableCategory(true); + xAxis.getTitle().setVisible(false); + } + + public void updateWeights() { + Section sections[] = this.checklist.getSections(); + double[] posY = new double[sections.length]; + double[] neuY = new double[sections.length]; + double[] negY = new double[sections.length]; + + int idx = 0; + for(Section sec : sections) { + double pos = 0.0; + double neu = 0.0; + double neg = 0.0; + + for(Question q : sec.getItems()) { + double w = q.getWeight(); + double s = q.getScore(); + if(s == 0.0) { + neu += w; + } else if(s > 0.0) { + pos += w; + } else { + neg += w; + } + } + + posY[idx] = pos / sec.getMaximumWeight(); + neuY[idx] = neu / sec.getMaximumWeight(); + negY[idx] = neg / sec.getMaximumWeight(); + + System.out.println("Updated "+sec.getIdentifier()+" : "+posY[idx]+" "+neuY[idx]+" "+negY[idx]); + + idx++; + + + } + + + + + positive.setYSeries(posY); + positive.enableStack(true); + neutral.setYSeries(neuY); + neutral.enableStack(true); + negative.setYSeries(negY); + negative.enableStack(true); + +// IAxisSet axisSet = chart.getAxisSet(); +// axisSet.adjustRange(); + chart.update(); + chart.redraw(); + } + + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java new file mode 100644 index 0000000000..ba006679bf --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java @@ -0,0 +1,36 @@ +package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; + +public abstract class Visualization extends Composite { + protected Checklist checklist; + protected Controller controller; + + public Visualization(Composite parent, Controller controller, Checklist checklist) { + super(parent, SWT.NO_SCROLL); + + GridData gridData = new GridData(); + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + this.setLayoutData(gridData); + + this.checklist = checklist; + this.controller = controller; + this.createVisualization(); + } + + protected void createVisualization() { + + } + + public void updateWeights() { + + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/resources/bullet_green.png b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/resources/bullet_green.png new file mode 100644 index 0000000000000000000000000000000000000000..058ad261f520490be9d3fc2e322392fdedfd1cbd GIT binary patch literal 295 zcmV+?0oeYDP)ef43{&%10 z`rmr0`TyJtv;LcOX%laN^>UMjsi!CYUwmcZ|JfI2{-1ED=f8fLD)C;hoM$LyFDY#DW^u;K&o-|vHe`x?xbw1zYx$2><(A#;6QU!sSfhO( ioL~suuJh6Vfb_?jd)=>7iZy|bXYh3Ob6Mw<&;$Tq>~Ep~ literal 0 HcmV?d00001 From 309b0ca257b480696dbf9d5b6f74dcf3ce0c7658 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 01:02:22 +0100 Subject: [PATCH 02/22] remove debug prints, add comments --- .../sharingwizard/AnswerRadioGroup.java | 5 +- .../wizard/sharingwizard/ChecklistDialog.java | 23 +++++---- .../wizard/sharingwizard/ChecklistWizard.java | 17 +++++-- .../wizard/sharingwizard/EvaluationPage.java | 46 ++---------------- .../wizard/sharingwizard/SectionPage.java | 6 ++- .../wizard/sharingwizard/WeightField.java | 32 +++--------- .../sharingwizard/checklist/Checklist.java | 4 ++ .../wizard/sharingwizard/checklist/Item.java | 5 +- .../sharingwizard/checklist/Question.java | 4 ++ .../sharingwizard/checklist/Section.java | 5 ++ .../checklist/WeightConfiguration.java | 4 ++ .../evaluation/MonitorVisualization.java | 4 ++ .../evaluation/StackVisualization.java | 12 ++--- .../evaluation/Visualization.java | 4 ++ .../evaluation/resources/bullet_green.png | Bin 295 -> 0 bytes .../evaluation/resources/bullet_red.png | Bin 287 -> 0 bytes 16 files changed, 81 insertions(+), 90 deletions(-) delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/resources/bullet_green.png delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/resources/bullet_red.png diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java index e28a6c95b9..506d29d78e 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java @@ -9,7 +9,10 @@ import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question.*; - +/** + * The radio group component for answering the questions, contains yes, no and n/a as possible answers + * + */ public class AnswerRadioGroup extends Composite { private Button yesButton; private Button noButton; diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java index 066615a086..877f19a8b2 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java @@ -37,6 +37,9 @@ public ChecklistDialog(Checklist checklist, Shell parentShell, Controller contro this.controller = controller; } + /** + * create a custom button bar, with the load/store/edit buttons for the weight profiles + */ protected void createButtonsForButtonBar(Composite parent) { // this code creates the button on the left side (settings) GridLayout layout = (GridLayout) parent.getLayout(); @@ -51,7 +54,7 @@ protected void createButtonsForButtonBar(Composite parent) { // add the settings button layout.numColumns++; - weightButton = new Button(parent, SWT.CHECK);//this.createButton(parent, 1000, "Settings", false); + weightButton = new Button(parent, SWT.CHECK); weightButton.setText("Edit"); final ChecklistDialog reference = this; @@ -115,10 +118,14 @@ public void handleEvent(Event event) { super.createButtonsForButtonBar(parent); } + /** + * enable or disable the edit mode + * @param weightsEditable whether the weights should be changeable + */ protected void setWeightsEditable(boolean weightsEditable) { loadButton.setVisible(weightsEditable); saveButton.setVisible(weightsEditable); - System.out.println("Editable: "+weightsEditable); + //System.out.println("Editable: "+weightsEditable); IWizardPage pages[] = this.getWizard().getPages(); for(IWizardPage page : pages) { if(page instanceof SectionPage) { @@ -128,9 +135,11 @@ protected void setWeightsEditable(boolean weightsEditable) { } this.dialogArea.update(); } - - - + + /** + * updates the current weight configuration + * @param result the weight configuration to load + */ protected void updateWeightConfig(String result) { checklist.setWeightConfiguration(new WeightConfiguration(result)); IWizard wizard = this.getWizard(); @@ -138,10 +147,6 @@ protected void updateWeightConfig(String result) { ChecklistWizard casted = (ChecklistWizard)wizard; casted.updateWeights(); } - - //this.updateWeights(); - //this.updateBar(); - //this.updateWizard(); } // remove progress monitor, taken from diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java index 8073dc0fc7..6b49b88c11 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java @@ -12,10 +12,14 @@ public class ChecklistWizard extends Wizard { private Checklist checklist; private Controller controller; + /** + * create a new checklist wizard + * @param checklist the checklist to use + * @param controller the controller opening the wizard + */ public ChecklistWizard(Checklist checklist, Controller controller) { super(); -// setNeedsProgressMonitor(true); this.checklist = checklist; this.controller = controller; this.setWindowTitle("Checklist Wizard"); @@ -24,7 +28,7 @@ public ChecklistWizard(Checklist checklist, Controller controller) { @Override public void addPages() { - + // add a page for each section Section[] sections = checklist.getSections(); pages = new SectionPage[sections.length]; for(int i = 0; i < sections.length; i++) { @@ -34,20 +38,27 @@ public void addPages() { pages[i] = p; } + // add the final evaluation page evaluationPage = new EvaluationPage(checklist, controller); this.addPage(evaluationPage); } + /** + * called when the dialog is finished, saves the current weights + */ @Override public boolean performFinish() { // Print the result to the console //this.pages = null; //return false; checklist.saveWeightDefaults(); - System.out.println(checklist); + //System.out.println(checklist); return true; } + /** + * updates the weights for each section and the evaluation + */ protected void updateWeights() { for(SectionPage page : pages) { page.updateWeights(); diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java index 53ba21f3a4..e5e1ccbc5c 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java @@ -35,6 +35,10 @@ import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.StackVisualization; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.Visualization; +/** + * final page containing the two different visualizations + * + */ public class EvaluationPage extends WizardPage { private Checklist checklist; @@ -75,12 +79,8 @@ public void createControl(Composite parent) { rootComposite.setLayoutData(rootData); createTopBar(rootComposite, layout.numColumns); - - // rootComposite.setBackground(rootComposite.getDisplay().getSystemColor(SWT.COLOR_BLUE)); this.showMonitorVisualization(); - // - //this.visualization = new StackVisualization(rootComposite, checklist); setControl(rootComposite); } @@ -89,8 +89,6 @@ public void createControl(Composite parent) { private Composite createTopBar(Composite parent, int span) { Composite c = new Composite(parent, SWT.NO_BACKGROUND); - // c.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_CYAN)); - GridData cData = new GridData(); cData.horizontalSpan = span; cData.horizontalAlignment = GridData.FILL; @@ -129,42 +127,6 @@ public void widgetSelected(SelectionEvent e) { } }); - /*Button load = new Button (c, SWT.PUSH); - load.setText("Load"); - load.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - FileDialog dialog = new FileDialog(load.getShell(), SWT.OPEN); - dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); - dialog.setFilterPath("config/weights"); - String result = dialog.open(); - if(result != null) { - updateWeightConfig(result); - } - } - }); - Button save = new Button (c, SWT.PUSH); - save.setText("Save"); - save.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - FileDialog dialog = new FileDialog(load.getShell(), SWT.SAVE); - String name = checklist.getWeightConfiguration().getName(); - if(name == "Last used") { - name = "last_used.txt"; - } - dialog.setFileName(name); - //dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); - dialog.setFilterPath("config/weights"); - String result = dialog.open(); - if(result != null) { - WeightConfiguration wc = checklist.getWeightConfiguration(); - wc.save(result); - updateBar(); - } - } - });*/ - Label separator = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL); GridData sepData = new GridData(); sepData.horizontalSpan = layout.numColumns; diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java index 7c8ced2b49..807a4f7bc8 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java @@ -25,6 +25,10 @@ import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question.Answer; +/** + * each SectionPage shows all the questions from a checklist section + * + */ public class SectionPage extends WizardPage { private Section section; private Composite container; @@ -44,8 +48,6 @@ public SectionPage(Section section) { @Override public void createControl(Composite parent) { final Composite rootComposite = new Composite(parent, SWT.NONE); - //parent.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_BLUE)); - System.out.println("Data: " + parent.getLayoutData()); GridLayout rootGrid = new GridLayout(); rootComposite.setLayout(rootGrid); diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java index 9d0ad5ed76..33b2ae3a91 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java @@ -14,6 +14,10 @@ import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Item; +/** + * a dropdown field for changing a question's weight + * + */ public class WeightField { private Item item; private Text field; @@ -24,9 +28,7 @@ public class WeightField { static final DecimalFormat df = new DecimalFormat("#.00"); - public WeightField(Composite composite, Item item, boolean enabled) { - //this.field = new Text(composite, SWT.BORDER); - + public WeightField(Composite composite, Item item, boolean enabled) { dropdown = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); dropdown.add("0.25"); dropdown.add("0.50"); @@ -42,29 +44,8 @@ public WeightField(Composite composite, Item item, boolean enabled) { GridData gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER); gridData.widthHint = 72; dropdown.setLayoutData(gridData); - /*field.setLayoutData(gridData); - field.addListener (SWT.Verify, e -> { - String string = e.text; - char [] chars = new char [string.length ()]; - string.getChars (0, chars.length, chars, 0); - for (int i=0; ief43{&%10 z`rmr0`TyJtv;LcOX%laN^>UMjsi!CYUwmcZ|JfI2{-1ED=f8fLD)C;hoM$LyFDY#DW^u;K&o-|vHe`x?xbw1zYx$2><(A#;6QU!sSfhO( ioL~suuJh6Vfb_?jd)=>7iZy|bXYh3Ob6Mw<&;$Tq>~Ep~ From 9886a7e345b687ddfacb8f3a1247b9e783c3a51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 21:08:47 +0100 Subject: [PATCH 03/22] try to fix conflicts --- .../org/deidentifier/arx/gui/Controller.java | 84 +++++++++++++++++-- 1 file changed, 76 insertions(+), 8 deletions(-) diff --git a/src/gui/org/deidentifier/arx/gui/Controller.java b/src/gui/org/deidentifier/arx/gui/Controller.java index 846372504e..d5e8847a5c 100644 --- a/src/gui/org/deidentifier/arx/gui/Controller.java +++ b/src/gui/org/deidentifier/arx/gui/Controller.java @@ -1,6 +1,6 @@ /* * ARX: Powerful Data Anonymization - * Copyright 2012 - 2016 Fabian Prasser, Florian Kohlmayer and contributors + * Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors * Copyright 2014 Karol Babioch * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,6 +18,7 @@ package org.deidentifier.arx.gui; +import java.awt.Desktop; import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -81,6 +82,7 @@ import org.deidentifier.arx.gui.view.impl.wizard.ImportWizard; import org.deidentifier.arx.gui.worker.Worker; import org.deidentifier.arx.gui.worker.WorkerAnonymize; +import org.deidentifier.arx.gui.worker.WorkerCreateCertificate; import org.deidentifier.arx.gui.worker.WorkerExport; import org.deidentifier.arx.gui.worker.WorkerImport; import org.deidentifier.arx.gui.worker.WorkerLoad; @@ -954,6 +956,72 @@ public void actionMenuEditSettings() { } } + /** + * Creates and displays a certificate + */ + public void actionMenuFileCreateCertificate() { + + if (model == null) { + main.showInfoDialog(main.getShell(), + Resources.getMessage("Controller.30"), //$NON-NLS-1$ + Resources.getMessage("Controller.31")); //$NON-NLS-1$ + return; + } else if (model.getOutput() == null) { + main.showInfoDialog(main.getShell(), + Resources.getMessage("Controller.32"), //$NON-NLS-1$ + Resources.getMessage("Controller.33")); //$NON-NLS-1$ + return; + } + + // Check node + if (model.getOutputNode().getAnonymity() != Anonymity.ANONYMOUS) { + if (!main.showQuestionDialog(main.getShell(), + Resources.getMessage("Controller.34"), //$NON-NLS-1$ + Resources.getMessage("Controller.156"))) //$NON-NLS-1$ + { + return; + } + } + + // Ask for file + String file = main.showSaveFileDialog(main.getShell(), "*.pdf"); //$NON-NLS-1$ + if (file == null) { + return; + } + if (!file.endsWith(".pdf")) { //$NON-NLS-1$ + file = file + ".pdf"; //$NON-NLS-1$ + } + + // Export + final WorkerCreateCertificate worker = new WorkerCreateCertificate(file, + model.getCSVSyntax(), + model.getInputConfig().getInput().getHandle(), + model.getOutputDefinition(), + model.getOutputConfig().getConfig(), + model.getResult(), + model.getOutputNode(), + model.getOutput(), + model); + + main.showProgressDialog(Resources.getMessage("Controller.154"), worker); //$NON-NLS-1$ + + if (worker.getError() != null) { + main.showErrorDialog(main.getShell(), + Resources.getMessage("Controller.155"), //$NON-NLS-1$ + worker.getError()); + return; + } + + // Open + if (Desktop.isDesktopSupported()) { + try { + Desktop.getDesktop().open(worker.getResult()); + } catch (Exception e) { + // Drop silently + } + } + } + /** * File->exit. */ @@ -1520,7 +1588,7 @@ public String actionShowFormatInputDialog(final Shell shell, return main.showFormatInputDialog(shell, title, text, null, locale, type, Arrays.asList(values)); } - + /** * Shows a dialog for selecting a format string for a data type. * @@ -1543,7 +1611,7 @@ public String actionShowFormatInputDialog(final Shell shell, return main.showFormatInputDialog(shell, title, text, preselected, locale, type, values); } - + /** * Shows a help dialog. * @@ -1563,7 +1631,6 @@ public void actionShowHelpDialog(String id) { public void actionShowInfoDialog(final Shell shell, final String header, final String text) { main.showInfoDialog(shell, header, text); } - /** * Shows an input dialog. * @@ -1579,6 +1646,7 @@ public String actionShowInputDialog(final Shell shell, final String initial) { return main.showInputDialog(shell, header, text, initial); } + /** * Shows an input dialog. * @@ -1665,7 +1733,6 @@ public boolean actionShowQuestionDialog(final Shell shell, final String text) { return main.showQuestionDialog(shell, header, text); } - /** * Shows a question dialog. * @@ -1677,6 +1744,7 @@ public boolean actionShowQuestionDialog(final String header, final String text) { return main.showQuestionDialog(this.main.getShell(), header, text); } + /** * Internal method for showing a "save file" dialog. * @@ -1687,7 +1755,7 @@ public boolean actionShowQuestionDialog(final String header, public String actionShowSaveFileDialog(final Shell shell, String filter) { return main.showSaveFileDialog(shell, filter); } - + /** * Includes all tuples in the research subset. */ @@ -1826,7 +1894,7 @@ public String isValid(String arg0) { model.setSubsetOrigin(Resources.getMessage("Controller.133")); //$NON-NLS-1$ update(new ModelEvent(this, ModelPart.RESEARCH_SUBSET, subset.getSet())); } - + /** * Registers a listener at the controller. * @@ -1839,7 +1907,7 @@ public void addListener(final ModelPart target, final IView listener) { } listeners.get(target).add(listener); } - + @Override public void dispose() { for (final Set listeners : getListeners().values()) { From 45d7d9ff6afc02edda04952169651de1afb92281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 21:18:12 +0100 Subject: [PATCH 04/22] change to upstream --- .../arx/gui/resources/messages.properties | 65 +- .../arx/gui/view/impl/MainWindow.java | 2137 ++++++++--------- 2 files changed, 1098 insertions(+), 1104 deletions(-) diff --git a/src/gui/org/deidentifier/arx/gui/resources/messages.properties b/src/gui/org/deidentifier/arx/gui/resources/messages.properties index 2efd790322..9234db46a9 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/messages.properties +++ b/src/gui/org/deidentifier/arx/gui/resources/messages.properties @@ -149,6 +149,9 @@ Controller.150=Not available Controller.151=Top/bottom coding is only available for variables with ratio or interval scale. Controller.152=Top/bottom coding Controller.153=An unexpected format error occurred. +Controller.154=Creating certificate +Controller.155=Cannot create certificate: +Controller.156=The data that you are about to create a certificate for does not fulfill all privacy models. Proceed? HierarchyWizard.0=Hierarchy wizard HierarchyWizard.1=Load... HierarchyWizard.11=Error saving hierarchy specification @@ -281,6 +284,7 @@ MainMenu.9=Save project as... MainMenu.40=Heuristic anonymization MainMenu.41=Create empty hierarchy MainMenu.42=Create top/bottom coding rule... +MainMenu.43=Create certificate... MainToolBar.1=Solution space\n MainToolBar.11=Open project... MainToolBar.12=\ - Pruned transformations: @@ -305,10 +309,10 @@ MainToolBar.31=S: MainToolBar.32=A: MainToolBar.33=L: MainToolBar.34=\n - Transformations with unknown properties: -MainToolBar.35=\n - Transformations with information loss available: +MainToolBar.35=\n - Transformations with known score: MainToolBar.36=\nSolution MainToolBar.37=\n - Transformation: -MainToolBar.38=\n - Information loss: +MainToolBar.38=\n - Score: MainToolBar.39=\n - Global optimum: MainToolBar.4=Applied: MainToolBar.42=Copy @@ -403,10 +407,10 @@ ModelCriterion.0=k-Anonymity ModelCriterion.1=-Anonymity ModelCriterion.2=-Differential privacy ModelCriterion.3=(e,d)-Differential privacy -ModelCriterion.4=Game-theoretic privacy +ModelCriterion.4=Profitability ModelCriterion.5=prosecutor ModelCriterion.6=journalist -ModelCriterion.7=No-attack game-theoretic privacy +ModelCriterion.7=No-attack profitability ProjectDialog.0=ARX Anonymization Tool ProjectDialog.1=New Project ProjectDialog.3=OK @@ -432,7 +436,7 @@ PropertiesView.40=IS- PropertiesView.41=Suppressed records PropertiesView.42=Equivalence classes PropertiesView.43=Suppressed classes -PropertiesView.46=Information loss +PropertiesView.46=Score PropertiesView.48=Successors PropertiesView.49=Predecessors PropertiesView.5=Data type @@ -488,7 +492,7 @@ PropertiesView.130=d-Disclosure privacy PropertiesView.131=d PropertiesView.132=k-map PropertiesView.133=Population size -PropertiesView.134=Game-theoretic privacy +PropertiesView.134=Profitability PropertiesView.135=Publisher's benefit PropertiesView.136=Publisher's loss PropertiesView.137=Adverary's gain @@ -575,7 +579,7 @@ PropertiesView.157=Precomputed PropertiesView.158=Considers microaggregation PropertiesView.159=Yes PropertiesView.170=No -Resources.0=3.5.0 +Resources.0=3.6.0 SeparatorDialog.10=An internal error happened: SeparatorDialog.11=Error SeparatorDialog.12=An internal error happened: @@ -598,7 +602,7 @@ StatisticsView.9=Classification accuracy StatisticsView.10=Classification accuracy WorkerAnonymize.0=Anonymizing WorkerAnonymize.1=Task interrupted\! -WorkerAnonymize.2=Determining information loss +WorkerAnonymize.2=Calculating score WorkerAnonymize.3=Encoding result data WorkerExport.0=Exporting data WorkerImport.0=Importing data @@ -627,7 +631,7 @@ AboutDialog.10=limitations under the License.\n AboutDialog.12=ARX Data Anonymization Tool AboutDialog.13=About AboutDialog.15=OK -AboutDialog.16=(c) Copyright 2012-2016 Fabian Prasser, Florian Kohlmayer and contributors +AboutDialog.16=(c) Copyright 2012-2017 Fabian Prasser, Florian Kohlmayer and contributors AboutDialog.18={firstname.lastname}@gmail.com AboutDialog.2=You may obtain a copy of the License at\n AboutDialog.21=Version: @@ -684,7 +688,7 @@ HierarchyView.9=Insert column HierarchyView.20=Remove functional hierarchy HierarchyView.21=This action will remove the underlying functional representation of the current hierarchy. Proceed? HierarchyView.22=Top/bottom coding -LatticeView.1=Information loss: +LatticeView.1=Score: LatticeView.10=Apply transformation LatticeView.11=Expand transformation LatticeView.7=The selected subset of the solution space is\ntoo large to be displayed (%d transformations).\nThe current maximum is %d.\nYou can change this in the settings. @@ -692,8 +696,8 @@ LatticeView.9=Add to clipboard ListView.1=Transformation ListView.10=Unknown ListView.2=Anonymity -ListView.3=Min. info. loss -ListView.4=Max. info. loss +ListView.3=Min. score +ListView.4=Max. score ListView.7=Unknown NodeClipboardView.0=Clipboard NodeClipboardView.1=Edit comment @@ -705,15 +709,15 @@ NodeClipboardView.6=Transformation NodeClipboardView.7=Comment NodeClipboardView.8=Move up NodeClipboardView.9=Move down -NodeClipboardView.10=Sort by information loss +NodeClipboardView.10=Sort by score NodeClipboardView.11=Copy NodeFilterView.10=Show NodeFilterView.11=Hide NodeFilterView.12=Unknown: NodeFilterView.13=Show NodeFilterView.14=Hide -NodeFilterView.15=Min. info. loss: -NodeFilterView.16=Max. info. loss: +NodeFilterView.15=Min. score: +NodeFilterView.16=Max. score: NodeFilterView.3=Filter NodeFilterView.4=Quasi-identifier: NodeFilterView.5=Visible levels @@ -723,7 +727,7 @@ NodeFilterView.8=Hide NodeFilterView.9=Not anonymous: NodeFilterView.20=Generalization: NodeFilterView.21=Classification: -NodeFilterView.22=Information loss: +NodeFilterView.22=Score: NodePropertiesView.0=Properties NodePropertiesView.10=Predecessors NodePropertiesView.12=Transformation @@ -731,17 +735,17 @@ NodePropertiesView.14=Checked NodePropertiesView.16=Property NodePropertiesView.17=Value NodePropertiesView.18=Anonymous -NodePropertiesView.19=Min. info. loss +NodePropertiesView.19=Min. score NodePropertiesView.2=Anonymous NodePropertiesView.22=Unknown -NodePropertiesView.23=Max. info. loss +NodePropertiesView.23=Max. score NodePropertiesView.26=Unknown NodePropertiesView.27=Successors NodePropertiesView.28=Predecessors NodePropertiesView.29=Transformation NodePropertiesView.30=Checked -NodePropertiesView.4=Min. info. loss -NodePropertiesView.6=Max. info. loss +NodePropertiesView.4=Min. score +NodePropertiesView.6=Max. score NodePropertiesView.8=Successors CriterionDefinitionView.0=Height CriterionDefinitionView.1=Precision @@ -809,13 +813,16 @@ CriterionDefinitionView.120=Attacker model: CriterionDefinitionView.121=Prosecutor CriterionDefinitionView.122=Journalist CriterionDefinitionView.123=Allow attack: -ViewFinancialModel.1=Publisher's benefit: -ViewFinancialModel.2=Publisher's loss: -ViewFinancialModel.3=Adverary's gain: -ViewFinancialModel.4=Adverary's cost: -ViewFinancialModel.0=... -ViewFinancialModel.5=Update amount -ViewFinancialModel.6=Please enter a number >= 0 +CriterionDefinitionView.124=Ignore +CriterionDefinitionView.125=Consider mean squared error +CriterionDefinitionView.126=Consider information loss +ViewCostBenefitModel.1=Publisher's benefit: +ViewCostBenefitModel.2=Publisher's loss: +ViewCostBenefitModel.3=Adverary's gain: +ViewCostBenefitModel.4=Adverary's cost: +ViewCostBenefitModel.0=... +ViewCostBenefitModel.5=Update amount +ViewCostBenefitModel.6=Please enter a number >= 0 CriterionDefinitionView.102=EMD with ordered distance CriterionDefinitionView.110=Grassberger-entropy-l-diversity CriterionSelectionDialog.0=Please select a privacy model from which the settings will be transfered @@ -828,7 +835,7 @@ CriterionSelectionDialog.6=Please select a privacy model which will be applied t CriterionSelectionDialog.7=Add a new privacy model CriterionSelectionDialog.8=Please select a privacy model to edit CriterionSelectionDialog.9=Edit a privacy model -CriterionSelectionDialog.10=Financial setup +CriterionSelectionDialog.10=Costs and benefits SubsetDefinitionView.0=Sample extraction SubsetDefinitionView.1=Select none SubsetDefinitionView.2=Select all @@ -1134,7 +1141,7 @@ ViewAttributeDefinition.8=Default ViewClipboard.0=Remove ViewClipboard.1=Move up ViewClipboard.2=Move down -ViewClipboard.3=Sort by information loss +ViewClipboard.3=Sort by score ViewCodingModel.0=Suppression ViewCodingModel.1=Generalization ViewCodingModel.2=Reset diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java index eb1cb8b416..8b841d363e 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java @@ -1,13 +1,13 @@ /* * ARX: Powerful Data Anonymization - * Copyright 2012 - 2016 Fabian Prasser, Florian Kohlmayer and contributors - * + * 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. @@ -65,9 +65,6 @@ import org.deidentifier.arx.gui.view.impl.risk.LayoutRisks; import org.deidentifier.arx.gui.view.impl.utility.LayoutUtility; import org.deidentifier.arx.gui.worker.Worker; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.ChecklistWizard; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.ChecklistDialog; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; @@ -86,1079 +83,1069 @@ import org.eclipse.swt.widgets.Monitor; import org.eclipse.swt.widgets.Shell; - /** * This class implements the global application window. * * @author Fabian Prasser */ public class MainWindow implements IView { - - /** Controller */ - private final Controller controller; - - /** View */ - private final Display display; - /** View */ - private final Shell shell; - /** View */ - private final AbstractMenu menu; - /** View */ - private final ComponentTitledFolder root; - /** View */ - private final LayoutExplore layoutExplore; - - /** - * Creates a new instance. - * - * @param display - * @param monitor - */ - public MainWindow(Display display, Monitor monitor) { - - // Init - this.display = display; - this.shell = new Shell(display); - - // Build controller - controller = new Controller(this); - controller.addListener(ModelPart.MODEL, this); - - // Style - shell.setImages(Resources.getIconSet(display)); - shell.setText(Resources.getMessage("MainWindow.0")); //$NON-NLS-1$ - shell.setMinimumSize(800, 600); - - // Center - SWTUtil.center(shell, monitor); - - // Maximize - shell.setMaximized(true); - - // Close listener - shell.addListener(SWT.Close, new Listener() { - @Override - public void handleEvent(final Event event) { - controller.actionMenuFileExit(); - event.doit = false; - } - }); - - // Build menu - List items = getMenu(); - menu = new MainMenu(shell, controller, items); - new MainToolBar(shell, controller, items); - - // Create shell - shell.setLayout(SWTUtil.createGridLayout(1)); - - // Create the tab folder - Map helpids = new HashMap(); - root = new ComponentTitledFolder(shell, controller, null, "id-70", helpids); //$NON-NLS-1$ - root.setLayoutData(SWTUtil.createFillGridData()); - - // Create the subviews - Composite item1 = root.createItem(Resources.getMessage("MainWindow.2"), controller.getResources().getManagedImage("perspective_define.png")); //$NON-NLS-1$ //$NON-NLS-2$ - helpids.put(item1, "id-3"); //$NON-NLS-1$ - new LayoutDefinition(item1, controller); - Composite item2 = root.createItem(Resources.getMessage("MainWindow.3"), controller.getResources().getManagedImage("perspective_explore.png")); //$NON-NLS-1$ //$NON-NLS-2$ - helpids.put(item2, "id-4"); //$NON-NLS-1$ - this.layoutExplore = new LayoutExplore(item2, controller); - Composite item3 = root.createItem(Resources.getMessage("MainWindow.1"), controller.getResources().getManagedImage("perspective_analyze.png")); //$NON-NLS-1$ //$NON-NLS-2$ - helpids.put(item3, "help.utility.overview"); //$NON-NLS-1$ - new LayoutUtility(item3, controller); - Composite item4 = root.createItem(Resources.getMessage("MainWindow.4"), controller.getResources().getManagedImage("perspective_risk.png")); //$NON-NLS-1$ //$NON-NLS-2$ - helpids.put(item4, "help.risk.overview"); //$NON-NLS-1$ - new LayoutRisks(item4, controller); - - // Hack to update visualizations - root.addSelectionListener(new SelectionAdapter(){ - @Override - public void widgetSelected(SelectionEvent arg0) { - switch (root.getSelectionIndex()) { - case 0: - controller.getModel().setPerspective(Perspective.CONFIGURATION); - break; - case 1: - controller.getModel().setPerspective(Perspective.EXPLORATION); - break; - case 2: - controller.getModel().setPerspective(Perspective.ANALYSIS); - break; - case 3: - controller.getModel().setPerspective(Perspective.RISK); - break; - } - controller.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, null)); - controller.update(new ModelEvent(this, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - }); - - // Now reset and disable - controller.reset(); - } - - @Override - public void dispose() { - controller.removeListener(this); - } - - /** - * Returns the controller. - * - * @return - */ - public Controller getController() { - return this.controller; - } - - /** - * Returns the shell. - * - * @return - */ - public Shell getShell() { - return shell; - } - - /** - * Is this shell disposed. - * - * @return - */ - public boolean isDisposed() { - return this.shell.isDisposed(); - } - - /** - * Executes the given runnable on show. - * - * @param runnable - */ - public void onShow(final Runnable runnable){ - - // Using a paint listener is a hack to reliably determine when the shell is visible - shell.addPaintListener(new PaintListener(){ - @Override - public void paintControl(PaintEvent arg0) { - shell.removePaintListener(this); - display.timerExec(200, runnable); - } - }); - } - - /** - * Resets the GUI. - */ - public void reset() { - root.setSelection(0); - root.setEnabled(false); - } - - /** - * Main SWT event loop. - */ - public void show() { - shell.open(); - } - - /** - * Shows an about dialog. - */ - public void showAboutDialog() { - final DialogAbout dialog = new DialogAbout(shell, controller); - dialog.create(); - dialog.open(); - } - - /** - * Shows the checklist wizard. - */ - public void showChecklistWizard() { - Checklist checklist = new Checklist(controller.getResources().getStream("checklist_khaled_el_emam.txt")); - final ChecklistDialog dialog = new ChecklistDialog(checklist, shell, controller, new ChecklistWizard(checklist, controller)); + + /** Controller */ + private final Controller controller; + + /** View */ + private final Display display; + /** View */ + private final Shell shell; + /** View */ + private final AbstractMenu menu; + /** View */ + private final ComponentTitledFolder root; + /** View */ + private final LayoutExplore layoutExplore; + + /** + * Creates a new instance. + * + * @param display + * @param monitor + */ + public MainWindow(Display display, Monitor monitor) { + + // Init + this.display = display; + this.shell = new Shell(display); + + // Build controller + controller = new Controller(this); + controller.addListener(ModelPart.MODEL, this); + + // Style + shell.setImages(Resources.getIconSet(display)); + shell.setText(Resources.getMessage("MainWindow.0")); //$NON-NLS-1$ + shell.setMinimumSize(800, 600); + + // Center + SWTUtil.center(shell, monitor); + + // Maximize + shell.setMaximized(true); + + // Close listener + shell.addListener(SWT.Close, new Listener() { + @Override + public void handleEvent(final Event event) { + controller.actionMenuFileExit(); + event.doit = false; + } + }); + + // Build menu + List items = getMenu(); + menu = new MainMenu(shell, controller, items); + new MainToolBar(shell, controller, items); + + // Create shell + shell.setLayout(SWTUtil.createGridLayout(1)); + + // Create the tab folder + Map helpids = new HashMap(); + root = new ComponentTitledFolder(shell, controller, null, "id-70", helpids); //$NON-NLS-1$ + root.setLayoutData(SWTUtil.createFillGridData()); + + // Create the subviews + Composite item1 = root.createItem(Resources.getMessage("MainWindow.2"), controller.getResources().getManagedImage("perspective_define.png")); //$NON-NLS-1$ //$NON-NLS-2$ + helpids.put(item1, "id-3"); //$NON-NLS-1$ + new LayoutDefinition(item1, controller); + Composite item2 = root.createItem(Resources.getMessage("MainWindow.3"), controller.getResources().getManagedImage("perspective_explore.png")); //$NON-NLS-1$ //$NON-NLS-2$ + helpids.put(item2, "id-4"); //$NON-NLS-1$ + this.layoutExplore = new LayoutExplore(item2, controller); + Composite item3 = root.createItem(Resources.getMessage("MainWindow.1"), controller.getResources().getManagedImage("perspective_analyze.png")); //$NON-NLS-1$ //$NON-NLS-2$ + helpids.put(item3, "help.utility.overview"); //$NON-NLS-1$ + new LayoutUtility(item3, controller); + Composite item4 = root.createItem(Resources.getMessage("MainWindow.4"), controller.getResources().getManagedImage("perspective_risk.png")); //$NON-NLS-1$ //$NON-NLS-2$ + helpids.put(item4, "help.risk.overview"); //$NON-NLS-1$ + new LayoutRisks(item4, controller); + + // Hack to update visualizations + root.addSelectionListener(new SelectionAdapter(){ + @Override + public void widgetSelected(SelectionEvent arg0) { + switch (root.getSelectionIndex()) { + case 0: + controller.getModel().setPerspective(Perspective.CONFIGURATION); + break; + case 1: + controller.getModel().setPerspective(Perspective.EXPLORATION); + break; + case 2: + controller.getModel().setPerspective(Perspective.ANALYSIS); + break; + case 3: + controller.getModel().setPerspective(Perspective.RISK); + break; + } + controller.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, null)); + controller.update(new ModelEvent(this, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + }); + + // Now reset and disable + controller.reset(); + } + + @Override + public void dispose() { + controller.removeListener(this); + } + + /** + * Returns the controller. + * + * @return + */ + public Controller getController() { + return this.controller; + } + + /** + * Returns the shell. + * + * @return + */ + public Shell getShell() { + return shell; + } + + /** + * Is this shell disposed. + * + * @return + */ + public boolean isDisposed() { + return this.shell.isDisposed(); + } + + /** + * Executes the given runnable on show. + * + * @param runnable + */ + public void onShow(final Runnable runnable){ + + // Using a paint listener is a hack to reliably determine when the shell is visible + shell.addPaintListener(new PaintListener(){ + @Override + public void paintControl(PaintEvent arg0) { + shell.removePaintListener(this); + display.timerExec(200, runnable); + } + }); + } + + /** + * Resets the GUI. + */ + public void reset() { + root.setSelection(0); + root.setEnabled(false); + } + + /** + * Main SWT event loop. + */ + public void show() { + shell.open(); + } + + /** + * Shows an about dialog. + */ + public void showAboutDialog() { + final DialogAbout dialog = new DialogAbout(shell, controller); + dialog.create(); dialog.open(); - } - - /** - * Shows a dialog for selecting privacy criteria. - * - * @param criteria - * @return - */ - public ModelCriterion showAddCriterionDialog(Model model, - List criteria) { - - // Dialog - final DialogCriterionUpdate dialog = new DialogCriterionUpdate(controller, shell, criteria, model, true); - dialog.create(); - if (dialog.open() != Window.OK) { - return null; - } else { - return dialog.getCriterion(); - } - } - - /** - * Shows the audit trail - */ - public void showAuditTrail(List auditTrail) { - DialogAuditTrail dialog = new DialogAuditTrail(shell, auditTrail); - dialog.create(); - dialog.open(); - } - /** - * Shows an input dialog for selecting a charset. - * - * @param shell - * @return - */ - public Charset showCharsetInputDialog(final Shell shell) { - - // Validator - final IInputValidator validator = new IInputValidator() { - @Override - public String isValid(final String arg0) { - return null; - } - }; - - // Extract list of formats - List charsets = new ArrayList(); - for (String charset : Charsets.getNamesOfAvailableCharsets()) { - charsets.add(charset); - } - - // Open dialog - final DialogComboSelection dlg = new DialogComboSelection(shell, Resources.getMessage("MainWindow.19"), //$NON-NLS-1$ - Resources.getMessage("MainWindow.20"), //$NON-NLS-1$ - charsets.toArray(new String[] {}), - Charsets.getNameOfDefaultCharset(), - validator); - - // Return value - if (dlg.open() == Window.OK) { - return Charsets.getCharsetForName(dlg.getValue()); - } else { - return null; - } - } - - /** - * Shows a dialog for configuring privacy criteria. - * - * @param criteria - * @param criterion - * @return - */ - public void showConfigureCriterionDialog(Model model, List criteria, ModelCriterion criterion) { - DialogCriterionUpdate dialog = new DialogCriterionUpdate(controller, shell, criteria, model, false, criterion); - dialog.create(); - dialog.open(); - } - - /** - * Shows a debug dialog. - */ - public void showDebugDialog() { - final DialogDebug dialog = new DialogDebug(shell, controller); - dialog.create(); - dialog.open(); - } - - /** - * Shows an error dialog. - * - * @param shell - * @param message - * @param text - */ - public void showErrorDialog(final Shell shell, final String message, final String text) { - DialogError dialog = new DialogError(shell, controller, message, text); - dialog.create(); - dialog.open(); - } - - /** - * Shows an error dialog. - * - * @param shell - * @param message - * @param throwable - */ - public void showErrorDialog(final Shell shell, final String message, final Throwable throwable) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - if (throwable != null) throwable.printStackTrace(pw); - final String trace = sw.toString(); - showErrorDialog(shell, message, trace); - } - - /** - * Shows an error dialog. - * - * @param message - * @param text - */ - public void showErrorDialog(final String message, final String text) { - showErrorDialog(this.shell, message, text); - } - - /** - * Shows an error dialog. - * - * @param message - * @param throwable - */ - public void showErrorDialog(final String message, final Throwable throwable) { - showErrorDialog(this.shell, message, throwable); - } - - /** - * Shows a find & replace dialog - * @param handle - * @param column - * @return A pair containing the string to be found and the string with which it is to be replaced, - * null if cancel was pressed. - */ - public Pair showFindReplaceDialog(Model model, DataHandle handle, int column) { - DialogFindReplace dialog = new DialogFindReplace(shell, model, handle, column); - dialog.create(); - dialog.open(); - return dialog.getValue(); - } - - /** - * Shows an input dialog for selecting formats string for data types. - * - * @param shell - * @param header - * @param text - * @param preselected Preselected format string, can be null - * @param locale The current locale - * @param description - * @param values - * @return - */ - public String showFormatInputDialog(final Shell shell, final String header, final String text, final String preselected, final Locale locale, final DataTypeDescription description, final Collection values) { - - // Check - if (!description.hasFormat()) { - throw new RuntimeException(Resources.getMessage("MainWindow.6")); //$NON-NLS-1$ - } - - // Init - final String DEFAULT = Resources.getMessage("MainWindow.7"); //$NON-NLS-1$ - - // Validator - final IInputValidator validator = new IInputValidator() { - @Override - public String isValid(final String arg0) { - DataType type; - try { - if (arg0.equals(DEFAULT)) { - type = description.newInstance(); - } else { - type = description.newInstance(arg0, locale); - } - } catch (final Exception e) { - return Resources.getMessage("MainWindow.11"); //$NON-NLS-1$ - } - for (final String value : values) { - if (!type.isValid(value)) { - return Resources.getMessage("MainWindow.13"); //$NON-NLS-1$ - } - } - return null; - } - }; - - // Try to find a valid formatter - String initial = ""; //$NON-NLS-1$ - if (preselected != null && validator.isValid(preselected) == null) { - initial = preselected; - } else if (validator.isValid(DEFAULT) == null) { - initial = DEFAULT; - } else { - for (final String format : description.getExampleFormats()) { - if (validator.isValid(format) == null) { - initial = format; - break; - } - } - } - - // Extract list of formats - List formats = new ArrayList(); - formats.add(DEFAULT); - formats.addAll(description.getExampleFormats()); - - // Open dialog - final DialogComboSelection dlg = new DialogComboSelection(shell, header, text, formats.toArray(new String[] {}), initial, validator); - - // Return value - if (dlg.open() == Window.OK) { - return dlg.getValue(); - } else { - return null; - } - } - - /** - * Shows a help dialog. - * - * @param id - */ - public void showHelpDialog(String id) { - try { - DialogHelp dialog = new DialogHelp(shell, controller, id); - dialog.open(); - } catch (Exception e) { - this.showErrorDialog(Resources.getMessage("MainWindow.12"), e); //$NON-NLS-1$ - } - } - - /** - * Shows an info dialog. - * - * @param shell - * @param header - * @param text - */ - public void showInfoDialog(final Shell shell, final String header, final String text) { - MessageDialog.openInformation(getShell(), header, text); - } - - /** - * Shows an input dialog. - * - * @param shell - * @param header - * @param text - * @param initial - * @return - */ - public String showInputDialog(final Shell shell, final String header, final String text, final String initial) { - return showInputDialog(shell, header, text, initial, null); - } - - /** - * Shows an input dialog. - * - * @param shell - * @param header - * @param text - * @param initial - * @param validator - * @return - */ - public String showInputDialog(final Shell shell, final String header, final String text, final String initial, final IInputValidator validator) { - final InputDialog dlg = new InputDialog(shell, header, text, initial, validator); - if (dlg.open() == Window.OK) { - return dlg.getValue(); - } else { - return null; - } - } - /** - * Shows a dialog that allows selecting multiple elements - * @param shell - * @param title - * @param text - * @param elements - * @param selected - * @return - */ - public List showMultiSelectionDialog(Shell shell, - String title, - String text, - List elements, - List selected) { - - // Open dialog - DialogMultiSelection dlg = new DialogMultiSelection(shell, title, text, elements, selected); - if (dlg.open() == Window.OK) { - return dlg.getSelectedItems(); - } else { - return null; - } - } - - /** - * Shows a file open dialog. - * - * @param shell - * @param filter - * @return - */ - public String showOpenFileDialog(final Shell shell, String filter) { - final FileDialog dialog = new FileDialog(shell, SWT.OPEN); - dialog.setFilterExtensions(new String[] { filter }); - dialog.setFilterIndex(0); - String file = dialog.open(); - if (file == null) { - return null; - } else if (!new File(file).exists()) { - showInfoDialog(shell, Resources.getMessage("MainWindow.5"), Resources.getMessage("MainWindow.14")); //$NON-NLS-1$ //$NON-NLS-2$ - return null; - } else { - return file; - } - } - - /** - * Shows an input dialog for ordering data items. - * - * @param shell - * @param header - * @param text - * @param type - * @param locale - * @param values - * @return - */ - public String[] showOrderValuesDialog(final Shell shell, final String header, final String text, final DataType type, final Locale locale, final String[] values) { - - // Open dialog - DialogOrderSelection dlg = new DialogOrderSelection(shell, values, type, locale, controller); - if (dlg.open() == Window.OK) { - return dlg.getResult(); - } else { - return null; - } - } - - /** - * Shows a progress dialog. - * - * @param text - * @param worker - */ - public void showProgressDialog(final String text, final Worker worker) { - try { - new ProgressMonitorDialog(shell).run(true, true, worker); - } catch (final Exception e) { - worker.setError(e); - } - } - - /** - * Shows a query dialog for selecting a research subset. - * - * @param query - * @param data - * @return - */ - public DialogQueryResult showQueryDialog(String query, Data data) { - - // Dialog - final DialogQuery dialog = new DialogQuery(data, shell, query); - dialog.create(); - if (dialog.open() != Window.OK) { - return null; - } else { - return dialog.getResult(); - } - } - - /** - * Shows a question dialog. - * - * @param shell - * @param header - * @param text - * @return - */ - public boolean showQuestionDialog(final Shell shell, final String header, final String text) { - return MessageDialog.openQuestion(getShell(), header, text); - } - - /** - * Shows a file save dialog. - * - * @param shell - * @param filter - * @return - */ - public String showSaveFileDialog(final Shell shell, String filter) { - final FileDialog dialog = new FileDialog(shell, SWT.SAVE); - dialog.setFilterExtensions(new String[] { filter }); - dialog.setFilterIndex(0); - return dialog.open(); - } - - /** - * Shows a dialog for selecting privacy criteria. - * - * @param criteria - * @return - */ - public ModelExplicitCriterion showSelectCriterionDialog(List criteria) { - - // Dialog - final DialogCriterionSelection dialog = new DialogCriterionSelection(controller, shell, criteria); - dialog.create(); - if (dialog.open() != Window.OK) { - return null; - } else { - return dialog.getCriterion(); - } - } - - /** - * Shows a top/bottom coding dialog - * @param type - * @return A pair containing the bottom value + inclusive and the top value + inclusive. - * Either bottom or top may be null if they have not been defined. The overall pair may be - * null if cancel was pressed. - */ - public Pair, Pair> showTopBottomCodingDialog(DataType type) { - DialogTopBottomCoding dialog = new DialogTopBottomCoding(shell, type); - dialog.create(); - dialog.open(); - return dialog.getValue(); - } - - @Override - public void update(final ModelEvent event) { - - // Careful! In the main window, this is also called after editing the project properties - if (event.part == ModelPart.MODEL) { - final Model model = (Model) event.data; - shell.setText(Resources.getMessage("MainWindow.0") + " - " + model.getName()); //$NON-NLS-1$ //$NON-NLS-2$ - root.setEnabled(true); - menu.update(event); - } - } - - - /** - * Creates the edit menu - * @return - */ - private MainMenuItem getEditMenu() { - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.21"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_anonymize.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditAnonymize(false); } - public boolean isEnabled(Model model) { - return model != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.40"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_anonymize_heuristic.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditAnonymize(true); } - public boolean isEnabled(Model model) { - return model != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.39"), //$NON-NLS-1$ - controller.getResources().getManagedImage("cross.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditReset(); } - public boolean isEnabled(Model model) { - return model != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.41"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuEditInitializeHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.42"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuEditCreateTopBottomCodingHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.23"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditCreateHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.30"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_find_replace.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuEditFindReplace(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.31"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_audit_trail.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionShowAuditTrail(); } - public boolean isEnabled(Model model) { - return model != null; - } - }); - - items.add(new MainMenuSeparator()); - - List subset = new ArrayList(); - - subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.1"), //$NON-NLS-1$ - controller.getResources().getManagedImage("page_white.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionSubsetNone(); } - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.2"), //$NON-NLS-1$ - controller.getResources().getManagedImage("page_white_text.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionSubsetAll(); } - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.3"), //$NON-NLS-1$ - controller.getResources().getManagedImage("disk.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionSubsetFile(); } - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.4"), //$NON-NLS-1$ - controller.getResources().getManagedImage("find.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionSubsetQuery(); } - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - items.add(new MainMenuGroup(Resources.getMessage("MainMenu.35"), subset) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.37"), //$NON-NLS-1$ - controller.getResources().getManagedImage("apply.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionApplySelectedTransformation(); } - public boolean isEnabled(Model model) { - return model != null && model.getResult() != null && model.getSelectedNode() != null; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.25"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_settings.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditSettings(); } - public boolean isEnabled(Model model) { - return model != null; - } - }); - - return new MainMenuGroup(Resources.getMessage("MainMenu.1"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } - - - /** - * Creates the help menu - * @return - */ - private MainMenuItem getHelpMenu() { - - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.27"), //$NON-NLS-1$ - controller.getResources().getManagedImage("help.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuHelpHelp(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.28"), //$NON-NLS-1$ - controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuHelpChecklistWizard(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.29"), //$NON-NLS-1$ - controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuHelpAbout(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.32"), //$NON-NLS-1$ - controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuHelpDebug(); } - public boolean isEnabled(Model model) { - return model != null && model.isDebugEnabled(); - } - }); - - return new MainMenuGroup(Resources.getMessage("MainMenu.2"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } - - /** - * Creates the global menu - * @return - */ - private List getMenu() { - - List menu = new ArrayList(); - - menu.add(getMenuFile()); - menu.add(getEditMenu()); - menu.add(getViewMenu()); - menu.add(getHelpMenu()); - - return menu; - } - - /** - * Creates the file menu - * @return - */ - private MainMenuItem getMenuFile() { - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.3"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_new.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileNew(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.5"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_load.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileOpen(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.4"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_save.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileSave(); } - public boolean isEnabled(Model model) { return model != null; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.9"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_save_as.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileSaveAs(); } - public boolean isEnabled(Model model) { return model != null; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.11"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_import_data.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileImportData(); } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() == Perspective.CONFIGURATION; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.13"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_export_data.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileExportData(); } - public boolean isEnabled(Model model) { - return model != null && model.getOutput() != null && model.getPerspective() == Perspective.ANALYSIS; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.15"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_import_hierarchy.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileImportHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.17"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_export_hierarchy.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileExportHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.19"), //$NON-NLS-1$ - controller.getResources().getManagedImage("exit.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuFileExit(); } - public boolean isEnabled(Model model) { - return true; - } - }); - - return new MainMenuGroup(Resources.getMessage("MainMenu.0"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } - - /** - * Creates the help menu - * @return - */ - private MainMenuItem getViewMenu() { - - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainWindow.2"), //$NON-NLS-1$ - controller.getResources().getManagedImage("perspective_define.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { - root.setSelection(0); - controller.getModel().setPerspective(Perspective.CONFIGURATION); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.CONFIGURATION; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainWindow.3"), //$NON-NLS-1$ - controller.getResources().getManagedImage("perspective_explore.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { - root.setSelection(1); - controller.getModel().setPerspective(Perspective.EXPLORATION); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.EXPLORATION; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainWindow.1"), //$NON-NLS-1$ - controller.getResources().getManagedImage("perspective_analyze.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { - root.setSelection(2); - controller.getModel().setPerspective(Perspective.ANALYSIS); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.ANALYSIS; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainWindow.4"), //$NON-NLS-1$ - controller.getResources().getManagedImage("perspective_risk.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { - root.setSelection(3); - controller.getModel().setPerspective(Perspective.RISK); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.RISK; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.0"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - controller.getResources().getManagedImage("explore_lattice.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { - layoutExplore.showLattice(); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { - return model != null && - model.getPerspective() == Perspective.EXPLORATION && - model.getResult() != null && - !layoutExplore.isShowLattice(); - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.2"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - controller.getResources().getManagedImage("explore_list.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { - layoutExplore.showList(); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { - return model != null && - model.getPerspective() == Perspective.EXPLORATION && - model.getResult() != null && - !layoutExplore.isShowList(); - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.3"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - controller.getResources().getManagedImage("explore_tiles.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { - layoutExplore.showTiles(); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { - return model != null && - model.getPerspective() == Perspective.EXPLORATION && - model.getResult() != null && - !layoutExplore.isShowTiles(); - } - }); - - - return new MainMenuGroup(Resources.getMessage("MainMenu.33"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } + } + + /** + * Shows a dialog for selecting privacy criteria. + * + * @param criteria + * @return + */ + public ModelCriterion showAddCriterionDialog(Model model, + List criteria) { + + // Dialog + final DialogCriterionUpdate dialog = new DialogCriterionUpdate(controller, shell, criteria, model, true); + dialog.create(); + if (dialog.open() != Window.OK) { + return null; + } else { + return dialog.getCriterion(); + } + } + + /** + * Shows the audit trail + */ + public void showAuditTrail(List auditTrail) { + DialogAuditTrail dialog = new DialogAuditTrail(shell, auditTrail); + dialog.create(); + dialog.open(); + } + /** + * Shows an input dialog for selecting a charset. + * + * @param shell + * @return + */ + public Charset showCharsetInputDialog(final Shell shell) { + + // Validator + final IInputValidator validator = new IInputValidator() { + @Override + public String isValid(final String arg0) { + return null; + } + }; + + // Extract list of formats + List charsets = new ArrayList(); + for (String charset : Charsets.getNamesOfAvailableCharsets()) { + charsets.add(charset); + } + + // Open dialog + final DialogComboSelection dlg = new DialogComboSelection(shell, Resources.getMessage("MainWindow.19"), //$NON-NLS-1$ + Resources.getMessage("MainWindow.20"), //$NON-NLS-1$ + charsets.toArray(new String[] {}), + Charsets.getNameOfDefaultCharset(), + validator); + + // Return value + if (dlg.open() == Window.OK) { + return Charsets.getCharsetForName(dlg.getValue()); + } else { + return null; + } + } + + /** + * Shows a dialog for configuring privacy criteria. + * + * @param criteria + * @param criterion + * @return + */ + public void showConfigureCriterionDialog(Model model, List criteria, ModelCriterion criterion) { + DialogCriterionUpdate dialog = new DialogCriterionUpdate(controller, shell, criteria, model, false, criterion); + dialog.create(); + dialog.open(); + } + + /** + * Shows a debug dialog. + */ + public void showDebugDialog() { + final DialogDebug dialog = new DialogDebug(shell, controller); + dialog.create(); + dialog.open(); + } + + /** + * Shows an error dialog. + * + * @param shell + * @param message + * @param text + */ + public void showErrorDialog(final Shell shell, final String message, final String text) { + DialogError dialog = new DialogError(shell, controller, message, text); + dialog.create(); + dialog.open(); + } + + /** + * Shows an error dialog. + * + * @param shell + * @param message + * @param throwable + */ + public void showErrorDialog(final Shell shell, final String message, final Throwable throwable) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + if (throwable != null) throwable.printStackTrace(pw); + final String trace = sw.toString(); + showErrorDialog(shell, message, trace); + } + + /** + * Shows an error dialog. + * + * @param message + * @param text + */ + public void showErrorDialog(final String message, final String text) { + showErrorDialog(this.shell, message, text); + } + + /** + * Shows an error dialog. + * + * @param message + * @param throwable + */ + public void showErrorDialog(final String message, final Throwable throwable) { + showErrorDialog(this.shell, message, throwable); + } + + /** + * Shows a find & replace dialog + * @param handle + * @param column + * @return A pair containing the string to be found and the string with which it is to be replaced, + * null if cancel was pressed. + */ + public Pair showFindReplaceDialog(Model model, DataHandle handle, int column) { + DialogFindReplace dialog = new DialogFindReplace(shell, model, handle, column); + dialog.create(); + dialog.open(); + return dialog.getValue(); + } + + /** + * Shows an input dialog for selecting formats string for data types. + * + * @param shell + * @param header + * @param text + * @param preselected Preselected format string, can be null + * @param locale The current locale + * @param description + * @param values + * @return + */ + public String showFormatInputDialog(final Shell shell, final String header, final String text, final String preselected, final Locale locale, final DataTypeDescription description, final Collection values) { + + // Check + if (!description.hasFormat()) { + throw new RuntimeException(Resources.getMessage("MainWindow.6")); //$NON-NLS-1$ + } + + // Init + final String DEFAULT = Resources.getMessage("MainWindow.7"); //$NON-NLS-1$ + + // Validator + final IInputValidator validator = new IInputValidator() { + @Override + public String isValid(final String arg0) { + DataType type; + try { + if (arg0.equals(DEFAULT)) { + type = description.newInstance(); + } else { + type = description.newInstance(arg0, locale); + } + } catch (final Exception e) { + return Resources.getMessage("MainWindow.11"); //$NON-NLS-1$ + } + for (final String value : values) { + if (!type.isValid(value)) { + return Resources.getMessage("MainWindow.13"); //$NON-NLS-1$ + } + } + return null; + } + }; + + // Try to find a valid formatter + String initial = ""; //$NON-NLS-1$ + if (preselected != null && validator.isValid(preselected) == null) { + initial = preselected; + } else if (validator.isValid(DEFAULT) == null) { + initial = DEFAULT; + } else { + for (final String format : description.getExampleFormats()) { + if (validator.isValid(format) == null) { + initial = format; + break; + } + } + } + + // Extract list of formats + List formats = new ArrayList(); + formats.add(DEFAULT); + formats.addAll(description.getExampleFormats()); + + // Open dialog + final DialogComboSelection dlg = new DialogComboSelection(shell, header, text, formats.toArray(new String[] {}), initial, validator); + + // Return value + if (dlg.open() == Window.OK) { + return dlg.getValue(); + } else { + return null; + } + } + + /** + * Shows a help dialog. + * + * @param id + */ + public void showHelpDialog(String id) { + try { + DialogHelp dialog = new DialogHelp(shell, controller, id); + dialog.open(); + } catch (Exception e) { + this.showErrorDialog(Resources.getMessage("MainWindow.12"), e); //$NON-NLS-1$ + } + } + + /** + * Shows an info dialog. + * + * @param shell + * @param header + * @param text + */ + public void showInfoDialog(final Shell shell, final String header, final String text) { + MessageDialog.openInformation(getShell(), header, text); + } + + /** + * Shows an input dialog. + * + * @param shell + * @param header + * @param text + * @param initial + * @return + */ + public String showInputDialog(final Shell shell, final String header, final String text, final String initial) { + return showInputDialog(shell, header, text, initial, null); + } + + /** + * Shows an input dialog. + * + * @param shell + * @param header + * @param text + * @param initial + * @param validator + * @return + */ + public String showInputDialog(final Shell shell, final String header, final String text, final String initial, final IInputValidator validator) { + final InputDialog dlg = new InputDialog(shell, header, text, initial, validator); + if (dlg.open() == Window.OK) { + return dlg.getValue(); + } else { + return null; + } + } + /** + * Shows a dialog that allows selecting multiple elements + * @param shell + * @param title + * @param text + * @param elements + * @param selected + * @return + */ + public List showMultiSelectionDialog(Shell shell, + String title, + String text, + List elements, + List selected) { + + // Open dialog + DialogMultiSelection dlg = new DialogMultiSelection(shell, title, text, elements, selected); + if (dlg.open() == Window.OK) { + return dlg.getSelectedItems(); + } else { + return null; + } + } + + /** + * Shows a file open dialog. + * + * @param shell + * @param filter + * @return + */ + public String showOpenFileDialog(final Shell shell, String filter) { + final FileDialog dialog = new FileDialog(shell, SWT.OPEN); + dialog.setFilterExtensions(new String[] { filter }); + dialog.setFilterIndex(0); + String file = dialog.open(); + if (file == null) { + return null; + } else if (!new File(file).exists()) { + showInfoDialog(shell, Resources.getMessage("MainWindow.5"), Resources.getMessage("MainWindow.14")); //$NON-NLS-1$ //$NON-NLS-2$ + return null; + } else { + return file; + } + } + + /** + * Shows an input dialog for ordering data items. + * + * @param shell + * @param header + * @param text + * @param type + * @param locale + * @param values + * @return + */ + public String[] showOrderValuesDialog(final Shell shell, final String header, final String text, final DataType type, final Locale locale, final String[] values) { + + // Open dialog + DialogOrderSelection dlg = new DialogOrderSelection(shell, values, type, locale, controller); + if (dlg.open() == Window.OK) { + return dlg.getResult(); + } else { + return null; + } + } + + /** + * Shows a progress dialog. + * + * @param text + * @param worker + */ + public void showProgressDialog(final String text, final Worker worker) { + try { + new ProgressMonitorDialog(shell).run(true, true, worker); + } catch (final Exception e) { + worker.setError(e); + } + } + + /** + * Shows a query dialog for selecting a research subset. + * + * @param query + * @param data + * @return + */ + public DialogQueryResult showQueryDialog(String query, Data data) { + + // Dialog + final DialogQuery dialog = new DialogQuery(data, shell, query); + dialog.create(); + if (dialog.open() != Window.OK) { + return null; + } else { + return dialog.getResult(); + } + } + + /** + * Shows a question dialog. + * + * @param shell + * @param header + * @param text + * @return + */ + public boolean showQuestionDialog(final Shell shell, final String header, final String text) { + return MessageDialog.openQuestion(getShell(), header, text); + } + + /** + * Shows a file save dialog. + * + * @param shell + * @param filter + * @return + */ + public String showSaveFileDialog(final Shell shell, String filter) { + final FileDialog dialog = new FileDialog(shell, SWT.SAVE); + dialog.setFilterExtensions(new String[] { filter }); + dialog.setFilterIndex(0); + return dialog.open(); + } + + /** + * Shows a dialog for selecting privacy criteria. + * + * @param criteria + * @return + */ + public ModelExplicitCriterion showSelectCriterionDialog(List criteria) { + + // Dialog + final DialogCriterionSelection dialog = new DialogCriterionSelection(controller, shell, criteria); + dialog.create(); + if (dialog.open() != Window.OK) { + return null; + } else { + return dialog.getCriterion(); + } + } + + /** + * Shows a top/bottom coding dialog + * @param type + * @return A pair containing the bottom value + inclusive and the top value + inclusive. + * Either bottom or top may be null if they have not been defined. The overall pair may be + * null if cancel was pressed. + */ + public Pair, Pair> showTopBottomCodingDialog(DataType type) { + DialogTopBottomCoding dialog = new DialogTopBottomCoding(shell, type); + dialog.create(); + dialog.open(); + return dialog.getValue(); + } + + @Override + public void update(final ModelEvent event) { + + // Careful! In the main window, this is also called after editing the project properties + if (event.part == ModelPart.MODEL) { + final Model model = (Model) event.data; + shell.setText(Resources.getMessage("MainWindow.0") + " - " + model.getName()); //$NON-NLS-1$ //$NON-NLS-2$ + root.setEnabled(true); + menu.update(event); + } + } + + + /** + * Creates the global menu + * @return + */ + private List getMenu() { + + List menu = new ArrayList(); + + menu.add(getMenuFile()); + menu.add(getMenuEdit()); + menu.add(getMenuView()); + menu.add(getMenuHelp()); + + return menu; + } + + + /** + * Creates the edit menu + * @return + */ + private MainMenuItem getMenuEdit() { + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.21"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_anonymize.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditAnonymize(false); } + public boolean isEnabled(Model model) { + return model != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.40"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_anonymize_heuristic.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditAnonymize(true); } + public boolean isEnabled(Model model) { + return model != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.39"), //$NON-NLS-1$ + controller.getResources().getManagedImage("cross.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditReset(); } + public boolean isEnabled(Model model) { + return model != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.41"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuEditInitializeHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.42"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuEditCreateTopBottomCodingHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.23"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditCreateHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.30"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_find_replace.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuEditFindReplace(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.31"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_audit_trail.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionShowAuditTrail(); } + public boolean isEnabled(Model model) { + return model != null; + } + }); + + items.add(new MainMenuSeparator()); + + List subset = new ArrayList(); + + subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.1"), //$NON-NLS-1$ + controller.getResources().getManagedImage("page_white.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionSubsetNone(); } + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.2"), //$NON-NLS-1$ + controller.getResources().getManagedImage("page_white_text.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionSubsetAll(); } + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.3"), //$NON-NLS-1$ + controller.getResources().getManagedImage("disk.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionSubsetFile(); } + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.4"), //$NON-NLS-1$ + controller.getResources().getManagedImage("find.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionSubsetQuery(); } + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + items.add(new MainMenuGroup(Resources.getMessage("MainMenu.35"), subset) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.37"), //$NON-NLS-1$ + controller.getResources().getManagedImage("apply.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionApplySelectedTransformation(); } + public boolean isEnabled(Model model) { + return model != null && model.getResult() != null && model.getSelectedNode() != null; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.25"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_settings.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditSettings(); } + public boolean isEnabled(Model model) { + return model != null; + } + }); + + return new MainMenuGroup(Resources.getMessage("MainMenu.1"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } + + /** + * Creates the file menu + * @return + */ + private MainMenuItem getMenuFile() { + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.3"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_new.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileNew(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.5"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_load.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileOpen(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.4"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_save.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileSave(); } + public boolean isEnabled(Model model) { return model != null; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.9"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_save_as.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileSaveAs(); } + public boolean isEnabled(Model model) { return model != null; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.11"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_import_data.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileImportData(); } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() == Perspective.CONFIGURATION; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.13"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_export_data.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileExportData(); } + public boolean isEnabled(Model model) { + return model != null && model.getOutput() != null && model.getPerspective() == Perspective.ANALYSIS; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.43"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_create_certificate.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileCreateCertificate(); } + public boolean isEnabled(Model model) { + return model != null && model.getOutput() != null && model.getPerspective() == Perspective.ANALYSIS; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.15"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_import_hierarchy.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileImportHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.17"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_export_hierarchy.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileExportHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.19"), //$NON-NLS-1$ + controller.getResources().getManagedImage("exit.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuFileExit(); } + public boolean isEnabled(Model model) { + return true; + } + }); + + return new MainMenuGroup(Resources.getMessage("MainMenu.0"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } + + /** + * Creates the help menu + * @return + */ + private MainMenuItem getMenuHelp() { + + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.27"), //$NON-NLS-1$ + controller.getResources().getManagedImage("help.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuHelpHelp(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.29"), //$NON-NLS-1$ + controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuHelpAbout(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.32"), //$NON-NLS-1$ + controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuHelpDebug(); } + public boolean isEnabled(Model model) { + return model != null && model.isDebugEnabled(); + } + }); + + return new MainMenuGroup(Resources.getMessage("MainMenu.2"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } + + /** + * Creates the help menu + * @return + */ + private MainMenuItem getMenuView() { + + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainWindow.2"), //$NON-NLS-1$ + controller.getResources().getManagedImage("perspective_define.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { + root.setSelection(0); + controller.getModel().setPerspective(Perspective.CONFIGURATION); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.CONFIGURATION; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainWindow.3"), //$NON-NLS-1$ + controller.getResources().getManagedImage("perspective_explore.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { + root.setSelection(1); + controller.getModel().setPerspective(Perspective.EXPLORATION); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.EXPLORATION; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainWindow.1"), //$NON-NLS-1$ + controller.getResources().getManagedImage("perspective_analyze.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { + root.setSelection(2); + controller.getModel().setPerspective(Perspective.ANALYSIS); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.ANALYSIS; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainWindow.4"), //$NON-NLS-1$ + controller.getResources().getManagedImage("perspective_risk.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { + root.setSelection(3); + controller.getModel().setPerspective(Perspective.RISK); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.RISK; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.0"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + controller.getResources().getManagedImage("explore_lattice.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { + layoutExplore.showLattice(); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { + return model != null && + model.getPerspective() == Perspective.EXPLORATION && + model.getResult() != null && + !layoutExplore.isShowLattice(); + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.2"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + controller.getResources().getManagedImage("explore_list.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { + layoutExplore.showList(); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { + return model != null && + model.getPerspective() == Perspective.EXPLORATION && + model.getResult() != null && + !layoutExplore.isShowList(); + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.3"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + controller.getResources().getManagedImage("explore_tiles.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { + layoutExplore.showTiles(); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { + return model != null && + model.getPerspective() == Perspective.EXPLORATION && + model.getResult() != null && + !layoutExplore.isShowTiles(); + } + }); + + + return new MainMenuGroup(Resources.getMessage("MainMenu.33"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } } From 82c375688c23051b5178fa33dccfd84f2c8a1a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 21:26:58 +0100 Subject: [PATCH 05/22] use upstream mainwindow --- .../arx/gui/view/impl/MainWindow.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java index 8b841d363e..a6f122bfb7 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java @@ -65,6 +65,9 @@ import org.deidentifier.arx.gui.view.impl.risk.LayoutRisks; import org.deidentifier.arx.gui.view.impl.utility.LayoutUtility; import org.deidentifier.arx.gui.worker.Worker; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.ChecklistWizard; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.ChecklistDialog; +import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; @@ -516,6 +519,12 @@ public void showInfoDialog(final Shell shell, final String header, final String MessageDialog.openInformation(getShell(), header, text); } + public void showChecklistWizard() { + Checklist checklist = new Checklist(controller.getResources().getStream("default_checklist.txt")); + final ChecklistDialog dialog = new ChecklistDialog(checklist, shell, controller, new ChecklistWizard(checklist, controller)); + dialog.open(); + } + /** * Shows an input dialog. * @@ -1016,6 +1025,15 @@ private MainMenuItem getMenuHelp() { items.add(new MainMenuSeparator()); + items.add(new MainMenuItem(Resources.getMessage("MainMenu.28"), //$NON-NLS-1$ + controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuHelpChecklistWizard(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + items.add(new MainMenuItem(Resources.getMessage("MainMenu.29"), //$NON-NLS-1$ controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ false) { From b3bbd71c6587741259872f71f7de4e0a4f956ba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 21:27:05 +0100 Subject: [PATCH 06/22] rename checklist file --- .../{checklist_khaled_el_emam.txt => default_checklist.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/gui/org/deidentifier/arx/gui/resources/{checklist_khaled_el_emam.txt => default_checklist.txt} (100%) diff --git a/src/gui/org/deidentifier/arx/gui/resources/checklist_khaled_el_emam.txt b/src/gui/org/deidentifier/arx/gui/resources/default_checklist.txt similarity index 100% rename from src/gui/org/deidentifier/arx/gui/resources/checklist_khaled_el_emam.txt rename to src/gui/org/deidentifier/arx/gui/resources/default_checklist.txt From 4637ba6f50cd684f0049a44a3007c5efcb1ff036 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 21:27:23 +0100 Subject: [PATCH 07/22] fix monitor visualization bug --- .../wizard/sharingwizard/evaluation/MonitorVisualization.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java index c9344be331..9ff61f8ca5 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java @@ -66,11 +66,11 @@ public void updateWeights() { Section s = sections[i]; ComponentRiskMonitor riskMonitor = monitors.get(i); - riskMonitor.setRisk((s.getScore() / 2.0) + 0.5); + riskMonitor.setRisk(1.0 - ((s.getScore() / 2.0) + 0.5)); // System.out.println("Setup"); } - totalMonitor.setRisk((checklist.getScore() / 2.0) + 0.5); + totalMonitor.setRisk(1.0 - ((checklist.getScore() / 2.0) + 0.5)); } } From 3edf21536f2ba8a8ba262065b70140100ea6b261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 21:32:37 +0100 Subject: [PATCH 08/22] try matching code layout to upstream --- .../arx/gui/view/impl/MainWindow.java | 2135 +++++++++-------- 1 file changed, 1069 insertions(+), 1066 deletions(-) diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java index a6f122bfb7..5bacdcf791 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java @@ -1,13 +1,13 @@ /* * 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. @@ -92,940 +92,943 @@ * @author Fabian Prasser */ public class MainWindow implements IView { - - /** Controller */ - private final Controller controller; - - /** View */ - private final Display display; - /** View */ - private final Shell shell; - /** View */ - private final AbstractMenu menu; - /** View */ - private final ComponentTitledFolder root; - /** View */ - private final LayoutExplore layoutExplore; - - /** - * Creates a new instance. - * - * @param display - * @param monitor - */ - public MainWindow(Display display, Monitor monitor) { - - // Init - this.display = display; - this.shell = new Shell(display); - - // Build controller - controller = new Controller(this); - controller.addListener(ModelPart.MODEL, this); - - // Style - shell.setImages(Resources.getIconSet(display)); - shell.setText(Resources.getMessage("MainWindow.0")); //$NON-NLS-1$ - shell.setMinimumSize(800, 600); - - // Center - SWTUtil.center(shell, monitor); - - // Maximize - shell.setMaximized(true); - - // Close listener - shell.addListener(SWT.Close, new Listener() { - @Override - public void handleEvent(final Event event) { - controller.actionMenuFileExit(); - event.doit = false; - } - }); - - // Build menu - List items = getMenu(); - menu = new MainMenu(shell, controller, items); - new MainToolBar(shell, controller, items); - - // Create shell - shell.setLayout(SWTUtil.createGridLayout(1)); - - // Create the tab folder - Map helpids = new HashMap(); - root = new ComponentTitledFolder(shell, controller, null, "id-70", helpids); //$NON-NLS-1$ - root.setLayoutData(SWTUtil.createFillGridData()); - - // Create the subviews - Composite item1 = root.createItem(Resources.getMessage("MainWindow.2"), controller.getResources().getManagedImage("perspective_define.png")); //$NON-NLS-1$ //$NON-NLS-2$ - helpids.put(item1, "id-3"); //$NON-NLS-1$ - new LayoutDefinition(item1, controller); - Composite item2 = root.createItem(Resources.getMessage("MainWindow.3"), controller.getResources().getManagedImage("perspective_explore.png")); //$NON-NLS-1$ //$NON-NLS-2$ - helpids.put(item2, "id-4"); //$NON-NLS-1$ - this.layoutExplore = new LayoutExplore(item2, controller); - Composite item3 = root.createItem(Resources.getMessage("MainWindow.1"), controller.getResources().getManagedImage("perspective_analyze.png")); //$NON-NLS-1$ //$NON-NLS-2$ - helpids.put(item3, "help.utility.overview"); //$NON-NLS-1$ - new LayoutUtility(item3, controller); - Composite item4 = root.createItem(Resources.getMessage("MainWindow.4"), controller.getResources().getManagedImage("perspective_risk.png")); //$NON-NLS-1$ //$NON-NLS-2$ - helpids.put(item4, "help.risk.overview"); //$NON-NLS-1$ - new LayoutRisks(item4, controller); - - // Hack to update visualizations - root.addSelectionListener(new SelectionAdapter(){ - @Override - public void widgetSelected(SelectionEvent arg0) { - switch (root.getSelectionIndex()) { - case 0: - controller.getModel().setPerspective(Perspective.CONFIGURATION); - break; - case 1: - controller.getModel().setPerspective(Perspective.EXPLORATION); - break; - case 2: - controller.getModel().setPerspective(Perspective.ANALYSIS); - break; - case 3: - controller.getModel().setPerspective(Perspective.RISK); - break; - } - controller.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, null)); - controller.update(new ModelEvent(this, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - }); - - // Now reset and disable - controller.reset(); - } - - @Override - public void dispose() { - controller.removeListener(this); - } - - /** - * Returns the controller. - * - * @return - */ - public Controller getController() { - return this.controller; - } - - /** - * Returns the shell. - * - * @return - */ - public Shell getShell() { - return shell; - } - - /** - * Is this shell disposed. - * - * @return - */ - public boolean isDisposed() { - return this.shell.isDisposed(); - } - - /** - * Executes the given runnable on show. - * - * @param runnable - */ - public void onShow(final Runnable runnable){ - - // Using a paint listener is a hack to reliably determine when the shell is visible - shell.addPaintListener(new PaintListener(){ - @Override - public void paintControl(PaintEvent arg0) { - shell.removePaintListener(this); - display.timerExec(200, runnable); - } - }); - } - - /** - * Resets the GUI. - */ - public void reset() { - root.setSelection(0); - root.setEnabled(false); - } - - /** - * Main SWT event loop. - */ - public void show() { - shell.open(); - } - - /** - * Shows an about dialog. - */ - public void showAboutDialog() { - final DialogAbout dialog = new DialogAbout(shell, controller); - dialog.create(); - dialog.open(); - } - - /** - * Shows a dialog for selecting privacy criteria. - * - * @param criteria - * @return - */ - public ModelCriterion showAddCriterionDialog(Model model, - List criteria) { - - // Dialog - final DialogCriterionUpdate dialog = new DialogCriterionUpdate(controller, shell, criteria, model, true); - dialog.create(); - if (dialog.open() != Window.OK) { - return null; - } else { - return dialog.getCriterion(); - } - } - - /** - * Shows the audit trail - */ - public void showAuditTrail(List auditTrail) { - DialogAuditTrail dialog = new DialogAuditTrail(shell, auditTrail); - dialog.create(); - dialog.open(); - } - /** - * Shows an input dialog for selecting a charset. - * - * @param shell - * @return - */ - public Charset showCharsetInputDialog(final Shell shell) { - - // Validator - final IInputValidator validator = new IInputValidator() { - @Override - public String isValid(final String arg0) { - return null; - } - }; - - // Extract list of formats - List charsets = new ArrayList(); - for (String charset : Charsets.getNamesOfAvailableCharsets()) { - charsets.add(charset); - } - - // Open dialog - final DialogComboSelection dlg = new DialogComboSelection(shell, Resources.getMessage("MainWindow.19"), //$NON-NLS-1$ - Resources.getMessage("MainWindow.20"), //$NON-NLS-1$ - charsets.toArray(new String[] {}), - Charsets.getNameOfDefaultCharset(), - validator); - - // Return value - if (dlg.open() == Window.OK) { - return Charsets.getCharsetForName(dlg.getValue()); - } else { - return null; - } - } - - /** - * Shows a dialog for configuring privacy criteria. - * - * @param criteria - * @param criterion - * @return - */ - public void showConfigureCriterionDialog(Model model, List criteria, ModelCriterion criterion) { - DialogCriterionUpdate dialog = new DialogCriterionUpdate(controller, shell, criteria, model, false, criterion); - dialog.create(); - dialog.open(); - } - - /** - * Shows a debug dialog. - */ - public void showDebugDialog() { - final DialogDebug dialog = new DialogDebug(shell, controller); - dialog.create(); - dialog.open(); - } - - /** - * Shows an error dialog. - * - * @param shell - * @param message - * @param text - */ - public void showErrorDialog(final Shell shell, final String message, final String text) { - DialogError dialog = new DialogError(shell, controller, message, text); - dialog.create(); - dialog.open(); - } - - /** - * Shows an error dialog. - * - * @param shell - * @param message - * @param throwable - */ - public void showErrorDialog(final Shell shell, final String message, final Throwable throwable) { - StringWriter sw = new StringWriter(); - PrintWriter pw = new PrintWriter(sw); - if (throwable != null) throwable.printStackTrace(pw); - final String trace = sw.toString(); - showErrorDialog(shell, message, trace); - } - - /** - * Shows an error dialog. - * - * @param message - * @param text - */ - public void showErrorDialog(final String message, final String text) { - showErrorDialog(this.shell, message, text); - } - - /** - * Shows an error dialog. - * - * @param message - * @param throwable - */ - public void showErrorDialog(final String message, final Throwable throwable) { - showErrorDialog(this.shell, message, throwable); - } - - /** - * Shows a find & replace dialog - * @param handle - * @param column - * @return A pair containing the string to be found and the string with which it is to be replaced, - * null if cancel was pressed. - */ - public Pair showFindReplaceDialog(Model model, DataHandle handle, int column) { - DialogFindReplace dialog = new DialogFindReplace(shell, model, handle, column); - dialog.create(); - dialog.open(); - return dialog.getValue(); - } - - /** - * Shows an input dialog for selecting formats string for data types. - * - * @param shell - * @param header - * @param text - * @param preselected Preselected format string, can be null - * @param locale The current locale - * @param description - * @param values - * @return - */ - public String showFormatInputDialog(final Shell shell, final String header, final String text, final String preselected, final Locale locale, final DataTypeDescription description, final Collection values) { - - // Check - if (!description.hasFormat()) { - throw new RuntimeException(Resources.getMessage("MainWindow.6")); //$NON-NLS-1$ - } - - // Init - final String DEFAULT = Resources.getMessage("MainWindow.7"); //$NON-NLS-1$ - - // Validator - final IInputValidator validator = new IInputValidator() { - @Override - public String isValid(final String arg0) { - DataType type; - try { - if (arg0.equals(DEFAULT)) { - type = description.newInstance(); - } else { - type = description.newInstance(arg0, locale); - } - } catch (final Exception e) { - return Resources.getMessage("MainWindow.11"); //$NON-NLS-1$ - } - for (final String value : values) { - if (!type.isValid(value)) { - return Resources.getMessage("MainWindow.13"); //$NON-NLS-1$ - } - } - return null; - } - }; - - // Try to find a valid formatter - String initial = ""; //$NON-NLS-1$ - if (preselected != null && validator.isValid(preselected) == null) { - initial = preselected; - } else if (validator.isValid(DEFAULT) == null) { - initial = DEFAULT; - } else { - for (final String format : description.getExampleFormats()) { - if (validator.isValid(format) == null) { - initial = format; - break; - } - } - } - - // Extract list of formats - List formats = new ArrayList(); - formats.add(DEFAULT); - formats.addAll(description.getExampleFormats()); - - // Open dialog - final DialogComboSelection dlg = new DialogComboSelection(shell, header, text, formats.toArray(new String[] {}), initial, validator); - - // Return value - if (dlg.open() == Window.OK) { - return dlg.getValue(); - } else { - return null; - } - } - - /** - * Shows a help dialog. - * - * @param id - */ - public void showHelpDialog(String id) { - try { - DialogHelp dialog = new DialogHelp(shell, controller, id); - dialog.open(); - } catch (Exception e) { - this.showErrorDialog(Resources.getMessage("MainWindow.12"), e); //$NON-NLS-1$ - } - } - - /** - * Shows an info dialog. - * - * @param shell - * @param header - * @param text - */ - public void showInfoDialog(final Shell shell, final String header, final String text) { - MessageDialog.openInformation(getShell(), header, text); - } - + + /** Controller */ + private final Controller controller; + + /** View */ + private final Display display; + /** View */ + private final Shell shell; + /** View */ + private final AbstractMenu menu; + /** View */ + private final ComponentTitledFolder root; + /** View */ + private final LayoutExplore layoutExplore; + + /** + * Creates a new instance. + * + * @param display + * @param monitor + */ + public MainWindow(Display display, Monitor monitor) { + + // Init + this.display = display; + this.shell = new Shell(display); + + // Build controller + controller = new Controller(this); + controller.addListener(ModelPart.MODEL, this); + + // Style + shell.setImages(Resources.getIconSet(display)); + shell.setText(Resources.getMessage("MainWindow.0")); //$NON-NLS-1$ + shell.setMinimumSize(800, 600); + + // Center + SWTUtil.center(shell, monitor); + + // Maximize + shell.setMaximized(true); + + // Close listener + shell.addListener(SWT.Close, new Listener() { + @Override + public void handleEvent(final Event event) { + controller.actionMenuFileExit(); + event.doit = false; + } + }); + + // Build menu + List items = getMenu(); + menu = new MainMenu(shell, controller, items); + new MainToolBar(shell, controller, items); + + // Create shell + shell.setLayout(SWTUtil.createGridLayout(1)); + + // Create the tab folder + Map helpids = new HashMap(); + root = new ComponentTitledFolder(shell, controller, null, "id-70", helpids); //$NON-NLS-1$ + root.setLayoutData(SWTUtil.createFillGridData()); + + // Create the subviews + Composite item1 = root.createItem(Resources.getMessage("MainWindow.2"), controller.getResources().getManagedImage("perspective_define.png")); //$NON-NLS-1$ //$NON-NLS-2$ + helpids.put(item1, "id-3"); //$NON-NLS-1$ + new LayoutDefinition(item1, controller); + Composite item2 = root.createItem(Resources.getMessage("MainWindow.3"), controller.getResources().getManagedImage("perspective_explore.png")); //$NON-NLS-1$ //$NON-NLS-2$ + helpids.put(item2, "id-4"); //$NON-NLS-1$ + this.layoutExplore = new LayoutExplore(item2, controller); + Composite item3 = root.createItem(Resources.getMessage("MainWindow.1"), controller.getResources().getManagedImage("perspective_analyze.png")); //$NON-NLS-1$ //$NON-NLS-2$ + helpids.put(item3, "help.utility.overview"); //$NON-NLS-1$ + new LayoutUtility(item3, controller); + Composite item4 = root.createItem(Resources.getMessage("MainWindow.4"), controller.getResources().getManagedImage("perspective_risk.png")); //$NON-NLS-1$ //$NON-NLS-2$ + helpids.put(item4, "help.risk.overview"); //$NON-NLS-1$ + new LayoutRisks(item4, controller); + + // Hack to update visualizations + root.addSelectionListener(new SelectionAdapter(){ + @Override + public void widgetSelected(SelectionEvent arg0) { + switch (root.getSelectionIndex()) { + case 0: + controller.getModel().setPerspective(Perspective.CONFIGURATION); + break; + case 1: + controller.getModel().setPerspective(Perspective.EXPLORATION); + break; + case 2: + controller.getModel().setPerspective(Perspective.ANALYSIS); + break; + case 3: + controller.getModel().setPerspective(Perspective.RISK); + break; + } + controller.update(new ModelEvent(this, ModelPart.SELECTED_UTILITY_VISUALIZATION, null)); + controller.update(new ModelEvent(this, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + }); + + // Now reset and disable + controller.reset(); + } + + @Override + public void dispose() { + controller.removeListener(this); + } + + /** + * Returns the controller. + * + * @return + */ + public Controller getController() { + return this.controller; + } + + /** + * Returns the shell. + * + * @return + */ + public Shell getShell() { + return shell; + } + + /** + * Is this shell disposed. + * + * @return + */ + public boolean isDisposed() { + return this.shell.isDisposed(); + } + + /** + * Executes the given runnable on show. + * + * @param runnable + */ + public void onShow(final Runnable runnable){ + + // Using a paint listener is a hack to reliably determine when the shell is visible + shell.addPaintListener(new PaintListener(){ + @Override + public void paintControl(PaintEvent arg0) { + shell.removePaintListener(this); + display.timerExec(200, runnable); + } + }); + } + + /** + * Resets the GUI. + */ + public void reset() { + root.setSelection(0); + root.setEnabled(false); + } + + /** + * Main SWT event loop. + */ + public void show() { + shell.open(); + } + + /** + * Shows an about dialog. + */ + public void showAboutDialog() { + final DialogAbout dialog = new DialogAbout(shell, controller); + dialog.create(); + dialog.open(); + } + + /** + * Shows a dialog for selecting privacy criteria. + * + * @param criteria + * @return + */ + public ModelCriterion showAddCriterionDialog(Model model, + List criteria) { + + // Dialog + final DialogCriterionUpdate dialog = new DialogCriterionUpdate(controller, shell, criteria, model, true); + dialog.create(); + if (dialog.open() != Window.OK) { + return null; + } else { + return dialog.getCriterion(); + } + } + + /** + * Shows the audit trail + */ + public void showAuditTrail(List auditTrail) { + DialogAuditTrail dialog = new DialogAuditTrail(shell, auditTrail); + dialog.create(); + dialog.open(); + } + /** + * Shows an input dialog for selecting a charset. + * + * @param shell + * @return + */ + public Charset showCharsetInputDialog(final Shell shell) { + + // Validator + final IInputValidator validator = new IInputValidator() { + @Override + public String isValid(final String arg0) { + return null; + } + }; + + // Extract list of formats + List charsets = new ArrayList(); + for (String charset : Charsets.getNamesOfAvailableCharsets()) { + charsets.add(charset); + } + + // Open dialog + final DialogComboSelection dlg = new DialogComboSelection(shell, Resources.getMessage("MainWindow.19"), //$NON-NLS-1$ + Resources.getMessage("MainWindow.20"), //$NON-NLS-1$ + charsets.toArray(new String[] {}), + Charsets.getNameOfDefaultCharset(), + validator); + + // Return value + if (dlg.open() == Window.OK) { + return Charsets.getCharsetForName(dlg.getValue()); + } else { + return null; + } + } + + /** + * Shows a dialog for configuring privacy criteria. + * + * @param criteria + * @param criterion + * @return + */ + public void showConfigureCriterionDialog(Model model, List criteria, ModelCriterion criterion) { + DialogCriterionUpdate dialog = new DialogCriterionUpdate(controller, shell, criteria, model, false, criterion); + dialog.create(); + dialog.open(); + } + + /** + * Shows a debug dialog. + */ + public void showDebugDialog() { + final DialogDebug dialog = new DialogDebug(shell, controller); + dialog.create(); + dialog.open(); + } + + /** + * Shows an error dialog. + * + * @param shell + * @param message + * @param text + */ + public void showErrorDialog(final Shell shell, final String message, final String text) { + DialogError dialog = new DialogError(shell, controller, message, text); + dialog.create(); + dialog.open(); + } + + /** + * Shows an error dialog. + * + * @param shell + * @param message + * @param throwable + */ + public void showErrorDialog(final Shell shell, final String message, final Throwable throwable) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + if (throwable != null) throwable.printStackTrace(pw); + final String trace = sw.toString(); + showErrorDialog(shell, message, trace); + } + + /** + * Shows an error dialog. + * + * @param message + * @param text + */ + public void showErrorDialog(final String message, final String text) { + showErrorDialog(this.shell, message, text); + } + + /** + * Shows an error dialog. + * + * @param message + * @param throwable + */ + public void showErrorDialog(final String message, final Throwable throwable) { + showErrorDialog(this.shell, message, throwable); + } + + /** + * Shows a find & replace dialog + * @param handle + * @param column + * @return A pair containing the string to be found and the string with which it is to be replaced, + * null if cancel was pressed. + */ + public Pair showFindReplaceDialog(Model model, DataHandle handle, int column) { + DialogFindReplace dialog = new DialogFindReplace(shell, model, handle, column); + dialog.create(); + dialog.open(); + return dialog.getValue(); + } + + /** + * Shows an input dialog for selecting formats string for data types. + * + * @param shell + * @param header + * @param text + * @param preselected Preselected format string, can be null + * @param locale The current locale + * @param description + * @param values + * @return + */ + public String showFormatInputDialog(final Shell shell, final String header, final String text, final String preselected, final Locale locale, final DataTypeDescription description, final Collection values) { + + // Check + if (!description.hasFormat()) { + throw new RuntimeException(Resources.getMessage("MainWindow.6")); //$NON-NLS-1$ + } + + // Init + final String DEFAULT = Resources.getMessage("MainWindow.7"); //$NON-NLS-1$ + + // Validator + final IInputValidator validator = new IInputValidator() { + @Override + public String isValid(final String arg0) { + DataType type; + try { + if (arg0.equals(DEFAULT)) { + type = description.newInstance(); + } else { + type = description.newInstance(arg0, locale); + } + } catch (final Exception e) { + return Resources.getMessage("MainWindow.11"); //$NON-NLS-1$ + } + for (final String value : values) { + if (!type.isValid(value)) { + return Resources.getMessage("MainWindow.13"); //$NON-NLS-1$ + } + } + return null; + } + }; + + // Try to find a valid formatter + String initial = ""; //$NON-NLS-1$ + if (preselected != null && validator.isValid(preselected) == null) { + initial = preselected; + } else if (validator.isValid(DEFAULT) == null) { + initial = DEFAULT; + } else { + for (final String format : description.getExampleFormats()) { + if (validator.isValid(format) == null) { + initial = format; + break; + } + } + } + + // Extract list of formats + List formats = new ArrayList(); + formats.add(DEFAULT); + formats.addAll(description.getExampleFormats()); + + // Open dialog + final DialogComboSelection dlg = new DialogComboSelection(shell, header, text, formats.toArray(new String[] {}), initial, validator); + + // Return value + if (dlg.open() == Window.OK) { + return dlg.getValue(); + } else { + return null; + } + } + + /** + * Shows a help dialog. + * + * @param id + */ + public void showHelpDialog(String id) { + try { + DialogHelp dialog = new DialogHelp(shell, controller, id); + dialog.open(); + } catch (Exception e) { + this.showErrorDialog(Resources.getMessage("MainWindow.12"), e); //$NON-NLS-1$ + } + } + + /** + * Shows the checklist wizard + */ public void showChecklistWizard() { Checklist checklist = new Checklist(controller.getResources().getStream("default_checklist.txt")); final ChecklistDialog dialog = new ChecklistDialog(checklist, shell, controller, new ChecklistWizard(checklist, controller)); dialog.open(); } - - /** - * Shows an input dialog. - * - * @param shell - * @param header - * @param text - * @param initial - * @return - */ - public String showInputDialog(final Shell shell, final String header, final String text, final String initial) { - return showInputDialog(shell, header, text, initial, null); - } - - /** - * Shows an input dialog. - * - * @param shell - * @param header - * @param text - * @param initial - * @param validator - * @return - */ - public String showInputDialog(final Shell shell, final String header, final String text, final String initial, final IInputValidator validator) { - final InputDialog dlg = new InputDialog(shell, header, text, initial, validator); - if (dlg.open() == Window.OK) { - return dlg.getValue(); - } else { - return null; - } - } - /** - * Shows a dialog that allows selecting multiple elements - * @param shell - * @param title - * @param text - * @param elements - * @param selected - * @return - */ - public List showMultiSelectionDialog(Shell shell, - String title, - String text, - List elements, - List selected) { - - // Open dialog - DialogMultiSelection dlg = new DialogMultiSelection(shell, title, text, elements, selected); - if (dlg.open() == Window.OK) { - return dlg.getSelectedItems(); - } else { - return null; - } - } - - /** - * Shows a file open dialog. - * - * @param shell - * @param filter - * @return - */ - public String showOpenFileDialog(final Shell shell, String filter) { - final FileDialog dialog = new FileDialog(shell, SWT.OPEN); - dialog.setFilterExtensions(new String[] { filter }); - dialog.setFilterIndex(0); - String file = dialog.open(); - if (file == null) { - return null; - } else if (!new File(file).exists()) { - showInfoDialog(shell, Resources.getMessage("MainWindow.5"), Resources.getMessage("MainWindow.14")); //$NON-NLS-1$ //$NON-NLS-2$ - return null; - } else { - return file; - } - } - - /** - * Shows an input dialog for ordering data items. - * - * @param shell - * @param header - * @param text - * @param type - * @param locale - * @param values - * @return - */ - public String[] showOrderValuesDialog(final Shell shell, final String header, final String text, final DataType type, final Locale locale, final String[] values) { - - // Open dialog - DialogOrderSelection dlg = new DialogOrderSelection(shell, values, type, locale, controller); - if (dlg.open() == Window.OK) { - return dlg.getResult(); - } else { - return null; - } - } - - /** - * Shows a progress dialog. - * - * @param text - * @param worker - */ - public void showProgressDialog(final String text, final Worker worker) { - try { - new ProgressMonitorDialog(shell).run(true, true, worker); - } catch (final Exception e) { - worker.setError(e); - } - } - - /** - * Shows a query dialog for selecting a research subset. - * - * @param query - * @param data - * @return - */ - public DialogQueryResult showQueryDialog(String query, Data data) { - - // Dialog - final DialogQuery dialog = new DialogQuery(data, shell, query); - dialog.create(); - if (dialog.open() != Window.OK) { - return null; - } else { - return dialog.getResult(); - } - } - - /** - * Shows a question dialog. - * - * @param shell - * @param header - * @param text - * @return - */ - public boolean showQuestionDialog(final Shell shell, final String header, final String text) { - return MessageDialog.openQuestion(getShell(), header, text); - } - - /** - * Shows a file save dialog. - * - * @param shell - * @param filter - * @return - */ - public String showSaveFileDialog(final Shell shell, String filter) { - final FileDialog dialog = new FileDialog(shell, SWT.SAVE); - dialog.setFilterExtensions(new String[] { filter }); - dialog.setFilterIndex(0); - return dialog.open(); - } - - /** - * Shows a dialog for selecting privacy criteria. - * - * @param criteria - * @return - */ - public ModelExplicitCriterion showSelectCriterionDialog(List criteria) { - - // Dialog - final DialogCriterionSelection dialog = new DialogCriterionSelection(controller, shell, criteria); - dialog.create(); - if (dialog.open() != Window.OK) { - return null; - } else { - return dialog.getCriterion(); - } - } - - /** - * Shows a top/bottom coding dialog - * @param type - * @return A pair containing the bottom value + inclusive and the top value + inclusive. - * Either bottom or top may be null if they have not been defined. The overall pair may be - * null if cancel was pressed. - */ - public Pair, Pair> showTopBottomCodingDialog(DataType type) { - DialogTopBottomCoding dialog = new DialogTopBottomCoding(shell, type); - dialog.create(); - dialog.open(); - return dialog.getValue(); - } - - @Override - public void update(final ModelEvent event) { - - // Careful! In the main window, this is also called after editing the project properties - if (event.part == ModelPart.MODEL) { - final Model model = (Model) event.data; - shell.setText(Resources.getMessage("MainWindow.0") + " - " + model.getName()); //$NON-NLS-1$ //$NON-NLS-2$ - root.setEnabled(true); - menu.update(event); - } - } - - - /** - * Creates the global menu - * @return - */ - private List getMenu() { - - List menu = new ArrayList(); - - menu.add(getMenuFile()); - menu.add(getMenuEdit()); - menu.add(getMenuView()); - menu.add(getMenuHelp()); - - return menu; - } - - - /** - * Creates the edit menu - * @return - */ - private MainMenuItem getMenuEdit() { - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.21"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_anonymize.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditAnonymize(false); } - public boolean isEnabled(Model model) { - return model != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.40"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_anonymize_heuristic.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditAnonymize(true); } - public boolean isEnabled(Model model) { - return model != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.39"), //$NON-NLS-1$ - controller.getResources().getManagedImage("cross.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditReset(); } - public boolean isEnabled(Model model) { - return model != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.41"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuEditInitializeHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.42"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuEditCreateTopBottomCodingHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.23"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditCreateHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.30"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_find_replace.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuEditFindReplace(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.31"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_audit_trail.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionShowAuditTrail(); } - public boolean isEnabled(Model model) { - return model != null; - } - }); - - items.add(new MainMenuSeparator()); - - List subset = new ArrayList(); - - subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.1"), //$NON-NLS-1$ - controller.getResources().getManagedImage("page_white.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionSubsetNone(); } - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.2"), //$NON-NLS-1$ - controller.getResources().getManagedImage("page_white_text.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionSubsetAll(); } - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.3"), //$NON-NLS-1$ - controller.getResources().getManagedImage("disk.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionSubsetFile(); } - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.4"), //$NON-NLS-1$ - controller.getResources().getManagedImage("find.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionSubsetQuery(); } - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - items.add(new MainMenuGroup(Resources.getMessage("MainMenu.35"), subset) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.37"), //$NON-NLS-1$ - controller.getResources().getManagedImage("apply.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionApplySelectedTransformation(); } - public boolean isEnabled(Model model) { - return model != null && model.getResult() != null && model.getSelectedNode() != null; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.25"), //$NON-NLS-1$ - controller.getResources().getManagedImage("edit_settings.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuEditSettings(); } - public boolean isEnabled(Model model) { - return model != null; - } - }); - - return new MainMenuGroup(Resources.getMessage("MainMenu.1"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } - - /** - * Creates the file menu - * @return - */ - private MainMenuItem getMenuFile() { - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.3"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_new.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileNew(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.5"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_load.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileOpen(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.4"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_save.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileSave(); } - public boolean isEnabled(Model model) { return model != null; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.9"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_save_as.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileSaveAs(); } - public boolean isEnabled(Model model) { return model != null; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.11"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_import_data.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileImportData(); } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() == Perspective.CONFIGURATION; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.13"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_export_data.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileExportData(); } - public boolean isEnabled(Model model) { - return model != null && model.getOutput() != null && model.getPerspective() == Perspective.ANALYSIS; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.43"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_create_certificate.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileCreateCertificate(); } - public boolean isEnabled(Model model) { - return model != null && model.getOutput() != null && model.getPerspective() == Perspective.ANALYSIS; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.15"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_import_hierarchy.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileImportHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.17"), //$NON-NLS-1$ - controller.getResources().getManagedImage("file_export_hierarchy.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuFileExportHierarchy(); } - public boolean isEnabled(Model model) { - return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; - } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.19"), //$NON-NLS-1$ - controller.getResources().getManagedImage("exit.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuFileExit(); } - public boolean isEnabled(Model model) { - return true; - } - }); - - return new MainMenuGroup(Resources.getMessage("MainMenu.0"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } - - /** - * Creates the help menu - * @return - */ - private MainMenuItem getMenuHelp() { - - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.27"), //$NON-NLS-1$ - controller.getResources().getManagedImage("help.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { controller.actionMenuHelpHelp(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.28"), //$NON-NLS-1$ + + /** + * Shows an info dialog. + * + * @param shell + * @param header + * @param text + */ + public void showInfoDialog(final Shell shell, final String header, final String text) { + MessageDialog.openInformation(getShell(), header, text); + } + + /** + * Shows an input dialog. + * + * @param shell + * @param header + * @param text + * @param initial + * @return + */ + public String showInputDialog(final Shell shell, final String header, final String text, final String initial) { + return showInputDialog(shell, header, text, initial, null); + } + + /** + * Shows an input dialog. + * + * @param shell + * @param header + * @param text + * @param initial + * @param validator + * @return + */ + public String showInputDialog(final Shell shell, final String header, final String text, final String initial, final IInputValidator validator) { + final InputDialog dlg = new InputDialog(shell, header, text, initial, validator); + if (dlg.open() == Window.OK) { + return dlg.getValue(); + } else { + return null; + } + } + /** + * Shows a dialog that allows selecting multiple elements + * @param shell + * @param title + * @param text + * @param elements + * @param selected + * @return + */ + public List showMultiSelectionDialog(Shell shell, + String title, + String text, + List elements, + List selected) { + + // Open dialog + DialogMultiSelection dlg = new DialogMultiSelection(shell, title, text, elements, selected); + if (dlg.open() == Window.OK) { + return dlg.getSelectedItems(); + } else { + return null; + } + } + + /** + * Shows a file open dialog. + * + * @param shell + * @param filter + * @return + */ + public String showOpenFileDialog(final Shell shell, String filter) { + final FileDialog dialog = new FileDialog(shell, SWT.OPEN); + dialog.setFilterExtensions(new String[] { filter }); + dialog.setFilterIndex(0); + String file = dialog.open(); + if (file == null) { + return null; + } else if (!new File(file).exists()) { + showInfoDialog(shell, Resources.getMessage("MainWindow.5"), Resources.getMessage("MainWindow.14")); //$NON-NLS-1$ //$NON-NLS-2$ + return null; + } else { + return file; + } + } + + /** + * Shows an input dialog for ordering data items. + * + * @param shell + * @param header + * @param text + * @param type + * @param locale + * @param values + * @return + */ + public String[] showOrderValuesDialog(final Shell shell, final String header, final String text, final DataType type, final Locale locale, final String[] values) { + + // Open dialog + DialogOrderSelection dlg = new DialogOrderSelection(shell, values, type, locale, controller); + if (dlg.open() == Window.OK) { + return dlg.getResult(); + } else { + return null; + } + } + + /** + * Shows a progress dialog. + * + * @param text + * @param worker + */ + public void showProgressDialog(final String text, final Worker worker) { + try { + new ProgressMonitorDialog(shell).run(true, true, worker); + } catch (final Exception e) { + worker.setError(e); + } + } + + /** + * Shows a query dialog for selecting a research subset. + * + * @param query + * @param data + * @return + */ + public DialogQueryResult showQueryDialog(String query, Data data) { + + // Dialog + final DialogQuery dialog = new DialogQuery(data, shell, query); + dialog.create(); + if (dialog.open() != Window.OK) { + return null; + } else { + return dialog.getResult(); + } + } + + /** + * Shows a question dialog. + * + * @param shell + * @param header + * @param text + * @return + */ + public boolean showQuestionDialog(final Shell shell, final String header, final String text) { + return MessageDialog.openQuestion(getShell(), header, text); + } + + /** + * Shows a file save dialog. + * + * @param shell + * @param filter + * @return + */ + public String showSaveFileDialog(final Shell shell, String filter) { + final FileDialog dialog = new FileDialog(shell, SWT.SAVE); + dialog.setFilterExtensions(new String[] { filter }); + dialog.setFilterIndex(0); + return dialog.open(); + } + + /** + * Shows a dialog for selecting privacy criteria. + * + * @param criteria + * @return + */ + public ModelExplicitCriterion showSelectCriterionDialog(List criteria) { + + // Dialog + final DialogCriterionSelection dialog = new DialogCriterionSelection(controller, shell, criteria); + dialog.create(); + if (dialog.open() != Window.OK) { + return null; + } else { + return dialog.getCriterion(); + } + } + + /** + * Shows a top/bottom coding dialog + * @param type + * @return A pair containing the bottom value + inclusive and the top value + inclusive. + * Either bottom or top may be null if they have not been defined. The overall pair may be + * null if cancel was pressed. + */ + public Pair, Pair> showTopBottomCodingDialog(DataType type) { + DialogTopBottomCoding dialog = new DialogTopBottomCoding(shell, type); + dialog.create(); + dialog.open(); + return dialog.getValue(); + } + + @Override + public void update(final ModelEvent event) { + + // Careful! In the main window, this is also called after editing the project properties + if (event.part == ModelPart.MODEL) { + final Model model = (Model) event.data; + shell.setText(Resources.getMessage("MainWindow.0") + " - " + model.getName()); //$NON-NLS-1$ //$NON-NLS-2$ + root.setEnabled(true); + menu.update(event); + } + } + + + /** + * Creates the global menu + * @return + */ + private List getMenu() { + + List menu = new ArrayList(); + + menu.add(getMenuFile()); + menu.add(getMenuEdit()); + menu.add(getMenuView()); + menu.add(getMenuHelp()); + + return menu; + } + + + /** + * Creates the edit menu + * @return + */ + private MainMenuItem getMenuEdit() { + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.21"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_anonymize.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditAnonymize(false); } + public boolean isEnabled(Model model) { + return model != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.40"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_anonymize_heuristic.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditAnonymize(true); } + public boolean isEnabled(Model model) { + return model != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.39"), //$NON-NLS-1$ + controller.getResources().getManagedImage("cross.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditReset(); } + public boolean isEnabled(Model model) { + return model != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.41"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuEditInitializeHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.42"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuEditCreateTopBottomCodingHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.23"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_create_hierarchy.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditCreateHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.30"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_find_replace.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuEditFindReplace(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.31"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_audit_trail.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionShowAuditTrail(); } + public boolean isEnabled(Model model) { + return model != null; + } + }); + + items.add(new MainMenuSeparator()); + + List subset = new ArrayList(); + + subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.1"), //$NON-NLS-1$ + controller.getResources().getManagedImage("page_white.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionSubsetNone(); } + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.2"), //$NON-NLS-1$ + controller.getResources().getManagedImage("page_white_text.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionSubsetAll(); } + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.3"), //$NON-NLS-1$ + controller.getResources().getManagedImage("disk.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionSubsetFile(); } + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + subset.add(new MainMenuItem(Resources.getMessage("SubsetDefinitionView.4"), //$NON-NLS-1$ + controller.getResources().getManagedImage("find.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionSubsetQuery(); } + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + items.add(new MainMenuGroup(Resources.getMessage("MainMenu.35"), subset) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return model != null && model.getInputConfig() != null && model.getInputConfig().getInput() != null; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.37"), //$NON-NLS-1$ + controller.getResources().getManagedImage("apply.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionApplySelectedTransformation(); } + public boolean isEnabled(Model model) { + return model != null && model.getResult() != null && model.getSelectedNode() != null; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.25"), //$NON-NLS-1$ + controller.getResources().getManagedImage("edit_settings.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuEditSettings(); } + public boolean isEnabled(Model model) { + return model != null; + } + }); + + return new MainMenuGroup(Resources.getMessage("MainMenu.1"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } + + /** + * Creates the file menu + * @return + */ + private MainMenuItem getMenuFile() { + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.3"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_new.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileNew(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.5"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_load.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileOpen(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.4"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_save.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileSave(); } + public boolean isEnabled(Model model) { return model != null; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.9"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_save_as.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileSaveAs(); } + public boolean isEnabled(Model model) { return model != null; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.11"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_import_data.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileImportData(); } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() == Perspective.CONFIGURATION; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.13"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_export_data.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileExportData(); } + public boolean isEnabled(Model model) { + return model != null && model.getOutput() != null && model.getPerspective() == Perspective.ANALYSIS; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.43"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_create_certificate.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileCreateCertificate(); } + public boolean isEnabled(Model model) { + return model != null && model.getOutput() != null && model.getPerspective() == Perspective.ANALYSIS; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.15"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_import_hierarchy.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileImportHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.17"), //$NON-NLS-1$ + controller.getResources().getManagedImage("file_export_hierarchy.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuFileExportHierarchy(); } + public boolean isEnabled(Model model) { + return model != null && model.getSelectedAttribute() != null && model.getPerspective() == Perspective.CONFIGURATION; + } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.19"), //$NON-NLS-1$ + controller.getResources().getManagedImage("exit.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuFileExit(); } + public boolean isEnabled(Model model) { + return true; + } + }); + + return new MainMenuGroup(Resources.getMessage("MainMenu.0"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } + + /** + * Creates the help menu + * @return + */ + private MainMenuItem getMenuHelp() { + + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.27"), //$NON-NLS-1$ + controller.getResources().getManagedImage("help.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { controller.actionMenuHelpHelp(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.28"), //$NON-NLS-1$ controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ true) { public void action(Controller controller) { controller.actionMenuHelpChecklistWizard(); } @@ -1033,137 +1036,137 @@ private MainMenuItem getMenuHelp() { }); items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.29"), //$NON-NLS-1$ - controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuHelpAbout(); } - public boolean isEnabled(Model model) { return true; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.32"), //$NON-NLS-1$ - controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { controller.actionMenuHelpDebug(); } - public boolean isEnabled(Model model) { - return model != null && model.isDebugEnabled(); - } - }); - - return new MainMenuGroup(Resources.getMessage("MainMenu.2"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } - - /** - * Creates the help menu - * @return - */ - private MainMenuItem getMenuView() { - - - List items = new ArrayList(); - - items.add(new MainMenuItem(Resources.getMessage("MainWindow.2"), //$NON-NLS-1$ - controller.getResources().getManagedImage("perspective_define.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { - root.setSelection(0); - controller.getModel().setPerspective(Perspective.CONFIGURATION); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.CONFIGURATION; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainWindow.3"), //$NON-NLS-1$ - controller.getResources().getManagedImage("perspective_explore.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { - root.setSelection(1); - controller.getModel().setPerspective(Perspective.EXPLORATION); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.EXPLORATION; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainWindow.1"), //$NON-NLS-1$ - controller.getResources().getManagedImage("perspective_analyze.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { - root.setSelection(2); - controller.getModel().setPerspective(Perspective.ANALYSIS); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.ANALYSIS; } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainWindow.4"), //$NON-NLS-1$ - controller.getResources().getManagedImage("perspective_risk.png"), //$NON-NLS-1$ - false) { - public void action(Controller controller) { - root.setSelection(3); - controller.getModel().setPerspective(Perspective.RISK); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.RISK; } - }); - - items.add(new MainMenuSeparator()); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.0"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - controller.getResources().getManagedImage("explore_lattice.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { - layoutExplore.showLattice(); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { - return model != null && - model.getPerspective() == Perspective.EXPLORATION && - model.getResult() != null && - !layoutExplore.isShowLattice(); - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.2"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - controller.getResources().getManagedImage("explore_list.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { - layoutExplore.showList(); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { - return model != null && - model.getPerspective() == Perspective.EXPLORATION && - model.getResult() != null && - !layoutExplore.isShowList(); - } - }); - - items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.3"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - controller.getResources().getManagedImage("explore_tiles.png"), //$NON-NLS-1$ - true) { - public void action(Controller controller) { - layoutExplore.showTiles(); - controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); - } - public boolean isEnabled(Model model) { - return model != null && - model.getPerspective() == Perspective.EXPLORATION && - model.getResult() != null && - !layoutExplore.isShowTiles(); - } - }); - - - return new MainMenuGroup(Resources.getMessage("MainMenu.33"), items) { //$NON-NLS-1$ - public boolean isEnabled(Model model) { - return true; - } - }; - } -} + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.29"), //$NON-NLS-1$ + controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuHelpAbout(); } + public boolean isEnabled(Model model) { return true; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.32"), //$NON-NLS-1$ + controller.getResources().getManagedImage("information.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { controller.actionMenuHelpDebug(); } + public boolean isEnabled(Model model) { + return model != null && model.isDebugEnabled(); + } + }); + + return new MainMenuGroup(Resources.getMessage("MainMenu.2"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } + + /** + * Creates the help menu + * @return + */ + private MainMenuItem getMenuView() { + + + List items = new ArrayList(); + + items.add(new MainMenuItem(Resources.getMessage("MainWindow.2"), //$NON-NLS-1$ + controller.getResources().getManagedImage("perspective_define.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { + root.setSelection(0); + controller.getModel().setPerspective(Perspective.CONFIGURATION); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.CONFIGURATION; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainWindow.3"), //$NON-NLS-1$ + controller.getResources().getManagedImage("perspective_explore.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { + root.setSelection(1); + controller.getModel().setPerspective(Perspective.EXPLORATION); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.EXPLORATION; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainWindow.1"), //$NON-NLS-1$ + controller.getResources().getManagedImage("perspective_analyze.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { + root.setSelection(2); + controller.getModel().setPerspective(Perspective.ANALYSIS); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.ANALYSIS; } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainWindow.4"), //$NON-NLS-1$ + controller.getResources().getManagedImage("perspective_risk.png"), //$NON-NLS-1$ + false) { + public void action(Controller controller) { + root.setSelection(3); + controller.getModel().setPerspective(Perspective.RISK); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { return model != null && model.getPerspective() != Perspective.RISK; } + }); + + items.add(new MainMenuSeparator()); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.0"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + controller.getResources().getManagedImage("explore_lattice.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { + layoutExplore.showLattice(); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { + return model != null && + model.getPerspective() == Perspective.EXPLORATION && + model.getResult() != null && + !layoutExplore.isShowLattice(); + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.2"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + controller.getResources().getManagedImage("explore_list.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { + layoutExplore.showList(); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { + return model != null && + model.getPerspective() == Perspective.EXPLORATION && + model.getResult() != null && + !layoutExplore.isShowList(); + } + }); + + items.add(new MainMenuItem(Resources.getMessage("MainMenu.34") + " " + Resources.getMessage("ExploreView.3"), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + controller.getResources().getManagedImage("explore_tiles.png"), //$NON-NLS-1$ + true) { + public void action(Controller controller) { + layoutExplore.showTiles(); + controller.update(new ModelEvent(controller, ModelPart.SELECTED_PERSPECTIVE, controller.getModel().getPerspective())); + } + public boolean isEnabled(Model model) { + return model != null && + model.getPerspective() == Perspective.EXPLORATION && + model.getResult() != null && + !layoutExplore.isShowTiles(); + } + }); + + + return new MainMenuGroup(Resources.getMessage("MainMenu.33"), items) { //$NON-NLS-1$ + public boolean isEnabled(Model model) { + return true; + } + }; + } +} \ No newline at end of file From 3767f2c12d7d47c3d17380eca656c94f0fcefd42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 22:33:29 +0100 Subject: [PATCH 09/22] comments --- .../arx/gui/resources/messages.properties | 20 +++++ .../arx/gui/view/impl/MainWindow.java | 2 +- .../sharingwizard/AnswerRadioGroup.java | 19 +++-- .../wizard/sharingwizard/ChecklistDialog.java | 49 +++++++++-- .../wizard/sharingwizard/ChecklistWizard.java | 29 ++++++- .../wizard/sharingwizard/EvaluationPage.java | 83 ++++++++++++------- .../wizard/sharingwizard/SectionPage.java | 29 ++++--- .../wizard/sharingwizard/WeightField.java | 32 +++++-- .../sharingwizard/checklist/Checklist.java | 58 +++++++++++-- .../wizard/sharingwizard/checklist/Item.java | 34 +++++++- .../sharingwizard/checklist/Question.java | 36 +++++++- .../sharingwizard/checklist/Section.java | 38 ++++++++- .../checklist/WeightConfiguration.java | 66 ++++++++++++--- .../evaluation/MonitorVisualization.java | 23 ++++- .../evaluation/StackVisualization.java | 37 ++++++++- .../evaluation/Visualization.java | 16 ++++ 16 files changed, 472 insertions(+), 99 deletions(-) diff --git a/src/gui/org/deidentifier/arx/gui/resources/messages.properties b/src/gui/org/deidentifier/arx/gui/resources/messages.properties index 9234db46a9..4562da7ba8 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/messages.properties +++ b/src/gui/org/deidentifier/arx/gui/resources/messages.properties @@ -1251,3 +1251,23 @@ ViewStatisticsClassificationInput.14=Confidence threshold [%] ViewStatisticsClassificationInput.15=Precision ViewStatisticsClassificationInput.16=Recall ViewStatisticsClassificationInput.17=Value [%] +RiskWizard.0=Checklist Wizard +RiskWizard.1=Answer the following questions +RiskWizard.2=Total +RiskWizard.3=Yes +RiskWizard.4=No +RiskWizard.5=N/A +RiskWizard.6=Edit +RiskWizard.7=Load +RiskWizard.8=Save +RiskWizard.9="Evaluation" +RiskWizard.10="Risk Evaluation" +RiskWizard.11="This is the risk evaluation based on your answers." +RiskWizard.12=Monitor +RiskWizard.13="Stacks" +RiskWizard.14=Last used +RiskWizard.15=Positive +RiskWizard.16=Neutral +RiskWizard.17=Negative +RiskWizard.18=Weighted Answers +RiskWizard.19=Visualization: \ No newline at end of file diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java index 5bacdcf791..b33b62aea8 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java @@ -1169,4 +1169,4 @@ public boolean isEnabled(Model model) { } }; } -} \ No newline at end of file +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java index 506d29d78e..4f3075685a 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java @@ -5,7 +5,7 @@ import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.*; - +import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question.*; @@ -14,12 +14,21 @@ * */ public class AnswerRadioGroup extends Composite { + private Button yesButton; private Button noButton; private Button n_aButton; + /** + * the question which will be updated, when the selected button changes + */ private Question item; - + + /** + * create a new answer radio group in the specified composite and targetItem + * @param parent + * @param targetItem + */ public AnswerRadioGroup(Composite parent, Question targetItem) { super(parent,SWT.NONE); this.item = targetItem; @@ -41,15 +50,15 @@ public void widgetSelected(SelectionEvent event) { }; yesButton = new Button(group, SWT.RADIO); - yesButton.setText("Yes"); + yesButton.setText(Resources.getMessage("RiskWizard.3")); yesButton.addSelectionListener(selectionListener); noButton = new Button(group, SWT.RADIO); - noButton.setText("No"); + noButton.setText(Resources.getMessage("RiskWizard.4")); noButton.addSelectionListener(selectionListener); n_aButton = new Button(group, SWT.RADIO); - n_aButton.setText("N/A"); + n_aButton.setText(Resources.getMessage("RiskWizard.5")); n_aButton.setSelection(true); n_aButton.addSelectionListener(selectionListener); } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java index 877f19a8b2..c98265124d 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java @@ -19,18 +19,49 @@ import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.WeightConfiguration; - +/** + * The ChecklistDialog is the dialog presented for the wizard + * @author Thomas Günzel + * + */ public class ChecklistDialog extends WizardDialog { - private Button weightButton; + + /** + * button to toggle the weight edit mode + */ + private Button weightEditButton; + + /** + * button to load a weight setting + */ private Button loadButton; + + /** + * button to save a weight setting + */ private Button saveButton; + + /** + * the used checklist + */ private Checklist checklist; + /** + * the arx controller + */ private Controller controller; + /** + * creates a new checklist dialog for a specified checklist + * @param checklist the checklist to use + * @param parentShell the parent for this dialog + * @param controller the arx controller + * @param newWizard the wizard + */ public ChecklistDialog(Checklist checklist, Shell parentShell, Controller controller, IWizard newWizard) { super(parentShell, newWizard); this.checklist = checklist; @@ -54,13 +85,13 @@ protected void createButtonsForButtonBar(Composite parent) { // add the settings button layout.numColumns++; - weightButton = new Button(parent, SWT.CHECK); - weightButton.setText("Edit"); + weightEditButton = new Button(parent, SWT.CHECK); + weightEditButton.setText(Resources.getMessage("RiskWizard.6")); final ChecklistDialog reference = this; loadButton = new Button(parent, SWT.PUSH); - loadButton.setText("Load"); + loadButton.setText(Resources.getMessage("RiskWizard.7")); loadButton.setVisible(false); loadButton.addSelectionListener(new SelectionAdapter() { @Override @@ -77,14 +108,14 @@ public void widgetSelected(SelectionEvent e) { layout.numColumns++; saveButton = new Button(parent, SWT.PUSH); - saveButton.setText("Save"); + saveButton.setText(Resources.getMessage("RiskWizard.8")); saveButton.setVisible(false); saveButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { FileDialog dialog = new FileDialog(saveButton.getShell(), SWT.SAVE); String name = checklist.getWeightConfiguration().getName(); - if(name == "Last used") { + if(name == Resources.getMessage("RiskWizard.14")) { name = "last_used.txt"; } dialog.setFileName(name); @@ -101,11 +132,11 @@ public void widgetSelected(SelectionEvent e) { Listener listener = new Listener() { public void handleEvent(Event event) { - reference.setWeightsEditable(weightButton.getSelection()); + reference.setWeightsEditable(weightEditButton.getSelection()); } }; - weightButton.addListener(SWT.Selection, listener); + weightEditButton.addListener(SWT.Selection, listener); // add a placeholder label that uses the empty space diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java index 6b49b88c11..9dc4b8f32d 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java @@ -2,14 +2,33 @@ import org.eclipse.jface.wizard.Wizard; import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.*; - +/** + * The checklist wizard for evaluating the data sharing risk + * + */ public class ChecklistWizard extends Wizard { - + + /** + * array containing each section's wizard page + */ protected SectionPage[] pages; + + /** + * final page showing the evaluation + */ protected EvaluationPage evaluationPage; + + /** + * the checklist used for the wizard + */ private Checklist checklist; + + /** + * the arx controller + */ private Controller controller; /** @@ -22,10 +41,12 @@ public ChecklistWizard(Checklist checklist, Controller controller) { this.checklist = checklist; this.controller = controller; - this.setWindowTitle("Checklist Wizard"); + this.setWindowTitle(Resources.getMessage("RiskWizard.0")); } - + /** + * adds the necessary pages to the wizard + */ @Override public void addPages() { // add a page for each section diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java index e5e1ccbc5c..05048d10be 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java @@ -3,34 +3,20 @@ import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.wizard.IWizard; import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Device; import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; -import org.swtchart.Chart; - -import java.awt.GridBagLayout; -import java.util.ArrayList; -import java.util.List; import org.deidentifier.arx.gui.Controller; -import org.deidentifier.arx.gui.view.SWTUtil; -import org.deidentifier.arx.gui.view.impl.common.ComponentRiskMonitor; - +import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.WeightConfiguration; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.MonitorVisualization; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.StackVisualization; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.Visualization; @@ -40,25 +26,40 @@ * */ public class EvaluationPage extends WizardPage { + /** + * the checklist + */ private Checklist checklist; private Label fileLabel; private Composite topBar; + /** + * the current visualization + */ private Visualization visualization; + private Composite rootComposite; private Controller controller; + /** + * create the evaluation page for the checklist + * @param checklist the checklist to use + * @param controller the arx controller + */ protected EvaluationPage(Checklist checklist, Controller controller) { - super("Evaluation"); + super(Resources.getMessage("RiskWizard.9")); this.checklist = checklist; this.controller = controller; - this.setTitle("Risk Evaluation"); - this.setDescription("This is the risk evaluation based on your answers."); + this.setTitle(Resources.getMessage("RiskWizard.10")); + this.setDescription(Resources.getMessage("RiskWizard.11")); } - + + /** + * creates the control and adds the visualization selection top bar + */ @Override public void createControl(Composite parent) { GridLayout layout = new GridLayout(); @@ -85,7 +86,12 @@ public void createControl(Composite parent) { setControl(rootComposite); } - + /** + * creates the top bar used for switching between visualizations + * @param parent the parent composite + * @param span the span to use for the bar + * @return + */ private Composite createTopBar(Composite parent, int span) { Composite c = new Composite(parent, SWT.NO_BACKGROUND); @@ -103,25 +109,27 @@ private Composite createTopBar(Composite parent, int span) { GridData weightData = new GridData(); weightData.grabExcessHorizontalSpace = true; weightLabel.setLayoutData(weightData); - weightLabel.setText("Visualization:"); + weightLabel.setText(Resources.getMessage("RiskWizard.19")); FontDescriptor boldDescriptor = FontDescriptor.createFrom(weightLabel.getFont()).setStyle(SWT.BOLD); Font boldFont = boldDescriptor.createFont(weightLabel.getDisplay()); weightLabel.setFont(boldFont); fileLabel = weightLabel; final Combo visualizationDropDown = new Combo(c, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); - visualizationDropDown.add("Monitor"); - visualizationDropDown.add("Stacks"); - visualizationDropDown.setText("Monitor"); + String monitorTitle = Resources.getMessage("RiskWizard.12"); + String stacksTitle = Resources.getMessage("RiskWizard.13"); + visualizationDropDown.add(monitorTitle); + visualizationDropDown.add(stacksTitle); + visualizationDropDown.setText(monitorTitle); visualizationDropDown.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { String selected = visualizationDropDown.getText(); - if(selected.equals("Stacks")) { - System.out.println("Select Stacks"); + if(selected.equals(stacksTitle)) { + //System.out.println("Select Stacks"); showStacksVisualization(); - } else if(selected.equals("Monitor")) { - System.out.println("Select Monitor"); + } else if(selected.equals(monitorTitle)) { + //System.out.println("Select Monitor"); showMonitorVisualization(); } } @@ -147,19 +155,31 @@ public void setVisible(boolean visible) { } } + /** + * update the current visualization when the weights change + */ protected void updateWeights() { visualization.updateWeights(); } - + /** + * change to monitor visualization + */ private void showMonitorVisualization() { setVisualization(new MonitorVisualization(rootComposite, controller, checklist)); } + /** + * change to stacks visualization + */ private void showStacksVisualization() { setVisualization(new StackVisualization(rootComposite, controller, checklist)); } + /** + * set the current visualization and update the UI + * @param visualization the visualization to change to + */ private void setVisualization(Visualization visualization) { removeVisualization(); this.visualization = visualization; @@ -167,8 +187,9 @@ private void setVisualization(Visualization visualization) { this.rootComposite.layout(); } - - + /** + * remove the current visualization from the UI + */ private void removeVisualization() { if(this.visualization != null) { this.visualization.dispose(); diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java index 807a4f7bc8..0576b6565f 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java @@ -7,23 +7,15 @@ import org.eclipse.jface.wizard.WizardPage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Spinner; -import org.eclipse.swt.widgets.Text; - +import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question.Answer; /** * each SectionPage shows all the questions from a checklist section @@ -35,16 +27,22 @@ public class SectionPage extends WizardPage { private boolean weightEditable; private List weightFields; - + /** + * create a new page for a section + * @param section the section of this page + */ public SectionPage(Section section) { super(section.getTitle()); this.weightEditable = false; this.section = section; this.setTitle(section.getTitle()); - this.setDescription("Answer the following questions"); + this.setDescription(Resources.getMessage("RiskWizard.1")); } + /** + * creates the control, by adding the questions inside a scroll view + */ @Override public void createControl(Composite parent) { final Composite rootComposite = new Composite(parent, SWT.NONE); @@ -90,6 +88,9 @@ public void handleEvent(org.eclipse.swt.widgets.Event e) { setControl(rootComposite); } + /** + * creates the interface for the individual items (questions) + */ private void createItems() { // add weight fields this.weightFields = new ArrayList(); @@ -125,6 +126,9 @@ private void createItems() { } } + /** + * enable or disable the weight edit mode + */ public void setWeightEditable(boolean editable) { if(editable == this.weightEditable) { return; @@ -137,6 +141,9 @@ public void setWeightEditable(boolean editable) { } } + /** + * update the weights (called when a new weight configuration is loaded) + */ protected void updateWeights() { if(this.weightFields == null) { return; diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java index 33b2ae3a91..6e458036d5 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java @@ -19,8 +19,11 @@ * */ public class WeightField { + /** + * the targeted item + */ private Item item; - private Text field; + private Combo dropdown; private boolean disableUpdateQuestion; @@ -28,6 +31,12 @@ public class WeightField { static final DecimalFormat df = new DecimalFormat("#.00"); + /** + * create a new weight field for an item (question or section) + * @param composite the composite + * @param item the item this field targets + * @param enabled whether this control is currently enabled + */ public WeightField(Composite composite, Item item, boolean enabled) { dropdown = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); dropdown.add("0.25"); @@ -50,7 +59,9 @@ public WeightField(Composite composite, Item item, boolean enabled) { } - + /** + * updates the text of the dropdown + */ public void updateText() { disableUpdateQuestion = true; double newWeight = item.getWeight(); @@ -71,24 +82,33 @@ public void updateText() { disableUpdateQuestion = false; } + /** + * updates the target item + */ protected void updateItem() { if(disableUpdateQuestion) { return; } try { - double value = df.parse(field.getText()).doubleValue(); + double value = df.parse(dropdown.getText()).doubleValue(); item.setWeight(value); } catch (ParseException e) { - e.printStackTrace(); + //e.printStackTrace(); } } - - + /** + * returns, whether the field is editable + * @return if field can be edited + */ public boolean isEnabled() { return enabled; } + /** + * change whether field can be edited + * @param enabled whether field can be edited + */ public void setEnabled(boolean enabled) { this.enabled = enabled; this.dropdown.setEnabled(enabled); diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java index 19c0c65bda..b19f124e97 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java @@ -13,14 +13,25 @@ * */ public class Checklist { + /** + * the array containing the sections of the checklist + */ private ArrayList
sections; + + /** + * the maximum achievable weight + */ private double maximumWeight = 0.0; + + /** + * the current weight configuration + */ protected WeightConfiguration weightConfiguration; - public Checklist() { - this("config/khaled_el_emam.txt"); - } - + /** + * create a checklist from a file + * @param filename the filename + */ public Checklist(String filename) { super(); weightConfiguration = new WeightConfiguration(); @@ -29,10 +40,14 @@ public Checklist(String filename) { BufferedReader bufferedReader = new BufferedReader(new FileReader(filename)); loadChecklist(bufferedReader); } catch(IOException e) { - e.printStackTrace(); + //e.printStackTrace(); } } + /** + * create a checklist from an input stream + * @param stream the input stream + */ public Checklist(InputStream stream) { super(); weightConfiguration = new WeightConfiguration(); @@ -41,6 +56,10 @@ public Checklist(InputStream stream) { loadChecklist(bufferedReader); } + /** + * loads the checklist using a buffered reader + * @param bufferedReader the buffered reader used to parse the file + */ private void loadChecklist(BufferedReader bufferedReader) { // create new and empty sections array sections = new ArrayList
(); @@ -65,7 +84,7 @@ private void loadChecklist(BufferedReader bufferedReader) { } else { // current line is an item if(currentSection == null) { - System.out.println("Invalid syntax. Checklist item before section (section-lines start with #)"); + //System.out.println("Invalid syntax. Checklist item before section (section-lines start with #)"); } // parse and add item @@ -85,23 +104,35 @@ private void loadChecklist(BufferedReader bufferedReader) { try { bufferedReader.close(); } catch (IOException e) { - e.printStackTrace(); + //e.printStackTrace(); } } } } + /** + * get all sections + * @return the sections + */ public Section[] getSections() { return (sections.toArray(new Section[sections.size()])); } + /** + * get the maximum weight + * @return the maximum weight + */ public double getMaximumWeight() { return maximumWeight; } + /** + * get the current score of the complete checklist + * @return the score + */ public double getScore() { if(maximumWeight == 0.0) { - System.out.println("This Checklist has a maximum weight of 0.0, it can't calculate a score: "+this); + //System.out.println("This Checklist has a maximum weight of 0.0, it can't calculate a score: "+this); return 0.0; } double result = 0.0; @@ -117,14 +148,25 @@ public String toString() { return "Checklist [score="+this.getScore()+", sections=" + sections + "\n]"; } + /** + * saves the current weights to the last used filename + */ public void saveWeightDefaults() { this.weightConfiguration.saveLastUsed(); } + /** + * gets the current weight configuration + * @return the weight configuration + */ public WeightConfiguration getWeightConfiguration() { return this.weightConfiguration; } + /** + * sets the weight configuration and updates the values + * @param weightConfiguration the weight configuration + */ public void setWeightConfiguration(WeightConfiguration weightConfiguration) { if(this.weightConfiguration == weightConfiguration) { return; diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java index 56c89adbe7..5d0f2f6419 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java @@ -5,14 +5,29 @@ * */ public abstract class Item { + /** + * the current weight configuration + */ private WeightConfiguration weightConfiguration; + + /** + * the identifier (used for the weight configuration) + */ protected String identifier; + + /** + * the item's title + */ protected String title; - + + /** + * create a new item from a line + * @param line the line to parse + */ public Item(String line) { String components[] = line.split(":",2); if(components.length != 2) { - System.err.println("Couldn't parse item! Original line: "+line); + //System.err.println("Couldn't parse item! Original line: "+line); return; } this.identifier = components[0].trim(); @@ -23,15 +38,26 @@ protected WeightConfiguration getWeightConfiguration() { return this.weightConfiguration; } + /** + * set weight configuration and update weights + * @param weightConfiguration + */ public void setWeightConfiguration(WeightConfiguration weightConfiguration) { this.weightConfiguration = weightConfiguration; updateWeights(); } + /** + * update the weights, used by subclasses to calculate the new score accordingly + */ public void updateWeights() { } + /** + * gets the current weight for this item according to the current weight configuration + * @return + */ public double getWeight() { if(weightConfiguration == null) { return 1.0; @@ -39,6 +65,10 @@ public double getWeight() { return weightConfiguration.weightForIdentifier(this.getIdentifier()); } + /** + * updates the weight configurations weight for this item + * @param weight the new weight for this item + */ public void setWeight(double weight) { weightConfiguration.setWeightForIdentifier(this.getIdentifier(), weight); } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java index 9bae248d89..bd8b8b1af4 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java @@ -1,21 +1,41 @@ package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; +import org.deidentifier.arx.gui.resources.Resources; + /** * represents a single question from the checklist * */ public class Question extends Item { + /** + * the section this question is in + */ private Section section; + public enum Answer { YES, NO, N_A } + /** + * the current answer + */ public Answer answer; - + + /** + * creates a new question in a section, from a line + * @param section the section this question is in + * @param line the line to parse + */ public Question(Section section, String line) { super(line); this.section = section; this.answer = Answer.N_A; } + /** + * creates a new question from a line, in a section + * @param section the section this question is in + * @param line the line to parse + * @return the question item + */ public static Question itemFromLine(Section section, String line) { line = line.trim(); Question item = new Question(section, line); @@ -26,17 +46,25 @@ public String getIdentifier() { return section.getIdentifier()+"."+identifier; } + /** + * get the current answer as a string + * @return the string + */ public String getAnswerString() { switch(answer) { case YES: - return "YES"; + return Resources.getMessage("RiskWizard.3"); case NO: - return "NO"; + return Resources.getMessage("RiskWizard.4"); default: - return "N/A"; + return Resources.getMessage("RiskWizard.5"); } } + /** + * returns the question's score using the weight and taking the answer into account + * @return the score + */ public double getScore() { switch(answer) { case YES: diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java index 856b9f2b4d..ec2b02c956 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java @@ -7,32 +7,60 @@ * */ public class Section extends Item { + /** + * the items this section contains + */ private ArrayList items; - private double maximumWeight = 0.0; + /** + * the maximum weight possible + */ + private double maximumWeight = 0.0; + /** + * create a new section from a line + * @param weightConfiguration the current weight configuration + * @param line the line to parse + */ public Section(WeightConfiguration weightConfiguration, String line) { super(line); this.items = new ArrayList(); setWeightConfiguration(weightConfiguration); } - + + /** + * create a new section from a line + * @param weightConfiguration the current weight configuration + * @param line the line to parse + * @return the section item + */ public static Section sectionFromLine(WeightConfiguration weightConfiguration, String line) { line = line.trim(); Section section = new Section(weightConfiguration, line); return section; } + /** + * get all questions in this section + * @return + */ public Question[] getItems() { return items.toArray(new Question[items.size()]); } + /** + * add a question to the section and updates the maximumWeight + * @param item the question to add + */ public void addItem(Question item) { item.setWeightConfiguration(this.getWeightConfiguration()); items.add(item); maximumWeight += Math.abs(item.getWeight()); } + /** + * updates the weights and calculates the maximum weight + */ public void updateWeights() { super.updateWeights(); @@ -47,9 +75,13 @@ public double getMaximumWeight() { return maximumWeight; } + /** + * calculates the score based on the section's question's scores + * @return + */ public double getScore() { if(maximumWeight == 0.0) { - System.out.println("This Section has a maximum weight of 0.0, it can't calculate a score: "+this); + //System.out.println("This Section has a maximum weight of 0.0, it can't calculate a score: "+this); return 0.0; } double result = 0.0; diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java index f72ff7e484..bb4194a61f 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java @@ -9,6 +9,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; + +import org.deidentifier.arx.gui.resources.Resources; + import java.util.Properties; /** @@ -16,17 +19,38 @@ * */ public class WeightConfiguration { + /** + * the current configurations filename + */ private String filename; + + /** + * the current configurations name (last path component) + */ private String name; + + /** + * a map, mapping the item identifiers to a weight + */ private Map weights; + /** + * path to the last used configuration file + */ private static final String lastUsedPath = "config/weights/last_used.txt"; + /** + * create a new configuration, preferably the previously used one + */ public WeightConfiguration() { this(lastUsedPath); - this.name = "Last used"; + this.name = Resources.getMessage("RiskWizard.14"); } + /** + * create a new configuration from a file + * @param filename the file's filename + */ public WeightConfiguration(String filename) { this.filename = filename; weights = new HashMap(); @@ -36,11 +60,19 @@ public WeightConfiguration(String filename) { } + /** + * update the name, based on the filename's path filename + */ private void updateName() { Path p = Paths.get(filename); this.name = p.getFileName().toString(); } + /** + * get the weight for an item's identifier + * @param identifier the identifier + * @return the weight + */ public double weightForIdentifier(String identifier) { if(weights.containsKey(identifier) == false) { return 1.0; @@ -48,11 +80,18 @@ public double weightForIdentifier(String identifier) { return weights.get(identifier); } + /** + * sets the weight for an item's identifier + * @param identifier the item identifier to change + * @param weight the weight to set + */ public void setWeightForIdentifier(String identifier, double weight) { weights.put(identifier, weight); } - + /** + * try to load the weights from the specified filename + */ private void loadProperties() { Properties props = new Properties(); try { @@ -68,10 +107,10 @@ private void loadProperties() { } in.close(); } catch (FileNotFoundException e) { - System.err.println("Couldn't open file: "+filename); + //System.err.println("Couldn't open file: "+filename); return; } catch (IOException e) { - System.err.println("Couldn't parse file: "+filename); + //System.err.println("Couldn't parse file: "+filename); return; } @@ -81,20 +120,27 @@ public String getName() { return this.name; } - + /** + * tries to save the weight configuration to the lastUsedPath + */ public void saveLastUsed() { save(lastUsedPath); } - + /** + * save the configuration to the current filename + */ public void save() { save(this.filename); } - + /** + * save the configuration to a new filename + * @param filename the filename to save to + */ public void save(String filename) { if(filename == null) { - System.out.println("No file specified to save to"); + //System.out.println("No file specified to save to"); return; } @@ -109,10 +155,10 @@ public void save(String filename) { props.store(out, null); out.close(); } catch (FileNotFoundException e) { - System.err.println("Couldn't open file: "+filename); + //System.err.println("Couldn't open file: "+filename); return; } catch (IOException e) { - System.err.println("Couldn't store file: "+filename); + //System.err.println("Couldn't store file: "+filename); return; } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java index 9ff61f8ca5..3ff1cd0853 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java @@ -4,6 +4,7 @@ import java.util.List; import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.SWTUtil; import org.deidentifier.arx.gui.view.impl.common.ComponentRiskMonitor; import org.eclipse.swt.SWT; @@ -18,13 +19,29 @@ * */ public class MonitorVisualization extends Visualization { + /** + * contains the monitors for each section + */ private List monitors; + + /** + * the total monitor, showing the overall score + */ private ComponentRiskMonitor totalMonitor; + /** + * create a new monitor visualization + * @param parent the parent + * @param controller the controller + * @param checklist the checklist to use + */ public MonitorVisualization(Composite parent, Controller controller, Checklist checklist) { super(parent, controller, checklist); } + /** + * creates the view containing the different monitors + */ protected void createVisualization() { Section sections[] = this.checklist.getSections(); monitors = new ArrayList(); @@ -47,7 +64,8 @@ protected void createVisualization() { monitors.add(riskMonitor); } - totalMonitor = new ComponentRiskMonitor(this, this.controller, "Total", "Total"); + String totalTitle = Resources.getMessage("RiskWizard.2"); + totalMonitor = new ComponentRiskMonitor(this, this.controller, totalTitle, totalTitle); totalMonitor.setLayoutData(SWTUtil.createFillGridData()); totalMonitor.setRisk(0.5); @@ -60,6 +78,9 @@ protected void createVisualization() { totalMonitor.setLayoutData(gridData); } + /** + * update the UI when the weights change + */ public void updateWeights() { Section sections[] = checklist.getSections(); for(int i = 0; i < sections.length; i++) { diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java index 1822073cda..70f9f563f4 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java @@ -6,6 +6,7 @@ import org.swtchart.*; import org.swtchart.ISeries.*; import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; @@ -15,15 +16,40 @@ * */ public class StackVisualization extends Visualization { + /** + * the displayed chart + */ private Chart chart; + + /** + * the bar series for the positive values + */ private IBarSeries positive; + + /** + * the bar series for the neutral values + */ private IBarSeries neutral; + + /** + * the bar series for the negative values + */ private IBarSeries negative; + + /** + * create a new stack visualization + * @param parent the parent + * @param controller the controller + * @param checklist the checklist + */ public StackVisualization(Composite parent, Controller controller, Checklist checklist) { super(parent, controller, checklist); } + /** + * creates the view containing the stack bar graph visualization + */ protected void createVisualization() { Section sections[] = this.checklist.getSections(); String sectionNames[] = new String[sections.length]; @@ -37,7 +63,7 @@ protected void createVisualization() { fillLayout.type = SWT.VERTICAL; this.setLayout(fillLayout); chart = new Chart(this, SWT.NONE); - chart.getTitle().setText("Weighted Answers"); + chart.getTitle().setText(Resources.getMessage("RiskWizard.18")); double[] positiveSeries = { 0.1, 0, 0}; double[] neutralSeries = { 0.1, 0, 0}; @@ -45,17 +71,17 @@ protected void createVisualization() { ISeriesSet seriesSet = chart.getSeriesSet(); - positive = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, "Positive"); + positive = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, Resources.getMessage("RiskWizard.15")); positive.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_GREEN)); positive.enableStack(true); positive.setYSeries(positiveSeries); - neutral = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, "Neutral"); + neutral = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, Resources.getMessage("RiskWizard.16")); neutral.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_GRAY)); neutral.enableStack(true); neutral.setYSeries(neutralSeries); - negative = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, "Negative"); + negative = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, Resources.getMessage("RiskWizard.17")); negative.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_RED)); negative.enableStack(true); negative.setYSeries(negativeSeries); @@ -73,6 +99,9 @@ protected void createVisualization() { xAxis.getTitle().setVisible(false); } + /** + * updates the UI when the weights/score changes + */ public void updateWeights() { Section sections[] = this.checklist.getSections(); double[] posY = new double[sections.length]; diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java index 86fd5e36b9..b6bcbd13dd 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java @@ -11,9 +11,19 @@ * */ public abstract class Visualization extends Composite { + /** + * the checklist used for the visualization + */ protected Checklist checklist; + protected Controller controller; + /** + * create a new visualization for the checklist + * @param parent the parent + * @param controller the controller + * @param checklist the checklist + */ public Visualization(Composite parent, Controller controller, Checklist checklist) { super(parent, SWT.NO_SCROLL); @@ -29,10 +39,16 @@ public Visualization(Composite parent, Controller controller, Checklist checklis this.createVisualization(); } + /** + * used in subclasses for the initial setup + */ protected void createVisualization() { } + /** + * used in subclasses to respond to changes + */ public void updateWeights() { } From c9c21b4b6f4c8bf707c89984fd006967397610c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Wed, 1 Feb 2017 22:52:46 +0100 Subject: [PATCH 10/22] fix typos in message.properties --- .../deidentifier/arx/gui/resources/messages.properties | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/org/deidentifier/arx/gui/resources/messages.properties b/src/gui/org/deidentifier/arx/gui/resources/messages.properties index 4562da7ba8..758bab3a79 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/messages.properties +++ b/src/gui/org/deidentifier/arx/gui/resources/messages.properties @@ -1260,11 +1260,11 @@ RiskWizard.5=N/A RiskWizard.6=Edit RiskWizard.7=Load RiskWizard.8=Save -RiskWizard.9="Evaluation" -RiskWizard.10="Risk Evaluation" -RiskWizard.11="This is the risk evaluation based on your answers." +RiskWizard.9=Evaluation +RiskWizard.10=Risk Evaluation +RiskWizard.11=This is the risk evaluation based on your answers. RiskWizard.12=Monitor -RiskWizard.13="Stacks" +RiskWizard.13=Stacks RiskWizard.14=Last used RiskWizard.15=Positive RiskWizard.16=Neutral From aab5a77270e52731800c577fd35e0beee9fbca99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Thu, 2 Feb 2017 02:59:27 +0100 Subject: [PATCH 11/22] persist risk wizard config in model --- .../org/deidentifier/arx/gui/model/Model.java | 21 ++++++ .../ModelRiskWizard.java} | 66 ++++--------------- .../wizard/sharingwizard/ChecklistDialog.java | 12 ++-- .../wizard/sharingwizard/ChecklistWizard.java | 13 +++- .../wizard/sharingwizard/WeightField.java | 10 +++ .../sharingwizard/checklist/Checklist.java | 19 ++---- .../wizard/sharingwizard/checklist/Item.java | 8 ++- .../sharingwizard/checklist/Section.java | 8 ++- 8 files changed, 76 insertions(+), 81 deletions(-) rename src/gui/org/deidentifier/arx/gui/{view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java => model/ModelRiskWizard.java} (69%) diff --git a/src/gui/org/deidentifier/arx/gui/model/Model.java b/src/gui/org/deidentifier/arx/gui/model/Model.java index fd21095812..9503efb4e8 100644 --- a/src/gui/org/deidentifier/arx/gui/model/Model.java +++ b/src/gui/org/deidentifier/arx/gui/model/Model.java @@ -262,6 +262,11 @@ public static enum Perspective { /** Selected quasi identifiers*/ private Set selectedQuasiIdentifiers = null; + /* ***************************************** + * RISK WIZARD + ******************************************/ + /** Current configuration for the risk wizard */ + private ModelRiskWizard riskWizardModel = null; /* ***************************************** * LOCAL RECODING @@ -1045,6 +1050,14 @@ public Set getSelectedQuasiIdentifiers() { } return this.selectedQuasiIdentifiers; } + + /** + * Returns the risk wizard configuration + * @return + */ + public ModelRiskWizard getRiskWizardModel() { + return riskWizardModel; + } /** * Returns the separator. @@ -1539,6 +1552,14 @@ public void setSelectedQuasiIdentifiers(Set set) { } /** + * Sets the current risk wizard configuration + * @param riskWizardModel + */ + public void setRiskWizardModel(ModelRiskWizard riskWizardModel) { + this.riskWizardModel = riskWizardModel; + } + + /** * * * @param snapshotSize diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java b/src/gui/org/deidentifier/arx/gui/model/ModelRiskWizard.java similarity index 69% rename from src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java rename to src/gui/org/deidentifier/arx/gui/model/ModelRiskWizard.java index bb4194a61f..6468251313 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/WeightConfiguration.java +++ b/src/gui/org/deidentifier/arx/gui/model/ModelRiskWizard.java @@ -1,9 +1,10 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; +package org.deidentifier.arx.gui.model; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.Serializable; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; @@ -18,54 +19,31 @@ * the weight configuration used when evaluating the checklist * */ -public class WeightConfiguration { +public class ModelRiskWizard implements Serializable { /** - * the current configurations filename + * the current serialization version */ - private String filename; - - /** - * the current configurations name (last path component) - */ - private String name; + private static final long serialVersionUID = 1L; /** * a map, mapping the item identifiers to a weight */ private Map weights; - /** - * path to the last used configuration file - */ - private static final String lastUsedPath = "config/weights/last_used.txt"; - /** * create a new configuration, preferably the previously used one */ - public WeightConfiguration() { - this(lastUsedPath); - this.name = Resources.getMessage("RiskWizard.14"); + public ModelRiskWizard() { + weights = new HashMap(); } /** * create a new configuration from a file * @param filename the file's filename */ - public WeightConfiguration(String filename) { - this.filename = filename; - weights = new HashMap(); - loadProperties(); - - updateName(); - - } - - /** - * update the name, based on the filename's path filename - */ - private void updateName() { - Path p = Paths.get(filename); - this.name = p.getFileName().toString(); + public ModelRiskWizard(String filename) { + this(); + loadProperties(filename); } /** @@ -91,8 +69,9 @@ public void setWeightForIdentifier(String identifier, double weight) { /** * try to load the weights from the specified filename + * @param filename the filename */ - private void loadProperties() { + private void loadProperties(String filename) { Properties props = new Properties(); try { FileInputStream in = new FileInputStream(filename); @@ -116,24 +95,6 @@ private void loadProperties() { } - public String getName() { - return this.name; - } - - /** - * tries to save the weight configuration to the lastUsedPath - */ - public void saveLastUsed() { - save(lastUsedPath); - } - - /** - * save the configuration to the current filename - */ - public void save() { - save(this.filename); - } - /** * save the configuration to a new filename * @param filename the filename to save to @@ -161,9 +122,6 @@ public void save(String filename) { //System.err.println("Couldn't store file: "+filename); return; } - - this.filename = filename; - updateName(); } } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java index c98265124d..959ef71799 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java @@ -19,9 +19,9 @@ import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.model.ModelRiskWizard; import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.WeightConfiguration; /** * The ChecklistDialog is the dialog presented for the wizard @@ -114,16 +114,12 @@ public void widgetSelected(SelectionEvent e) { @Override public void widgetSelected(SelectionEvent e) { FileDialog dialog = new FileDialog(saveButton.getShell(), SWT.SAVE); - String name = checklist.getWeightConfiguration().getName(); - if(name == Resources.getMessage("RiskWizard.14")) { - name = "last_used.txt"; - } - dialog.setFileName(name); + dialog.setFileName("weights.txt"); dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); dialog.setFilterPath("config/weights"); String result = dialog.open(); if(result != null) { - WeightConfiguration wc = checklist.getWeightConfiguration(); + ModelRiskWizard wc = checklist.getWeightConfiguration(); wc.save(result); } } @@ -172,7 +168,7 @@ protected void setWeightsEditable(boolean weightsEditable) { * @param result the weight configuration to load */ protected void updateWeightConfig(String result) { - checklist.setWeightConfiguration(new WeightConfiguration(result)); + checklist.setWeightConfiguration(new ModelRiskWizard(result)); IWizard wizard = this.getWizard(); if(wizard instanceof ChecklistWizard) { ChecklistWizard casted = (ChecklistWizard)wizard; diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java index 9dc4b8f32d..4fc75be3f5 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java @@ -2,6 +2,8 @@ import org.eclipse.jface.wizard.Wizard; import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.model.Model; +import org.deidentifier.arx.gui.model.ModelRiskWizard; import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.*; @@ -40,6 +42,15 @@ public ChecklistWizard(Checklist checklist, Controller controller) { super(); this.checklist = checklist; + // try to restore a saved version of the weights + Model model = controller.getModel(); + if(model != null) { + ModelRiskWizard savedModel = model.getRiskWizardModel(); + if(savedModel != null) { + System.out.println(savedModel); + this.checklist.setWeightConfiguration(savedModel); + } + } this.controller = controller; this.setWindowTitle(Resources.getMessage("RiskWizard.0")); } @@ -72,7 +83,7 @@ public boolean performFinish() { // Print the result to the console //this.pages = null; //return false; - checklist.saveWeightDefaults(); + this.controller.getModel().setRiskWizardModel(this.checklist.getWeightConfiguration()); //System.out.println(checklist); return true; } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java index 6e458036d5..58c18787e0 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java @@ -47,6 +47,16 @@ public WeightField(Composite composite, Item item, boolean enabled) { dropdown.add("3.00"); dropdown.add("5.00"); + WeightField reference = this; + + ModifyListener modifyListener = new ModifyListener() { + public void modifyText(ModifyEvent e) { + reference.updateItem(); + } + }; + + dropdown.addModifyListener(modifyListener); + this.item = item; this.setEnabled(enabled); diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java index b19f124e97..27d32fff33 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java @@ -8,6 +8,8 @@ import java.io.InputStreamReader; import java.util.ArrayList; +import org.deidentifier.arx.gui.model.ModelRiskWizard; + /** * the Checklist holds the sections and calculates the overall score * @@ -26,7 +28,7 @@ public class Checklist { /** * the current weight configuration */ - protected WeightConfiguration weightConfiguration; + protected ModelRiskWizard weightConfiguration; /** * create a checklist from a file @@ -34,7 +36,7 @@ public class Checklist { */ public Checklist(String filename) { super(); - weightConfiguration = new WeightConfiguration(); + weightConfiguration = new ModelRiskWizard(); try { // initialize reader BufferedReader bufferedReader = new BufferedReader(new FileReader(filename)); @@ -50,7 +52,7 @@ public Checklist(String filename) { */ public Checklist(InputStream stream) { super(); - weightConfiguration = new WeightConfiguration(); + weightConfiguration = new ModelRiskWizard(); // initialize reader BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); loadChecklist(bufferedReader); @@ -148,18 +150,11 @@ public String toString() { return "Checklist [score="+this.getScore()+", sections=" + sections + "\n]"; } - /** - * saves the current weights to the last used filename - */ - public void saveWeightDefaults() { - this.weightConfiguration.saveLastUsed(); - } - /** * gets the current weight configuration * @return the weight configuration */ - public WeightConfiguration getWeightConfiguration() { + public ModelRiskWizard getWeightConfiguration() { return this.weightConfiguration; } @@ -167,7 +162,7 @@ public WeightConfiguration getWeightConfiguration() { * sets the weight configuration and updates the values * @param weightConfiguration the weight configuration */ - public void setWeightConfiguration(WeightConfiguration weightConfiguration) { + public void setWeightConfiguration(ModelRiskWizard weightConfiguration) { if(this.weightConfiguration == weightConfiguration) { return; } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java index 5d0f2f6419..e4240d4289 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java @@ -1,5 +1,7 @@ package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; +import org.deidentifier.arx.gui.model.ModelRiskWizard; + /** * this is the base class for the Question as well as the Section. * @@ -8,7 +10,7 @@ public abstract class Item { /** * the current weight configuration */ - private WeightConfiguration weightConfiguration; + private ModelRiskWizard weightConfiguration; /** * the identifier (used for the weight configuration) @@ -34,7 +36,7 @@ public Item(String line) { this.title = components[1].trim(); } - protected WeightConfiguration getWeightConfiguration() { + protected ModelRiskWizard getWeightConfiguration() { return this.weightConfiguration; } @@ -42,7 +44,7 @@ protected WeightConfiguration getWeightConfiguration() { * set weight configuration and update weights * @param weightConfiguration */ - public void setWeightConfiguration(WeightConfiguration weightConfiguration) { + public void setWeightConfiguration(ModelRiskWizard weightConfiguration) { this.weightConfiguration = weightConfiguration; updateWeights(); } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java index ec2b02c956..119a823ff1 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java @@ -2,6 +2,8 @@ import java.util.ArrayList; +import org.deidentifier.arx.gui.model.ModelRiskWizard; + /** * represents a section from the checklist * @@ -22,7 +24,7 @@ public class Section extends Item { * @param weightConfiguration the current weight configuration * @param line the line to parse */ - public Section(WeightConfiguration weightConfiguration, String line) { + public Section(ModelRiskWizard weightConfiguration, String line) { super(line); this.items = new ArrayList(); setWeightConfiguration(weightConfiguration); @@ -34,7 +36,7 @@ public Section(WeightConfiguration weightConfiguration, String line) { * @param line the line to parse * @return the section item */ - public static Section sectionFromLine(WeightConfiguration weightConfiguration, String line) { + public static Section sectionFromLine(ModelRiskWizard weightConfiguration, String line) { line = line.trim(); Section section = new Section(weightConfiguration, line); return section; @@ -98,7 +100,7 @@ public double getScore() { @Override public String toString() { - return "\n\tSection [id=" + this.getIdentifier() + ", title=" + this.getTitle() + ", weight=" + this.getWeight() + ", score="+ this.getScore() +", items=" + items + ", config="+this.getWeightConfiguration().getName()+"\n\t]"; + return "\n\tSection [id=" + this.getIdentifier() + ", title=" + this.getTitle() + ", weight=" + this.getWeight() + ", score="+ this.getScore() +", items=" + items + ", config="+this.getWeightConfiguration()+"\n\t]"; } } From 9806971eb60052364d46ccf907e6a3aa30fa4999 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Thu, 2 Feb 2017 03:03:24 +0100 Subject: [PATCH 12/22] remove debug log --- .../arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java index 4fc75be3f5..eb5b7d74d2 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java @@ -47,7 +47,6 @@ public ChecklistWizard(Checklist checklist, Controller controller) { if(model != null) { ModelRiskWizard savedModel = model.getRiskWizardModel(); if(savedModel != null) { - System.out.println(savedModel); this.checklist.setWeightConfiguration(savedModel); } } From 134419ab5aa8334d5a5849bd4fdbe5db6d067953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Gu=CC=88nzel?= Date: Thu, 2 Feb 2017 03:03:55 +0100 Subject: [PATCH 13/22] =?UTF-8?q?remove=20=E2=80=9Clast=20used=E2=80=9D=20?= =?UTF-8?q?from=20messages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gui/org/deidentifier/arx/gui/resources/messages.properties | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/org/deidentifier/arx/gui/resources/messages.properties b/src/gui/org/deidentifier/arx/gui/resources/messages.properties index 758bab3a79..32ac19f9db 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/messages.properties +++ b/src/gui/org/deidentifier/arx/gui/resources/messages.properties @@ -1265,7 +1265,6 @@ RiskWizard.10=Risk Evaluation RiskWizard.11=This is the risk evaluation based on your answers. RiskWizard.12=Monitor RiskWizard.13=Stacks -RiskWizard.14=Last used RiskWizard.15=Positive RiskWizard.16=Neutral RiskWizard.17=Negative From 85ec1d098df32bd16fd228624b2546795ea8fe9e Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Thu, 2 Feb 2017 19:27:26 +0100 Subject: [PATCH 14/22] Initial rework of the code implementing the questionnaire --- .../org/deidentifier/arx/gui/model/Model.java | 7 +- .../arx/gui/model/ModelRiskWizard.java | 127 ----------- .../arx/gui/resources/default_checklist.txt | 4 +- .../arx/gui/view/impl/MainWindow.java | 10 +- .../arx/gui/view/impl/wizard/RiskWizard.java | 108 +++++++++ .../wizard/RiskWizardComponentAnswer.java | 88 ++++++++ .../wizard/RiskWizardComponentWeight.java | 145 ++++++++++++ .../wizard/RiskWizardDialogChecklist.java | 209 ++++++++++++++++++ .../impl/wizard/RiskWizardPageEvaluation.java | 208 +++++++++++++++++ .../impl/wizard/RiskWizardPageSection.java | 180 +++++++++++++++ .../impl/wizard/RiskWizardVisualization.java | 73 ++++++ .../RiskWizardVisualizationMonitor.java | 120 ++++++++++ .../wizard/RiskWizardVisualizationStack.java | 166 ++++++++++++++ .../sharingwizard/AnswerRadioGroup.java | 66 ------ .../wizard/sharingwizard/ChecklistDialog.java | 200 ----------------- .../wizard/sharingwizard/ChecklistWizard.java | 100 --------- .../wizard/sharingwizard/EvaluationPage.java | 200 ----------------- .../wizard/sharingwizard/SectionPage.java | 155 ------------- .../wizard/sharingwizard/WeightField.java | 127 ----------- .../sharingwizard/checklist/Checklist.java | 179 --------------- .../wizard/sharingwizard/checklist/Item.java | 86 ------- .../sharingwizard/checklist/Question.java | 83 ------- .../sharingwizard/checklist/Section.java | 106 --------- .../evaluation/MonitorVisualization.java | 97 -------- .../evaluation/StackVisualization.java | 153 ------------- .../evaluation/Visualization.java | 56 ----- .../arx/risk/RiskQuestionnaire.java | 199 +++++++++++++++++ .../arx/risk/RiskQuestionnaireItem.java | 108 +++++++++ .../arx/risk/RiskQuestionnaireQuestion.java | 115 ++++++++++ .../arx/risk/RiskQuestionnaireSection.java | 134 +++++++++++ .../arx/risk/RiskQuestionnaireWeights.java | 138 ++++++++++++ 31 files changed, 2002 insertions(+), 1745 deletions(-) delete mode 100644 src/gui/org/deidentifier/arx/gui/model/ModelRiskWizard.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizard.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardComponentAnswer.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardComponentWeight.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialogChecklist.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardPageEvaluation.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardPageSection.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualization.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationMonitor.java create mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationStack.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java delete mode 100644 src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java create mode 100644 src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java create mode 100644 src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java create mode 100644 src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java create mode 100644 src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java create mode 100644 src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java diff --git a/src/gui/org/deidentifier/arx/gui/model/Model.java b/src/gui/org/deidentifier/arx/gui/model/Model.java index f2d7e2da29..2c7d96b13c 100644 --- a/src/gui/org/deidentifier/arx/gui/model/Model.java +++ b/src/gui/org/deidentifier/arx/gui/model/Model.java @@ -46,6 +46,7 @@ import org.deidentifier.arx.io.CSVSyntax; import org.deidentifier.arx.metric.MetricConfiguration; import org.deidentifier.arx.metric.MetricDescription; +import org.deidentifier.arx.risk.RiskQuestionnaireWeights; /** * This class implements a large portion of the model used by the GUI. @@ -266,7 +267,7 @@ public static enum Perspective { * RISK WIZARD ******************************************/ /** Current configuration for the risk wizard */ - private ModelRiskWizard riskWizardModel = null; + private RiskQuestionnaireWeights riskWizardModel = null; /* ***************************************** * LOCAL RECODING @@ -1054,7 +1055,7 @@ public Set getSelectedQuasiIdentifiers() { * Returns the risk wizard configuration * @return */ - public ModelRiskWizard getRiskWizardModel() { + public RiskQuestionnaireWeights getRiskWizardModel() { return riskWizardModel; } @@ -1554,7 +1555,7 @@ public void setSelectedQuasiIdentifiers(Set set) { * Sets the current risk wizard configuration * @param riskWizardModel */ - public void setRiskWizardModel(ModelRiskWizard riskWizardModel) { + public void setRiskWizardModel(RiskQuestionnaireWeights riskWizardModel) { this.riskWizardModel = riskWizardModel; } diff --git a/src/gui/org/deidentifier/arx/gui/model/ModelRiskWizard.java b/src/gui/org/deidentifier/arx/gui/model/ModelRiskWizard.java deleted file mode 100644 index 6468251313..0000000000 --- a/src/gui/org/deidentifier/arx/gui/model/ModelRiskWizard.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.deidentifier.arx.gui.model; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.Serializable; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.Map; -import java.util.Map.Entry; - -import org.deidentifier.arx.gui.resources.Resources; - -import java.util.Properties; - -/** - * the weight configuration used when evaluating the checklist - * - */ -public class ModelRiskWizard implements Serializable { - /** - * the current serialization version - */ - private static final long serialVersionUID = 1L; - - /** - * a map, mapping the item identifiers to a weight - */ - private Map weights; - - /** - * create a new configuration, preferably the previously used one - */ - public ModelRiskWizard() { - weights = new HashMap(); - } - - /** - * create a new configuration from a file - * @param filename the file's filename - */ - public ModelRiskWizard(String filename) { - this(); - loadProperties(filename); - } - - /** - * get the weight for an item's identifier - * @param identifier the identifier - * @return the weight - */ - public double weightForIdentifier(String identifier) { - if(weights.containsKey(identifier) == false) { - return 1.0; - } - return weights.get(identifier); - } - - /** - * sets the weight for an item's identifier - * @param identifier the item identifier to change - * @param weight the weight to set - */ - public void setWeightForIdentifier(String identifier, double weight) { - weights.put(identifier, weight); - } - - /** - * try to load the weights from the specified filename - * @param filename the filename - */ - private void loadProperties(String filename) { - Properties props = new Properties(); - try { - FileInputStream in = new FileInputStream(filename); - props.load(in); - - for(Entry entry : props.entrySet()) { - String key = (String) entry.getKey(); - String value = (String) entry.getValue(); - - double weight = Double.parseDouble(value); - weights.put(key, weight); - } - in.close(); - } catch (FileNotFoundException e) { - //System.err.println("Couldn't open file: "+filename); - return; - } catch (IOException e) { - //System.err.println("Couldn't parse file: "+filename); - return; - } - - } - - /** - * save the configuration to a new filename - * @param filename the filename to save to - */ - public void save(String filename) { - if(filename == null) { - //System.out.println("No file specified to save to"); - return; - } - - Properties props = new Properties(); - for(Entry entry: weights.entrySet()) { - props.setProperty(entry.getKey(), Double.toString(entry.getValue())); - } - - FileOutputStream out; - try { - out = new FileOutputStream(filename); - props.store(out, null); - out.close(); - } catch (FileNotFoundException e) { - //System.err.println("Couldn't open file: "+filename); - return; - } catch (IOException e) { - //System.err.println("Couldn't store file: "+filename); - return; - } - } - -} diff --git a/src/gui/org/deidentifier/arx/gui/resources/default_checklist.txt b/src/gui/org/deidentifier/arx/gui/resources/default_checklist.txt index baa09a09e8..a13247bcb8 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/default_checklist.txt +++ b/src/gui/org/deidentifier/arx/gui/resources/default_checklist.txt @@ -1,6 +1,6 @@ #mitigating: Mitigating Controls sharing-forbids: The data sharing agreement forbids the recipient from disclosing the database to third parties - sharing-enforceable: The data sharing agreement is enforceable in all jurisdictions where the recipient will use the data + sharing-enforceable: The data sharing agreement is enforceable in all jurisdictions where the recipient will use the data sharing-audits: The data sharing agreement will allow surprise audits of the recipient's record management system and practices sharing-dblimits: The data sharing agreement imposes strong limits linking the database with other administrative or clinical data sources privacy-policy: The recipient has a written privacy policy @@ -15,7 +15,7 @@ physically-secure: Computer systems are housed in a physically secure environment physically-privatearea: There is no public access to areas where computers holding the data will be data-destruction: The data will be destroyed once its purpose has been accomplished (e.g., the study has been published or other funding agency data retention period expires) - staff-restricted: Access rights are only provided to users on a ‘need to know’ basis consistent with the stated purpose for which the data was collected + staff-restricted: Access rights are only provided to users on a "need to know" basis consistent with the stated purpose for which the data was collected #motives: Motives and Capacity criminal-value: The disclosed database has potential commercial or criminal value diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java index b33b62aea8..eca6d7cd02 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java @@ -65,9 +65,9 @@ import org.deidentifier.arx.gui.view.impl.risk.LayoutRisks; import org.deidentifier.arx.gui.view.impl.utility.LayoutUtility; import org.deidentifier.arx.gui.worker.Worker; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.ChecklistWizard; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.ChecklistDialog; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; +import org.deidentifier.arx.gui.view.impl.wizard.RiskWizard; +import org.deidentifier.arx.gui.view.impl.wizard.RiskWizardDialogChecklist; +import org.deidentifier.arx.risk.RiskQuestionnaire; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; @@ -512,8 +512,8 @@ public void showHelpDialog(String id) { * Shows the checklist wizard */ public void showChecklistWizard() { - Checklist checklist = new Checklist(controller.getResources().getStream("default_checklist.txt")); - final ChecklistDialog dialog = new ChecklistDialog(checklist, shell, controller, new ChecklistWizard(checklist, controller)); + RiskQuestionnaire checklist = new RiskQuestionnaire(controller.getResources().getStream("default_checklist.txt")); + final RiskWizardDialogChecklist dialog = new RiskWizardDialogChecklist(checklist, shell, new RiskWizard(checklist, controller)); dialog.open(); } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizard.java new file mode 100644 index 0000000000..0814df806b --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizard.java @@ -0,0 +1,108 @@ +/* + * 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.wizard; + +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.model.Model; +import org.deidentifier.arx.gui.resources.Resources; +import org.deidentifier.arx.risk.RiskQuestionnaire; +import org.deidentifier.arx.risk.RiskQuestionnaireSection; +import org.deidentifier.arx.risk.RiskQuestionnaireWeights; +import org.eclipse.jface.wizard.Wizard; + +/** + * The questionnaire wizard for evaluating data sharing risks + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskWizard extends Wizard { + + /** Array containing each section's wizard page */ + protected RiskWizardPageSection[] pages; + + /** Final page showing the evaluation */ + protected RiskWizardPageEvaluation evaluationPage; + + /** The questionnaire used for the wizard */ + private RiskQuestionnaire checklist; + + /** Controller */ + private Controller controller; + + /** + * Create a new questionnaire wizard + * + * @param checklist + * @param controller + */ + public RiskWizard(RiskQuestionnaire checklist, Controller controller) { + super(); + + this.checklist = checklist; + // try to restore a saved version of the weights + Model model = controller.getModel(); + if (model != null) { + RiskQuestionnaireWeights savedModel = model.getRiskWizardModel(); + if (savedModel != null) { + this.checklist.setWeightConfiguration(savedModel); + } + } + this.controller = controller; + this.setWindowTitle(Resources.getMessage("RiskWizard.0")); + } + + /** + * Adds the necessary pages to the wizard + */ + @Override + public void addPages() { + // add a page for each section + RiskQuestionnaireSection[] sections = checklist.getSections(); + pages = new RiskWizardPageSection[sections.length]; + for (int i = 0; i < sections.length; i++) { + RiskQuestionnaireSection s = sections[i]; + RiskWizardPageSection p = new RiskWizardPageSection(s); + this.addPage(p); + pages[i] = p; + } + + // add the final evaluation page + evaluationPage = new RiskWizardPageEvaluation(checklist, controller); + this.addPage(evaluationPage); + } + + /** + * Called when the dialog is finished, saves the current weights + */ + @Override + public boolean performFinish() { + this.controller.getModel().setRiskWizardModel(this.checklist.getWeightConfiguration()); + return true; + } + + /** + * Updates the weights for each section and the evaluation + */ + protected void updateWeights() { + for (RiskWizardPageSection page : pages) { + page.updateWeights(); + } + evaluationPage.updateWeights(); + } +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardComponentAnswer.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardComponentAnswer.java new file mode 100644 index 0000000000..147fde15fc --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardComponentAnswer.java @@ -0,0 +1,88 @@ +/* + * 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.wizard; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.*; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.layout.RowLayout; +import org.eclipse.swt.widgets.*; +import org.deidentifier.arx.gui.resources.Resources; +import org.deidentifier.arx.risk.RiskQuestionnaireQuestion; +import org.deidentifier.arx.risk.RiskQuestionnaireQuestion.*; + +/** + * The radio group component for answering the questions, contains yes, no and + * n/a as possible answers + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskWizardComponentAnswer extends Composite { + + /** Widget */ + private Button yesButton; + /** Widget */ + private Button noButton; + /** Widget */ + private Button n_aButton; + /** The question which will be updated, when the selected button changes */ + private RiskQuestionnaireQuestion item; + + /** + * create a new answer radio group in the specified composite and targetItem + * + * @param parent + * @param targetItem + */ + public RiskWizardComponentAnswer(Composite parent, RiskQuestionnaireQuestion targetItem) { + super(parent, SWT.NONE); + this.item = targetItem; + this.setLayout(new FillLayout()); + Group group = new Group(this, SWT.SHADOW_IN); + group.setLayout(new RowLayout(SWT.HORIZONTAL)); + + SelectionListener selectionListener = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent event) { + Button button = ((Button) event.widget); + if (button == yesButton) { + item.answer = Answer.YES; + } else if (button == noButton) { + item.answer = Answer.NO; + } else { + item.answer = Answer.N_A; + } + }; + }; + + yesButton = new Button(group, SWT.RADIO); + yesButton.setText(Resources.getMessage("RiskWizard.3")); + yesButton.addSelectionListener(selectionListener); + + noButton = new Button(group, SWT.RADIO); + noButton.setText(Resources.getMessage("RiskWizard.4")); + noButton.addSelectionListener(selectionListener); + + n_aButton = new Button(group, SWT.RADIO); + n_aButton.setText(Resources.getMessage("RiskWizard.5")); + n_aButton.setSelection(true); + n_aButton.addSelectionListener(selectionListener); + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardComponentWeight.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardComponentWeight.java new file mode 100644 index 0000000000..b5f898a6bd --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardComponentWeight.java @@ -0,0 +1,145 @@ +/* + * 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.wizard; + +import java.text.DecimalFormat; +import java.text.ParseException; + +import org.deidentifier.arx.risk.RiskQuestionnaireItem; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; + +/** + * A drop down field for changing a question's weight + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskWizardComponentWeight { + + /** The targeted item */ + private RiskQuestionnaireItem item; + /** Widget */ + private Combo dropdown; + /** Flag */ + private boolean disableUpdateQuestion; + /** Flag */ + private boolean enabled; + /** Format */ + static final DecimalFormat df = new DecimalFormat("#.00"); + + /** + * create a new weight field for an item (question or section) + * + * @param composite + * the composite + * @param item + * the item this field targets + * @param enabled + * whether this control is currently enabled + */ + public RiskWizardComponentWeight(Composite composite, RiskQuestionnaireItem item, boolean enabled) { + dropdown = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); + dropdown.add("0.25"); + dropdown.add("0.50"); + dropdown.add("1.00"); + dropdown.add("1.50"); + dropdown.add("2.00"); + dropdown.add("3.00"); + dropdown.add("5.00"); + + ModifyListener modifyListener = new ModifyListener() { + @Override + public void modifyText(ModifyEvent e) { + RiskWizardComponentWeight.this.updateItem(); + } + }; + + dropdown.addModifyListener(modifyListener); + + this.item = item; + this.setEnabled(enabled); + + GridData gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER); + gridData.widthHint = 72; + dropdown.setLayoutData(gridData); + + updateText(); + } + + /** + * returns, whether the field is editable + * + * @return if field can be edited + */ + public boolean isEnabled() { + return enabled; + } + + /** + * change whether field can be edited + * + * @param enabled + * whether field can be edited + */ + public void setEnabled(boolean enabled) { + this.enabled = enabled; + this.dropdown.setEnabled(enabled); + } + + /** + * updates the text of the dropdown + */ + public void updateText() { + disableUpdateQuestion = true; + double newWeight = item.getWeight(); + String weightString = df.format(newWeight); + // System.out.println("Weight: "+weightString+" item="+item.getIdentifier()); + + boolean containsText = false; + for (String t : dropdown.getItems()) { + if (t.equals(weightString)) { + containsText = true; + } + } + if (containsText == false) { + dropdown.add(weightString); + } + + dropdown.setText(df.format(newWeight)); + disableUpdateQuestion = false; + } + + /** + * updates the target item + */ + protected void updateItem() { + if (disableUpdateQuestion) { return; } + try { + double value = df.parse(dropdown.getText()).doubleValue(); + item.setWeight(value); + } catch (ParseException e) { + // e.printStackTrace(); + } + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialogChecklist.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialogChecklist.java new file mode 100644 index 0000000000..5feb341f84 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialogChecklist.java @@ -0,0 +1,209 @@ +/* + * 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.wizard; + +import org.deidentifier.arx.gui.resources.Resources; +import org.deidentifier.arx.risk.RiskQuestionnaire; +import org.deidentifier.arx.risk.RiskQuestionnaireWeights; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.IWizardPage; +import org.eclipse.jface.wizard.ProgressMonitorPart; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.FileDialog; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Shell; + +/** + * The ChecklistDialog is the dialog presented for the wizard + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskWizardDialogChecklist extends WizardDialog { + + /** Widget */ + private Button weightEditButton; + + /** Widget */ + private Button loadButton; + + /** Widget */ + private Button saveButton; + + /** Model */ + private RiskQuestionnaire checklist; + + /** + * creates a new checklist dialog for a specified checklist + * + * @param checklist + * the checklist to use + * @param parentShell + * the parent for this dialog + * @param controller + * the arx controller + * @param newWizard + * the wizard + */ + public RiskWizardDialogChecklist(RiskQuestionnaire checklist, Shell parentShell, IWizard newWizard) { + super(parentShell, newWizard); + this.checklist = checklist; + } + + /** + * create a custom button bar, with the load/store/edit buttons for the + * weight profiles + */ + @Override + protected void createButtonsForButtonBar(Composite parent) { + // this code creates the button on the left side (settings) + GridLayout layout = (GridLayout) parent.getLayout(); + layout.horizontalSpacing = 0; + + // adjust the parent to use the full width + GridData gridData = (GridData) parent.getLayoutData(); + gridData.grabExcessHorizontalSpace = true; + gridData.minimumWidth = 650; + gridData.horizontalAlignment = GridData.FILL; + + // add the settings button + layout.numColumns++; + + weightEditButton = new Button(parent, SWT.CHECK); + weightEditButton.setText(Resources.getMessage("RiskWizard.6")); + + final RiskWizardDialogChecklist reference = this; + + loadButton = new Button(parent, SWT.PUSH); + loadButton.setText(Resources.getMessage("RiskWizard.7")); + loadButton.setVisible(false); + loadButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dialog = new FileDialog(loadButton.getShell(), SWT.OPEN); + dialog.setFilterExtensions(new String[] { "*.txt", "*.properties", "*.weights" }); + dialog.setFilterPath("config/weights"); + String result = dialog.open(); + if (result != null) { + updateWeightConfig(result); + } + } + }); + layout.numColumns++; + + saveButton = new Button(parent, SWT.PUSH); + saveButton.setText(Resources.getMessage("RiskWizard.8")); + saveButton.setVisible(false); + saveButton.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + FileDialog dialog = new FileDialog(saveButton.getShell(), SWT.SAVE); + dialog.setFileName("weights.txt"); + dialog.setFilterExtensions(new String[] { "*.txt", "*.properties", "*.weights" }); + dialog.setFilterPath("config/weights"); + String result = dialog.open(); + if (result != null) { + RiskQuestionnaireWeights wc = checklist.getWeightConfiguration(); + wc.save(result); + } + } + }); + layout.numColumns++; + + Listener listener = new Listener() { + @Override + public void handleEvent(Event event) { + reference.setWeightsEditable(weightEditButton.getSelection()); + } + }; + + weightEditButton.addListener(SWT.Selection, listener); + + // Add a placeholder label that uses the empty space + layout.numColumns++; + Label placeholder = new Label(parent, 1); + placeholder.setText(""); + placeholder.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); + + super.createButtonsForButtonBar(parent); + } + + @Override + protected Control createDialogArea(Composite parent) { + Control ctrl = super.createDialogArea(parent); + getProgressMonitor(); + return ctrl; + } + + @Override + protected IProgressMonitor getProgressMonitor() { + // remove progress monitor, taken from + // http://commercialjavaproducts.blogspot.de/2010/11/remove-progress-monitor-part-from-jface.html + ProgressMonitorPart monitor = (ProgressMonitorPart) super.getProgressMonitor(); + GridData gridData = new GridData(GridData.FILL_HORIZONTAL); + gridData.heightHint = 0; + monitor.setLayoutData(gridData); + monitor.setVisible(false); + return monitor; + } + + /** + * enable or disable the edit mode + * + * @param weightsEditable + * whether the weights should be changeable + */ + protected void setWeightsEditable(boolean weightsEditable) { + loadButton.setVisible(weightsEditable); + saveButton.setVisible(weightsEditable); + IWizardPage pages[] = this.getWizard().getPages(); + for (IWizardPage page : pages) { + if (page instanceof RiskWizardPageSection) { + RiskWizardPageSection sectionPage = (RiskWizardPageSection) page; + sectionPage.setWeightEditable(weightsEditable); + } + } + this.dialogArea.update(); + } + + /** + * updates the current weight configuration + * + * @param result + * the weight configuration to load + */ + protected void updateWeightConfig(String result) { + checklist.setWeightConfiguration(new RiskQuestionnaireWeights(result)); + IWizard wizard = this.getWizard(); + if (wizard instanceof RiskWizard) { + RiskWizard casted = (RiskWizard) wizard; + casted.updateWeights(); + } + } +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardPageEvaluation.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardPageEvaluation.java new file mode 100644 index 0000000000..6ac92b20ec --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardPageEvaluation.java @@ -0,0 +1,208 @@ +/* + * 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.wizard; + +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.resources.Resources; +import org.deidentifier.arx.risk.RiskQuestionnaire; +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +/** + * Final page containing the two different visualizations + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskWizardPageEvaluation extends WizardPage { + + /** The checklist */ + private RiskQuestionnaire checklist; + /** The current visualization */ + private RiskWizardVisualization visualization; + /** Widget */ + private Composite rootComposite; + /** Widget */ + private Controller controller; + + /** + * create the evaluation page for the checklist + * + * @param checklist + * the checklist to use + * @param controller + * the arx controller + */ + protected RiskWizardPageEvaluation(RiskQuestionnaire checklist, Controller controller) { + super(Resources.getMessage("RiskWizard.9")); + + this.checklist = checklist; + this.controller = controller; + this.setTitle(Resources.getMessage("RiskWizard.10")); + this.setDescription(Resources.getMessage("RiskWizard.11")); + } + + /** + * creates the control and adds the visualization selection top bar + */ + @Override + public void createControl(Composite parent) { + GridLayout layout = new GridLayout(); + layout.numColumns = 1; + layout.marginHeight = 0; + layout.marginTop = 0; + layout.marginBottom = 0; + layout.verticalSpacing = 0; + layout.makeColumnsEqualWidth = true; + + rootComposite = new Composite(parent, SWT.NO_BACKGROUND); + rootComposite.setLayout(layout); + GridData rootData = new GridData(); + rootData.grabExcessHorizontalSpace = true; + rootData.horizontalAlignment = GridData.FILL; + rootData.grabExcessVerticalSpace = true; + rootData.verticalAlignment = GridData.FILL; + rootComposite.setLayoutData(rootData); + + createTopBar(rootComposite, layout.numColumns); + + this.showMonitorVisualization(); + + setControl(rootComposite); + } + + @Override + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) { + this.updateWeights(); + } + } + + /** + * creates the top bar used for switching between visualizations + * + * @param parent + * the parent composite + * @param span + * the span to use for the bar + * @return + */ + private Composite createTopBar(Composite parent, int span) { + Composite c = new Composite(parent, SWT.NO_BACKGROUND); + + GridData cData = new GridData(); + cData.horizontalSpan = span; + cData.horizontalAlignment = GridData.FILL; + c.setLayoutData(cData); + + GridLayout layout = new GridLayout(); + layout.numColumns = 3; + c.setLayout(layout); + + Label weightLabel = new Label(c, SWT.LEFT); + GridData weightData = new GridData(); + weightData.grabExcessHorizontalSpace = true; + weightLabel.setLayoutData(weightData); + weightLabel.setText(Resources.getMessage("RiskWizard.19")); + FontDescriptor boldDescriptor = FontDescriptor.createFrom(weightLabel.getFont()) + .setStyle(SWT.BOLD); + Font boldFont = boldDescriptor.createFont(weightLabel.getDisplay()); + weightLabel.setFont(boldFont); + + final Combo visualizationDropDown = new Combo(c, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); + final String monitorTitle = Resources.getMessage("RiskWizard.12"); + final String stacksTitle = Resources.getMessage("RiskWizard.13"); + visualizationDropDown.add(monitorTitle); + visualizationDropDown.add(stacksTitle); + visualizationDropDown.setText(monitorTitle); + visualizationDropDown.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + String selected = visualizationDropDown.getText(); + if (selected.equals(stacksTitle)) { + showStacksVisualization(); + } else if (selected.equals(monitorTitle)) { + showMonitorVisualization(); + } + } + }); + + Label separator = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL); + GridData sepData = new GridData(); + sepData.horizontalSpan = layout.numColumns; + sepData.grabExcessHorizontalSpace = true; + sepData.horizontalAlignment = GridData.FILL; + separator.setLayoutData(sepData); + + return c; + } + + /** + * remove the current visualization from the UI + */ + private void removeVisualization() { + if (this.visualization != null) { + this.visualization.dispose(); + } + } + + /** + * set the current visualization and update the UI + * + * @param visualization + * the visualization to change to + */ + private void setVisualization(RiskWizardVisualization visualization) { + removeVisualization(); + this.visualization = visualization; + updateWeights(); + this.rootComposite.layout(); + } + + /** + * change to monitor visualization + */ + private void showMonitorVisualization() { + setVisualization(new RiskWizardVisualizationMonitor(rootComposite, controller, checklist)); + } + + /** + * change to stacks visualization + */ + private void showStacksVisualization() { + setVisualization(new RiskWizardVisualizationStack(rootComposite, controller, checklist)); + } + + /** + * update the current visualization when the weights change + */ + protected void updateWeights() { + visualization.updateWeights(); + } + +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardPageSection.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardPageSection.java new file mode 100644 index 0000000000..a9d077d3bc --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardPageSection.java @@ -0,0 +1,180 @@ +/* + * 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.wizard; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.resource.FontDescriptor; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.ScrolledComposite; +import org.eclipse.swt.graphics.Font; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.deidentifier.arx.gui.resources.Resources; +import org.deidentifier.arx.risk.RiskQuestionnaireQuestion; +import org.deidentifier.arx.risk.RiskQuestionnaireSection; + +/** + * Each SectionPage shows all the questions from a checklist section + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskWizardPageSection extends WizardPage { + + /** Widget */ + private RiskQuestionnaireSection section; + /** Widget */ + private Composite container; + /** Field */ + private boolean weightEditable; + /** Field */ + private List weightFields; + + /** + * create a new page for a section + * + * @param section + * the section of this page + */ + public RiskWizardPageSection(RiskQuestionnaireSection section) { + super(section.getTitle()); + + this.weightEditable = false; + this.section = section; + this.setTitle(section.getTitle()); + this.setDescription(Resources.getMessage("RiskWizard.1")); + } + + /** + * creates the control, by adding the questions inside a scroll view + */ + @Override + public void createControl(Composite parent) { + final Composite rootComposite = new Composite(parent, SWT.NONE); + + GridLayout rootGrid = new GridLayout(); + rootComposite.setLayout(rootGrid); + + final ScrolledComposite sc = new ScrolledComposite(rootComposite, SWT.BORDER | SWT.V_SCROLL); + GridData sgd = new GridData(GridData.FILL_BOTH); + sgd.grabExcessHorizontalSpace = true; + sgd.grabExcessVerticalSpace = true; + sgd.widthHint = 400;// SWT.DEFAULT; + sgd.heightHint = 300; + sc.setLayoutData(sgd); + + sc.setExpandHorizontal(true); + sc.setExpandVertical(true); + + container = new Composite(sc, SWT.NULL); + GridLayout layout = new GridLayout(); + container.setLayout(layout); + layout.numColumns = 3; + layout.verticalSpacing = 12; + + createItems(); + + rootComposite.addListener(SWT.Resize, new Listener() { + int width = -1; + + @Override + public void handleEvent(org.eclipse.swt.widgets.Event e) { + int newWidth = rootComposite.getSize().x; + if (newWidth != width) { + sc.setMinHeight(container.computeSize(newWidth, SWT.DEFAULT).y + 40); + width = newWidth; + } + } + }); + + sc.setContent(container); + sc.setMinSize(container.computeSize(400, SWT.DEFAULT)); + sc.layout(); + + setControl(rootComposite); + } + + /** + * enable or disable the weight edit mode + */ + public void setWeightEditable(boolean editable) { + if (editable == this.weightEditable) { return; } + this.weightEditable = editable; + + // TODO iterate and set + for (RiskWizardComponentWeight w : this.weightFields) { + w.setEnabled(editable); + } + } + + /** + * creates the interface for the individual items (questions) + */ + private void createItems() { + // add weight fields + this.weightFields = new ArrayList(); + this.weightFields.add(new RiskWizardComponentWeight(container, this.section, false)); + + Label label = new Label(container, SWT.NONE | SWT.WRAP); + label.setText(this.section.getTitle()); + // from + // http://eclipsesource.com/blogs/2014/02/10/swt-best-practices-changing-fonts/ + FontDescriptor boldDescriptor = FontDescriptor.createFrom(label.getFont()) + .setStyle(SWT.BOLD); + Font boldFont = boldDescriptor.createFont(label.getDisplay()); + label.setFont(boldFont); + + GridData headerGridData = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); + headerGridData.verticalAlignment = GridData.CENTER; + headerGridData.grabExcessVerticalSpace = false; + headerGridData.horizontalSpan = 2; + label.setLayoutData(headerGridData); + + RiskQuestionnaireQuestion[] items = section.getItems(); + for (int i = 0; i < items.length; i++) { + RiskQuestionnaireQuestion itm = items[i]; + + this.weightFields.add(new RiskWizardComponentWeight(container, itm, false)); + + Label label1 = new Label(container, SWT.NONE | SWT.WRAP); + label1.setText(itm.getTitle()); + GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); + gd.verticalAlignment = GridData.CENTER; + gd.grabExcessVerticalSpace = false; + label1.setLayoutData(gd); + + new RiskWizardComponentAnswer(container, itm); + } + } + + /** + * update the weights (called when a new weight configuration is loaded) + */ + protected void updateWeights() { + if (this.weightFields == null) { return; } + for (RiskWizardComponentWeight field : weightFields) { + field.updateText(); + } + } +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualization.java new file mode 100644 index 0000000000..c6dd99a8ae --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualization.java @@ -0,0 +1,73 @@ +/* + * 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.wizard; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.risk.RiskQuestionnaire; + +/** + * Base class for the visualizations + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public abstract class RiskWizardVisualization extends Composite { + + /** Checklist used for the visualization */ + protected RiskQuestionnaire checklist; + /** Controller */ + protected Controller controller; + + /** + * Create a new visualization for the checklist + * + * @param parent + * the parent + * @param controller + * the controller + * @param checklist + * the checklist + */ + public RiskWizardVisualization(Composite parent, Controller controller, RiskQuestionnaire checklist) { + super(parent, SWT.NO_SCROLL); + + GridData gridData = new GridData(); + gridData.grabExcessHorizontalSpace = true; + gridData.grabExcessVerticalSpace = true; + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + this.setLayoutData(gridData); + + this.checklist = checklist; + this.controller = controller; + this.createVisualization(); + } + + /** + * Used in subclasses to respond to changes + */ + public abstract void updateWeights(); + + /** + * Used in subclasses for the initial setup + */ + protected abstract void createVisualization(); +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationMonitor.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationMonitor.java new file mode 100644 index 0000000000..d021d78e07 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationMonitor.java @@ -0,0 +1,120 @@ +/* + * 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.wizard; + +import java.util.ArrayList; +import java.util.List; + +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.resources.Resources; +import org.deidentifier.arx.gui.view.SWTUtil; +import org.deidentifier.arx.gui.view.impl.common.ComponentRiskMonitor; +import org.deidentifier.arx.risk.RiskQuestionnaire; +import org.deidentifier.arx.risk.RiskQuestionnaireSection; +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; + +/** + * The monitor visualization + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskWizardVisualizationMonitor extends RiskWizardVisualization { + + /** Contains the monitors for each section */ + private List monitors; + + /** Overall monitor, showing the overall score */ + private ComponentRiskMonitor totalMonitor; + + /** + * Create a new monitor visualization + * + * @param parent + * the parent + * @param controller + * the controller + * @param checklist + * the checklist to use + */ + public RiskWizardVisualizationMonitor(Composite parent, + Controller controller, + RiskQuestionnaire checklist) { + super(parent, controller, checklist); + } + + /** + * Update the UI when the weights change + */ + @Override + public void updateWeights() { + RiskQuestionnaireSection sections[] = checklist.getSections(); + for (int i = 0; i < sections.length; i++) { + RiskQuestionnaireSection s = sections[i]; + + ComponentRiskMonitor riskMonitor = monitors.get(i); + riskMonitor.setRisk(1.0 - ((s.getScore() / 2.0) + 0.5)); + } + + totalMonitor.setRisk(1.0 - ((checklist.getScore() / 2.0) + 0.5)); + } + + /** + * Creates the view containing the different monitors + */ + @Override + protected void createVisualization() { + RiskQuestionnaireSection sections[] = this.checklist.getSections(); + monitors = new ArrayList(); + + GridLayout layout = SWTUtil.createGridLayoutWithEqualWidth(sections.length); + layout.marginHeight = 0; + layout.marginTop = 0; + layout.marginBottom = 0; + layout.makeColumnsEqualWidth = true; + this.setLayout(layout); + + for (int i = 0; i < sections.length; i++) { + String title = sections[i].getTitle(); + + ComponentRiskMonitor riskMonitor = new ComponentRiskMonitor(this, + this.controller, + title, + title); + riskMonitor.setLayoutData(SWTUtil.createFillGridData()); + riskMonitor.setRisk(0.5); + monitors.add(riskMonitor); + } + + String totalTitle = Resources.getMessage("RiskWizard.2"); + totalMonitor = new ComponentRiskMonitor(this, this.controller, totalTitle, totalTitle); + totalMonitor.setLayoutData(SWTUtil.createFillGridData()); + totalMonitor.setRisk(0.5); + + GridData gridData = new GridData(); + gridData.grabExcessVerticalSpace = true; + gridData.horizontalAlignment = SWT.FILL; + gridData.verticalAlignment = SWT.FILL; + gridData.minimumHeight = 150; + gridData.horizontalSpan = layout.numColumns; + totalMonitor.setLayoutData(gridData); + } +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationStack.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationStack.java new file mode 100644 index 0000000000..416cc6b1e3 --- /dev/null +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationStack.java @@ -0,0 +1,166 @@ +/* + * 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.wizard; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.FillLayout; +import org.eclipse.swt.widgets.Composite; +import org.swtchart.*; +import org.swtchart.ISeries.*; +import org.deidentifier.arx.gui.Controller; +import org.deidentifier.arx.gui.resources.Resources; +import org.deidentifier.arx.risk.RiskQuestionnaire; +import org.deidentifier.arx.risk.RiskQuestionnaireQuestion; +import org.deidentifier.arx.risk.RiskQuestionnaireSection; + +/** + * The stack visualization + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskWizardVisualizationStack extends RiskWizardVisualization { + + /** Displayed chart */ + private Chart chart; + + /** Bar series for the positive values */ + private IBarSeries positive; + + /** Bar series for the neutral values */ + private IBarSeries neutral; + + /** Bar series for the negative values */ + private IBarSeries negative; + + /** + * Create a new stack visualization + * + * @param parent + * the parent + * @param controller + * the controller + * @param checklist + * the checklist + */ + public RiskWizardVisualizationStack(Composite parent, Controller controller, RiskQuestionnaire checklist) { + super(parent, controller, checklist); + } + + /** + * Updates the UI when the weights/score changes + */ + @Override + public void updateWeights() { + RiskQuestionnaireSection sections[] = this.checklist.getSections(); + double[] posY = new double[sections.length]; + double[] neuY = new double[sections.length]; + double[] negY = new double[sections.length]; + + int idx = 0; + for (RiskQuestionnaireSection sec : sections) { + double pos = 0.0; + double neu = 0.0; + double neg = 0.0; + + for (RiskQuestionnaireQuestion q : sec.getItems()) { + double w = q.getWeight(); + double s = q.getScore(); + if (s == 0.0) { + neu += w; + } else if (s > 0.0) { + pos += w; + } else { + neg += w; + } + } + + posY[idx] = pos / sec.getMaximumWeight(); + neuY[idx] = neu / sec.getMaximumWeight(); + negY[idx] = neg / sec.getMaximumWeight(); + + idx++; + } + + positive.setYSeries(posY); + positive.enableStack(true); + neutral.setYSeries(neuY); + neutral.enableStack(true); + negative.setYSeries(negY); + negative.enableStack(true); + + chart.update(); + chart.redraw(); + } + + /** + * Creates the view containing the stack bar graph visualization + */ + @Override + protected void createVisualization() { + RiskQuestionnaireSection sections[] = this.checklist.getSections(); + String sectionNames[] = new String[sections.length]; + int idx = 0; + for (RiskQuestionnaireSection s : sections) { + sectionNames[idx] = s.getTitle(); + idx++; + } + + FillLayout fillLayout = new FillLayout(); + fillLayout.type = SWT.VERTICAL; + this.setLayout(fillLayout); + chart = new Chart(this, SWT.NONE); + chart.getTitle().setText(Resources.getMessage("RiskWizard.18")); + + double[] positiveSeries = { 0.1, 0, 0 }; + double[] neutralSeries = { 0.1, 0, 0 }; + double[] negativeSeries = { 0.1, 0, 0 }; + + ISeriesSet seriesSet = chart.getSeriesSet(); + + positive = (IBarSeries) seriesSet.createSeries(SeriesType.BAR, + Resources.getMessage("RiskWizard.15")); + positive.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_GREEN)); + positive.enableStack(true); + positive.setYSeries(positiveSeries); + + neutral = (IBarSeries) seriesSet.createSeries(SeriesType.BAR, + Resources.getMessage("RiskWizard.16")); + neutral.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_GRAY)); + neutral.enableStack(true); + neutral.setYSeries(neutralSeries); + + negative = (IBarSeries) seriesSet.createSeries(SeriesType.BAR, + Resources.getMessage("RiskWizard.17")); + negative.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_RED)); + negative.enableStack(true); + negative.setYSeries(negativeSeries); + + IAxisSet axisSet = chart.getAxisSet(); + axisSet.adjustRange(); + + IAxis yAxis = axisSet.getYAxis(0); + yAxis.setRange(new Range(0.0, 1.05)); + yAxis.getTitle().setVisible(false); + + IAxis xAxis = axisSet.getXAxis(0); + xAxis.setCategorySeries(sectionNames); + xAxis.enableCategory(true); + xAxis.getTitle().setVisible(false); + } +} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java deleted file mode 100644 index 4f3075685a..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/AnswerRadioGroup.java +++ /dev/null @@ -1,66 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.*; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.layout.RowLayout; -import org.eclipse.swt.widgets.*; -import org.deidentifier.arx.gui.resources.Resources; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question.*; - -/** - * The radio group component for answering the questions, contains yes, no and n/a as possible answers - * - */ -public class AnswerRadioGroup extends Composite { - - private Button yesButton; - private Button noButton; - private Button n_aButton; - - /** - * the question which will be updated, when the selected button changes - */ - private Question item; - - /** - * create a new answer radio group in the specified composite and targetItem - * @param parent - * @param targetItem - */ - public AnswerRadioGroup(Composite parent, Question targetItem) { - super(parent,SWT.NONE); - this.item = targetItem; - this.setLayout(new FillLayout()); - Group group = new Group(this, SWT.SHADOW_IN); - group.setLayout(new RowLayout(SWT.HORIZONTAL)); - - SelectionListener selectionListener = new SelectionAdapter () { - public void widgetSelected(SelectionEvent event) { - Button button = ((Button) event.widget); - if(button == yesButton) { - item.answer = Answer.YES; - } else if(button == noButton) { - item.answer = Answer.NO; - } else { - item.answer = Answer.N_A; - } - }; - }; - - yesButton = new Button(group, SWT.RADIO); - yesButton.setText(Resources.getMessage("RiskWizard.3")); - yesButton.addSelectionListener(selectionListener); - - noButton = new Button(group, SWT.RADIO); - noButton.setText(Resources.getMessage("RiskWizard.4")); - noButton.addSelectionListener(selectionListener); - - n_aButton = new Button(group, SWT.RADIO); - n_aButton.setText(Resources.getMessage("RiskWizard.5")); - n_aButton.setSelection(true); - n_aButton.addSelectionListener(selectionListener); - } - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java deleted file mode 100644 index 959ef71799..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistDialog.java +++ /dev/null @@ -1,200 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jface.wizard.IWizard; -import org.eclipse.jface.wizard.IWizardPage; -import org.eclipse.jface.wizard.ProgressMonitorPart; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.FileDialog; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; -import org.deidentifier.arx.gui.Controller; -import org.deidentifier.arx.gui.model.ModelRiskWizard; -import org.deidentifier.arx.gui.resources.Resources; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; - -/** - * The ChecklistDialog is the dialog presented for the wizard - * @author Thomas Günzel - * - */ -public class ChecklistDialog extends WizardDialog { - - /** - * button to toggle the weight edit mode - */ - private Button weightEditButton; - - /** - * button to load a weight setting - */ - private Button loadButton; - - /** - * button to save a weight setting - */ - private Button saveButton; - - /** - * the used checklist - */ - private Checklist checklist; - - /** - * the arx controller - */ - private Controller controller; - - /** - * creates a new checklist dialog for a specified checklist - * @param checklist the checklist to use - * @param parentShell the parent for this dialog - * @param controller the arx controller - * @param newWizard the wizard - */ - public ChecklistDialog(Checklist checklist, Shell parentShell, Controller controller, IWizard newWizard) { - super(parentShell, newWizard); - this.checklist = checklist; - this.controller = controller; - } - - /** - * create a custom button bar, with the load/store/edit buttons for the weight profiles - */ - protected void createButtonsForButtonBar(Composite parent) { - // this code creates the button on the left side (settings) - GridLayout layout = (GridLayout) parent.getLayout(); - layout.horizontalSpacing = 0; - - // adjust the parent to use the full width - GridData gridData = (GridData) parent.getLayoutData(); - gridData.grabExcessHorizontalSpace = true; - gridData.minimumWidth = 650; - gridData.horizontalAlignment = GridData.FILL; - - // add the settings button - layout.numColumns++; - - weightEditButton = new Button(parent, SWT.CHECK); - weightEditButton.setText(Resources.getMessage("RiskWizard.6")); - - final ChecklistDialog reference = this; - - loadButton = new Button(parent, SWT.PUSH); - loadButton.setText(Resources.getMessage("RiskWizard.7")); - loadButton.setVisible(false); - loadButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - FileDialog dialog = new FileDialog(loadButton.getShell(), SWT.OPEN); - dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); - dialog.setFilterPath("config/weights"); - String result = dialog.open(); - if(result != null) { - updateWeightConfig(result); - } - } - }); - layout.numColumns++; - - saveButton = new Button(parent, SWT.PUSH); - saveButton.setText(Resources.getMessage("RiskWizard.8")); - saveButton.setVisible(false); - saveButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - FileDialog dialog = new FileDialog(saveButton.getShell(), SWT.SAVE); - dialog.setFileName("weights.txt"); - dialog.setFilterExtensions(new String [] {"*.txt","*.properties","*.weights"}); - dialog.setFilterPath("config/weights"); - String result = dialog.open(); - if(result != null) { - ModelRiskWizard wc = checklist.getWeightConfiguration(); - wc.save(result); - } - } - }); - layout.numColumns++; - - Listener listener = new Listener() { - public void handleEvent(Event event) { - reference.setWeightsEditable(weightEditButton.getSelection()); - } - }; - - weightEditButton.addListener(SWT.Selection, listener); - - - // add a placeholder label that uses the empty space - layout.numColumns++; - Label placeholder = new Label(parent, 1); - placeholder.setText(""); - placeholder.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false)); - - - super.createButtonsForButtonBar(parent); - } - - /** - * enable or disable the edit mode - * @param weightsEditable whether the weights should be changeable - */ - protected void setWeightsEditable(boolean weightsEditable) { - loadButton.setVisible(weightsEditable); - saveButton.setVisible(weightsEditable); - //System.out.println("Editable: "+weightsEditable); - IWizardPage pages[] = this.getWizard().getPages(); - for(IWizardPage page : pages) { - if(page instanceof SectionPage) { - SectionPage sectionPage = (SectionPage)page; - sectionPage.setWeightEditable(weightsEditable); - } - } - this.dialogArea.update(); - } - - /** - * updates the current weight configuration - * @param result the weight configuration to load - */ - protected void updateWeightConfig(String result) { - checklist.setWeightConfiguration(new ModelRiskWizard(result)); - IWizard wizard = this.getWizard(); - if(wizard instanceof ChecklistWizard) { - ChecklistWizard casted = (ChecklistWizard)wizard; - casted.updateWeights(); - } - } - - // remove progress monitor, taken from - // http://commercialjavaproducts.blogspot.de/2010/11/remove-progress-monitor-part-from-jface.html - - @Override - protected Control createDialogArea(Composite parent) { - Control ctrl = super.createDialogArea(parent); - getProgressMonitor(); - return ctrl; - } - - @Override - protected IProgressMonitor getProgressMonitor() { - ProgressMonitorPart monitor = (ProgressMonitorPart) super.getProgressMonitor(); - GridData gridData = new GridData(GridData.FILL_HORIZONTAL); - gridData.heightHint = 0; - monitor.setLayoutData(gridData); - monitor.setVisible(false); - return monitor; - } - - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java deleted file mode 100644 index eb5b7d74d2..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/ChecklistWizard.java +++ /dev/null @@ -1,100 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; - -import org.eclipse.jface.wizard.Wizard; -import org.deidentifier.arx.gui.Controller; -import org.deidentifier.arx.gui.model.Model; -import org.deidentifier.arx.gui.model.ModelRiskWizard; -import org.deidentifier.arx.gui.resources.Resources; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.*; - -/** - * The checklist wizard for evaluating the data sharing risk - * - */ -public class ChecklistWizard extends Wizard { - - /** - * array containing each section's wizard page - */ - protected SectionPage[] pages; - - /** - * final page showing the evaluation - */ - protected EvaluationPage evaluationPage; - - /** - * the checklist used for the wizard - */ - private Checklist checklist; - - /** - * the arx controller - */ - private Controller controller; - - /** - * create a new checklist wizard - * @param checklist the checklist to use - * @param controller the controller opening the wizard - */ - public ChecklistWizard(Checklist checklist, Controller controller) { - super(); - - this.checklist = checklist; - // try to restore a saved version of the weights - Model model = controller.getModel(); - if(model != null) { - ModelRiskWizard savedModel = model.getRiskWizardModel(); - if(savedModel != null) { - this.checklist.setWeightConfiguration(savedModel); - } - } - this.controller = controller; - this.setWindowTitle(Resources.getMessage("RiskWizard.0")); - } - - /** - * adds the necessary pages to the wizard - */ - @Override - public void addPages() { - // add a page for each section - Section[] sections = checklist.getSections(); - pages = new SectionPage[sections.length]; - for(int i = 0; i < sections.length; i++) { - Section s = sections[i]; - SectionPage p = new SectionPage(s); - this.addPage(p); - pages[i] = p; - } - - // add the final evaluation page - evaluationPage = new EvaluationPage(checklist, controller); - this.addPage(evaluationPage); - } - - /** - * called when the dialog is finished, saves the current weights - */ - @Override - public boolean performFinish() { - // Print the result to the console - //this.pages = null; - //return false; - this.controller.getModel().setRiskWizardModel(this.checklist.getWeightConfiguration()); - //System.out.println(checklist); - return true; - } - - /** - * updates the weights for each section and the evaluation - */ - protected void updateWeights() { - for(SectionPage page : pages) { - page.updateWeights(); - } - evaluationPage.updateWeights(); - } - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java deleted file mode 100644 index 05048d10be..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/EvaluationPage.java +++ /dev/null @@ -1,200 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; - - - -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; - -import org.deidentifier.arx.gui.Controller; -import org.deidentifier.arx.gui.resources.Resources; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.MonitorVisualization; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.StackVisualization; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation.Visualization; - -/** - * final page containing the two different visualizations - * - */ -public class EvaluationPage extends WizardPage { - /** - * the checklist - */ - private Checklist checklist; - - private Label fileLabel; - private Composite topBar; - - /** - * the current visualization - */ - private Visualization visualization; - - private Composite rootComposite; - - private Controller controller; - - /** - * create the evaluation page for the checklist - * @param checklist the checklist to use - * @param controller the arx controller - */ - protected EvaluationPage(Checklist checklist, Controller controller) { - super(Resources.getMessage("RiskWizard.9")); - - this.checklist = checklist; - this.controller = controller; - this.setTitle(Resources.getMessage("RiskWizard.10")); - this.setDescription(Resources.getMessage("RiskWizard.11")); - } - - /** - * creates the control and adds the visualization selection top bar - */ - @Override - public void createControl(Composite parent) { - GridLayout layout = new GridLayout(); - layout.numColumns = 1; - layout.marginHeight = 0; - layout.marginTop = 0; - layout.marginBottom = 0; - layout.verticalSpacing = 0; - layout.makeColumnsEqualWidth = true; - - rootComposite = new Composite(parent, SWT.NO_BACKGROUND); - rootComposite.setLayout(layout); - GridData rootData = new GridData(); - rootData.grabExcessHorizontalSpace = true; - rootData.horizontalAlignment = GridData.FILL; - rootData.grabExcessVerticalSpace = true; - rootData.verticalAlignment = GridData.FILL; - rootComposite.setLayoutData(rootData); - - createTopBar(rootComposite, layout.numColumns); - - this.showMonitorVisualization(); - - setControl(rootComposite); - } - - /** - * creates the top bar used for switching between visualizations - * @param parent the parent composite - * @param span the span to use for the bar - * @return - */ - private Composite createTopBar(Composite parent, int span) { - Composite c = new Composite(parent, SWT.NO_BACKGROUND); - - GridData cData = new GridData(); - cData.horizontalSpan = span; - cData.horizontalAlignment = GridData.FILL; - c.setLayoutData(cData); - - GridLayout layout = new GridLayout(); - layout.numColumns = 3; - c.setLayout(layout); - - - Label weightLabel = new Label(c, SWT.LEFT); - GridData weightData = new GridData(); - weightData.grabExcessHorizontalSpace = true; - weightLabel.setLayoutData(weightData); - weightLabel.setText(Resources.getMessage("RiskWizard.19")); - FontDescriptor boldDescriptor = FontDescriptor.createFrom(weightLabel.getFont()).setStyle(SWT.BOLD); - Font boldFont = boldDescriptor.createFont(weightLabel.getDisplay()); - weightLabel.setFont(boldFont); - fileLabel = weightLabel; - - final Combo visualizationDropDown = new Combo(c, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); - String monitorTitle = Resources.getMessage("RiskWizard.12"); - String stacksTitle = Resources.getMessage("RiskWizard.13"); - visualizationDropDown.add(monitorTitle); - visualizationDropDown.add(stacksTitle); - visualizationDropDown.setText(monitorTitle); - visualizationDropDown.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - String selected = visualizationDropDown.getText(); - if(selected.equals(stacksTitle)) { - //System.out.println("Select Stacks"); - showStacksVisualization(); - } else if(selected.equals(monitorTitle)) { - //System.out.println("Select Monitor"); - showMonitorVisualization(); - } - } - }); - - Label separator = new Label(c, SWT.SEPARATOR | SWT.HORIZONTAL); - GridData sepData = new GridData(); - sepData.horizontalSpan = layout.numColumns; - sepData.grabExcessHorizontalSpace = true; - sepData.horizontalAlignment = GridData.FILL; - separator.setLayoutData(sepData); - - topBar = c; - return c; - } - - - @Override - public void setVisible(boolean visible) { - super.setVisible(visible); - if(visible) { - this.updateWeights(); - } - } - - /** - * update the current visualization when the weights change - */ - protected void updateWeights() { - visualization.updateWeights(); - } - - /** - * change to monitor visualization - */ - private void showMonitorVisualization() { - setVisualization(new MonitorVisualization(rootComposite, controller, checklist)); - } - - /** - * change to stacks visualization - */ - private void showStacksVisualization() { - setVisualization(new StackVisualization(rootComposite, controller, checklist)); - } - - /** - * set the current visualization and update the UI - * @param visualization the visualization to change to - */ - private void setVisualization(Visualization visualization) { - removeVisualization(); - this.visualization = visualization; - updateWeights(); - this.rootComposite.layout(); - } - - /** - * remove the current visualization from the UI - */ - private void removeVisualization() { - if(this.visualization != null) { - this.visualization.dispose(); - } - } - - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java deleted file mode 100644 index 0576b6565f..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/SectionPage.java +++ /dev/null @@ -1,155 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; - -import java.util.ArrayList; -import java.util.List; - -import org.eclipse.jface.resource.FontDescriptor; -import org.eclipse.jface.wizard.WizardPage; -import org.eclipse.swt.SWT; -import org.eclipse.swt.custom.ScrolledComposite; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.deidentifier.arx.gui.resources.Resources; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; - -/** - * each SectionPage shows all the questions from a checklist section - * - */ -public class SectionPage extends WizardPage { - private Section section; - private Composite container; - private boolean weightEditable; - private List weightFields; - - /** - * create a new page for a section - * @param section the section of this page - */ - public SectionPage(Section section) { - super(section.getTitle()); - - this.weightEditable = false; - this.section = section; - this.setTitle(section.getTitle()); - this.setDescription(Resources.getMessage("RiskWizard.1")); - } - - /** - * creates the control, by adding the questions inside a scroll view - */ - @Override - public void createControl(Composite parent) { - final Composite rootComposite = new Composite(parent, SWT.NONE); - - GridLayout rootGrid = new GridLayout(); - rootComposite.setLayout(rootGrid); - - final ScrolledComposite sc = new ScrolledComposite(rootComposite, SWT.BORDER | SWT.V_SCROLL); - GridData sgd = new GridData(GridData.FILL_BOTH); - sgd.grabExcessHorizontalSpace = true; - sgd.grabExcessVerticalSpace = true; - sgd.widthHint = 400;//SWT.DEFAULT; - sgd.heightHint = 300; - sc.setLayoutData(sgd); - - sc.setExpandHorizontal(true); - sc.setExpandVertical(true); - - container = new Composite(sc, SWT.NULL); - GridLayout layout = new GridLayout(); - container.setLayout(layout); - layout.numColumns = 3; - layout.verticalSpacing = 12; - - createItems(); - - rootComposite.addListener(SWT.Resize, new Listener() { - int width = -1; - @Override - public void handleEvent(org.eclipse.swt.widgets.Event e) { - int newWidth = rootComposite.getSize().x; - if (newWidth != width) { - sc.setMinHeight(container.computeSize(newWidth, SWT.DEFAULT).y+40); - width = newWidth; - } - } - }); - - sc.setContent(container); - sc.setMinSize(container.computeSize(400, SWT.DEFAULT)); - sc.layout(); - - setControl(rootComposite); - } - - /** - * creates the interface for the individual items (questions) - */ - private void createItems() { - // add weight fields - this.weightFields = new ArrayList(); - this.weightFields.add(new WeightField(container, this.section, false)); - - Label label = new Label(container, SWT.NONE | SWT.WRAP); - label.setText(this.section.getTitle()); - // from http://eclipsesource.com/blogs/2014/02/10/swt-best-practices-changing-fonts/ - FontDescriptor boldDescriptor = FontDescriptor.createFrom(label.getFont()).setStyle(SWT.BOLD); - Font boldFont = boldDescriptor.createFont(label.getDisplay()); - label.setFont( boldFont ); - - GridData headerGridData = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); - headerGridData.verticalAlignment = GridData.CENTER; - headerGridData.grabExcessVerticalSpace = false; - headerGridData.horizontalSpan = 2; - label.setLayoutData(headerGridData); - - Question[] items = section.getItems(); - for(int i = 0; i < items.length; i++) { - Question itm = items[i]; - - this.weightFields.add(new WeightField(container, itm, false)); - - Label label1 = new Label(container, SWT.NONE | SWT.WRAP); - label1.setText(itm.getTitle()); - GridData gd = new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL); - gd.verticalAlignment = GridData.CENTER; - gd.grabExcessVerticalSpace = false; - label1.setLayoutData(gd); - - new AnswerRadioGroup(container, itm); - } - } - - /** - * enable or disable the weight edit mode - */ - public void setWeightEditable(boolean editable) { - if(editable == this.weightEditable) { - return; - } - this.weightEditable = editable; - - // TODO iterate and set - for(WeightField w : this.weightFields) { - w.setEnabled(editable); - } - } - - /** - * update the weights (called when a new weight configuration is loaded) - */ - protected void updateWeights() { - if(this.weightFields == null) { - return; - } - for(WeightField field : weightFields) { - field.updateText(); - } - } -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java deleted file mode 100644 index 58c18787e0..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/WeightField.java +++ /dev/null @@ -1,127 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard; - -import java.text.DecimalFormat; -import java.text.ParseException; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Combo; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Text; - -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Item; - -/** - * a dropdown field for changing a question's weight - * - */ -public class WeightField { - /** - * the targeted item - */ - private Item item; - - private Combo dropdown; - private boolean disableUpdateQuestion; - - private boolean enabled; - - static final DecimalFormat df = new DecimalFormat("#.00"); - - /** - * create a new weight field for an item (question or section) - * @param composite the composite - * @param item the item this field targets - * @param enabled whether this control is currently enabled - */ - public WeightField(Composite composite, Item item, boolean enabled) { - dropdown = new Combo(composite, SWT.DROP_DOWN | SWT.READ_ONLY | SWT.BORDER); - dropdown.add("0.25"); - dropdown.add("0.50"); - dropdown.add("1.00"); - dropdown.add("1.50"); - dropdown.add("2.00"); - dropdown.add("3.00"); - dropdown.add("5.00"); - - WeightField reference = this; - - ModifyListener modifyListener = new ModifyListener() { - public void modifyText(ModifyEvent e) { - reference.updateItem(); - } - }; - - dropdown.addModifyListener(modifyListener); - - this.item = item; - this.setEnabled(enabled); - - GridData gridData = new GridData(GridData.VERTICAL_ALIGN_CENTER); - gridData.widthHint = 72; - dropdown.setLayoutData(gridData); - - - updateText(); - } - - - /** - * updates the text of the dropdown - */ - public void updateText() { - disableUpdateQuestion = true; - double newWeight = item.getWeight(); - String weightString = df.format(newWeight); - //System.out.println("Weight: "+weightString+" item="+item.getIdentifier()); - - boolean containsText = false; - for(String t : dropdown.getItems()) { - if(t.equals(weightString)) { - containsText = true; - } - } - if(containsText == false) { - dropdown.add(weightString); - } - - dropdown.setText(df.format(newWeight)); - disableUpdateQuestion = false; - } - - /** - * updates the target item - */ - protected void updateItem() { - if(disableUpdateQuestion) { - return; - } - try { - double value = df.parse(dropdown.getText()).doubleValue(); - item.setWeight(value); - } catch (ParseException e) { - //e.printStackTrace(); - } - } - - /** - * returns, whether the field is editable - * @return if field can be edited - */ - public boolean isEnabled() { - return enabled; - } - - /** - * change whether field can be edited - * @param enabled whether field can be edited - */ - public void setEnabled(boolean enabled) { - this.enabled = enabled; - this.dropdown.setEnabled(enabled); - } - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java deleted file mode 100644 index 27d32fff33..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Checklist.java +++ /dev/null @@ -1,179 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; - -import java.io.BufferedReader; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; - -import org.deidentifier.arx.gui.model.ModelRiskWizard; - -/** - * the Checklist holds the sections and calculates the overall score - * - */ -public class Checklist { - /** - * the array containing the sections of the checklist - */ - private ArrayList
sections; - - /** - * the maximum achievable weight - */ - private double maximumWeight = 0.0; - - /** - * the current weight configuration - */ - protected ModelRiskWizard weightConfiguration; - - /** - * create a checklist from a file - * @param filename the filename - */ - public Checklist(String filename) { - super(); - weightConfiguration = new ModelRiskWizard(); - try { - // initialize reader - BufferedReader bufferedReader = new BufferedReader(new FileReader(filename)); - loadChecklist(bufferedReader); - } catch(IOException e) { - //e.printStackTrace(); - } - } - - /** - * create a checklist from an input stream - * @param stream the input stream - */ - public Checklist(InputStream stream) { - super(); - weightConfiguration = new ModelRiskWizard(); - // initialize reader - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); - loadChecklist(bufferedReader); - } - - /** - * loads the checklist using a buffered reader - * @param bufferedReader the buffered reader used to parse the file - */ - private void loadChecklist(BufferedReader bufferedReader) { - // create new and empty sections array - sections = new ArrayList
(); - - try { - - // hold a reference to the current section - Section currentSection = null; - - // read first line, then iterate over the lines - String line = bufferedReader.readLine(); - while (line != null) { - line = line.trim(); // get rid of leading/trailing whitespaces - if(line.length() == 0) { - // do nothing - } else if(line.startsWith("#") == true) { - // current line is a section - line = line.substring(1); - currentSection = Section.sectionFromLine(weightConfiguration, line); - sections.add(currentSection); - maximumWeight += Math.abs(currentSection.getWeight()); - } else { - // current line is an item - if(currentSection == null) { - //System.out.println("Invalid syntax. Checklist item before section (section-lines start with #)"); - } - - // parse and add item - Question newItem = Question.itemFromLine(currentSection, line); - currentSection.addItem(newItem); - } - - // read next line - line = bufferedReader.readLine(); - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - if(bufferedReader != null) { - try { - bufferedReader.close(); - } catch (IOException e) { - //e.printStackTrace(); - } - } - } - } - - /** - * get all sections - * @return the sections - */ - public Section[] getSections() { - return (sections.toArray(new Section[sections.size()])); - } - - /** - * get the maximum weight - * @return the maximum weight - */ - public double getMaximumWeight() { - return maximumWeight; - } - - /** - * get the current score of the complete checklist - * @return the score - */ - public double getScore() { - if(maximumWeight == 0.0) { - //System.out.println("This Checklist has a maximum weight of 0.0, it can't calculate a score: "+this); - return 0.0; - } - double result = 0.0; - for(Section s : sections) { - result += s.getWeight() * s.getScore(); - } - result /= maximumWeight; - return result; - } - - @Override - public String toString() { - return "Checklist [score="+this.getScore()+", sections=" + sections + "\n]"; - } - - /** - * gets the current weight configuration - * @return the weight configuration - */ - public ModelRiskWizard getWeightConfiguration() { - return this.weightConfiguration; - } - - /** - * sets the weight configuration and updates the values - * @param weightConfiguration the weight configuration - */ - public void setWeightConfiguration(ModelRiskWizard weightConfiguration) { - if(this.weightConfiguration == weightConfiguration) { - return; - } - - this.weightConfiguration = weightConfiguration; - this.maximumWeight = 0.0; - for(Section s : this.sections) { - s.setWeightConfiguration(weightConfiguration); - maximumWeight += Math.abs(s.getWeight()); - } - - } - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java deleted file mode 100644 index e4240d4289..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Item.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; - -import org.deidentifier.arx.gui.model.ModelRiskWizard; - -/** - * this is the base class for the Question as well as the Section. - * - */ -public abstract class Item { - /** - * the current weight configuration - */ - private ModelRiskWizard weightConfiguration; - - /** - * the identifier (used for the weight configuration) - */ - protected String identifier; - - /** - * the item's title - */ - protected String title; - - /** - * create a new item from a line - * @param line the line to parse - */ - public Item(String line) { - String components[] = line.split(":",2); - if(components.length != 2) { - //System.err.println("Couldn't parse item! Original line: "+line); - return; - } - this.identifier = components[0].trim(); - this.title = components[1].trim(); - } - - protected ModelRiskWizard getWeightConfiguration() { - return this.weightConfiguration; - } - - /** - * set weight configuration and update weights - * @param weightConfiguration - */ - public void setWeightConfiguration(ModelRiskWizard weightConfiguration) { - this.weightConfiguration = weightConfiguration; - updateWeights(); - } - - /** - * update the weights, used by subclasses to calculate the new score accordingly - */ - public void updateWeights() { - - } - - /** - * gets the current weight for this item according to the current weight configuration - * @return - */ - public double getWeight() { - if(weightConfiguration == null) { - return 1.0; - } - return weightConfiguration.weightForIdentifier(this.getIdentifier()); - } - - /** - * updates the weight configurations weight for this item - * @param weight the new weight for this item - */ - public void setWeight(double weight) { - weightConfiguration.setWeightForIdentifier(this.getIdentifier(), weight); - } - - public String getTitle() { - return title; - } - - public String getIdentifier() { - return identifier; - } - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java deleted file mode 100644 index bd8b8b1af4..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Question.java +++ /dev/null @@ -1,83 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; - -import org.deidentifier.arx.gui.resources.Resources; - -/** - * represents a single question from the checklist - * - */ -public class Question extends Item { - /** - * the section this question is in - */ - private Section section; - - public enum Answer { YES, NO, N_A } - - /** - * the current answer - */ - public Answer answer; - - /** - * creates a new question in a section, from a line - * @param section the section this question is in - * @param line the line to parse - */ - public Question(Section section, String line) { - super(line); - this.section = section; - this.answer = Answer.N_A; - } - - /** - * creates a new question from a line, in a section - * @param section the section this question is in - * @param line the line to parse - * @return the question item - */ - public static Question itemFromLine(Section section, String line) { - line = line.trim(); - Question item = new Question(section, line); - return item; - } - - public String getIdentifier() { - return section.getIdentifier()+"."+identifier; - } - - /** - * get the current answer as a string - * @return the string - */ - public String getAnswerString() { - switch(answer) { - case YES: - return Resources.getMessage("RiskWizard.3"); - case NO: - return Resources.getMessage("RiskWizard.4"); - default: - return Resources.getMessage("RiskWizard.5"); - } - } - - /** - * returns the question's score using the weight and taking the answer into account - * @return the score - */ - public double getScore() { - switch(answer) { - case YES: - return this.getWeight(); - case NO: - return -this.getWeight(); - default: - return 0.0; - } - } - - @Override - public String toString() { - return "\n\t\tQuestion [id=" + this.getIdentifier() + ", answer=" + this.getAnswerString() + ", weight=" + this.getWeight() + ", title=" + title + "]"; - } -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java deleted file mode 100644 index 119a823ff1..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/checklist/Section.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist; - -import java.util.ArrayList; - -import org.deidentifier.arx.gui.model.ModelRiskWizard; - -/** - * represents a section from the checklist - * - */ -public class Section extends Item { - /** - * the items this section contains - */ - private ArrayList items; - - /** - * the maximum weight possible - */ - private double maximumWeight = 0.0; - - /** - * create a new section from a line - * @param weightConfiguration the current weight configuration - * @param line the line to parse - */ - public Section(ModelRiskWizard weightConfiguration, String line) { - super(line); - this.items = new ArrayList(); - setWeightConfiguration(weightConfiguration); - } - - /** - * create a new section from a line - * @param weightConfiguration the current weight configuration - * @param line the line to parse - * @return the section item - */ - public static Section sectionFromLine(ModelRiskWizard weightConfiguration, String line) { - line = line.trim(); - Section section = new Section(weightConfiguration, line); - return section; - } - - /** - * get all questions in this section - * @return - */ - public Question[] getItems() { - return items.toArray(new Question[items.size()]); - } - - /** - * add a question to the section and updates the maximumWeight - * @param item the question to add - */ - public void addItem(Question item) { - item.setWeightConfiguration(this.getWeightConfiguration()); - items.add(item); - maximumWeight += Math.abs(item.getWeight()); - } - - /** - * updates the weights and calculates the maximum weight - */ - public void updateWeights() { - super.updateWeights(); - - maximumWeight = 0.0; - for(Question item : items) { - item.setWeightConfiguration(this.getWeightConfiguration()); - maximumWeight += Math.abs(item.getWeight()); - } - } - - public double getMaximumWeight() { - return maximumWeight; - } - - /** - * calculates the score based on the section's question's scores - * @return - */ - public double getScore() { - if(maximumWeight == 0.0) { - //System.out.println("This Section has a maximum weight of 0.0, it can't calculate a score: "+this); - return 0.0; - } - double result = 0.0; - for(Question q : items) { - result += q.getScore(); - } - // if the weight is negative, 'flip' the answers rating (yes will be -1, no will be 1) - if(this.getWeight() < 0.0) { - result = (result * (-1.0)); - } - result /= maximumWeight; - return result; - } - - @Override - public String toString() { - return "\n\tSection [id=" + this.getIdentifier() + ", title=" + this.getTitle() + ", weight=" + this.getWeight() + ", score="+ this.getScore() +", items=" + items + ", config="+this.getWeightConfiguration()+"\n\t]"; - } - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java deleted file mode 100644 index 3ff1cd0853..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/MonitorVisualization.java +++ /dev/null @@ -1,97 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation; - -import java.util.ArrayList; -import java.util.List; - -import org.deidentifier.arx.gui.Controller; -import org.deidentifier.arx.gui.resources.Resources; -import org.deidentifier.arx.gui.view.SWTUtil; -import org.deidentifier.arx.gui.view.impl.common.ComponentRiskMonitor; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Composite; - -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.*; - -/** - * the monitor visualization - * - */ -public class MonitorVisualization extends Visualization { - /** - * contains the monitors for each section - */ - private List monitors; - - /** - * the total monitor, showing the overall score - */ - private ComponentRiskMonitor totalMonitor; - - /** - * create a new monitor visualization - * @param parent the parent - * @param controller the controller - * @param checklist the checklist to use - */ - public MonitorVisualization(Composite parent, Controller controller, Checklist checklist) { - super(parent, controller, checklist); - } - - /** - * creates the view containing the different monitors - */ - protected void createVisualization() { - Section sections[] = this.checklist.getSections(); - monitors = new ArrayList(); - - //Composite rootComposite = new Composite(parent, SWT.NONE); - GridLayout layout = SWTUtil.createGridLayoutWithEqualWidth(sections.length); - layout.marginHeight = 0; - layout.marginTop = 0; - layout.marginBottom = 0; -// layout.verticalSpacing = 0; - layout.makeColumnsEqualWidth = true; - this.setLayout(layout); - - for(int i = 0; i < sections.length; i++) { - String title = sections[i].getTitle(); - - ComponentRiskMonitor riskMonitor = new ComponentRiskMonitor(this, this.controller, title, title); - riskMonitor.setLayoutData(SWTUtil.createFillGridData()); - riskMonitor.setRisk(0.5); - monitors.add(riskMonitor); - } - - String totalTitle = Resources.getMessage("RiskWizard.2"); - totalMonitor = new ComponentRiskMonitor(this, this.controller, totalTitle, totalTitle); - totalMonitor.setLayoutData(SWTUtil.createFillGridData()); - totalMonitor.setRisk(0.5); - - GridData gridData = new GridData(); - gridData.grabExcessVerticalSpace = true; - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.FILL; - gridData.minimumHeight = 150; - gridData.horizontalSpan = layout.numColumns; - totalMonitor.setLayoutData(gridData); - } - - /** - * update the UI when the weights change - */ - public void updateWeights() { - Section sections[] = checklist.getSections(); - for(int i = 0; i < sections.length; i++) { - Section s = sections[i]; - - ComponentRiskMonitor riskMonitor = monitors.get(i); - riskMonitor.setRisk(1.0 - ((s.getScore() / 2.0) + 0.5)); - // System.out.println("Setup"); - } - - totalMonitor.setRisk(1.0 - ((checklist.getScore() / 2.0) + 0.5)); - } - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java deleted file mode 100644 index 70f9f563f4..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/StackVisualization.java +++ /dev/null @@ -1,153 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Composite; -import org.swtchart.*; -import org.swtchart.ISeries.*; -import org.deidentifier.arx.gui.Controller; -import org.deidentifier.arx.gui.resources.Resources; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Question; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Section; - -/** - * the stack visualization - * - */ -public class StackVisualization extends Visualization { - /** - * the displayed chart - */ - private Chart chart; - - /** - * the bar series for the positive values - */ - private IBarSeries positive; - - /** - * the bar series for the neutral values - */ - private IBarSeries neutral; - - /** - * the bar series for the negative values - */ - private IBarSeries negative; - - - /** - * create a new stack visualization - * @param parent the parent - * @param controller the controller - * @param checklist the checklist - */ - public StackVisualization(Composite parent, Controller controller, Checklist checklist) { - super(parent, controller, checklist); - } - - /** - * creates the view containing the stack bar graph visualization - */ - protected void createVisualization() { - Section sections[] = this.checklist.getSections(); - String sectionNames[] = new String[sections.length]; - int idx = 0; - for(Section s : sections) { - sectionNames[idx] = s.getTitle(); - idx++; - } - - FillLayout fillLayout = new FillLayout(); - fillLayout.type = SWT.VERTICAL; - this.setLayout(fillLayout); - chart = new Chart(this, SWT.NONE); - chart.getTitle().setText(Resources.getMessage("RiskWizard.18")); - - double[] positiveSeries = { 0.1, 0, 0}; - double[] neutralSeries = { 0.1, 0, 0}; - double[] negativeSeries = { 0.1, 0, 0}; - - ISeriesSet seriesSet = chart.getSeriesSet(); - - positive = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, Resources.getMessage("RiskWizard.15")); - positive.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_GREEN)); - positive.enableStack(true); - positive.setYSeries(positiveSeries); - - neutral = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, Resources.getMessage("RiskWizard.16")); - neutral.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_GRAY)); - neutral.enableStack(true); - neutral.setYSeries(neutralSeries); - - negative = (IBarSeries)seriesSet.createSeries(SeriesType.BAR, Resources.getMessage("RiskWizard.17")); - negative.setBarColor(this.getDisplay().getSystemColor(SWT.COLOR_RED)); - negative.enableStack(true); - negative.setYSeries(negativeSeries); - - IAxisSet axisSet = chart.getAxisSet(); - axisSet.adjustRange(); - - IAxis yAxis = axisSet.getYAxis(0); - yAxis.setRange(new Range(0.0, 1.05)); - yAxis.getTitle().setVisible(false); - - IAxis xAxis = axisSet.getXAxis(0); - xAxis.setCategorySeries(sectionNames); - xAxis.enableCategory(true); - xAxis.getTitle().setVisible(false); - } - - /** - * updates the UI when the weights/score changes - */ - public void updateWeights() { - Section sections[] = this.checklist.getSections(); - double[] posY = new double[sections.length]; - double[] neuY = new double[sections.length]; - double[] negY = new double[sections.length]; - - int idx = 0; - for(Section sec : sections) { - double pos = 0.0; - double neu = 0.0; - double neg = 0.0; - - for(Question q : sec.getItems()) { - double w = q.getWeight(); - double s = q.getScore(); - if(s == 0.0) { - neu += w; - } else if(s > 0.0) { - pos += w; - } else { - neg += w; - } - } - - posY[idx] = pos / sec.getMaximumWeight(); - neuY[idx] = neu / sec.getMaximumWeight(); - negY[idx] = neg / sec.getMaximumWeight(); - - //System.out.println("Updated "+sec.getIdentifier()+" : "+posY[idx]+" "+neuY[idx]+" "+negY[idx]); - - idx++; - - - } - - - positive.setYSeries(posY); - positive.enableStack(true); - neutral.setYSeries(neuY); - neutral.enableStack(true); - negative.setYSeries(negY); - negative.enableStack(true); - - chart.update(); - chart.redraw(); - } - - -} diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java deleted file mode 100644 index b6bcbd13dd..0000000000 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/sharingwizard/evaluation/Visualization.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.evaluation; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.widgets.Composite; -import org.deidentifier.arx.gui.Controller; -import org.deidentifier.arx.gui.view.impl.wizard.sharingwizard.checklist.Checklist; - -/** - * base class for the visualizations - * - */ -public abstract class Visualization extends Composite { - /** - * the checklist used for the visualization - */ - protected Checklist checklist; - - protected Controller controller; - - /** - * create a new visualization for the checklist - * @param parent the parent - * @param controller the controller - * @param checklist the checklist - */ - public Visualization(Composite parent, Controller controller, Checklist checklist) { - super(parent, SWT.NO_SCROLL); - - GridData gridData = new GridData(); - gridData.grabExcessHorizontalSpace = true; - gridData.grabExcessVerticalSpace = true; - gridData.horizontalAlignment = SWT.FILL; - gridData.verticalAlignment = SWT.FILL; - this.setLayoutData(gridData); - - this.checklist = checklist; - this.controller = controller; - this.createVisualization(); - } - - /** - * used in subclasses for the initial setup - */ - protected void createVisualization() { - - } - - /** - * used in subclasses to respond to changes - */ - public void updateWeights() { - - } - -} diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java new file mode 100644 index 0000000000..c279f1cb0a --- /dev/null +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java @@ -0,0 +1,199 @@ +/* + * 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.risk; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; + +/** + * The questionnaire holds the sections and calculates the overall score + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskQuestionnaire { + + /** The array containing the sections of the checklist */ + private ArrayList sections; + + /** The maximum achievable weight */ + private double maximumWeight = 0.0; + + /** Current weight configuration */ + protected RiskQuestionnaireWeights weightConfiguration; + + /** + * Create a checklist from an input stream + * + * @param stream + * the input stream + */ + public RiskQuestionnaire(InputStream stream) { + super(); + weightConfiguration = new RiskQuestionnaireWeights(); + // initialize reader + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); + loadChecklist(bufferedReader); + } + + /** + * Create a checklist from a file + * + * @param filename + * the filename + */ + public RiskQuestionnaire(String filename) { + super(); + weightConfiguration = new RiskQuestionnaireWeights(); + try { + // initialize reader + BufferedReader bufferedReader = new BufferedReader(new FileReader(filename)); + loadChecklist(bufferedReader); + } catch (IOException e) { + // e.printStackTrace(); + } + } + + /** + * Get the maximum weight + * + * @return the maximum weight + */ + public double getMaximumWeight() { + return maximumWeight; + } + + /** + * Get the current score of the complete checklist + * + * @return the score + */ + public double getScore() { + if (maximumWeight == 0.0) { + // System.out.println("This Checklist has a maximum weight of 0.0, it can't calculate a score: "+this); + return 0.0; + } + double result = 0.0; + for (RiskQuestionnaireSection s : sections) { + result += s.getWeight() * s.getScore(); + } + result /= maximumWeight; + return result; + } + + /** + * Get all sections + * + * @return the sections + */ + public RiskQuestionnaireSection[] getSections() { + return (sections.toArray(new RiskQuestionnaireSection[sections.size()])); + } + + /** + * Gets the current weight configuration + * + * @return the weight configuration + */ + public RiskQuestionnaireWeights getWeightConfiguration() { + return this.weightConfiguration; + } + + /** + * Sets the weight configuration and updates the values + * + * @param weightConfiguration + * the weight configuration + */ + public void setWeightConfiguration(RiskQuestionnaireWeights weightConfiguration) { + if (this.weightConfiguration == weightConfiguration) { return; } + + this.weightConfiguration = weightConfiguration; + this.maximumWeight = 0.0; + for (RiskQuestionnaireSection s : this.sections) { + s.setWeightConfiguration(weightConfiguration); + maximumWeight += Math.abs(s.getWeight()); + } + } + + @Override + public String toString() { + return "Checklist [score=" + this.getScore() + ", sections=" + sections + "\n]"; + } + + /** + * Loads the checklist using a buffered reader + * + * @param bufferedReader + */ + private void loadChecklist(BufferedReader bufferedReader) { + // create new and empty sections array + sections = new ArrayList(); + + try { + + // hold a reference to the current section + RiskQuestionnaireSection currentSection = null; + + // read first line, then iterate over the lines + String line = bufferedReader.readLine(); + while (line != null) { + line = line.trim(); // get rid of leading/trailing whitespaces + if (line.length() == 0) { + // do nothing + } else if (line.startsWith("#") == true) { + // current line is a section + line = line.substring(1); + currentSection = RiskQuestionnaireSection.sectionFromLine(weightConfiguration, + line); + sections.add(currentSection); + maximumWeight += Math.abs(currentSection.getWeight()); + } else { + // current line is an item + if (currentSection == null) { + // System.out.println("Invalid syntax. Checklist item before section (section-lines start with #)"); + } + + // parse and add item + RiskQuestionnaireQuestion newItem = RiskQuestionnaireQuestion.itemFromLine(currentSection, + line); + currentSection.addItem(newItem); + } + + // read next line + line = bufferedReader.readLine(); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (bufferedReader != null) { + try { + bufferedReader.close(); + } catch (IOException e) { + // e.printStackTrace(); + } + } + } + } +} diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java new file mode 100644 index 0000000000..9d4b83acbf --- /dev/null +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java @@ -0,0 +1,108 @@ +/* + * 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.risk; + +/** + * This is the base class for the Question as well as the Section. + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public abstract class RiskQuestionnaireItem { + + /** Current weight configuration */ + private RiskQuestionnaireWeights weightConfiguration; + + /** Identifier (used for the weight configuration) */ + protected String identifier; + + /** Item's title */ + protected String title; + + /** + * Create a new item from a line + * + * @param line + * the line to parse + */ + public RiskQuestionnaireItem(String line) { + String components[] = line.split(":", 2); + if (components.length != 2) { + // System.err.println("Couldn't parse item! Original line: "+line); + return; + } + this.identifier = components[0].trim(); + this.title = components[1].trim(); + } + + /** + * Returns the identifier + * + * @return + */ + public String getIdentifier() { + return identifier; + } + + /** + * Returns the title + * + * @return + */ + public String getTitle() { + return title; + } + + /** + * Gets the current weight for this item according to the current weight + * configuration + * + * @return + */ + public double getWeight() { + if (weightConfiguration == null) { return 1.0; } + return weightConfiguration.weightForIdentifier(this.getIdentifier()); + } + + /** + * Updates the weight configurations weight for this item + * + * @param weight + */ + public void setWeight(double weight) { + weightConfiguration.setWeightForIdentifier(this.getIdentifier(), weight); + } + + /** + * Set weight configuration and update weights + * + * @param weightConfiguration + */ + public void setWeightConfiguration(RiskQuestionnaireWeights weightConfiguration) { + this.weightConfiguration = weightConfiguration; + } + + /** + * Returns the config + * + * @return + */ + protected RiskQuestionnaireWeights getWeightConfiguration() { + return this.weightConfiguration; + } +} diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java new file mode 100644 index 0000000000..0ac30b3fbd --- /dev/null +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java @@ -0,0 +1,115 @@ +/* + * 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.risk; + +import org.deidentifier.arx.gui.resources.Resources; + +/** + * Represents a single question from the checklist + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskQuestionnaireQuestion extends RiskQuestionnaireItem { + + /** Enum for answers */ + public enum Answer { + YES, + NO, + N_A + } + + /** + * Creates a new question from a line, in a section + * + * @param section + * @param line + * @return the question item + */ + public static RiskQuestionnaireQuestion itemFromLine(RiskQuestionnaireSection section, + String line) { + line = line.trim(); + RiskQuestionnaireQuestion item = new RiskQuestionnaireQuestion(section, line); + return item; + } + + /** The section this question is in */ + private RiskQuestionnaireSection section; + + /** Current answer */ + public Answer answer; + + /** + * Creates a new question in a section, from a line + * + * @param section + * @param line + */ + public RiskQuestionnaireQuestion(RiskQuestionnaireSection section, String line) { + super(line); + this.section = section; + this.answer = Answer.N_A; + } + + /** + * Get the current answer as a string + * + * @return the string + */ + public String getAnswerString() { + switch (answer) { + case YES: + return Resources.getMessage("RiskWizard.3"); + case NO: + return Resources.getMessage("RiskWizard.4"); + default: + return Resources.getMessage("RiskWizard.5"); + } + } + + /** + * Returns the identifier + */ + @Override + public String getIdentifier() { + return section.getIdentifier() + "." + identifier; + } + + /** + * Returns the question's score using the weight and taking the answer into + * account + * + * @return the score + */ + public double getScore() { + switch (answer) { + case YES: + return this.getWeight(); + case NO: + return -this.getWeight(); + default: + return 0.0; + } + } + + @Override + public String toString() { + return "\n\t\tQuestion [id=" + this.getIdentifier() + ", answer=" + this.getAnswerString() + + ", weight=" + this.getWeight() + ", title=" + title + "]"; + } +} diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java new file mode 100644 index 0000000000..aa356a0ea1 --- /dev/null +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java @@ -0,0 +1,134 @@ +/* + * 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.risk; + +import java.util.ArrayList; + +/** + * Represents a section from the checklist + * + * @author Thomas Guenzel + * @author Fabian Prasser + */ +public class RiskQuestionnaireSection extends RiskQuestionnaireItem { + + /** + * Create a new section from a line + * + * @param weightConfiguration + * @param line + * @return the section item + */ + public static RiskQuestionnaireSection + sectionFromLine(RiskQuestionnaireWeights weightConfiguration, String line) { + line = line.trim(); + RiskQuestionnaireSection section = new RiskQuestionnaireSection(weightConfiguration, line); + return section; + } + + /** The items this section contains */ + private ArrayList items; + + /** The maximum weight possible */ + private double maximumWeight = 0.0; + + /** + * Create a new section from a line + * + * @param weightConfiguration + * the current weight configuration + * @param line + * the line to parse + */ + public RiskQuestionnaireSection(RiskQuestionnaireWeights weightConfiguration, String line) { + super(line); + this.items = new ArrayList(); + setWeightConfiguration(weightConfiguration); + } + + /** + * Add a question to the section and updates the maximumWeight + * + * @param item + * the question to add + */ + public void addItem(RiskQuestionnaireQuestion item) { + item.setWeightConfiguration(this.getWeightConfiguration()); + items.add(item); + maximumWeight += Math.abs(item.getWeight()); + } + + /** + * Get all questions in this section + * + * @return + */ + public RiskQuestionnaireQuestion[] getItems() { + return items.toArray(new RiskQuestionnaireQuestion[items.size()]); + } + + /** + * Returns the maximum weight + * + * @return + */ + public double getMaximumWeight() { + return maximumWeight; + } + + /** + * Calculates the score based on the section's question's scores + * + * @return + */ + public double getScore() { + if (maximumWeight == 0.0) { + // System.out.println("This Section has a maximum weight of 0.0, it can't calculate a score: "+this); + return 0.0; + } + double result = 0.0; + for (RiskQuestionnaireQuestion q : items) { + result += q.getScore(); + } + // if the weight is negative, 'flip' the answers rating (yes will be -1, + // no will be 1) + if (this.getWeight() < 0.0) { + result = (result * (-1.0)); + } + result /= maximumWeight; + return result; + } + + @Override + public String toString() { + return "\n\tSection [id=" + this.getIdentifier() + ", title=" + this.getTitle() + + ", weight=" + this.getWeight() + ", score=" + this.getScore() + ", items=" + items + + ", config=" + this.getWeightConfiguration() + "\n\t]"; + } + + /** + * Updates the weights and calculates the maximum weight + */ + public void updateWeights() { + maximumWeight = 0.0; + for (RiskQuestionnaireQuestion item : items) { + item.setWeightConfiguration(this.getWeightConfiguration()); + maximumWeight += Math.abs(item.getWeight()); + } + } +} diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java new file mode 100644 index 0000000000..80222e8cbc --- /dev/null +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java @@ -0,0 +1,138 @@ +/* + * 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.risk; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +/** + * The weight configuration used when evaluating the checklist + * + */ +public class RiskQuestionnaireWeights implements Serializable { + + /** SVUID */ + private static final long serialVersionUID = -7601091333545929290L; + + /** Map, mapping the item identifiers to a weight */ + private Map weights; + + /** + * Create a new configuration + */ + public RiskQuestionnaireWeights() { + weights = new HashMap(); + } + + /** + * Create a new configuration from a file + * + * @param filename + */ + public RiskQuestionnaireWeights(String filename) { + this(); + loadProperties(filename); + } + + /** + * Save the configuration to a new filename + * + * @param filename + */ + public void save(String filename) { + if (filename == null) { + // System.out.println("No file specified to save to"); + return; + } + + Properties props = new Properties(); + for (Entry entry : weights.entrySet()) { + props.setProperty(entry.getKey(), Double.toString(entry.getValue())); + } + + FileOutputStream out; + try { + out = new FileOutputStream(filename); + props.store(out, null); + out.close(); + } catch (FileNotFoundException e) { + // System.err.println("Couldn't open file: "+filename); + return; + } catch (IOException e) { + // System.err.println("Couldn't store file: "+filename); + return; + } + } + + /** + * Sets the weight for an item's identifier + * + * @param identifier + * @param weight + */ + public void setWeightForIdentifier(String identifier, double weight) { + weights.put(identifier, weight); + } + + /** + * Get the weight for an item's identifier + * + * @param identifier + * @return the weight + */ + public double weightForIdentifier(String identifier) { + if (weights.containsKey(identifier) == false) { return 1.0; } + return weights.get(identifier); + } + + /** + * Try to load the weights from the specified filename + * + * @param filename + */ + private void loadProperties(String filename) { + Properties props = new Properties(); + try { + FileInputStream in = new FileInputStream(filename); + props.load(in); + + for (Entry entry : props.entrySet()) { + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + + double weight = Double.parseDouble(value); + weights.put(key, weight); + } + in.close(); + } catch (FileNotFoundException e) { + // System.err.println("Couldn't open file: "+filename); + return; + } catch (IOException e) { + // System.err.println("Couldn't parse file: "+filename); + return; + } + + } +} From 03ddcdb238166b42d4f52b891bff7c52567d4761 Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Fri, 3 Feb 2017 17:25:51 +0100 Subject: [PATCH 15/22] Add --- default.weights | 37 ++++++++ .../arx/gui/resources/messages.properties | 4 +- .../arx/risk/RiskQuestionnaire.java | 86 ++++++++----------- .../arx/risk/RiskQuestionnaireItem.java | 59 ++++++------- .../arx/risk/RiskQuestionnaireQuestion.java | 6 +- 5 files changed, 100 insertions(+), 92 deletions(-) create mode 100644 default.weights diff --git a/default.weights b/default.weights new file mode 100644 index 0000000000..f2db77e539 --- /dev/null +++ b/default.weights @@ -0,0 +1,37 @@ +#Fri Feb 03 11:20:12 CET 2017 +privacy.sensitive-data=1.0 +mitigating.privacy-policy=1.0 +privacy.injury-serious=1.0 +motives.recipient-only-choice=1.0 +motives=1.0 +motives.recipient-wants-harm=1.0 +mitigating.security-documentation=1.0 +mitigating.staff-confidential=1.0 +privacy.injury-risk=1.0 +motives.re-identify-resources=1.0 +mitigating.staff-trained=1.0 +mitigating.sharing-forbids=1.0 +privacy.sensitive-context=1.0 +privacy.foreign-laws-risk=1.0 +mitigating.physically-privatearea=1.0 +mitigating.sharing-dblimits=1.0 +privacy.large-database=1.0 +mitigating.staff-restricted=1.0 +mitigating.breach-protocol=1.0 +mitigating.data-destruction=1.0 +mitigating.physically-secure=1.0 +motives.criminal-value=1.0 +motives.re-identify-expertise=1.0 +mitigating.system-full-control=1.0 +mitigating.sharing-enforceable=1.0 +mitigating.privacy-on-site=1.0 +privacy.highly-detailed=1.0 +mitigating.recipient-assessment=1.0 +mitigating=1.0 +privacy.no-promise=1.0 +motives.re-identify-motive=1.0 +privacy.no-expectation=1.0 +mitigating.sharing-audits=1.0 +privacy.no-guarantee=1.0 +mitigating.system-backlog=1.0 +privacy=1.0 diff --git a/src/gui/org/deidentifier/arx/gui/resources/messages.properties b/src/gui/org/deidentifier/arx/gui/resources/messages.properties index 32ac19f9db..dd13af358a 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/messages.properties +++ b/src/gui/org/deidentifier/arx/gui/resources/messages.properties @@ -265,7 +265,7 @@ MainMenu.21=Anonymize MainMenu.23=Create hierarchy... MainMenu.25=Settings... MainMenu.27=Help -MainMenu.28=Checklist wizard... +MainMenu.28=Risk analysis questionnaire... MainMenu.29=About MainMenu.3=New project... MainMenu.30=Find/replace... @@ -1251,7 +1251,7 @@ ViewStatisticsClassificationInput.14=Confidence threshold [%] ViewStatisticsClassificationInput.15=Precision ViewStatisticsClassificationInput.16=Recall ViewStatisticsClassificationInput.17=Value [%] -RiskWizard.0=Checklist Wizard +RiskWizard.0=Risk analysis questionnaire RiskWizard.1=Answer the following questions RiskWizard.2=Total RiskWizard.3=Yes diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java index c279f1cb0a..099a261bd3 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java @@ -23,6 +23,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; +import java.util.List; + /** * The questionnaire holds the sections and calculates the overall score @@ -31,55 +33,33 @@ * @author Fabian Prasser */ public class RiskQuestionnaire { + + // TODO: LOAD/SAVE OF WEIGHTS DOES NOT WORK CURRENTLY /** The array containing the sections of the checklist */ - private ArrayList sections; + private List sections = new ArrayList<>(); /** The maximum achievable weight */ - private double maximumWeight = 0.0; - - /** Current weight configuration */ - protected RiskQuestionnaireWeights weightConfiguration; - - /** - * Create a checklist from an input stream - * - * @param stream - * the input stream - */ - public RiskQuestionnaire(InputStream stream) { - super(); - weightConfiguration = new RiskQuestionnaireWeights(); - // initialize reader - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream)); - loadChecklist(bufferedReader); - } + private double maxScore = 0.0d; /** - * Create a checklist from a file + * Create a questionnaire from an input stream * - * @param filename - * the filename + * @param stream the input stream + * @throws IOException */ - public RiskQuestionnaire(String filename) { - super(); - weightConfiguration = new RiskQuestionnaireWeights(); - try { - // initialize reader - BufferedReader bufferedReader = new BufferedReader(new FileReader(filename)); - loadChecklist(bufferedReader); - } catch (IOException e) { - // e.printStackTrace(); - } + public RiskQuestionnaire(InputStream stream) throws IOException { + load(new BufferedReader(new InputStreamReader(stream))); } /** - * Get the maximum weight + * Create a questionnaire from a file * - * @return the maximum weight + * @param filename the filename + * @throws IOException */ - public double getMaximumWeight() { - return maximumWeight; + public RiskQuestionnaire(String filename) throws IOException { + load(new BufferedReader(new FileReader(filename))); } /** @@ -88,15 +68,11 @@ public double getMaximumWeight() { * @return the score */ public double getScore() { - if (maximumWeight == 0.0) { - // System.out.println("This Checklist has a maximum weight of 0.0, it can't calculate a score: "+this); - return 0.0; - } double result = 0.0; for (RiskQuestionnaireSection s : sections) { - result += s.getWeight() * s.getScore(); + result += s.getScore(); } - result /= maximumWeight; + result /= maxScore; return result; } @@ -128,24 +104,26 @@ public void setWeightConfiguration(RiskQuestionnaireWeights weightConfiguration) if (this.weightConfiguration == weightConfiguration) { return; } this.weightConfiguration = weightConfiguration; - this.maximumWeight = 0.0; + this.maxScore = 0.0; for (RiskQuestionnaireSection s : this.sections) { s.setWeightConfiguration(weightConfiguration); - maximumWeight += Math.abs(s.getWeight()); + maxScore += Math.abs(s.getWeight()); } } @Override public String toString() { - return "Checklist [score=" + this.getScore() + ", sections=" + sections + "\n]"; + return "Questionnaire [score=" + this.getScore() + ", sections=" + sections + "\n]"; } /** * Loads the checklist using a buffered reader * * @param bufferedReader + * @throws IOException */ - private void loadChecklist(BufferedReader bufferedReader) { + private void load(BufferedReader bufferedReader) throws IOException { + // create new and empty sections array sections = new ArrayList(); @@ -163,10 +141,9 @@ private void loadChecklist(BufferedReader bufferedReader) { } else if (line.startsWith("#") == true) { // current line is a section line = line.substring(1); - currentSection = RiskQuestionnaireSection.sectionFromLine(weightConfiguration, - line); + currentSection = RiskQuestionnaireSection.sectionFromLine(weightConfiguration, line); sections.add(currentSection); - maximumWeight += Math.abs(currentSection.getWeight()); + maxScore += Math.abs(currentSection.getWeight()); } else { // current line is an item if (currentSection == null) { @@ -182,16 +159,21 @@ private void loadChecklist(BufferedReader bufferedReader) { // read next line line = bufferedReader.readLine(); } + + if (maxScore <= 0d) { + throw new IOException("Invalid overall weight: " + maxScore); + } + } catch (FileNotFoundException e) { - e.printStackTrace(); + throw(e); } catch (IOException e) { - e.printStackTrace(); + throw(e); } finally { if (bufferedReader != null) { try { bufferedReader.close(); } catch (IOException e) { - // e.printStackTrace(); + // Ignore } } } diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java index 9d4b83acbf..526e880ad3 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java @@ -17,6 +17,8 @@ package org.deidentifier.arx.risk; +import java.io.IOException; + /** * This is the base class for the Question as well as the Section. * @@ -25,26 +27,36 @@ */ public abstract class RiskQuestionnaireItem { - /** Current weight configuration */ - private RiskQuestionnaireWeights weightConfiguration; - /** Identifier (used for the weight configuration) */ - protected String identifier; + private String identifier = null; /** Item's title */ - protected String title; + private String title = null; + /** Weight */ + private double weight = 1d; + /** - * Create a new item from a line - * + * Creates a new instance + * @param line + * @throws IOException + */ + public RiskQuestionnaireItem(String line) throws IOException { + parse(line); + } + + /** + * Parse the item * @param line - * the line to parse + * @throws IOException */ - public RiskQuestionnaireItem(String line) { + private void parse(String line) throws IOException { + if (line == null) { + throw new IOException("Invalid questionnaire definition: " + line); + } String components[] = line.split(":", 2); - if (components.length != 2) { - // System.err.println("Couldn't parse item! Original line: "+line); - return; + if (components == null ||components.length != 2) { + throw new IOException("Invalid questionnaire definition: " + line); } this.identifier = components[0].trim(); this.title = components[1].trim(); @@ -75,8 +87,7 @@ public String getTitle() { * @return */ public double getWeight() { - if (weightConfiguration == null) { return 1.0; } - return weightConfiguration.weightForIdentifier(this.getIdentifier()); + return this.weight; } /** @@ -85,24 +96,6 @@ public double getWeight() { * @param weight */ public void setWeight(double weight) { - weightConfiguration.setWeightForIdentifier(this.getIdentifier(), weight); - } - - /** - * Set weight configuration and update weights - * - * @param weightConfiguration - */ - public void setWeightConfiguration(RiskQuestionnaireWeights weightConfiguration) { - this.weightConfiguration = weightConfiguration; - } - - /** - * Returns the config - * - * @return - */ - protected RiskQuestionnaireWeights getWeightConfiguration() { - return this.weightConfiguration; + this.weight = weight; } } diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java index 0ac30b3fbd..0463eb1517 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java @@ -41,16 +41,12 @@ public enum Answer { * @param line * @return the question item */ - public static RiskQuestionnaireQuestion itemFromLine(RiskQuestionnaireSection section, - String line) { + public static RiskQuestionnaireQuestion itemFromLine(String line) { line = line.trim(); RiskQuestionnaireQuestion item = new RiskQuestionnaireQuestion(section, line); return item; } - /** The section this question is in */ - private RiskQuestionnaireSection section; - /** Current answer */ public Answer answer; From 0fd6b5245253c36d8a5e32db30ba019f71fc9e06 Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Fri, 3 Feb 2017 18:13:10 +0100 Subject: [PATCH 16/22] Update --- default.weights | 2 +- .../arx/risk/RiskQuestionnaire.java | 80 ++++++----------- .../arx/risk/RiskQuestionnaireItem.java | 6 +- .../arx/risk/RiskQuestionnaireQuestion.java | 41 +++------ .../arx/risk/RiskQuestionnaireSection.java | 87 ++++--------------- .../arx/risk/RiskQuestionnaireWeights.java | 75 +++------------- 6 files changed, 74 insertions(+), 217 deletions(-) diff --git a/default.weights b/default.weights index f2db77e539..794e36531c 100644 --- a/default.weights +++ b/default.weights @@ -34,4 +34,4 @@ privacy.no-expectation=1.0 mitigating.sharing-audits=1.0 privacy.no-guarantee=1.0 mitigating.system-backlog=1.0 -privacy=1.0 +privacy=1.0 \ No newline at end of file diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java index 099a261bd3..8c2160d4fa 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java @@ -39,9 +39,6 @@ public class RiskQuestionnaire { /** The array containing the sections of the checklist */ private List sections = new ArrayList<>(); - /** The maximum achievable weight */ - private double maxScore = 0.0d; - /** * Create a questionnaire from an input stream * @@ -68,11 +65,14 @@ public RiskQuestionnaire(String filename) throws IOException { * @return the score */ public double getScore() { + double result = 0.0; + double max = 0d; for (RiskQuestionnaireSection s : sections) { result += s.getScore(); + max += s.getWeight(); } - result /= maxScore; + result /= max; return result; } @@ -84,36 +84,14 @@ public double getScore() { public RiskQuestionnaireSection[] getSections() { return (sections.toArray(new RiskQuestionnaireSection[sections.size()])); } - + /** - * Gets the current weight configuration - * - * @return the weight configuration + * Sets the weights + * @param weights */ - public RiskQuestionnaireWeights getWeightConfiguration() { - return this.weightConfiguration; - } - - /** - * Sets the weight configuration and updates the values - * - * @param weightConfiguration - * the weight configuration - */ - public void setWeightConfiguration(RiskQuestionnaireWeights weightConfiguration) { - if (this.weightConfiguration == weightConfiguration) { return; } - - this.weightConfiguration = weightConfiguration; - this.maxScore = 0.0; - for (RiskQuestionnaireSection s : this.sections) { - s.setWeightConfiguration(weightConfiguration); - maxScore += Math.abs(s.getWeight()); - } - } - - @Override - public String toString() { - return "Questionnaire [score=" + this.getScore() + ", sections=" + sections + "\n]"; + public void setWeights(RiskQuestionnaireWeights weights) { + // TODO + throw new UnsupportedOperationException(""); } /** @@ -123,47 +101,43 @@ public String toString() { * @throws IOException */ private void load(BufferedReader bufferedReader) throws IOException { - - // create new and empty sections array - sections = new ArrayList(); try { - // hold a reference to the current section + // Hold a reference to the current section RiskQuestionnaireSection currentSection = null; - // read first line, then iterate over the lines + // Read first line, then iterate over the lines String line = bufferedReader.readLine(); while (line != null) { - line = line.trim(); // get rid of leading/trailing whitespaces + + // Get rid of leading/trailing whitespaces + line = line.trim(); if (line.length() == 0) { - // do nothing - } else if (line.startsWith("#") == true) { - // current line is a section - line = line.substring(1); - currentSection = RiskQuestionnaireSection.sectionFromLine(weightConfiguration, line); + + // Ignore + + } else if (line.startsWith("#")) { + + // Current line is a section + currentSection = new RiskQuestionnaireSection(line.substring(1)); sections.add(currentSection); - maxScore += Math.abs(currentSection.getWeight()); + } else { - // current line is an item + + // Current line is an item if (currentSection == null) { - // System.out.println("Invalid syntax. Checklist item before section (section-lines start with #)"); + throw new IOException("Invalid questionnaire specification"); } // parse and add item - RiskQuestionnaireQuestion newItem = RiskQuestionnaireQuestion.itemFromLine(currentSection, - line); - currentSection.addItem(newItem); + currentSection.addItem(new RiskQuestionnaireQuestion(line)); } // read next line line = bufferedReader.readLine(); } - if (maxScore <= 0d) { - throw new IOException("Invalid overall weight: " + maxScore); - } - } catch (FileNotFoundException e) { throw(e); } catch (IOException e) { diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java index 526e880ad3..ea3fcbec17 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java @@ -18,6 +18,7 @@ package org.deidentifier.arx.risk; import java.io.IOException; +import java.io.Serializable; /** * This is the base class for the Question as well as the Section. @@ -25,7 +26,10 @@ * @author Thomas Guenzel * @author Fabian Prasser */ -public abstract class RiskQuestionnaireItem { +public abstract class RiskQuestionnaireItem implements Serializable { + + /** SVUID*/ + private static final long serialVersionUID = -9134631374669047761L; /** Identifier (used for the weight configuration) */ private String identifier = null; diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java index 0463eb1517..2c24719c7f 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java @@ -17,6 +17,9 @@ package org.deidentifier.arx.risk; +import java.io.IOException; +import java.io.Serializable; + import org.deidentifier.arx.gui.resources.Resources; /** @@ -25,7 +28,10 @@ * @author Thomas Guenzel * @author Fabian Prasser */ -public class RiskQuestionnaireQuestion extends RiskQuestionnaireItem { +public class RiskQuestionnaireQuestion extends RiskQuestionnaireItem implements Serializable { + + /** SVUID*/ + private static final long serialVersionUID = 1342060103957413041L; /** Enum for answers */ public enum Answer { @@ -34,19 +40,6 @@ public enum Answer { N_A } - /** - * Creates a new question from a line, in a section - * - * @param section - * @param line - * @return the question item - */ - public static RiskQuestionnaireQuestion itemFromLine(String line) { - line = line.trim(); - RiskQuestionnaireQuestion item = new RiskQuestionnaireQuestion(section, line); - return item; - } - /** Current answer */ public Answer answer; @@ -55,10 +48,10 @@ public static RiskQuestionnaireQuestion itemFromLine(String line) { * * @param section * @param line + * @throws IOException */ - public RiskQuestionnaireQuestion(RiskQuestionnaireSection section, String line) { - super(line); - this.section = section; + public RiskQuestionnaireQuestion(String line) throws IOException { + super(line.trim()); this.answer = Answer.N_A; } @@ -78,14 +71,6 @@ public String getAnswerString() { } } - /** - * Returns the identifier - */ - @Override - public String getIdentifier() { - return section.getIdentifier() + "." + identifier; - } - /** * Returns the question's score using the weight and taking the answer into * account @@ -102,10 +87,4 @@ public double getScore() { return 0.0; } } - - @Override - public String toString() { - return "\n\t\tQuestion [id=" + this.getIdentifier() + ", answer=" + this.getAnswerString() + - ", weight=" + this.getWeight() + ", title=" + title + "]"; - } } diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java index aa356a0ea1..0ef4c2d573 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java @@ -17,7 +17,10 @@ package org.deidentifier.arx.risk; +import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; +import java.util.List; /** * Represents a section from the checklist @@ -25,52 +28,33 @@ * @author Thomas Guenzel * @author Fabian Prasser */ -public class RiskQuestionnaireSection extends RiskQuestionnaireItem { - - /** - * Create a new section from a line - * - * @param weightConfiguration - * @param line - * @return the section item - */ - public static RiskQuestionnaireSection - sectionFromLine(RiskQuestionnaireWeights weightConfiguration, String line) { - line = line.trim(); - RiskQuestionnaireSection section = new RiskQuestionnaireSection(weightConfiguration, line); - return section; - } +public class RiskQuestionnaireSection extends RiskQuestionnaireItem implements Serializable { + /** SVUID*/ + private static final long serialVersionUID = -6574573674768245518L; + /** The items this section contains */ - private ArrayList items; - - /** The maximum weight possible */ - private double maximumWeight = 0.0; + private List items = new ArrayList<>(); /** * Create a new section from a line * - * @param weightConfiguration - * the current weight configuration - * @param line - * the line to parse + * @param weightConfiguration the current weight configuration + * @param line the line to parse + * @throws IOException */ - public RiskQuestionnaireSection(RiskQuestionnaireWeights weightConfiguration, String line) { - super(line); + public RiskQuestionnaireSection(String line) throws IOException { + super(line.trim()); this.items = new ArrayList(); - setWeightConfiguration(weightConfiguration); } /** * Add a question to the section and updates the maximumWeight * - * @param item - * the question to add + * @param item the question to add */ public void addItem(RiskQuestionnaireQuestion item) { - item.setWeightConfiguration(this.getWeightConfiguration()); items.add(item); - maximumWeight += Math.abs(item.getWeight()); } /** @@ -82,53 +66,20 @@ public RiskQuestionnaireQuestion[] getItems() { return items.toArray(new RiskQuestionnaireQuestion[items.size()]); } - /** - * Returns the maximum weight - * - * @return - */ - public double getMaximumWeight() { - return maximumWeight; - } - /** * Calculates the score based on the section's question's scores * * @return */ public double getScore() { - if (maximumWeight == 0.0) { - // System.out.println("This Section has a maximum weight of 0.0, it can't calculate a score: "+this); - return 0.0; - } - double result = 0.0; + + double result = 0d; + double max = 0d; for (RiskQuestionnaireQuestion q : items) { result += q.getScore(); + max += q.getWeight(); } - // if the weight is negative, 'flip' the answers rating (yes will be -1, - // no will be 1) - if (this.getWeight() < 0.0) { - result = (result * (-1.0)); - } - result /= maximumWeight; + result /= max; return result; } - - @Override - public String toString() { - return "\n\tSection [id=" + this.getIdentifier() + ", title=" + this.getTitle() + - ", weight=" + this.getWeight() + ", score=" + this.getScore() + ", items=" + items + - ", config=" + this.getWeightConfiguration() + "\n\t]"; - } - - /** - * Updates the weights and calculates the maximum weight - */ - public void updateWeights() { - maximumWeight = 0.0; - for (RiskQuestionnaireQuestion item : items) { - item.setWeightConfiguration(this.getWeightConfiguration()); - maximumWeight += Math.abs(item.getWeight()); - } - } } diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java index 80222e8cbc..2475f4a27d 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java @@ -17,10 +17,6 @@ package org.deidentifier.arx.risk; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; import java.io.Serializable; import java.util.HashMap; import java.util.Map; @@ -37,53 +33,18 @@ public class RiskQuestionnaireWeights implements Serializable { private static final long serialVersionUID = -7601091333545929290L; /** Map, mapping the item identifiers to a weight */ - private Map weights; + private Map weights = new HashMap(); /** - * Create a new configuration - */ - public RiskQuestionnaireWeights() { - weights = new HashMap(); - } - - /** - * Create a new configuration from a file - * - * @param filename - */ - public RiskQuestionnaireWeights(String filename) { - this(); - loadProperties(filename); - } - - /** - * Save the configuration to a new filename + * Returns properties * - * @param filename */ - public void save(String filename) { - if (filename == null) { - // System.out.println("No file specified to save to"); - return; - } - + public Properties asProperties() { Properties props = new Properties(); for (Entry entry : weights.entrySet()) { props.setProperty(entry.getKey(), Double.toString(entry.getValue())); } - - FileOutputStream out; - try { - out = new FileOutputStream(filename); - props.store(out, null); - out.close(); - } catch (FileNotFoundException e) { - // System.err.println("Couldn't open file: "+filename); - return; - } catch (IOException e) { - // System.err.println("Couldn't store file: "+filename); - return; - } + return props; } /** @@ -92,7 +53,7 @@ public void save(String filename) { * @param identifier * @param weight */ - public void setWeightForIdentifier(String identifier, double weight) { + public void setWeight(String identifier, double weight) { weights.put(identifier, weight); } @@ -102,37 +63,25 @@ public void setWeightForIdentifier(String identifier, double weight) { * @param identifier * @return the weight */ - public double weightForIdentifier(String identifier) { + public double getWeight(String identifier) { if (weights.containsKey(identifier) == false) { return 1.0; } return weights.get(identifier); } /** - * Try to load the weights from the specified filename - * - * @param filename + * Load weights + * @param properties */ - private void loadProperties(String filename) { - Properties props = new Properties(); + public void loadFromProperties(Properties properties) { try { - FileInputStream in = new FileInputStream(filename); - props.load(in); - - for (Entry entry : props.entrySet()) { + for (Entry entry : properties.entrySet()) { String key = (String) entry.getKey(); String value = (String) entry.getValue(); - double weight = Double.parseDouble(value); weights.put(key, weight); } - in.close(); - } catch (FileNotFoundException e) { - // System.err.println("Couldn't open file: "+filename); - return; - } catch (IOException e) { - // System.err.println("Couldn't parse file: "+filename); - return; + } catch (Exception e) { + throw new IllegalArgumentException("Invalid properties"); } - } } From 66ede45824c48c4b80c17b013149f7796db72a80 Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Wed, 8 Feb 2017 11:31:58 +0100 Subject: [PATCH 17/22] Update --- .../arx/risk/RiskQuestionnaire.java | 7 ++- .../arx/risk/RiskQuestionnaireItem.java | 44 +++++++++---------- .../arx/risk/RiskQuestionnaireSection.java | 16 +++++++ 3 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java index 8c2160d4fa..87c55fdf6e 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java @@ -34,8 +34,6 @@ */ public class RiskQuestionnaire { - // TODO: LOAD/SAVE OF WEIGHTS DOES NOT WORK CURRENTLY - /** The array containing the sections of the checklist */ private List sections = new ArrayList<>(); @@ -90,8 +88,9 @@ public RiskQuestionnaireSection[] getSections() { * @param weights */ public void setWeights(RiskQuestionnaireWeights weights) { - // TODO - throw new UnsupportedOperationException(""); + for (RiskQuestionnaireSection section : this.sections) { + section.setWeights(weights); + } } /** diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java index ea3fcbec17..9d45a3b48a 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireItem.java @@ -28,18 +28,18 @@ */ public abstract class RiskQuestionnaireItem implements Serializable { - /** SVUID*/ + /** SVUID */ private static final long serialVersionUID = -9134631374669047761L; /** Identifier (used for the weight configuration) */ - private String identifier = null; + private String identifier = null; /** Item's title */ - private String title = null; + private String title = null; /** Weight */ - private double weight = 1d; - + private double weight = 1d; + /** * Creates a new instance * @param line @@ -49,23 +49,6 @@ public RiskQuestionnaireItem(String line) throws IOException { parse(line); } - /** - * Parse the item - * @param line - * @throws IOException - */ - private void parse(String line) throws IOException { - if (line == null) { - throw new IOException("Invalid questionnaire definition: " + line); - } - String components[] = line.split(":", 2); - if (components == null ||components.length != 2) { - throw new IOException("Invalid questionnaire definition: " + line); - } - this.identifier = components[0].trim(); - this.title = components[1].trim(); - } - /** * Returns the identifier * @@ -102,4 +85,21 @@ public double getWeight() { public void setWeight(double weight) { this.weight = weight; } + + /** + * Parse the item + * @param line + * @throws IOException + */ + private void parse(String line) throws IOException { + if (line == null) { + throw new IOException("Invalid questionnaire definition: " + line); + } + String components[] = line.split(":", 2); + if (components == null ||components.length != 2) { + throw new IOException("Invalid questionnaire definition: " + line); + } + this.identifier = components[0].trim(); + this.title = components[1].trim(); + } } diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java index 0ef4c2d573..3e5bfaf580 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireSection.java @@ -82,4 +82,20 @@ public double getScore() { result /= max; return result; } + + /** + * Set weights + */ + public void setWeights(RiskQuestionnaireWeights weights) { + Double weight = weights.getWeight(this.getIdentifier()); + if (weight != null) { + this.setWeight(weight); + } + for (RiskQuestionnaireQuestion item : this.items) { + weight = weights.getWeight(this.getIdentifier()+":"+item.getIdentifier()); + if (weight != null) { + item.setWeight(weight); + } + } + } } From 3d502fbb69407744ff09ff17fdc0667fea2f77df Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Thu, 9 Feb 2017 19:07:18 +0100 Subject: [PATCH 18/22] Update documentation --- .../arx/gui/view/impl/wizard/HierarchyWizard.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/HierarchyWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/HierarchyWizard.java index 3251317365..5b8a066c83 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/HierarchyWizard.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/HierarchyWizard.java @@ -52,10 +52,10 @@ public class HierarchyWizard extends ARXWizard> { */ public static class HierarchyWizardResult { - /** TODO */ + /** Hierarchy */ public final Hierarchy hierarchy; - /** TODO */ + /** Builder */ public final HierarchyBuilder builder; /** From d28f12d42d3aa9104de72d8cd18b29a89038f5d7 Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Thu, 9 Feb 2017 19:17:14 +0100 Subject: [PATCH 19/22] Some further updates --- .../org/deidentifier/arx/gui/model/Model.java | 221 ++++++++++-------- .../arx/gui/resources/messages.properties | 5 +- .../arx/gui/view/impl/MainWindow.java | 14 +- .../arx/gui/view/impl/wizard/RiskWizard.java | 47 ++-- ...ogChecklist.java => RiskWizardDialog.java} | 66 ++++-- .../wizard/RiskWizardVisualizationStack.java | 15 +- .../arx/risk/HIPAAMatcherAttributeValue.java | 24 +- ...HIPAAConstants.java => RiskConstants.java} | 48 ++-- .../arx/risk/RiskModelHIPAASafeHarbor.java | 2 +- .../arx/risk/RiskQuestionnaire.java | 44 ++-- .../arx/risk/RiskQuestionnaireQuestion.java | 6 +- .../arx/risk/RiskQuestionnaireWeights.java | 20 +- ...AConstantsUS.java => RiskConstantsUS.java} | 12 +- .../arx/risk/resources/us/readme.txt | 8 +- .../resources/us/risk-questionnaire.data} | 0 15 files changed, 294 insertions(+), 238 deletions(-) rename src/gui/org/deidentifier/arx/gui/view/impl/wizard/{RiskWizardDialogChecklist.java => RiskWizardDialog.java} (77%) rename src/main/org/deidentifier/arx/risk/{HIPAAConstants.java => RiskConstants.java} (86%) rename src/main/org/deidentifier/arx/risk/resources/us/{HIPAAConstantsUS.java => RiskConstantsUS.java} (73%) rename src/{gui/org/deidentifier/arx/gui/resources/default_checklist.txt => main/org/deidentifier/arx/risk/resources/us/risk-questionnaire.data} (100%) diff --git a/src/gui/org/deidentifier/arx/gui/model/Model.java b/src/gui/org/deidentifier/arx/gui/model/Model.java index 2c7d96b13c..c120b7397c 100644 --- a/src/gui/org/deidentifier/arx/gui/model/Model.java +++ b/src/gui/org/deidentifier/arx/gui/model/Model.java @@ -17,6 +17,7 @@ package org.deidentifier.arx.gui.model; +import java.io.IOException; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; @@ -46,6 +47,8 @@ import org.deidentifier.arx.io.CSVSyntax; import org.deidentifier.arx.metric.MetricConfiguration; import org.deidentifier.arx.metric.MetricDescription; +import org.deidentifier.arx.risk.RiskConstants; +import org.deidentifier.arx.risk.RiskQuestionnaire; import org.deidentifier.arx.risk.RiskQuestionnaireWeights; /** @@ -75,141 +78,140 @@ public static enum Perspective { *******************************************/ /** The current anonymizer, if any. */ - private transient ARXAnonymizer anonymizer = null; - + private transient ARXAnonymizer anonymizer = null; + /** The current output data. */ - private transient DataHandle output = null; - + private transient DataHandle output = null; + /** The currently displayed transformation. */ - private transient ARXNode outputNode = null; - + private transient ARXNode outputNode = null; + /** The path to the project file. */ - private transient String path = null; - + private transient String path = null; + /** The current result. */ - private transient ARXResult result = null; - + private transient ARXResult result = null; + /** The currently selected node. */ - private transient ARXNode selectedNode = null; - + private transient ARXNode selectedNode = null; + /** The clip board. */ - private transient ModelClipboard clipboard = null; - - /** The perspective */ - private transient Perspective perspective = Perspective.CONFIGURATION; + private transient ModelClipboard clipboard = null; + /** The perspective */ + private transient Perspective perspective = Perspective.CONFIGURATION; /* ***************************************** * PARAMETERS AND THRESHOLDS *******************************************/ /** Anonymization parameter. */ - private double snapshotSizeDataset = 0.2d; - + private double snapshotSizeDataset = 0.2d; + /** Anonymization parameter. */ - private double snapshotSizeSnapshot = 0.8d; - + private double snapshotSizeSnapshot = 0.8d; + /** Anonymization parameter. */ - private int historySize = 200; - + private int historySize = 200; + /** Threshold. */ - private int maximalSizeForComplexOperations = 5000000; - + private int maximalSizeForComplexOperations = 5000000; + /** Threshold. */ - private int initialNodesInViewer = 100; - + private int initialNodesInViewer = 100; + /** Threshold. */ - private int maxNodesInViewer = 700; + private int maxNodesInViewer = 700; /* ***************************************** * PROJECT METADATA ******************************************/ /** The project description. */ - private String description; - + private String description; + /** The size of the input file. */ - private long inputBytes = 0L; //$NON-NLS-1$ - + private long inputBytes = 0L; //$NON-NLS-1$ + /** Is the project file modified. */ - private boolean modified = false; - + private boolean modified = false; + /** The project name. */ - private String name = null; - + private String name = null; + /** Left for backwards compatibility only! */ - private char separator = ';'; //$NON-NLS-1$ + private char separator = ';'; //$NON-NLS-1$ /** The projects CSV syntax */ - private CSVSyntax csvSyntax; - + private CSVSyntax csvSyntax; + /** Execution time of last anonymization. */ - private long time; - + 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; + private Locale locale = null; - /** The audit trail*/ - private List auditTrail = new ArrayList(); + /** The audit trail */ + private List auditTrail = new ArrayList(); /* ***************************************** * DEBUGGING ******************************************/ /** Is the debugging mode enabled. */ - private boolean debugEnabled = false; + private boolean debugEnabled = false; /* ***************************************** * VISUALIZATIONS ******************************************/ /** Indices of groups in the current output view. */ - private int[] groups; - + private int[] groups; + /** Label. */ - private String optimalNodeAsString; - + private String optimalNodeAsString; + /** Label. */ - private String outputNodeAsString; - + private String outputNodeAsString; + /** Current selection. */ - private String selectedAttribute = null; - + private String selectedAttribute = null; + /** Enable/disable. */ - private Boolean showVisualization = true; - + private Boolean showVisualization = true; + /** Last two selections. */ - private String[] pair = new String[] { null, null }; + private String[] pair = new String[] { null, null}; /* ***************************************** * SUBSET MANAGEMENT ******************************************/ /** Query. */ - private String query = ""; //$NON-NLS-1$ - + private String query = ""; //$NON-NLS-1$ + /** Origin of current subset. */ - private String subsetOrigin = "All"; //$NON-NLS-1$ + private String subsetOrigin = "All"; //$NON-NLS-1$ /* ***************************************** * SUB-MODELS ******************************************/ /** The current input configuration. */ - private ModelConfiguration inputConfig = new ModelConfiguration(); - + private ModelConfiguration inputConfig = new ModelConfiguration(); + /** A filter describing which transformations are currently selected. */ - private ModelNodeFilter nodeFilter = null; - + private ModelNodeFilter nodeFilter = null; + /** Configuration of the data view. */ - private ModelViewConfig viewConfig = new ModelViewConfig(); - + private ModelViewConfig viewConfig = new ModelViewConfig(); + /** The current output configuration. */ - private ModelConfiguration outputConfig = null; + private ModelConfiguration outputConfig = null; /** The current risk model. */ - private ModelRisk riskModel = null; + private ModelRisk riskModel = null; /* ***************************************** * PRIVACY CRITERIA @@ -240,34 +242,28 @@ public static enum Perspective { private Map dDisclosurePrivacyModel = new HashMap(); /** Model for a specific privacy criterion. */ - private ModelProfitabilityCriterion stackelbergPrivacyModel = new ModelProfitabilityCriterion(); + private ModelProfitabilityCriterion stackelbergPrivacyModel = new ModelProfitabilityCriterion(); /* ***************************************** * UTILITY ANALYSIS ******************************************/ /** Configuration. */ - private MetricConfiguration metricConfig = null; - + private MetricConfiguration metricConfig = null; + /** Description. */ - private MetricDescription metricDescription = null; - + private MetricDescription metricDescription = null; + /** Summary statistics */ - private Boolean useListwiseDeletion = true; + private Boolean useListwiseDeletion = true; /** Utility estimation during anonymization */ - private Boolean useFunctionalHierarchies = true; - + private Boolean useFunctionalHierarchies = true; + /* ***************************************** * RISK ANALYSIS ******************************************/ - /** Selected quasi identifiers*/ - private Set selectedQuasiIdentifiers = null; - - /* ***************************************** - * RISK WIZARD - ******************************************/ - /** Current configuration for the risk wizard */ - private RiskQuestionnaireWeights riskWizardModel = null; + /** Selected quasi identifiers */ + private Set selectedQuasiIdentifiers = null; /* ***************************************** * LOCAL RECODING @@ -284,7 +280,15 @@ public static enum Perspective { private Set selectedClasses = null; /** Model */ private ModelClassification classificationModel = new ModelClassification(); - + + /* ***************************************** + * RISK WIZARD + ******************************************/ + /** Current configuration for the risk wizard */ + private RiskQuestionnaireWeights riskQuestionnaireWeights = null; + /** Current configuration for the risk wizard */ + private RiskQuestionnaire riskQuestionnaire = null; + /** * Creates a new instance. * @@ -938,6 +942,29 @@ public ModelRisk getRiskModel() { return riskModel; } + /** + * Returns the risk wizard configuration + * @return + * @throws IOException + */ + public RiskQuestionnaire getRiskQuestionnaire() throws IOException { + if (this.riskQuestionnaire == null) { + this.riskQuestionnaire = new RiskQuestionnaire(RiskConstants.getUSData()); + } + return this.riskQuestionnaire; + } + + /** + * Returns the risk wizard configuration + * @return + */ + public RiskQuestionnaireWeights getRiskQuestionnaireWeights() { + if (this.riskQuestionnaireWeights == null) { + this.riskQuestionnaireWeights = new RiskQuestionnaireWeights(); + } + return this.riskQuestionnaireWeights; + } + /** * Returns the currently selected attribute. * @@ -946,7 +973,6 @@ public ModelRisk getRiskModel() { public String getSelectedAttribute() { return selectedAttribute; } - /** * Returns the selected features @@ -1008,7 +1034,7 @@ public Set getSelectedFeatures() { public ARXNode getSelectedNode() { return selectedNode; } - + /** * Returns a set of quasi identifiers selected for risk analysis * @return @@ -1050,14 +1076,6 @@ public Set getSelectedQuasiIdentifiers() { } return this.selectedQuasiIdentifiers; } - - /** - * Returns the risk wizard configuration - * @return - */ - public RiskQuestionnaireWeights getRiskWizardModel() { - return riskWizardModel; - } /** * Returns the separator. @@ -1483,6 +1501,15 @@ public void setResult(final ARXResult result) { setModified(); } + /** + * Sets the risk wizard configuration + * @param weights + * @return + */ + public void setRiskQuestionnaireWeights(RiskQuestionnaireWeights weights) { + this.riskQuestionnaireWeights = weights; + } + /** * Marks this project as saved. */ @@ -1551,14 +1578,6 @@ public void setSelectedQuasiIdentifiers(Set set) { this.setModified(); } - /** - * Sets the current risk wizard configuration - * @param riskWizardModel - */ - public void setRiskWizardModel(RiskQuestionnaireWeights riskWizardModel) { - this.riskWizardModel = riskWizardModel; - } - /** * * diff --git a/src/gui/org/deidentifier/arx/gui/resources/messages.properties b/src/gui/org/deidentifier/arx/gui/resources/messages.properties index dd13af358a..c83cb1ec63 100644 --- a/src/gui/org/deidentifier/arx/gui/resources/messages.properties +++ b/src/gui/org/deidentifier/arx/gui/resources/messages.properties @@ -343,6 +343,7 @@ MainWindow.6=This dialog can only be used for data types with format MainWindow.7=Default MainWindow.8=Error\! MainWindow.9=An unexpected error happened ( +MainWindow.30=Error opening questionnaire Model.0a=Threshold must be in range [0,1] Model.0b=Internal error: invalid variant of risk-based privacy model Model.0c=Internal error: invalid variant of t-closeness @@ -1269,4 +1270,6 @@ RiskWizard.15=Positive RiskWizard.16=Neutral RiskWizard.17=Negative RiskWizard.18=Weighted Answers -RiskWizard.19=Visualization: \ No newline at end of file +RiskWizard.19=Visualization: +RiskWizard.20=Error saving weights +RiskWizard.21=Error loading weights \ No newline at end of file diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java index eca6d7cd02..1b2bb8f00c 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/MainWindow.java @@ -64,10 +64,9 @@ import org.deidentifier.arx.gui.view.impl.menu.DialogTopBottomCoding; import org.deidentifier.arx.gui.view.impl.risk.LayoutRisks; import org.deidentifier.arx.gui.view.impl.utility.LayoutUtility; -import org.deidentifier.arx.gui.worker.Worker; import org.deidentifier.arx.gui.view.impl.wizard.RiskWizard; -import org.deidentifier.arx.gui.view.impl.wizard.RiskWizardDialogChecklist; -import org.deidentifier.arx.risk.RiskQuestionnaire; +import org.deidentifier.arx.gui.view.impl.wizard.RiskWizardDialog; +import org.deidentifier.arx.gui.worker.Worker; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; @@ -512,9 +511,12 @@ public void showHelpDialog(String id) { * Shows the checklist wizard */ public void showChecklistWizard() { - RiskQuestionnaire checklist = new RiskQuestionnaire(controller.getResources().getStream("default_checklist.txt")); - final RiskWizardDialogChecklist dialog = new RiskWizardDialogChecklist(checklist, shell, new RiskWizard(checklist, controller)); - dialog.open(); + try { + RiskWizardDialog dialog = new RiskWizardDialog(new RiskWizard(controller)); + dialog.open(); + } catch (Exception e) { + controller.actionShowInfoDialog(this.getShell(), Resources.getMessage("Controller.13"), Resources.getMessage("MainWindow.30")); //$NON-NLS-1$ //$NON-NLS-2$ + } } /** diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizard.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizard.java index 0814df806b..b34f1f6cd1 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizard.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizard.java @@ -17,12 +17,12 @@ package org.deidentifier.arx.gui.view.impl.wizard; +import java.io.IOException; + import org.deidentifier.arx.gui.Controller; -import org.deidentifier.arx.gui.model.Model; import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.risk.RiskQuestionnaire; import org.deidentifier.arx.risk.RiskQuestionnaireSection; -import org.deidentifier.arx.risk.RiskQuestionnaireWeights; import org.eclipse.jface.wizard.Wizard; /** @@ -40,7 +40,7 @@ public class RiskWizard extends Wizard { protected RiskWizardPageEvaluation evaluationPage; /** The questionnaire used for the wizard */ - private RiskQuestionnaire checklist; + private RiskQuestionnaire questionnaire; /** Controller */ private Controller controller; @@ -48,32 +48,21 @@ public class RiskWizard extends Wizard { /** * Create a new questionnaire wizard * - * @param checklist * @param controller + * @throws IOException */ - public RiskWizard(RiskQuestionnaire checklist, Controller controller) { + public RiskWizard(Controller controller) throws IOException { super(); - - this.checklist = checklist; - // try to restore a saved version of the weights - Model model = controller.getModel(); - if (model != null) { - RiskQuestionnaireWeights savedModel = model.getRiskWizardModel(); - if (savedModel != null) { - this.checklist.setWeightConfiguration(savedModel); - } - } + this.questionnaire = controller.getModel().getRiskQuestionnaire(); + this.questionnaire.setWeights(controller.getModel().getRiskQuestionnaireWeights()); this.controller = controller; this.setWindowTitle(Resources.getMessage("RiskWizard.0")); } - /** - * Adds the necessary pages to the wizard - */ @Override public void addPages() { // add a page for each section - RiskQuestionnaireSection[] sections = checklist.getSections(); + RiskQuestionnaireSection[] sections = questionnaire.getSections(); pages = new RiskWizardPageSection[sections.length]; for (int i = 0; i < sections.length; i++) { RiskQuestionnaireSection s = sections[i]; @@ -83,16 +72,32 @@ public void addPages() { } // add the final evaluation page - evaluationPage = new RiskWizardPageEvaluation(checklist, controller); + evaluationPage = new RiskWizardPageEvaluation(questionnaire, controller); this.addPage(evaluationPage); } + /** + * Returns the controller + * @return + */ + public Controller getController() { + return this.controller; + } + + /** + * Returns the questionnaire + * @return + */ + public RiskQuestionnaire getQuestionnaire() { + return this.questionnaire; + } + /** * Called when the dialog is finished, saves the current weights */ @Override public boolean performFinish() { - this.controller.getModel().setRiskWizardModel(this.checklist.getWeightConfiguration()); + this.controller.getModel().setRiskQuestionnaireWeights(this.questionnaire.getWeights()); return true; } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialogChecklist.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialog.java similarity index 77% rename from src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialogChecklist.java rename to src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialog.java index 5feb341f84..5e0d2133c4 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialogChecklist.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardDialog.java @@ -17,6 +17,12 @@ package org.deidentifier.arx.gui.view.impl.wizard; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.util.Properties; + +import org.deidentifier.arx.gui.Controller; import org.deidentifier.arx.gui.resources.Resources; import org.deidentifier.arx.risk.RiskQuestionnaire; import org.deidentifier.arx.risk.RiskQuestionnaireWeights; @@ -37,7 +43,6 @@ import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Shell; /** * The ChecklistDialog is the dialog presented for the wizard @@ -45,35 +50,35 @@ * @author Thomas Guenzel * @author Fabian Prasser */ -public class RiskWizardDialogChecklist extends WizardDialog { +public class RiskWizardDialog extends WizardDialog { /** Widget */ - private Button weightEditButton; + private Button weightEditButton; /** Widget */ - private Button loadButton; + private Button loadButton; /** Widget */ - private Button saveButton; + private Button saveButton; /** Model */ - private RiskQuestionnaire checklist; + private RiskQuestionnaire questionnaire; + + /** Controller */ + private Controller controller; /** * creates a new checklist dialog for a specified checklist * - * @param checklist - * the checklist to use - * @param parentShell - * the parent for this dialog - * @param controller - * the arx controller - * @param newWizard - * the wizard + * @param checklist the checklist to use + * @param parentShell the parent for this dialog + * @param controller the arx controller + * @param newWizard the wizard */ - public RiskWizardDialogChecklist(RiskQuestionnaire checklist, Shell parentShell, IWizard newWizard) { - super(parentShell, newWizard); - this.checklist = checklist; + public RiskWizardDialog(RiskWizard wizard) { + super(wizard.getShell(), wizard); + this.questionnaire = wizard.getQuestionnaire(); + this.controller = wizard.getController();; } /** @@ -98,7 +103,7 @@ protected void createButtonsForButtonBar(Composite parent) { weightEditButton = new Button(parent, SWT.CHECK); weightEditButton.setText(Resources.getMessage("RiskWizard.6")); - final RiskWizardDialogChecklist reference = this; + final RiskWizardDialog reference = this; loadButton = new Button(parent, SWT.PUSH); loadButton.setText(Resources.getMessage("RiskWizard.7")); @@ -129,8 +134,11 @@ public void widgetSelected(SelectionEvent e) { dialog.setFilterPath("config/weights"); String result = dialog.open(); if (result != null) { - RiskQuestionnaireWeights wc = checklist.getWeightConfiguration(); - wc.save(result); + try { + questionnaire.getWeights().asProperties().store(new FileOutputStream(result), null); + } catch (Exception exception) { + controller.actionShowInfoDialog(getShell(), Resources.getMessage("Controller.13"), Resources.getMessage("RiskWizard.20")); + } } } }); @@ -199,11 +207,19 @@ protected void setWeightsEditable(boolean weightsEditable) { * the weight configuration to load */ protected void updateWeightConfig(String result) { - checklist.setWeightConfiguration(new RiskQuestionnaireWeights(result)); - IWizard wizard = this.getWizard(); - if (wizard instanceof RiskWizard) { - RiskWizard casted = (RiskWizard) wizard; - casted.updateWeights(); + try { + RiskQuestionnaireWeights weights = new RiskQuestionnaireWeights(); + Properties properties = new Properties(); + properties.load(new FileInputStream(new File(result))); + weights.loadFromProperties(properties); + questionnaire.setWeights(weights); + IWizard wizard = this.getWizard(); + if (wizard instanceof RiskWizard) { + RiskWizard casted = (RiskWizard) wizard; + casted.updateWeights(); + } + } catch (Exception e) { + controller.actionShowInfoDialog(getShell(), Resources.getMessage("Controller.13"), Resources.getMessage("RiskWizard.21")); } } } diff --git a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationStack.java b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationStack.java index 416cc6b1e3..c310469282 100644 --- a/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationStack.java +++ b/src/gui/org/deidentifier/arx/gui/view/impl/wizard/RiskWizardVisualizationStack.java @@ -74,13 +74,14 @@ public void updateWeights() { int idx = 0; for (RiskQuestionnaireSection sec : sections) { - double pos = 0.0; - double neu = 0.0; - double neg = 0.0; - + double pos = 0.0d; + double neu = 0.0d; + double neg = 0.0d; + double max = 0.0d; for (RiskQuestionnaireQuestion q : sec.getItems()) { double w = q.getWeight(); double s = q.getScore(); + max += w; if (s == 0.0) { neu += w; } else if (s > 0.0) { @@ -90,9 +91,9 @@ public void updateWeights() { } } - posY[idx] = pos / sec.getMaximumWeight(); - neuY[idx] = neu / sec.getMaximumWeight(); - negY[idx] = neg / sec.getMaximumWeight(); + posY[idx] = pos / max; + neuY[idx] = neu / max; + negY[idx] = neg / max; idx++; } diff --git a/src/main/org/deidentifier/arx/risk/HIPAAMatcherAttributeValue.java b/src/main/org/deidentifier/arx/risk/HIPAAMatcherAttributeValue.java index 06ce204fa5..922489ea4d 100644 --- a/src/main/org/deidentifier/arx/risk/HIPAAMatcherAttributeValue.java +++ b/src/main/org/deidentifier/arx/risk/HIPAAMatcherAttributeValue.java @@ -47,7 +47,7 @@ static class HIPAAMatcherAge extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherAge(HIPAAConstants constants) { + HIPAAMatcherAge(RiskConstants constants) { super(constants); } @@ -76,7 +76,7 @@ static class HIPAAMatcherCity extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherCity(HIPAAConstants constants) { + HIPAAMatcherCity(RiskConstants constants) { super(constants); } @@ -97,7 +97,7 @@ static class HIPAAMatcherDate extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherDate(HIPAAConstants constants) { + HIPAAMatcherDate(RiskConstants constants) { super(constants); } @@ -160,7 +160,7 @@ static class HIPAAMatcherEMail extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherEMail(HIPAAConstants constants) { + HIPAAMatcherEMail(RiskConstants constants) { super(constants); } @@ -181,7 +181,7 @@ static class HIPAAMatcherFirstName extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherFirstName(HIPAAConstants constants) { + HIPAAMatcherFirstName(RiskConstants constants) { super(constants); } @@ -223,7 +223,7 @@ static class HIPAAMatcherIP extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherIP(HIPAAConstants constants) { + HIPAAMatcherIP(RiskConstants constants) { super(constants); } @@ -244,7 +244,7 @@ static class HIPAAMatcherLastName extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherLastName(HIPAAConstants constants) { + HIPAAMatcherLastName(RiskConstants constants) { super(constants); } @@ -274,7 +274,7 @@ static class HIPAAMatcherState extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherState(HIPAAConstants constants) { + HIPAAMatcherState(RiskConstants constants) { super(constants); } @@ -314,7 +314,7 @@ static class HIPAAMatcherURL extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherURL(HIPAAConstants constants) { + HIPAAMatcherURL(RiskConstants constants) { super(constants); } @@ -352,7 +352,7 @@ static class HIPAAMatcherZIP extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherZIP(HIPAAConstants constants) { + HIPAAMatcherZIP(RiskConstants constants) { super(constants); zipCodes = new HashSet<>(); @@ -392,13 +392,13 @@ public boolean matches(String value) { } /** Constants*/ - protected final HIPAAConstants constants; + protected final RiskConstants constants; /** * Creates a new instance * @param constants */ - public HIPAAMatcherAttributeValue(HIPAAConstants constants) { + public HIPAAMatcherAttributeValue(RiskConstants constants) { this.constants = constants; } diff --git a/src/main/org/deidentifier/arx/risk/HIPAAConstants.java b/src/main/org/deidentifier/arx/risk/RiskConstants.java similarity index 86% rename from src/main/org/deidentifier/arx/risk/HIPAAConstants.java rename to src/main/org/deidentifier/arx/risk/RiskConstants.java index f9b39607fb..2263b73bea 100644 --- a/src/main/org/deidentifier/arx/risk/HIPAAConstants.java +++ b/src/main/org/deidentifier/arx/risk/RiskConstants.java @@ -30,23 +30,23 @@ import java.util.Map.Entry; import java.util.Set; -import org.deidentifier.arx.risk.resources.us.HIPAAConstantsUS; +import org.deidentifier.arx.risk.resources.us.RiskConstantsUS; /** - * Utility class providing access to important constants for finding HIPAA identifiers. + * Utility class providing access to important constants for risk analyses. * * @author Fabian Prasser */ -public abstract class HIPAAConstants { +public abstract class RiskConstants { /** US data*/ - private static final HIPAAConstants dataUS = new HIPAAConstantsUS(); + private static final RiskConstants dataUS = new RiskConstantsUS(); /** * Returns constants for the US * @return */ - public static HIPAAConstants getUSData() { + public static RiskConstants getUSData() { return dataUS; } @@ -66,6 +66,13 @@ public static HIPAAConstants getUSData() { /** Default charset */ private static final Charset CHARSET = StandardCharsets.UTF_8; + /** + * Returns a stream for the given file + * @param file + * @return + */ + public abstract InputStream getInputStream(String file); + /** * Returns all matchers for the given category * @param category @@ -115,7 +122,7 @@ public boolean isFirstname(String value) { public boolean isLastname(String value) { return getLastnames().contains(value); } - + /** * States * @@ -125,7 +132,7 @@ public boolean isLastname(String value) { public boolean isState(String value) { return getStates().contains(value); } - + /** * Zip codes * @@ -139,7 +146,7 @@ public boolean isZipcode(String value) { /** Cities */ private Set getCities() { if (cities == null) { - cities = load("cities.csv"); + cities = loadSet("cities.csv"); } return cities; } @@ -147,7 +154,7 @@ private Set getCities() { /** First names */ private Set getFirstnames() { if (firstnames == null) { - firstnames = load("firstnames.csv"); + firstnames = loadSet("firstnames.csv"); } return firstnames; } @@ -155,11 +162,11 @@ private Set getFirstnames() { /** Last names */ private Set getLastnames() { if (lastnames == null) { - lastnames = load("lastnames.csv"); + lastnames = loadSet("lastnames.csv"); } return lastnames; } - + /** * Returns all name configurations * @return @@ -203,7 +210,7 @@ private Map> getNameConfigurations() { /** States */ private Set getStates() { if (states == null) { - states = load("states.csv"); + states = loadSet("states.csv"); } return states; } @@ -211,17 +218,17 @@ private Set getStates() { /** Zip codes */ private Set getZipcodes() { if (zipcodes == null) { - zipcodes = load("zipcodes.csv"); + zipcodes = loadSet("zipcodes.csv"); } return zipcodes; } - + /** * Loads the given set of resources * @param file * @return */ - private Set load(String file) { + private Set loadSet(String file) { InputStream stream = getInputStream(file); BufferedReader br = new BufferedReader(new InputStreamReader(stream, CHARSET)); Set set = new HashSet(); @@ -232,21 +239,14 @@ private Set load(String file) { line = br.readLine(); } } catch (IOException e) { - e.printStackTrace(); + throw new IllegalStateException(e); } finally { try { br.close(); } catch (IOException e) { - e.printStackTrace(); + /** Ignore*/ } } return set; } - - /** - * Implement this to load the according file - * @param file - * @return - */ - protected abstract InputStream getInputStream(String file); } diff --git a/src/main/org/deidentifier/arx/risk/RiskModelHIPAASafeHarbor.java b/src/main/org/deidentifier/arx/risk/RiskModelHIPAASafeHarbor.java index 8e3eba2167..6e67808bcd 100644 --- a/src/main/org/deidentifier/arx/risk/RiskModelHIPAASafeHarbor.java +++ b/src/main/org/deidentifier/arx/risk/RiskModelHIPAASafeHarbor.java @@ -134,7 +134,7 @@ public HIPAAIdentifierMatch[] getMatches(DataHandleInternal handle, */ private List getConfigurations() { - HIPAAConstants constants = HIPAAConstants.getUSData(); + RiskConstants constants = RiskConstants.getUSData(); List configurations = new ArrayList(); diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java index 87c55fdf6e..fecb46e896 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java @@ -18,10 +18,9 @@ import java.io.BufferedReader; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; -import java.io.InputStream; import java.io.InputStreamReader; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -32,29 +31,22 @@ * @author Thomas Guenzel * @author Fabian Prasser */ -public class RiskQuestionnaire { - - /** The array containing the sections of the checklist */ - private List sections = new ArrayList<>(); +public class RiskQuestionnaire implements Serializable { - /** - * Create a questionnaire from an input stream - * - * @param stream the input stream - * @throws IOException - */ - public RiskQuestionnaire(InputStream stream) throws IOException { - load(new BufferedReader(new InputStreamReader(stream))); - } + /** SVUID */ + private static final long serialVersionUID = 5949613671782771835L; + + /** The array containing the sections of the questionnaire */ + private List sections = new ArrayList<>(); /** - * Create a questionnaire from a file + * Create a questionnaire * - * @param filename the filename + * @param data * @throws IOException */ - public RiskQuestionnaire(String filename) throws IOException { - load(new BufferedReader(new FileReader(filename))); + public RiskQuestionnaire(RiskConstants data) throws IOException { + load(new BufferedReader(new InputStreamReader(data.getInputStream("risk-questionnaire.data")))); } /** @@ -83,6 +75,20 @@ public RiskQuestionnaireSection[] getSections() { return (sections.toArray(new RiskQuestionnaireSection[sections.size()])); } + /** + * Returns the current weights + */ + public RiskQuestionnaireWeights getWeights() { + RiskQuestionnaireWeights weights = new RiskQuestionnaireWeights(); + for (RiskQuestionnaireSection section : this.sections) { + weights.setWeight(section.getIdentifier(), section.getWeight()); + for (RiskQuestionnaireItem item : section.getItems()) { + weights.setWeight(section.getIdentifier()+":"+item.getIdentifier(), item.getWeight()); + } + } + return weights; + } + /** * Sets the weights * @param weights diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java index 2c24719c7f..6a845c8a4b 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireQuestion.java @@ -30,9 +30,6 @@ */ public class RiskQuestionnaireQuestion extends RiskQuestionnaireItem implements Serializable { - /** SVUID*/ - private static final long serialVersionUID = 1342060103957413041L; - /** Enum for answers */ public enum Answer { YES, @@ -40,6 +37,9 @@ public enum Answer { N_A } + /** SVUID*/ + private static final long serialVersionUID = 1342060103957413041L; + /** Current answer */ public Answer answer; diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java index 2475f4a27d..8a005211e0 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaireWeights.java @@ -47,16 +47,6 @@ public Properties asProperties() { return props; } - /** - * Sets the weight for an item's identifier - * - * @param identifier - * @param weight - */ - public void setWeight(String identifier, double weight) { - weights.put(identifier, weight); - } - /** * Get the weight for an item's identifier * @@ -84,4 +74,14 @@ public void loadFromProperties(Properties properties) { throw new IllegalArgumentException("Invalid properties"); } } + + /** + * Sets the weight for an item's identifier + * + * @param identifier + * @param weight + */ + public void setWeight(String identifier, double weight) { + weights.put(identifier, weight); + } } diff --git a/src/main/org/deidentifier/arx/risk/resources/us/HIPAAConstantsUS.java b/src/main/org/deidentifier/arx/risk/resources/us/RiskConstantsUS.java similarity index 73% rename from src/main/org/deidentifier/arx/risk/resources/us/HIPAAConstantsUS.java rename to src/main/org/deidentifier/arx/risk/resources/us/RiskConstantsUS.java index db950d3fda..6f9011dcb4 100644 --- a/src/main/org/deidentifier/arx/risk/resources/us/HIPAAConstantsUS.java +++ b/src/main/org/deidentifier/arx/risk/resources/us/RiskConstantsUS.java @@ -18,19 +18,17 @@ import java.io.InputStream; -import org.deidentifier.arx.risk.HIPAAConstants; +import org.deidentifier.arx.risk.RiskConstants; /** * Utility class providing access to important constants for finding HIPAA identifiers. * * @author Fabian Prasser */ -public class HIPAAConstantsUS extends HIPAAConstants{ +public class RiskConstantsUS extends RiskConstants{ - /** - * Returns constants for the US population - */ - protected InputStream getInputStream(String file) { - return HIPAAConstantsUS.class.getResourceAsStream(file); + @Override + public InputStream getInputStream(String file) { + return RiskConstantsUS.class.getResourceAsStream(file); } } diff --git a/src/main/org/deidentifier/arx/risk/resources/us/readme.txt b/src/main/org/deidentifier/arx/risk/resources/us/readme.txt index 0e33721548..3326144490 100644 --- a/src/main/org/deidentifier/arx/risk/resources/us/readme.txt +++ b/src/main/org/deidentifier/arx/risk/resources/us/readme.txt @@ -29,4 +29,10 @@ lastnames.csv zip.csv *********** -(1) http://simplemaps.com/resources/us-cities-data \ No newline at end of file +(1) http://simplemaps.com/resources/us-cities-data + +************** +Questionnaire +************** + +K. E. Emam, “De-identifying health data for secondary use: A framework,” Technical Report, CHEO Research Institute, 2008. \ No newline at end of file diff --git a/src/gui/org/deidentifier/arx/gui/resources/default_checklist.txt b/src/main/org/deidentifier/arx/risk/resources/us/risk-questionnaire.data similarity index 100% rename from src/gui/org/deidentifier/arx/gui/resources/default_checklist.txt rename to src/main/org/deidentifier/arx/risk/resources/us/risk-questionnaire.data From 007bd1805c8438316b5009569529ed28f39bf2bd Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Mon, 15 Jan 2018 20:12:30 +0100 Subject: [PATCH 20/22] Bugfix: rename classes --- .../org/deidentifier/arx/gui/model/Model.java | 4 +- .../deidentifier/arx/risk/HIPAAConstants.java | 252 ++++++++++++++++++ .../arx/risk/HIPAAMatcherAttributeValue.java | 24 +- .../arx/risk/RiskModelHIPAASafeHarbor.java | 2 +- .../arx/risk/RiskQuestionnaire.java | 2 +- .../risk/resources/us/HIPAAConstantsUS.java | 36 +++ 6 files changed, 304 insertions(+), 16 deletions(-) create mode 100644 src/main/org/deidentifier/arx/risk/HIPAAConstants.java create mode 100644 src/main/org/deidentifier/arx/risk/resources/us/HIPAAConstantsUS.java diff --git a/src/gui/org/deidentifier/arx/gui/model/Model.java b/src/gui/org/deidentifier/arx/gui/model/Model.java index 1abc3db239..cd4a286226 100644 --- a/src/gui/org/deidentifier/arx/gui/model/Model.java +++ b/src/gui/org/deidentifier/arx/gui/model/Model.java @@ -49,7 +49,7 @@ import org.deidentifier.arx.io.CSVSyntax; import org.deidentifier.arx.metric.MetricConfiguration; import org.deidentifier.arx.metric.MetricDescription; -import org.deidentifier.arx.risk.RiskConstants; +import org.deidentifier.arx.risk.HIPAAConstants; import org.deidentifier.arx.risk.RiskQuestionnaire; import org.deidentifier.arx.risk.RiskQuestionnaireWeights; @@ -1047,7 +1047,7 @@ public ModelRisk getRiskModel() { */ public RiskQuestionnaire getRiskQuestionnaire() throws IOException { if (this.riskQuestionnaire == null) { - this.riskQuestionnaire = new RiskQuestionnaire(RiskConstants.getUSData()); + this.riskQuestionnaire = new RiskQuestionnaire(HIPAAConstants.getUSData()); } return this.riskQuestionnaire; } diff --git a/src/main/org/deidentifier/arx/risk/HIPAAConstants.java b/src/main/org/deidentifier/arx/risk/HIPAAConstants.java new file mode 100644 index 0000000000..22597a4053 --- /dev/null +++ b/src/main/org/deidentifier/arx/risk/HIPAAConstants.java @@ -0,0 +1,252 @@ +/* + * ARX: Powerful Data Anonymization + * Copyright 2012 - 2018 Fabian Prasser 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.risk; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.deidentifier.arx.risk.resources.us.HIPAAConstantsUS; + +/** + * Utility class providing access to important constants for finding HIPAA identifiers. + * + * @author Fabian Prasser + */ +public abstract class HIPAAConstants { + + /** US data*/ + private static final HIPAAConstants dataUS = new HIPAAConstantsUS(); + + /** + * Returns constants for the US + * @return + */ + public static HIPAAConstants getUSData() { + return dataUS; + } + + /** Cities */ + private Set cities = null; + /** First names */ + private Set firstnames = null; + /** Last names */ + private Set lastnames = null; + /** States */ + private Set states = null; + /** Zip codes */ + private Set zipcodes = null; + /** Labels */ + private Map> labels = null; + + /** Default charset */ + private static final Charset CHARSET = StandardCharsets.UTF_8; + + /** + * Returns all matchers for the given category + * @param category + * @return + */ + public List getNameMatchers(String category) { + + // Check + if (!getNameConfigurations().containsKey(category)) { + return new ArrayList(); + } + + // Collect each matcher + List result = new ArrayList(); + for (Entry entry2 : getNameConfigurations().get(category).entrySet()) { + result.add(new HIPAAMatcherAttributeName(entry2.getKey(), entry2.getValue())); + } + + // Return + return result; + } + + /** + * Cities + * @param value + * @return + */ + public boolean isCity(String value) { + return getCities().contains(value); + } + + /** + * First names + * @param value + * @return + */ + public boolean isFirstname(String value) { + return getFirstnames().contains(value); + } + + /** + * Last names + * + * @param value + * @return + */ + public boolean isLastname(String value) { + return getLastnames().contains(value); + } + + /** + * States + * + * @param value + * @return + */ + public boolean isState(String value) { + return getStates().contains(value); + } + + /** + * Zip codes + * + * @param value + * @return + */ + public boolean isZipcode(String value) { + return getZipcodes().contains(value); + } + + /** Cities */ + private Set getCities() { + if (cities == null) { + cities = load("cities.csv"); + } + return cities; + } + + /** First names */ + private Set getFirstnames() { + if (firstnames == null) { + firstnames = load("firstnames.csv"); + } + return firstnames; + } + + /** Last names */ + private Set getLastnames() { + if (lastnames == null) { + lastnames = load("lastnames.csv"); + } + return lastnames; + } + + /** + * Returns all name configurations + * @return + */ + private Map> getNameConfigurations() { + + if (this.labels == null) { + + InputStream stream = getInputStream("labels.properties"); + BufferedReader br = new BufferedReader(new InputStreamReader(stream, CHARSET)); + this.labels = new HashMap>(); + + try { + String line = br.readLine(); + while (line != null) { + + String[] parts = line.split("="); + String label = parts[0]; + parts = parts[1].split(","); + Map map = new HashMap(); + for (int i = 0; i < parts.length; i += 2) { + map.put(parts[i], Integer.valueOf(parts[i+1])); + } + labels.put(label, map); + line = br.readLine(); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + return this.labels; + } + + /** States */ + private Set getStates() { + if (states == null) { + states = load("states.csv"); + } + return states; + } + + /** Zip codes */ + private Set getZipcodes() { + if (zipcodes == null) { + zipcodes = load("zipcodes.csv"); + } + return zipcodes; + } + + /** + * Loads the given set of resources + * @param file + * @return + */ + private Set load(String file) { + InputStream stream = getInputStream(file); + BufferedReader br = new BufferedReader(new InputStreamReader(stream, CHARSET)); + Set set = new HashSet(); + try { + String line = br.readLine(); + while (line != null) { + set.add(line); + line = br.readLine(); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + br.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return set; + } + + /** + * Implement this to load the according file + * @param file + * @return + */ + protected abstract InputStream getInputStream(String file); +} diff --git a/src/main/org/deidentifier/arx/risk/HIPAAMatcherAttributeValue.java b/src/main/org/deidentifier/arx/risk/HIPAAMatcherAttributeValue.java index cb7645830a..267a915b09 100644 --- a/src/main/org/deidentifier/arx/risk/HIPAAMatcherAttributeValue.java +++ b/src/main/org/deidentifier/arx/risk/HIPAAMatcherAttributeValue.java @@ -47,7 +47,7 @@ static class HIPAAMatcherAge extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherAge(RiskConstants constants) { + HIPAAMatcherAge(HIPAAConstants constants) { super(constants); } @@ -76,7 +76,7 @@ static class HIPAAMatcherCity extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherCity(RiskConstants constants) { + HIPAAMatcherCity(HIPAAConstants constants) { super(constants); } @@ -97,7 +97,7 @@ static class HIPAAMatcherDate extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherDate(RiskConstants constants) { + HIPAAMatcherDate(HIPAAConstants constants) { super(constants); } @@ -160,7 +160,7 @@ static class HIPAAMatcherEMail extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherEMail(RiskConstants constants) { + HIPAAMatcherEMail(HIPAAConstants constants) { super(constants); } @@ -181,7 +181,7 @@ static class HIPAAMatcherFirstName extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherFirstName(RiskConstants constants) { + HIPAAMatcherFirstName(HIPAAConstants constants) { super(constants); } @@ -223,7 +223,7 @@ static class HIPAAMatcherIP extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherIP(RiskConstants constants) { + HIPAAMatcherIP(HIPAAConstants constants) { super(constants); } @@ -244,7 +244,7 @@ static class HIPAAMatcherLastName extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherLastName(RiskConstants constants) { + HIPAAMatcherLastName(HIPAAConstants constants) { super(constants); } @@ -274,7 +274,7 @@ static class HIPAAMatcherState extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherState(RiskConstants constants) { + HIPAAMatcherState(HIPAAConstants constants) { super(constants); } @@ -314,7 +314,7 @@ static class HIPAAMatcherURL extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherURL(RiskConstants constants) { + HIPAAMatcherURL(HIPAAConstants constants) { super(constants); } @@ -352,7 +352,7 @@ static class HIPAAMatcherZIP extends HIPAAMatcherAttributeValue { * Creates a new instance * @param constants */ - HIPAAMatcherZIP(RiskConstants constants) { + HIPAAMatcherZIP(HIPAAConstants constants) { super(constants); zipCodes = new HashSet<>(); @@ -392,13 +392,13 @@ public boolean matches(String value) { } /** Constants*/ - protected final RiskConstants constants; + protected final HIPAAConstants constants; /** * Creates a new instance * @param constants */ - public HIPAAMatcherAttributeValue(RiskConstants constants) { + public HIPAAMatcherAttributeValue(HIPAAConstants constants) { this.constants = constants; } diff --git a/src/main/org/deidentifier/arx/risk/RiskModelHIPAASafeHarbor.java b/src/main/org/deidentifier/arx/risk/RiskModelHIPAASafeHarbor.java index 0434e3a86f..bdaa0b159c 100644 --- a/src/main/org/deidentifier/arx/risk/RiskModelHIPAASafeHarbor.java +++ b/src/main/org/deidentifier/arx/risk/RiskModelHIPAASafeHarbor.java @@ -134,7 +134,7 @@ public HIPAAIdentifierMatch[] getMatches(DataHandleInternal handle, */ private List getConfigurations() { - RiskConstants constants = RiskConstants.getUSData(); + HIPAAConstants constants = HIPAAConstants.getUSData(); List configurations = new ArrayList(); diff --git a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java index fecb46e896..3e94c639f9 100644 --- a/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java +++ b/src/main/org/deidentifier/arx/risk/RiskQuestionnaire.java @@ -45,7 +45,7 @@ public class RiskQuestionnaire implements Serializable { * @param data * @throws IOException */ - public RiskQuestionnaire(RiskConstants data) throws IOException { + public RiskQuestionnaire(HIPAAConstants data) throws IOException { load(new BufferedReader(new InputStreamReader(data.getInputStream("risk-questionnaire.data")))); } diff --git a/src/main/org/deidentifier/arx/risk/resources/us/HIPAAConstantsUS.java b/src/main/org/deidentifier/arx/risk/resources/us/HIPAAConstantsUS.java new file mode 100644 index 0000000000..fef9617b4d --- /dev/null +++ b/src/main/org/deidentifier/arx/risk/resources/us/HIPAAConstantsUS.java @@ -0,0 +1,36 @@ +/* + * ARX: Powerful Data Anonymization + * Copyright 2012 - 2018 Fabian Prasser 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.risk.resources.us; + +import java.io.InputStream; + +import org.deidentifier.arx.risk.HIPAAConstants; + +/** + * Utility class providing access to important constants for finding HIPAA identifiers. + * + * @author Fabian Prasser + */ +public class HIPAAConstantsUS extends HIPAAConstants{ + + /** + * Returns constants for the US population + */ + protected InputStream getInputStream(String file) { + return HIPAAConstantsUS.class.getResourceAsStream(file); + } +} From ad4a7f0ccb7c4f4c9731522118b923eb190c333c Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Sun, 8 Mar 2020 13:11:26 +0100 Subject: [PATCH 21/22] Add further files --- data/.gitignore | 95 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 85 insertions(+), 10 deletions(-) diff --git a/data/.gitignore b/data/.gitignore index 58377b2fdd..82b395b884 100644 --- a/data/.gitignore +++ b/data/.gitignore @@ -61,13 +61,88 @@ /test.csv /.gitignore /tlfnc -/adult_subset.csv -/atus_subset.csv -/cup_subset.csv -/fars_subset.csv -/ihis_subset.csv -/adult_age_microaggregated.csv -/dis_hierarchy_age.csv -/dis_hierarchy_gender.csv -/dis_hierarchy_zipcode.csv -/dis.csv +/adult_subset.csv +/atus_subset.csv +/cup_subset.csv +/fars_subset.csv +/ihis_subset.csv +/adult_age_microaggregated.csv +/dis_hierarchy_age.csv +/dis_hierarchy_gender.csv +/dis_hierarchy_zipcode.csv +/dis.csv +/adult_12000.csv +/adult_12000_subset.csv +/adult_15000.csv +/adult_15000_subset.csv +/adult_18000.csv +/adult_18000_subset.csv +/adult_21000.csv +/adult_21000_subset.csv +/adult_24000.csv +/adult_24000_subset.csv +/adult_27000.csv +/adult_27000_subset.csv +/adult_3000.csv +/adult_3000_subset.csv +/adult_30162.csv +/adult_30162_subset.csv +/adult_6000.csv +/adult_6000_subset.csv +/adult_9000.csv +/adult_9000_subset.csv +/ihis_100000.csv +/ihis_1000000.csv +/ihis_1000000_subset.csv +/ihis_100000_subset.csv +/ihis_1100000.csv +/ihis_1100000_subset.csv +/ihis_1193504.csv +/ihis_1193504_subset.csv +/ihis_200000.csv +/ihis_200000_subset.csv +/ihis_300000.csv +/ihis_300000_subset.csv +/ihis_400000.csv +/ihis_400000_subset.csv +/ihis_500000.csv +/ihis_500000_subset.csv +/ihis_600000.csv +/ihis_600000_subset.csv +/ihis_700000.csv +/ihis_700000_subset.csv +/ihis_800000.csv +/ihis_800000_subset.csv +/ihis_900000.csv +/ihis_900000_subset.csv +/ss13acs.csv +/ss13acs_hierarchy_o_AGEP.csv +/ss13acs_hierarchy_o_CIT.csv +/ss13acs_hierarchy_o_COW.csv +/ss13acs_hierarchy_o_DDRS.csv +/ss13acs_hierarchy_o_DEAR.csv +/ss13acs_hierarchy_o_DEYE.csv +/ss13acs_hierarchy_o_DOUT.csv +/ss13acs_hierarchy_o_DPHY.csv +/ss13acs_hierarchy_o_DREM.csv +/ss13acs_hierarchy_o_FER.csv +/ss13acs_hierarchy_o_GCL.csv +/ss13acs_hierarchy_o_HINS1.csv +/ss13acs_hierarchy_o_HINS2.csv +/ss13acs_hierarchy_o_HINS3.csv +/ss13acs_hierarchy_o_HINS4.csv +/ss13acs_hierarchy_o_HINS5.csv +/ss13acs_hierarchy_o_HINS6.csv +/ss13acs_hierarchy_o_HINS7.csv +/ss13acs_hierarchy_o_INTP.csv +/ss13acs_hierarchy_o_MAR.csv +/ss13acs_hierarchy_o_MARHD.csv +/ss13acs_hierarchy_o_MARHM.csv +/ss13acs_hierarchy_o_MARHW.csv +/ss13acs_hierarchy_o_MIG.csv +/ss13acs_hierarchy_o_MIL.csv +/ss13acs_hierarchy_o_PWGTP.csv +/ss13acs_hierarchy_o_RELP.csv +/ss13acs_hierarchy_o_SCHG.csv +/ss13acs_hierarchy_o_SCHL.csv +/ss13acs_hierarchy_o_SEX.csv From 5a426fa802aaba169334d4ff37f365d40fc4c33c Mon Sep 17 00:00:00 2001 From: Fabian Prasser Date: Sun, 8 Mar 2020 13:21:27 +0100 Subject: [PATCH 22/22] Add comment --- src/gui/org/deidentifier/arx/gui/Controller.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/org/deidentifier/arx/gui/Controller.java b/src/gui/org/deidentifier/arx/gui/Controller.java index fc2358916b..d17b22de64 100644 --- a/src/gui/org/deidentifier/arx/gui/Controller.java +++ b/src/gui/org/deidentifier/arx/gui/Controller.java @@ -1476,7 +1476,7 @@ public void actionMenuHelpAbout() { } /** - * Shows the "about" dialog. + * Shows the "risk analysis" dialog. */ public void actionMenuHelpChecklistWizard() { main.showChecklistWizard();