/*
* ARX: Powerful Data Anonymization
* Copyright 2012 - 2017 Fabian Prasser, Florian Kohlmayer and contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.deidentifier.arx.gui.view.impl.utility;
import java.util.ArrayList;
import java.util.List;
import org.deidentifier.arx.gui.Controller;
import org.deidentifier.arx.gui.model.Model;
import org.deidentifier.arx.gui.model.ModelEvent;
import org.deidentifier.arx.gui.model.ModelEvent.ModelPart;
import org.deidentifier.arx.gui.model.ModelLocalRecoding.LocalRecodingMode;
import org.deidentifier.arx.gui.resources.Resources;
import org.deidentifier.arx.gui.view.SWTUtil;
import org.deidentifier.arx.gui.view.def.IView;
import org.deidentifier.arx.gui.view.impl.common.ComponentGSSlider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
/**
* This view allows to use local recoding
*
* @author Fabian Prasser
*/
public class ViewLocalRecoding implements IView, ViewStatisticsBasic {
/** Internal stuff. */
private Model model;
/** Internal stuff. */
private final Controller controller;
/** Internal stuff. */
private Button button;
/** Internal stuff. */
private final Composite root;
/** Widget */
private ComponentGSSlider slider;
/** Widget */
private Combo combo;
/** Constant */
private static final double[] FIXPOINT_PARAMETERS = new double[] { 0.01d, 0.05d, 0.1d, 0.2d, 0.3d};
/** Constant */
private static final double[] MULTIPASS_PARAMETERS = new double[] { 10d, 50d, 100d, 500d, 1000d };
/**
* Constructor.
*
* @param parent
* @param controller
*/
protected ViewLocalRecoding(final Composite parent,
final Controller controller) {
// Register
controller.addListener(ModelPart.OUTPUT, this);
controller.addListener(ModelPart.MODEL, this);
controller.addListener(ModelPart.RESULT, this);
this.controller = controller;
this.root = parent;
this.create(this.root);
}
@Override
public void dispose() {
controller.removeListener(this);
}
@Override
public Composite getParent() {
return this.root;
}
public LayoutUtility.ViewUtilityType getType() {
return LayoutUtility.ViewUtilityType.LOCAL_RECODING;
}
@Override
public void reset() {
slider.setSelection(0.5d);
SWTUtil.disable(root);
}
@Override
public void update(final ModelEvent event) {
if (event.part == ModelPart.MODEL) {
this.model = (Model) event.data;
}
this.update();
}
/**
* Creates the view.
*
* @param group
*/
private void create(Composite root) {
GridLayout layout = SWTUtil.createGridLayout(1);
layout.marginBottom = 3;
layout.marginTop = 3;
layout.marginLeft = 3;
layout.marginRight = 3;
root.setLayout(layout);
root = new Composite(root, SWT.NONE);
root.setLayoutData(SWTUtil.createFillGridData());
root.setLayout(SWTUtil.createGridLayout(2));
this.slider = new ComponentGSSlider(root);
this.slider.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent arg0) {
if (model != null && model.getInputConfig() != null) {
model.getLocalRecodingModel().setGsFactor(slider.getSelection());
}
}
});
this.slider.setLayoutData(SWTUtil.createFillGridData(2));
this.combo = new Combo(root, SWT.READ_ONLY);
this.combo.setItems(getListOftModes());
this.combo.select(0);
this.combo.setLayoutData(SWTUtil.createFillHorizontallyGridData(false));
this.combo.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent arg0) {
if (combo.getSelectionIndex() != -1) {
String item = combo.getItem(combo.getSelectionIndex());
for (LocalRecodingMode mode : LocalRecodingMode.values()) {
if (mode == LocalRecodingMode.FIXPOINT_ADAPTIVE) {
for (double parameter : FIXPOINT_PARAMETERS) {
if (item.equals(getLabelForMode(mode, parameter))) {
model.getLocalRecodingModel().setMode(LocalRecodingMode.FIXPOINT_ADAPTIVE);
model.getLocalRecodingModel().setAdaptionFactor(parameter);
return;
}
}
} else if (mode == LocalRecodingMode.MULTI_PASS) {
for (double parameter : MULTIPASS_PARAMETERS) {
if (item.equals(getLabelForMode(mode, parameter))) {
model.getLocalRecodingModel().setMode(LocalRecodingMode.MULTI_PASS);
model.getLocalRecodingModel().setNumIterations((int)parameter);
return;
}
}
} else if (mode == LocalRecodingMode.SINGLE_PASS) {
if (item.equals(getLabelForMode(mode, 0d))) {
model.getLocalRecodingModel().setMode(LocalRecodingMode.SINGLE_PASS);
return;
}
} else if (mode == LocalRecodingMode.FIXPOINT) {
if (item.equals(getLabelForMode(mode, 0d))) {
model.getLocalRecodingModel().setMode(LocalRecodingMode.FIXPOINT);
return;
}
}
}
}
}
});
this.button = new Button(root, SWT.NONE);
this.button.setText(Resources.getMessage("ViewLocalRecoding.0")); //$NON-NLS-1$
this.button.addSelectionListener(new SelectionAdapter(){
@Override
public void widgetSelected(SelectionEvent arg0) {
if (model.getResult() != null && model.getOutput() != null) {
controller.actionApplyLocalRecoding();
}
}
});
}
/**
* Returns the index of the given element in the given array
* @param array
* @param element
* @return
*/
private int getIndexOf(String[] array, String element) {
for (int i=0; i<array.length; i++) {
if (array[i].equals(element)) {
return i;
}
}
return -1;
}
/**
* Returns a string label for the mode
* @param mode
* @return
*/
private String getLabelForMode(LocalRecodingMode mode) {
String label = mode.toString().replace("_", "-").toLowerCase();
return label.substring(0, 1).toUpperCase() + label.substring(1);
}
/**
* Returns a label for the given configuration
* @param mode
* @param parameter
* @return
*/
private String getLabelForMode(LocalRecodingMode mode, double parameter) {
String label = getLabelForMode(mode);
if (mode == LocalRecodingMode.FIXPOINT_ADAPTIVE) {
return label + " (" + parameter + ")";
} else if (mode == LocalRecodingMode.MULTI_PASS) {
return label + " (" + (int)parameter + ")";
} else if (mode == LocalRecodingMode.SINGLE_PASS) {
return label;
} else if (mode == LocalRecodingMode.FIXPOINT) {
return label;
} else {
throw new RuntimeException("Unknown mode");
}
}
/**
* Returns a list of entries for the combo box
* @return
*/
private String[] getListOftModes() {
List<String> result = new ArrayList<String>();
for (LocalRecodingMode mode : LocalRecodingMode.values()) {
if (mode == LocalRecodingMode.FIXPOINT_ADAPTIVE) {
for (double parameter : FIXPOINT_PARAMETERS) {
result.add(getLabelForMode(mode, parameter));
}
} else if (mode == LocalRecodingMode.MULTI_PASS) {
for (double parameter : MULTIPASS_PARAMETERS) {
result.add(getLabelForMode(mode, parameter));
}
} else if (mode == LocalRecodingMode.SINGLE_PASS) {
result.add(getLabelForMode(mode, 0d));
} else if (mode == LocalRecodingMode.FIXPOINT) {
result.add(getLabelForMode(mode, 0d));
}
}
return result.toArray(new String[result.size()]);
}
/**
* Updates all controlls
*/
private void update() {
boolean enabled = false;
if (this.model == null || this.model.getResult() == null || this.model.getOutput() == null) {
enabled = false;
} else {
enabled = this.model.getResult().isOptimizable(this.model.getOutput());
}
if (!enabled) {
reset();
return;
}
SWTUtil.enable(root);
this.button.setEnabled(true);
this.slider.setSelection(this.model.getLocalRecodingModel().getGsFactor());
String label = null;
LocalRecodingMode mode = this.model.getLocalRecodingModel().getMode();
if (mode == LocalRecodingMode.FIXPOINT_ADAPTIVE) {
label = getLabelForMode(mode, this.model.getLocalRecodingModel().getAdaptionFactor());
} else if (mode == LocalRecodingMode.MULTI_PASS) {
label = getLabelForMode(mode, this.model.getLocalRecodingModel().getNumIterations());
} else {
label = getLabelForMode(mode, 0d);
}
this.combo.select(getIndexOf(this.combo.getItems(), label));
}
}