summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Wouters2014-01-15 03:52:27 (EST)
committerLaurent Wouters2014-01-15 03:52:27 (EST)
commiteab7ff81dbf2eec27075dd51a7700d2884f32766 (patch)
tree127f3c001e40fe77a8275f7e35da01e971ee1347
parentca7141698c55d367fd5668ecb671bd243df9fec5 (diff)
downloadorg.eclipse.papyrus-eab7ff81dbf2eec27075dd51a7700d2884f32766.zip
org.eclipse.papyrus-eab7ff81dbf2eec27075dd51a7700d2884f32766.tar.gz
org.eclipse.papyrus-eab7ff81dbf2eec27075dd51a7700d2884f32766.tar.bz2
Added a style-based shape provider using the 'svgFile' property
Change-Id: Ib582fb4d8d5e96ed16db560c935d8b18a584cd2a Signed-off-by: Laurent Wouters <laurent.wouters@cea.fr>
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml11
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/figure/node/SVGNodePlateFigure.java7
-rwxr-xr-xplugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java136
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/AbstractShapeProvider.java76
4 files changed, 228 insertions, 2 deletions
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml
index af729be..412b9fe 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml
@@ -169,4 +169,15 @@
type="java.util.Collection">
</propertyTester>
</extension>
+<extension
+ point="org.eclipse.papyrus.infra.gmfdiag.common.shapeProvider">
+ <shapeProvider
+ class="org.eclipse.papyrus.infra.gmfdiag.common.providers.StyleBasedShapeProvider"
+ description="Provides shapes based on the applied styles."
+ id="org.eclipse.papyrus.infra.gmfdiag.common.providers.StyleBasedShapeProvider"
+ name="StyleBasedShapeProvider">
+ <Priority
+ name="Low"></Priority>
+ </shapeProvider>
+</extension>
</plugin>
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/figure/node/SVGNodePlateFigure.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/figure/node/SVGNodePlateFigure.java
index ef0b380..203c45e 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/figure/node/SVGNodePlateFigure.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/figure/node/SVGNodePlateFigure.java
@@ -99,6 +99,7 @@ public class SVGNodePlateFigure extends DefaultSizeNodeFigure {
}
}
+ protected SVGDocument svgDocument = null;
private PrecisionDimension svgDimension = null;
@@ -131,6 +132,7 @@ public class SVGNodePlateFigure extends DefaultSizeNodeFigure {
* the SVG document
*/
public void setSVGDocument(SVGDocument svgDocument) {
+ this.svgDocument = svgDocument;
if(svgDocument != null) {
this.svgDimension = getSvgDimension(svgDocument);
Element element = svgDocument.getElementById("PapyrusPath");
@@ -142,6 +144,11 @@ public class SVGNodePlateFigure extends DefaultSizeNodeFigure {
if(element != null) {
labelBounds = toDraw2DRectangle((SVGRectElement)element);
}
+ } else {
+ this.svgDimension = null;
+ this.outlinePoints = null;
+ this.outlineDimension = null;
+ this.labelBounds = null;
}
}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java
new file mode 100755
index 0000000..cb188ea
--- /dev/null
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/providers/StyleBasedShapeProvider.java
@@ -0,0 +1,136 @@
+/*****************************************************************************
+ * Copyright (c) 2014 CEA LIST.
+ *
+ * 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:
+ * CEA LIST - Initial API and implementation
+ *
+ *****************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.common.providers;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker;
+import org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener;
+import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
+import org.eclipse.gmf.runtime.notation.NotationPackage;
+import org.eclipse.gmf.runtime.notation.StringValueStyle;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.infra.gmfdiag.common.Activator;
+import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.AbstractShapeProvider;
+import org.eclipse.papyrus.infra.gmfdiag.common.service.shape.ProviderNotificationManager;
+import org.w3c.dom.svg.SVGDocument;
+
+/**
+ * Shape provider based on the applied style
+ *
+ * @author Laurent Wouters
+ */
+public class StyleBasedShapeProvider extends AbstractShapeProvider {
+
+ protected static final String STYLE_PROPERTY = "svgFile";
+
+ private ProviderNotificationManager manager;
+
+ private List<SVGDocument> listEmptySVG;
+ private List<RenderedImage> listEmptyRendered;
+ private List<SVGDocument> listSingletonSVG;
+ private List<RenderedImage> listSingletonRendered;
+
+ public StyleBasedShapeProvider() {
+ listEmptySVG = new ArrayList<SVGDocument>(0);
+ listEmptyRendered = new ArrayList<RenderedImage>(0);
+ listSingletonSVG = new ArrayList<SVGDocument>(1);
+ listSingletonSVG.add(null);
+ listSingletonRendered = new ArrayList<RenderedImage>(1);
+ listSingletonRendered.add(null);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#getShapes(org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ public List<RenderedImage> getShapes(EObject view) {
+ if (!(view instanceof View))
+ return listEmptyRendered;
+ View v = (View) view;
+ String svgFile = extract((StringValueStyle) v.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
+ if (svgFile == null)
+ return listEmptyRendered;
+ SVGDocument svg = getSVGDocument(view, svgFile);
+ RenderedImage img = null;
+ try {
+ img = renderSVGDocument(view, svg);
+ } catch (IOException e) {
+ Activator.log.error("Failed to render the svg file: " + svgFile, e);
+ }
+ listSingletonRendered.set(0, img);
+ return listSingletonRendered;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#getSVGDocument(org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ public List<SVGDocument> getSVGDocument(EObject view) {
+ if (!(view instanceof View))
+ return listEmptySVG;
+ View v = (View) view;
+ String svgFile = extract((StringValueStyle) v.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
+ if (svgFile == null)
+ return listEmptySVG;
+ SVGDocument svg = getSVGDocument(view, svgFile);
+ listSingletonSVG.set(0, svg);
+ return listSingletonSVG;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#providesShapes(org.eclipse.emf.ecore.EObject)
+ */
+ @Override
+ public boolean providesShapes(EObject view) {
+ if (!(view instanceof View))
+ return false;
+ View v = (View) view;
+ String svgFile = extract((StringValueStyle) v.getNamedStyle(NotationPackage.eINSTANCE.getStringValueStyle(), STYLE_PROPERTY));
+ return (svgFile != null);
+ }
+
+ /**
+ * Extracts the primitive value from the given style
+ *
+ * @param style
+ * The style
+ * @return The primitive value
+ */
+ private String extract(StringValueStyle style) {
+ if (style == null || style.getStringValue() == null || style.getStringValue().isEmpty()) {
+ return null;
+ }
+ return style.getStringValue();
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.common.service.shape.IShapeProvider#createProviderNotificationManager(org.eclipse.gmf.runtime.diagram.core.listener.DiagramEventBroker, org.eclipse.emf.ecore.EObject,
+ * org.eclipse.gmf.runtime.diagram.core.listener.NotificationListener)
+ */
+ @Override
+ public ProviderNotificationManager createProviderNotificationManager(DiagramEventBroker diagramEventBroker, EObject view, NotificationListener notificationListener) {
+ if (manager != null)
+ return manager;
+ manager = new ProviderNotificationManager(diagramEventBroker, view, notificationListener) {
+ @Override
+ protected void registerListeners() {
+
+ }
+ };
+ return manager;
+ }
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/AbstractShapeProvider.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/AbstractShapeProvider.java
index e73fc03..09d2f5d 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/AbstractShapeProvider.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/service/shape/AbstractShapeProvider.java
@@ -17,11 +17,14 @@ import java.io.IOException;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
+import java.util.WeakHashMap;
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.dom.util.DOMUtilities;
import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.gmf.runtime.common.core.service.AbstractProvider;
import org.eclipse.gmf.runtime.common.core.service.IOperation;
import org.eclipse.gmf.runtime.draw2d.ui.render.RenderedImage;
@@ -58,6 +61,11 @@ public abstract class AbstractShapeProvider extends AbstractProvider implements
/** description of the factory */
protected String description;
+ /**
+ * Maps of URIs for SVG files referred to with relative paths
+ */
+ private WeakHashMap<Resource, Map<String, String>> relativePaths;
+
/** Cache for the loaded SVG document */
private Map<String, SVGDocument> cache;
@@ -130,13 +138,32 @@ public abstract class AbstractShapeProvider extends AbstractProvider implements
* Loads a SVG document from the given location.
* This method uses a cache so that any given document is only loaded once.
*
+ * @param view
+ * The view object to retrieve a svg document for
+ * @param location
+ * The location to load the document from
+ * @return the Document SVG from its location, can return null if this is not a svg
+ */
+ protected synchronized SVGDocument getSVGDocument(EObject view, String location) {
+ if (relativePaths == null) {
+ relativePaths = new WeakHashMap<Resource, Map<String, String>>();
+ }
+ String canonical = getCanonicalURI(view, location);
+ return getSVGDocument(canonical);
+ }
+
+ /**
+ * Loads a SVG document from the given location.
+ * This method uses a cache so that any given document is only loaded once.
+ *
* @param location
* The location to load the document from
* @return the Document SVG from its location, can return null if this is not a svg
*/
protected synchronized SVGDocument getSVGDocument(String location) {
- if (cache == null)
+ if (cache == null) {
cache = new HashMap<String, SVGDocument>();
+ }
if (cache.containsKey(location))
return cache.get(location);
SVGDocument doc = doGetSVGDocument(location);
@@ -176,6 +203,47 @@ public abstract class AbstractShapeProvider extends AbstractProvider implements
return null;
}
+ /**
+ * Translates the given uri as a string to a canonical Eclipse URI
+ * The uri may be relative to the currently edited EMF resource
+ *
+ * @param model
+ * The model element used to retrieve the EMF resource that is currently edited
+ * @param uri
+ * The potentially relative URI of a svg file
+ * @return The canonical URI of the resource
+ */
+ private String getCanonicalURI(EObject model, String uri) {
+ if (uri.startsWith("platform:/")) {
+ return uri;
+ }
+
+ Map<String, String> resMap = relativePaths.get(model.eResource());
+ if (resMap == null) {
+ resMap = new HashMap<String, String>();
+ relativePaths.put(model.eResource(), resMap);
+ }
+ String canonical = resMap.get(uri);
+ if (canonical != null) {
+ return canonical;
+ }
+
+ URI resURI = model.eResource().getURI();
+ if (!resURI.isPlatform()) {
+ return null;
+ }
+ StringBuilder builder = new StringBuilder("platform:/");
+ String[] segments = resURI.segments();
+ for (int i = 0; i < segments.length - 1; i++) {
+ builder.append(segments[i]);
+ builder.append("/");
+ }
+ builder.append(uri);
+ canonical = builder.toString();
+ resMap.put(uri, canonical);
+ return canonical;
+ }
+
protected RenderedImage renderSVGDocument(EObject view, SVGDocument document) throws IOException {
postProcess(view, document);
String svgAsText = toString(document);
@@ -202,7 +270,11 @@ public abstract class AbstractShapeProvider extends AbstractProvider implements
public synchronized void refresh(IEditorPart editorPart) {
// Clears the cache of loaded SVG documents
// This will force their reloading
- if (cache != null)
+ if (cache != null) {
cache.clear();
+ }
+ if (relativePaths != null) {
+ relativePaths.clear();
+ }
}
}