blob: 7ad25e824d54613acd50a1485e8e7def7f878218 [file] [log] [blame]
/*
* Copyright (c) 2006, 2007 Borland Software Corporation
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Dmitry Stadnik (Borland) - initial API and implementation
*/
package org.eclipse.gmf.examples.taipan.gmf.editor.providers;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.transaction.RunnableWithResult;
import org.eclipse.emf.workspace.util.WorkspaceSynchronizer;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.examples.taipan.Route;
import org.eclipse.gmf.examples.taipan.Ship;
import org.eclipse.gmf.examples.taipan.TaiPanPackage;
import org.eclipse.gmf.examples.taipan.gmf.editor.expressions.TaiPanOCLFactory;
import org.eclipse.gmf.examples.taipan.gmf.editor.part.TaiPanDiagramEditor;
import org.eclipse.gmf.examples.taipan.gmf.editor.part.TaiPanDiagramEditorPlugin;
import org.eclipse.gmf.examples.taipan.gmf.editor.part.TaiPanDiagramEditorUtil;
import org.eclipse.gmf.examples.taipan.gmf.editor.part.TaiPanVisualIDRegistry;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;
import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ColumnPixelData;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.jface.viewers.IOpenListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableColorProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.OpenEvent;
import org.eclipse.jface.viewers.TableLayout;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.ViewPart;
/**
* @generated
*/
public class TaiPanMetricProvider {
/**
* @generated
*/
public static class MetricsAction extends Action {
/**
* @generated
*/
private IWorkbenchPage page;
/**
* @generated
*/
public MetricsAction(IWorkbenchPage page) {
setText("Metrics");
this.page = page;
}
/**
* @generated
*/
public void run() {
IWorkbenchPart workbenchPart = page.getActivePart();
IViewPart metricsView = null;
try {
metricsView = page.findView(org.eclipse.gmf.examples.taipan.gmf.editor.providers.TaiPanMetricProvider.ResultView.VIEW_ID);
if (metricsView == null) {
metricsView = page.showView(org.eclipse.gmf.examples.taipan.gmf.editor.providers.TaiPanMetricProvider.ResultView.VIEW_ID);
} else {
if (metricsView != null && workbenchPart instanceof IDiagramWorkbenchPart) {
final IDiagramWorkbenchPart part = (IDiagramWorkbenchPart) workbenchPart;
((ResultView) metricsView).setInput(part);
}
page.activate(metricsView);
}
} catch (PartInitException e) {
TaiPanDiagramEditorPlugin.getInstance().logError("Diagram metric view failure", e); //$NON-NLS-1$
}
}
}
/**
* @generated
*/
static List calculateMetrics(IDiagramWorkbenchPart diagramPart) {
final DiagramEditPart diagramEditPart = diagramPart.getDiagramEditPart();
try {
return (List) diagramPart.getDiagramEditPart().getEditingDomain().runExclusive(new RunnableWithResult.Impl() {
public void run() {
Diagram diagram = diagramEditPart.getDiagramView();
ArrayList<ElementMetrics> metrics = new ArrayList<ElementMetrics>(50);
calculateSemanticElementMetrics(diagramEditPart, metrics);
setResult(metrics);
}
});
} catch (InterruptedException e) {
return Collections.EMPTY_LIST;
}
}
/**
* NOTE: metrics are being collected for domain elements contained in the semantic element associated with diagram view, actual diagram content (elements present there) is not taken into account.
* @generated
*/
static void calculateSemanticElementMetrics(DiagramEditPart diagramEditPart, List<ElementMetrics> metricsList) {
Diagram diagram = diagramEditPart.getDiagramView();
EObject next = diagram.getElement();
Iterator/*<EObject>*/it = next != null ? next.eAllContents() : Collections.EMPTY_LIST.iterator();
HashMap<EObject, ElementMetrics> target2row = new HashMap<EObject, ElementMetrics>();
while (next != null) {
ArrayList<Metric> res = new ArrayList<Metric>(5);
if (TaiPanPackage.eINSTANCE.getRoute().isInstance(next)) {
res.add(new Metric("RouteRelb", calcRouteRelb((Route) next), new Double(0.1), new Double(0.9)));
}
if (TaiPanPackage.eINSTANCE.getShip().isInstance(next)) {
res.add(new Metric("ShipLoad", calcShipLoad((Ship) next), new Double(1.0), new Double(5.0)));
}
if (!res.isEmpty()) {
ElementMetrics row = new ElementMetrics(next, formatElementName(next), (Metric[]) res.toArray(new Metric[res.size()]));
metricsList.add(row);
target2row.put(next, row);
}
next = it.hasNext() ? (EObject) it.next() : null;
}
if (!target2row.isEmpty()) { // list was modified, need to process only semantic metrics
// bind semantic elements to notation
TaiPanDiagramEditorUtil.LazyElement2ViewMap element2ViewMap = new TaiPanDiagramEditorUtil.LazyElement2ViewMap(diagram, target2row.keySet());
for (Iterator it2 = target2row.entrySet().iterator(); it2.hasNext();) {
Map.Entry entry = (Map.Entry) it2.next();
EObject semanticElement = (EObject) entry.getKey();
View targetView = TaiPanDiagramEditorUtil.findView(diagramEditPart, semanticElement, element2ViewMap);
ElementMetrics elementMetrics = (ElementMetrics) entry.getValue();
elementMetrics.diagramElementID = targetView.eResource().getURIFragment(targetView);
}
}
}
/**
* @generated
*/
private static String formatViewName(View viewTarget) {
StringBuffer notationQNameBuf = new StringBuffer();
notationQNameBuf.append(formatElementName(viewTarget));
if (viewTarget.getElement() != null) {
notationQNameBuf.append("->").append(formatElementName(viewTarget.getElement())); //$NON-NLS-1$
}
int visualID = TaiPanVisualIDRegistry.getVisualID(viewTarget);
notationQNameBuf.append('[').append(visualID < 0 ? Integer.toString(System.identityHashCode(viewTarget)) : Integer.toString(visualID)).append(']');
return notationQNameBuf.toString();
}
/**
* @generated
*/
private static String formatElementName(EObject object) {
return EMFCoreUtil.getQualifiedName(object, true);
}
/**
* @generated
*/
private static class ElementMetrics {
/**
* @generated
*/
final Metric[] metrics;
/**
* @generated
*/
final String targetElementQName;
/**
* @generated
*/
final Image elementImage;
/**
* @generated
*/
String diagramElementID;
/**
* @generated
*/
ElementMetrics(EObject target, String name, Metric[] metrics) {
assert metrics.length > 0;
assert name != null;
this.metrics = metrics;
this.targetElementQName = name;
EClass imageTarget = target.eClass();
if (target instanceof View) {
View viewTarget = (View) target;
if ("".equals(viewTarget.getType()) && viewTarget.getElement() != null) { //$NON-NLS-1$
imageTarget = viewTarget.getElement().eClass();
}
}
this.elementImage = TaiPanElementTypes.getImage(imageTarget);
}
/**
* @generated
*/
Metric getMetricByKey(String key) {
for (int i = 0; i < metrics.length; i++) {
if (metrics[i].key.equals(key)) {
return metrics[i];
}
}
return null;
}
}
/**
* @generated
*/
private static class Metric implements Comparable {
/**
* @generated
*/
final String key;
/**
* @generated
*/
final Double value;
/**
* @generated
*/
final Double lowLimit;
/**
* @generated
*/
final Double highLimit;
/**
* @generated
*/
final String displayValue;
/**
* @generated
*/
Metric(String key, Double value) {
this(key, value, null, null);
}
/**
* @generated
*/
Metric(String key, Double value, Double low, Double high) {
assert key != null;
this.key = key;
this.value = value;
this.lowLimit = low;
this.highLimit = high;
this.displayValue = (value != null) ? NumberFormat.getInstance().format(value) : "null"; //$NON-NLS-1$
}
/**
* @generated
*/
public int compareTo(Object other) {
Metric otherMetric = (Metric) other;
if (value != null && otherMetric.value != null) {
return (value.longValue() < otherMetric.value.longValue()) ? -1 : (value.longValue() == otherMetric.value.longValue() ? 0 : 1);
}
return (value == null && otherMetric.value == null) ? 0 : (value == null) ? -1 : 1;
}
}
/**
* @generated
*/
private static String[] getMetricKeys() {
return new String[] { "RouteRelb", "ShipLoad" };
}
/**
* @generated
*/
private static String[] getMetricToolTips() {
return new String[] { "Route Reliability" + '\n' + "Safety of the route." + '\n' + "low: 0.1" + "high: 0.9",
"Ship Load" + '\n' + "Quantity of items loaded on ship." + '\n' + "low: 1.0" + "high: 5.0" };
}
/**
* @generated
*/
public static Double calcRouteRelb(Route target) {
Object val = TaiPanOCLFactory.getExpression(8, TaiPanPackage.eINSTANCE.getRoute(), null).evaluate(target);
if (val instanceof Number) {
return val.getClass() == Double.class ? (Double) val : new Double(((Number) val).doubleValue());
}
return null;
}
/**
* @generated
*/
public static Double calcShipLoad(Ship target) {
// TODO: implement this method
// Ensure that you remove @generated or mark it @generated NOT
throw new UnsupportedOperationException("No user java implementation provided"); //$NON-NLS-1$
}
/**
* @generated
*/
public static class ResultView extends ViewPart implements IOpenListener {
/**
* @generated
*/
public static final String VIEW_ID = "org.eclipse.gmf.examples.taipan.gmf.editor.metricView"; //$NON-NLS-1$
/**
* @generated
*/
private static int MAX_VISIBLE_KEY_CHAR_COUNT = 8;
/**
* @generated
*/
private TableViewer viewer;
/**
* @generated
*/
private Resource diagramResource;
/**
* @generated
*/
void setInput(IDiagramWorkbenchPart diagramPart) {
diagramResource = diagramPart.getDiagram().eResource();
setTitleToolTip(diagramResource.getURI().path());
List metrics = calculateMetrics(diagramPart);
adjustLayout(metrics);
viewer.setInput(metrics);
}
/**
* @generated
*/
private void adjustLayout(List metricResultList) {
Map maxValStrMap = calcMetricMaxValueStrLenMap(metricResultList);
Table table = viewer.getTable();
TableLayout layout = new TableLayout();
org.eclipse.swt.graphics.GC gc = new org.eclipse.swt.graphics.GC(table);
gc.setFont(JFaceResources.getDialogFont());
int padding = gc.stringExtent("X").x * 2; //$NON-NLS-1$
for (int i = 0; i < getMetricKeys().length; i++) {
final String nextKey = getMetricKeys()[i];
String valueStr = (String) maxValStrMap.get(nextKey);
int minWidth = valueStr != null ? gc.stringExtent(valueStr).x + padding : 20;
layout.addColumnData(new ColumnPixelData(minWidth, true));
}
gc.dispose();
layout.addColumnData(new ColumnWeightData(1, 50, true));
viewer.getTable().setLayout(layout);
viewer.getTable().layout(true, true);
}
/**
* @generated
*/
public void createPartControl(Composite parent) {
this.viewer = new TableViewer(parent, SWT.FULL_SELECTION);
final Table table = viewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
for (int i = 0; i < getMetricKeys().length; i++) {
TableColumn column = new TableColumn(table, SWT.NONE);
column.setAlignment(SWT.RIGHT);
column.setMoveable(true);
column.setText(getMetricKeys()[i]);
column.setToolTipText(getMetricToolTips()[i]);
}
TableColumn objectColumn = new TableColumn(table, SWT.NONE);
objectColumn.setText("Element");
objectColumn.setToolTipText("Measurement element");
viewer.setLabelProvider(new Labels());
viewer.setContentProvider(new ArrayContentProvider());
viewer.addOpenListener(this);
SelectionListener headerSelListener = new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
table.setSortColumn((TableColumn) e.getSource());
table.setSortDirection((table.getSortDirection() != SWT.DOWN) ? SWT.DOWN : SWT.UP);
viewer.refresh();
}
public void widgetDefaultSelected(SelectionEvent e) {
}
};
TableColumn[] columns = viewer.getTable().getColumns();
for (int i = 0; i < columns.length; i++) {
columns[i].addSelectionListener(headerSelListener);
}
viewer.setSorter(new ViewerSorter() {
public int compare(Viewer viewer, Object e1, Object e2) {
TableColumn c = table.getSortColumn();
int result = 0;
if (c != null) {
Metric mc1 = ((ElementMetrics) e1).getMetricByKey(c.getText());
Metric mc2 = ((ElementMetrics) e2).getMetricByKey(c.getText());
result = (mc1 != null && mc2 != null) ? mc1.compareTo(mc2) : (mc1 == null ? -1 : 1);
} else {
result = ((ElementMetrics) e1).targetElementQName.compareTo(((ElementMetrics) e2).targetElementQName);
}
return table.getSortDirection() == SWT.DOWN ? result : -result;
}
});
IEditorPart editor = getSite().getPage().getActiveEditor();
if (editor != null && editor.getClass().equals(TaiPanDiagramEditor.class)) {
setInput((TaiPanDiagramEditor) editor);
}
}
/**
* @generated
*/
public void open(OpenEvent event) {
try {
IEditorPart editorPart = getSite().getPage().openEditor(new FileEditorInput(WorkspaceSynchronizer.getFile(diagramResource)), TaiPanDiagramEditor.ID);
if (editorPart == null) {
return;
}
IDiagramWorkbenchPart diagramPart = (IDiagramWorkbenchPart) editorPart.getAdapter(IDiagramWorkbenchPart.class);
ElementMetrics selection = (ElementMetrics) ((IStructuredSelection) event.getSelection()).getFirstElement();
String viewID = selection.diagramElementID;
if (viewID != null) {
View targetView = (View) diagramPart.getDiagram().eResource().getEObject(viewID);
if (targetView != null) {
EditPart targetEditPart = (EditPart) diagramPart.getDiagramGraphicalViewer().getEditPartRegistry().get(targetView);
if (targetEditPart != null) {
TaiPanDiagramEditorUtil.selectElementsInDiagram(diagramPart, Collections.singletonList(targetEditPart));
}
}
}
} catch (PartInitException e) {
TaiPanDiagramEditorPlugin.getInstance().logError("Can't open diagram editor", e); //$NON-NLS-1$
}
}
/**
* @generated
*/
private static Map calcMetricMaxValueStrLenMap(List allMetrics) {
Map metric2MaxStrLen = new HashMap();
for (int i = 0; i < getMetricKeys().length; i++) {
String nextKey = getMetricKeys()[i];
int trimPos = Math.min(nextKey.length(), MAX_VISIBLE_KEY_CHAR_COUNT);
metric2MaxStrLen.put(nextKey, nextKey.substring(0, trimPos));
}
for (Iterator it = allMetrics.iterator(); it.hasNext();) {
ElementMetrics elementMetrics = (ElementMetrics) it.next();
for (int i = 0; i < elementMetrics.metrics.length; i++) {
Metric metric = elementMetrics.metrics[i];
String valueStr = (String) metric2MaxStrLen.get(metric.key);
if (valueStr == null || metric.displayValue.length() > valueStr.length()) {
metric2MaxStrLen.put(metric.key, metric.displayValue);
}
}
}
return metric2MaxStrLen;
}
/**
* @generated
*/
public void setFocus() {
}
/**
* @generated
*/
private class Labels extends LabelProvider implements ITableLabelProvider, ITableColorProvider {
/**
* @generated
*/
private boolean isElementColumn(int columnIndex) {
return columnIndex >= getMetricKeys().length;
}
/**
* @generated
*/
public Image getColumnImage(Object element, int columnIndex) {
return isElementColumn(columnIndex) ? ((ElementMetrics) element).elementImage : null;
}
/**
* @generated
*/
public String getColumnText(Object element, int columnIndex) {
ElementMetrics elementMetrics = (ElementMetrics) element;
if (columnIndex == getMetricKeys().length) {
return elementMetrics.targetElementQName;
}
final String key = getMetricKeys()[columnIndex];
Metric metric = elementMetrics.getMetricByKey(key);
return (metric != null) ? metric.displayValue : "-"; //$NON-NLS-1$
}
/**
* @generated
*/
public Color getBackground(Object element, int columnIndex) {
return null;
}
/**
* @generated
*/
public Color getForeground(Object element, int columnIndex) {
if (isElementColumn(columnIndex)) {
return null;
}
ElementMetrics columnElement = (ElementMetrics) element;
final String key = getMetricKeys()[columnIndex];
Metric metric = columnElement.getMetricByKey(key);
if (metric != null && metric.value != null) {
if (metric.highLimit != null && metric.highLimit.longValue() < metric.value.longValue()) {
return ColorConstants.red;
} else if (metric.lowLimit != null && metric.lowLimit.longValue() > metric.value.longValue()) {
return ColorConstants.blue;
}
}
return null;
}
}
}
}