/* Copyright (C) 2011 by Claas Wilke (claas.wilke@tu-dresden.de) This file is part of Dresden OCL. Dresden OCL is free software: you can redistribute it and/or modify it 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. Dresden OCL is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Dresden OCL. If not, see <http://www.gnu.org/licenses/>. */ package org.dresdenocl.metrics.ui; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import org.dresdenocl.metrics.OclMetrics; import org.dresdenocl.metrics.metric.Metric; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableColumn; import org.eclipse.ui.ISelectionListener; import org.eclipse.ui.ISelectionService; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.part.ViewPart; import org.dresdenocl.model.IModel; import org.dresdenocl.model.IModelListener; import org.dresdenocl.model.ModelAccessException; import org.dresdenocl.model.event.IModelRegistryListener; import org.dresdenocl.model.event.ModelRegistryEvent; import org.dresdenocl.modelbus.IModelBusConstants; import org.dresdenocl.modelbus.ModelBusPlugin; import org.dresdenocl.pivotmodel.Constraint; /** * <p> * This class provides the view which is used to present the results of the * Dresden OCL Metrics. * </p> * * @author Claas Wilke */ public class MetricsView extends ViewPart implements ISelectionListener, IModelRegistryListener, IModelListener { /** * The currently selected {@link Constraint}s for that the metrics shall be * displayed. */ private Set<Constraint> currentlySelectedConstraints = new HashSet<Constraint>(); /** The {@link Metric} of this {@link MetricsView}. */ private Metric myResult; /** * The {@link TableViewer} used to present the results of the * interpretation. */ private TableViewer myTableViewer; /** * The current {@link IModel} of this {@link MetricsView}. */ private IModel myCurrentModel; /** * <p> * Creates a new {@link MetricsView}. * </p> */ public MetricsView() { /* Register this view as a model listener. */ ModelBusPlugin.getModelRegistry().addModelRegistryListener(this); if (ModelBusPlugin.getModelRegistry().getActiveModel() != null) { this.myCurrentModel = ModelBusPlugin.getModelRegistry() .getActiveModel(); this.myCurrentModel.addListener(this); refreshView(); } } /* * (non-Javadoc) * * @see org.eclipse.ui.part.WorkbenchPart#dispose() */ public void dispose() { /* Remove this view as listener of related plug-ins. */ ModelBusPlugin.getModelRegistry().removeModelRegistryListener(this); ((ISelectionService) getSite().getService(ISelectionService.class)) .removeSelectionListener(this); super.dispose(); } /* * (non-Javadoc) * * @seeorg.dresdenocl.modelbus.event.IModelRegistryListener# * activeModelChanged * (org.dresdenocl.modelbus.event.ModelRegistryEvent) */ public void activeModelChanged(ModelRegistryEvent event) { if (this.myCurrentModel != null) this.myCurrentModel.removeListener(this); // no else. this.clearResults(); this.myCurrentModel = ModelBusPlugin.getModelRegistry() .getActiveModel(); if (this.myCurrentModel != null) this.myCurrentModel.addListener(this); // no else. } /** * <p> * Called to create and initialize the {@link MetricsView}. * </p> * * @param parent * The parent composite of the created {@link TableViewer}. */ public void createPartControl(Composite parent) { final Table table; TableColumn column; this.myTableViewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); /* Set the content and label provider. */ this.myTableViewer.setContentProvider(new ResultsContentProvider()); this.myTableViewer.setLabelProvider(new ResultsLabelProvider()); table = myTableViewer.getTable(); table.setLayoutData(new GridData(GridData.FILL_BOTH)); /* Initialize the columns of the table. */ column = new TableColumn(table, SWT.LEFT); column.setText("Metric"); column = new TableColumn(table, SWT.LEFT); column.setText("Result"); table.setHeaderVisible(true); table.setLinesVisible(true); this.myTableViewer.setInput(this.myResult); for (int index = 0; index < table.getColumnCount(); index++) { table.getColumn(index).pack(); } this.getViewSite().getPage().addSelectionListener(this); this.getViewSite().setSelectionProvider(this.myTableViewer); } /* * (non-Javadoc) * * @see * org.dresdenocl.modelbus.event.IModelRegistryListener#modelAdded * (org.dresdenocl.modelbus.event.ModelRegistryEvent) */ public void modelAdded(ModelRegistryEvent event) { /* Do nothing until a new active IModel has been set. */ } public void modelRemoved(ModelRegistryEvent event) { /* Do nothing until a new active IModel has been set. */ } /* * (non-Javadoc) * * @seeorg.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui. * IWorkbenchPart, org.eclipse.jface.viewers.ISelection) */ public void selectionChanged(IWorkbenchPart part, ISelection selection) { /* Check if the selection of the models view changed. */ if (part.getSite() != null && part.getSite().getId() .equals(IModelBusConstants.MODELS_VIEW_ID)) { /* Check if the selection is a tree selection. */ if (selection instanceof TreeSelection) { /* Get an iterator to iterate over the selection. */ Iterator<?> selectionIt; selectionIt = ((TreeSelection) selection).iterator(); /* Clear the currently selected constraints and model objects. */ this.clearConstraintSelection(); /* * Add all selected constraints and types to the constraint * selection. */ while (selectionIt.hasNext()) { Object anObject; anObject = selectionIt.next(); if (anObject instanceof Constraint) { this.addConstraintSelection((Constraint) anObject); } // no else. } // end while. this.refreshView(); } // no else (no tree selection, could not happen). } // no else (nothing has to be updated). } /** * <p> * Passing the focus request to the viewer's control. * </p> */ public void setFocus() { this.myTableViewer.getControl().setFocus(); } /** * <p> * Clears the {@link IInterpretationResult} of this {@link MetricsView}. * </p> */ public void clearResults() { this.myResult = null; this.refreshView(); } /** * <p> * Clears the {@link IInterpretationResult} of this {@link MetricsView} for * the currently selected {@link IModelInstanceElement}s and * {@link Constraint}s. * </p> */ /** * <p> * Returns the currently selected {@link Constraint}s that shall be * interpreted. * </p> * * @return The currently selected {@link Constraint}s that shall be * interpreted. */ public Set<Constraint> getCurrentlySelectedConstraints() { return this.currentlySelectedConstraints; } /** * <p> * Returns the {@link TableViewer} used to present the results of the * interpretation. * </p> * * @return The {@link TableViewer} used to present the results of the * interpretation. */ public TableViewer getTableViewer() { return this.myTableViewer; } /** * <p> * Refreshes this {@link MetricsView}. * </p> */ public void refreshView() { if (ModelBusPlugin.getModelRegistry().getActiveModel() != null) { try { Collection<Constraint> constraints = getCurrentlySelectedConstraints(); if (constraints == null || constraints.size() == 0) constraints = ModelBusPlugin.getModelRegistry() .getActiveModel().getConstraints(); // no else. myResult = OclMetrics.computeMetric(constraints); } catch (ModelAccessException e) { showMessage(e.getMessage()); } /* Execute in a GUI thread to avoid IllegalThreadExceptions. */ MetricsUiPlugin.getDefault().getWorkbench().getDisplay() .asyncExec(new Runnable() { /* * (non-Javadoc) * * @see java.lang.Runnable#run() */ public void run() { myTableViewer.setInput(myResult); for (int index = 0; index < myTableViewer .getTable().getColumnCount(); index++) { myTableViewer.getTable().getColumn(index) .pack(); } // end for. myTableViewer.refresh(); } }); } } /** * <p> * Opens a MessageDialog and shows a given message. * </p> * * @param message * The message which shall be shown. */ public void showMessage(String message) { MessageDialog.openInformation(this.myTableViewer.getControl() .getShell(), "Message header", message); } /** * <p> * Adds a {@link Constraint} to the current {@link Constraint} selection. * </p> * * @param aConstraint * The {@link Constraint} which shall be added. */ private void addConstraintSelection(Constraint aConstraint) { this.currentlySelectedConstraints.add(aConstraint); } /** * <p> * Clears the {@link Constraint} selection for all actions which need * {@link Constraint} selection. * </p> */ private void clearConstraintSelection() { this.currentlySelectedConstraints.clear(); } /* * (non-Javadoc) * * @see * org.dresdenocl.model.IModelListener#modelChanged(org.dresdenocl * .pivot.model.IModel) */ public void modelChanged(IModel model) { this.refreshView(); } }