/* * Copyright (c) 2012 Data Harmonisation Panel * * All rights reserved. This program and the accompanying materials are made * available under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the License, * or (at your option) any later version. * * You should have received a copy of the GNU Lesser General Public License * along with this distribution. If not, see <http://www.gnu.org/licenses/>. * * Contributors: * HUMBOLDT EU Integrated Project #030962 * Data Harmonisation Panel <http://www.dhpanel.eu> */ package eu.esdihumboldt.hale.ui.views.transformation; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Map; import java.util.Observable; import java.util.Observer; import java.util.Set; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IAction; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.part.WorkbenchPart; import org.eclipse.zest.core.viewers.GraphViewer; import org.eclipse.zest.layouts.LayoutAlgorithm; import org.eclipse.zest.layouts.algorithms.TreeLayoutAlgorithm; import eu.esdihumboldt.hale.common.align.model.Alignment; import eu.esdihumboldt.hale.common.align.model.Cell; import eu.esdihumboldt.hale.common.instance.model.Instance; import eu.esdihumboldt.hale.ui.HaleUI; import eu.esdihumboldt.hale.ui.common.graph.content.TransformationTreeContentProvider; import eu.esdihumboldt.hale.ui.common.graph.labels.TransformationTreeLabelProvider; import eu.esdihumboldt.hale.ui.service.align.AlignmentService; import eu.esdihumboldt.hale.ui.service.align.AlignmentServiceAdapter; import eu.esdihumboldt.hale.ui.service.align.AlignmentServiceListener; import eu.esdihumboldt.hale.ui.service.instance.sample.InstanceSampleService; import eu.esdihumboldt.hale.ui.views.mapping.AbstractMappingView; import eu.esdihumboldt.hale.ui.views.transformation.internal.TransformationViewPlugin; import eu.esdihumboldt.util.Pair; /** * View displaying transformation tree(s). * * @author Simon Templer */ public class TransformationView extends AbstractMappingView { /** * The view ID */ public static final String ID = "eu.esdihumboldt.hale.ui.views.transformation"; private static final String MEMENTO_KEY_INSTANCE_SAMPLE = "apply_sample_instances"; private AlignmentServiceListener alignmentListener; private Observer instanceSampleObserver; private IAction instanceAction; private boolean initInstanceAction = false; /** * @see ViewPart#init(IViewSite, IMemento) */ @Override public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); if (memento != null) { Boolean value = memento.getBoolean(MEMENTO_KEY_INSTANCE_SAMPLE); if (value != null) { initInstanceAction = value; } } } /** * @see eu.esdihumboldt.hale.ui.views.mapping.AbstractMappingView#createViewControl(org.eclipse.swt.widgets.Composite) */ @Override public void createViewControl(Composite parent) { super.createViewControl(parent); IActionBars bars = getViewSite().getActionBars(); bars.getToolBarManager() .add(instanceAction = new Action("Apply sample instances", IAction.AS_CHECK_BOX) { @Override public void run() { update(); } }); instanceAction.setImageDescriptor( TransformationViewPlugin.getImageDescriptor("icons/samples.gif")); instanceAction.setChecked(initInstanceAction); update(); AlignmentService as = PlatformUI.getWorkbench().getService(AlignmentService.class); as.addListener(alignmentListener = new AlignmentServiceAdapter() { @Override public void alignmentCleared() { update(); } @Override public void cellsRemoved(Iterable<Cell> cells) { update(); } @Override public void cellsReplaced(Map<? extends Cell, ? extends Cell> cells) { update(); } @Override public void cellsAdded(Iterable<Cell> cells) { update(); } @Override public void alignmentChanged() { update(); } @Override public void customFunctionsChanged() { update(); } @Override public void cellsPropertyChanged(Iterable<Cell> cells, String propertyName) { if (Cell.PROPERTY_DISABLE_FOR.equals(propertyName) || Cell.PROPERTY_ENABLE_FOR.equals(propertyName)) update(); // Could add/remove cells from transformation tree else { final Display display = PlatformUI.getWorkbench().getDisplay(); display.syncExec(new Runnable() { @Override public void run() { // refresh view getViewer().refresh(); } }); } } }); final InstanceSampleService iss = PlatformUI.getWorkbench() .getService(InstanceSampleService.class); iss.addObserver(instanceSampleObserver = new Observer() { @SuppressWarnings("unchecked") @Override public void update(Observable o, Object arg) { if (!instanceAction.isChecked()) { return; } Object input = getViewer().getInput(); Collection<Instance> oldInstances = null; int sampleCount = 0; if (input instanceof Pair<?, ?>) { Object second = ((Pair<?, ?>) input).getSecond(); if (second instanceof Collection<?>) { oldInstances = (Collection<Instance>) second; sampleCount = oldInstances.size(); } } Collection<Instance> newSamples = iss.getReferenceInstances(); if (sampleCount == newSamples.size()) { // still to decide if update is necessary if (sampleCount == 0) { return; } // check if instances equal? Set<Instance> test = new HashSet<Instance>(oldInstances); test.removeAll(newSamples); if (test.isEmpty()) { return; } } TransformationView.this.update(); } }); } /** * Set the current alignment */ private void update() { final Display display = PlatformUI.getWorkbench().getDisplay(); // TODO add configuration option if instances should be included? display.syncExec(new Runnable() { @Override public void run() { AlignmentService as = PlatformUI.getWorkbench().getService(AlignmentService.class); Alignment alignment = as.getAlignment(); InstanceSampleService iss = PlatformUI.getWorkbench() .getService(InstanceSampleService.class); Collection<Instance> instances = iss.getReferenceInstances(); if (instanceAction.isChecked()) { if (instances != null && !instances.isEmpty()) { instances = new ArrayList<Instance>(instances); // alignment paired with instances as input getViewer().setInput(new Pair<Object, Object>(alignment, instances)); } else { getViewer().setInput(null); } } else { // only the alignment as input getViewer().setInput(alignment); } getViewer().applyLayout(); } }); } /** * @see WorkbenchPart#dispose() */ @Override public void dispose() { if (alignmentListener != null) { AlignmentService as = PlatformUI.getWorkbench().getService(AlignmentService.class); as.removeListener(alignmentListener); } if (instanceSampleObserver != null) { InstanceSampleService iss = PlatformUI.getWorkbench() .getService(InstanceSampleService.class); iss.deleteObserver(instanceSampleObserver); } super.dispose(); } /** * @see AbstractMappingView#createLabelProvider(GraphViewer) */ @Override protected IBaseLabelProvider createLabelProvider(GraphViewer viewer) { return new TransformationTreeLabelProvider(viewer, HaleUI.getServiceProvider()); } /** * @see AbstractMappingView#createContentProvider() */ @Override protected IContentProvider createContentProvider() { return new TransformationTreeContentProvider(); } /** * @see AbstractMappingView#createLayout() */ @Override protected LayoutAlgorithm createLayout() { return new TreeLayoutAlgorithm(TreeLayoutAlgorithm.RIGHT_LEFT); } /** * @see ViewPart#saveState(IMemento) */ @Override public void saveState(IMemento memento) { super.saveState(memento); memento.putBoolean(MEMENTO_KEY_INSTANCE_SAMPLE, instanceAction.isChecked()); } }