-/*******************************************************************************\r
- * Copyright (c) 2007, 2016 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- * Semantum Oy - refactoring\r
- *******************************************************************************/\r
-package org.simantics.diagram.adapter;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Set;\r
-\r
-import org.simantics.db.AsyncReadGraph;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.procedure.AsyncProcedure;\r
-import org.simantics.diagram.adapter.RouteGraphUtils.BackendConnection;\r
-import org.simantics.diagram.connection.RouteGraph;\r
-import org.simantics.diagram.connection.RouteGraphConnectionClass;\r
-import org.simantics.diagram.connection.rendering.ConnectionStyle;\r
-import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer;\r
-import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle;\r
-import org.simantics.diagram.content.ResourceTerminal;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.ui.DiagramModelHints;\r
-import org.simantics.g2d.canvas.ICanvasContext;\r
-import org.simantics.g2d.connection.ConnectionEntity;\r
-import org.simantics.g2d.diagram.IDiagram;\r
-import org.simantics.g2d.diagram.handler.DataElementMap;\r
-import org.simantics.g2d.diagram.handler.Topology.Connection;\r
-import org.simantics.g2d.diagram.handler.Topology.Terminal;\r
-import org.simantics.g2d.element.ElementClass;\r
-import org.simantics.g2d.element.ElementHints;\r
-import org.simantics.g2d.element.IElement;\r
-import org.simantics.g2d.element.handler.TerminalTopology;\r
-import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;\r
-import org.simantics.g2d.utils.TopologicalSelectionExpander;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.scenegraph.g2d.nodes.connection.IRouteGraphListener;\r
-import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphChangeEvent;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.structural2.modelingRules.IModelingRules;\r
-\r
-import gnu.trove.set.hash.THashSet;\r
-\r
-/**\r
- * An element class for single connection entity elements. A connection entity\r
- * consists of connection edge segments and branch points as its children.\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
-public class RouteGraphConnectionClassFactory extends SyncElementFactory {\r
-\r
- public static final ElementClass CLASS = RouteGraphConnectionClass.CLASS;\r
-\r
- public static final ILineEndStyle HEAD = RouteGraphUtils.HEAD;\r
- public static final ILineEndStyle TAIL = RouteGraphUtils.TAIL;\r
-\r
- protected Layer0 L0;\r
- protected DiagramResource DIA;\r
- protected StructuralResource2 STR;\r
- protected ModelingResources MOD;\r
-\r
- public RouteGraphConnectionClassFactory(ReadGraph graph) {\r
- this.L0 = Layer0.getInstance(graph);\r
- this.DIA = DiagramResource.getInstance(graph);\r
- this.STR = StructuralResource2.getInstance(graph);\r
- this.MOD = ModelingResources.getInstance(graph);\r
- }\r
-\r
- @Override\r
- public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,\r
- final AsyncProcedure<ElementClass> procedure) {\r
- procedure.execute(graph, CLASS.newClassWith(false, new StaticObjectAdapter(elementType)));\r
- }\r
-\r
- @Override\r
- protected Resource getElementClassBaseType(AsyncReadGraph graph) {\r
- return DIA.Connection;\r
- }\r
-\r
- @Override\r
- public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, final Resource connection,\r
- IElement element) throws DatabaseException {\r
-\r
- IModelingRules modelingRules = diagram.getHint(DiagramModelHints.KEY_MODELING_RULES);\r
- Resource diagramRuntime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);\r
-\r
- Set<BackendConnection> backendConnections = new THashSet<>();\r
- RouteGraph rg = RouteGraphUtils.load(graph, diagramRuntime, connection, canvas, diagram, modelingRules, backendConnections);\r
-\r
- // Load connection line style.\r
- ConnectionStyle style = RouteGraphUtils.readConnectionStyle(graph, modelingRules, connection, STR);\r
- StyledRouteGraphRenderer renderer = RouteGraphUtils.getRenderer(graph, style);\r
-\r
- // Finish element load\r
- element.setHint(RouteGraphConnectionClass.KEY_ROUTEGRAPH, rg);\r
- element.setHint(RouteGraphConnectionClass.KEY_RENDERER, renderer);\r
- element.setHint(RouteGraphConnectionClass.KEY_PICK_TOLERANCE, 0.5);\r
-\r
- // Initialize ConnectionEntity in element\r
- element.setHint(ElementHints.KEY_CONNECTION_ENTITY, new CE(diagram, connection, element, backendConnections));\r
-\r
- // Setup graph writeback support for route graph modifications\r
- Session session = graph.getSession();\r
- element.setHint(RouteGraphConnectionClass.KEY_RG_LISTENER, new IRouteGraphListener() {\r
- @Override\r
- public void routeGraphChanged(RouteGraphChangeEvent event) {\r
- RouteGraphUtils.scheduleSynchronize(session, connection, event);\r
- }\r
- });\r
- }\r
-\r
- /**\r
- * Must have this in order for {@link TopologicalSelectionExpander} to work.\r
- * Otherwise this is pretty useless and should be deprecated altogether.\r
- * \r
- * @see ElementHints#KEY_CONNECTION_ENTITY\r
- */\r
- private static class CE implements ConnectionEntity {\r
-\r
- /**\r
- * Needed to gain access to {@link DataElementMap}.\r
- */\r
- final IDiagram diagram;\r
-\r
- /**\r
- * The connection instance resource in the graph database back-end.\r
- */\r
- final Resource connection;\r
-\r
- /**\r
- * The current element mapped to connection. \r
- */\r
- IElement connectionElement;\r
-\r
- /**\r
- * @see #getTerminalConnections(Collection)\r
- */\r
- final Set<BackendConnection> backendConnections;\r
-\r
- /**\r
- * Cache.\r
- */\r
- transient Set<Connection> terminalConnections;\r
-\r
- public CE(IDiagram diagram, Resource connection, IElement connectionElement, Set<BackendConnection> backendConnections) {\r
- if (connectionElement == null)\r
- throw new NullPointerException("null connection element");\r
- this.diagram = diagram;\r
- this.connection = connection;\r
- this.connectionElement = connectionElement;\r
- this.backendConnections = backendConnections;\r
- IElement ce = getConnection0();\r
- if (ce != null)\r
- this.connectionElement = ce;\r
- }\r
-\r
- public IElement getConnection0() {\r
- DataElementMap dem = diagram.getDiagramClass().getSingleItem(DataElementMap.class);\r
- IElement connectionElement = dem.getElement(diagram, connection);\r
- return connectionElement;\r
- }\r
-\r
- @Override\r
- public IElement getConnection() {\r
- IElement c = getConnection0();\r
- if (c == null)\r
- c = this.connectionElement;\r
- return c;\r
- }\r
-\r
- @Override\r
- public Collection<IElement> getBranchPoints(Collection<IElement> result) {\r
- return result != null ? result : Collections.<IElement> emptyList();\r
- }\r
-\r
- @Override\r
- public Collection<IElement> getSegments(Collection<IElement> result) {\r
- return result != null ? result : Collections.<IElement> emptyList();\r
- }\r
-\r
- @Override\r
- public Collection<Connection> getTerminalConnections(Collection<Connection> result) {\r
- if (terminalConnections == null)\r
- terminalConnections = calculateTerminalConnections();\r
- if (result == null)\r
- result = new ArrayList<Connection>(terminalConnections);\r
- else\r
- result.addAll(terminalConnections);\r
- return terminalConnections;\r
- }\r
-\r
- private Set<Connection> calculateTerminalConnections() {\r
- Set<Connection> result = new THashSet<Connection>(backendConnections.size());\r
- DataElementMap dem = diagram.getDiagramClass().getSingleItem(DataElementMap.class);\r
- IElement connectionElement = dem.getElement(diagram, connection);\r
- if (connectionElement == null)\r
- throw new NullPointerException("connection is not mapped");\r
- ArrayList<Terminal> ts = new ArrayList<Terminal>();\r
- for (BackendConnection bc : backendConnections) {\r
- IElement e = dem.getElement(diagram, bc.node);\r
- if (e == null)\r
- continue;\r
- TerminalTopology tt = e.getElementClass().getSingleItem(TerminalTopology.class);\r
- ts.clear();\r
- tt.getTerminals(e, ts);\r
- for (Terminal t : ts) {\r
- if (t instanceof ResourceTerminal) {\r
- ResourceTerminal rt = (ResourceTerminal) t;\r
- if (bc.terminal.equals(rt.getResource())) {\r
- result.add(new Connection(connectionElement, bc.end, e, t));\r
- break;\r
- }\r
- }\r
- }\r
- }\r
- return result;\r
- }\r
-\r
- @Override\r
- public void setListener(ConnectionListener listener) {\r
- throw new UnsupportedOperationException();\r
- }\r
-\r
- @Override\r
- public String toString() {\r
- return getClass().getSimpleName() + "[resource=" + connection + ", connectionElement=" + getConnection()\r
- + "]";\r
- }\r
-\r
- }\r
-\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2016 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * 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:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ * Semantum Oy - refactoring
+ *******************************************************************************/
+package org.simantics.diagram.adapter;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import org.simantics.db.AsyncReadGraph;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.procedure.AsyncProcedure;
+import org.simantics.diagram.adapter.RouteGraphUtils.BackendConnection;
+import org.simantics.diagram.connection.RouteGraph;
+import org.simantics.diagram.connection.RouteGraphConnectionClass;
+import org.simantics.diagram.connection.rendering.ConnectionStyle;
+import org.simantics.diagram.connection.rendering.StyledRouteGraphRenderer;
+import org.simantics.diagram.connection.rendering.arrows.ILineEndStyle;
+import org.simantics.diagram.content.ResourceTerminal;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.ui.DiagramModelHints;
+import org.simantics.g2d.canvas.ICanvasContext;
+import org.simantics.g2d.connection.ConnectionEntity;
+import org.simantics.g2d.diagram.IDiagram;
+import org.simantics.g2d.diagram.handler.DataElementMap;
+import org.simantics.g2d.diagram.handler.Topology.Connection;
+import org.simantics.g2d.diagram.handler.Topology.Terminal;
+import org.simantics.g2d.element.ElementClass;
+import org.simantics.g2d.element.ElementHints;
+import org.simantics.g2d.element.IElement;
+import org.simantics.g2d.element.handler.TerminalTopology;
+import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
+import org.simantics.g2d.utils.TopologicalSelectionExpander;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.scenegraph.g2d.nodes.connection.IRouteGraphListener;
+import org.simantics.scenegraph.g2d.nodes.connection.RouteGraphChangeEvent;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.structural2.modelingRules.IModelingRules;
+
+import gnu.trove.set.hash.THashSet;
+
+/**
+ * An element class for single connection entity elements. A connection entity
+ * consists of connection edge segments and branch points as its children.
+ *
+ * @author Tuukka Lehtonen
+ */
+public class RouteGraphConnectionClassFactory extends SyncElementFactory {
+
+ public static final ElementClass CLASS = RouteGraphConnectionClass.CLASS;
+
+ public static final ILineEndStyle HEAD = RouteGraphUtils.HEAD;
+ public static final ILineEndStyle TAIL = RouteGraphUtils.TAIL;
+
+ protected Layer0 L0;
+ protected DiagramResource DIA;
+ protected StructuralResource2 STR;
+ protected ModelingResources MOD;
+
+ public RouteGraphConnectionClassFactory(ReadGraph graph) {
+ this.L0 = Layer0.getInstance(graph);
+ this.DIA = DiagramResource.getInstance(graph);
+ this.STR = StructuralResource2.getInstance(graph);
+ this.MOD = ModelingResources.getInstance(graph);
+ }
+
+ @Override
+ public void create(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementType,
+ final AsyncProcedure<ElementClass> procedure) {
+ procedure.execute(graph, CLASS.newClassWith(false, new StaticObjectAdapter(elementType)));
+ }
+
+ @Override
+ protected Resource getElementClassBaseType(AsyncReadGraph graph) {
+ return DIA.Connection;
+ }
+
+ @Override
+ public void load(ReadGraph graph, ICanvasContext canvas, IDiagram diagram, final Resource connection,
+ IElement element) throws DatabaseException {
+
+ IModelingRules modelingRules = diagram.getHint(DiagramModelHints.KEY_MODELING_RULES);
+ Resource diagramRuntime = diagram.getHint(DiagramModelHints.KEY_DIAGRAM_RUNTIME_RESOURCE);
+
+ Set<BackendConnection> backendConnections = new THashSet<>();
+ RouteGraph rg = RouteGraphUtils.load(graph, diagramRuntime, connection, canvas, diagram, element, modelingRules, backendConnections);
+
+ // Load connection line style.
+ ConnectionStyle style = RouteGraphUtils.readConnectionStyle(graph, modelingRules, connection, STR);
+ StyledRouteGraphRenderer renderer = RouteGraphUtils.getRenderer(graph, style);
+
+ // Finish element load
+ element.setHint(RouteGraphConnectionClass.KEY_ROUTEGRAPH, rg);
+ element.setHint(RouteGraphConnectionClass.KEY_RENDERER, renderer);
+ element.setHint(RouteGraphConnectionClass.KEY_PICK_TOLERANCE, 0.5);
+
+ // Initialize ConnectionEntity in element
+ element.setHint(ElementHints.KEY_CONNECTION_ENTITY, new CE(diagram, connection, element, backendConnections));
+
+ // Setup graph writeback support for route graph modifications
+ Session session = graph.getSession();
+ element.setHint(RouteGraphConnectionClass.KEY_RG_LISTENER, new IRouteGraphListener() {
+ @Override
+ public void routeGraphChanged(RouteGraphChangeEvent event) {
+ RouteGraphUtils.scheduleSynchronize(session, connection, event);
+ }
+ });
+ }
+
+ /**
+ * Must have this in order for {@link TopologicalSelectionExpander} to work.
+ * Otherwise this is pretty useless and should be deprecated altogether.
+ *
+ * @see ElementHints#KEY_CONNECTION_ENTITY
+ */
+ public static class CE implements ConnectionEntity {
+
+ /**
+ * Needed to gain access to {@link DataElementMap}.
+ */
+ final IDiagram diagram;
+
+ /**
+ * The connection instance resource in the graph database back-end.
+ */
+ final Resource connection;
+
+ /**
+ * The current element mapped to connection.
+ */
+ IElement connectionElement;
+
+ /**
+ * @see #getTerminalConnections(Collection)
+ */
+ final Set<BackendConnection> backendConnections;
+
+ /**
+ * Cache.
+ */
+ transient Set<Connection> terminalConnections;
+
+ public CE(IDiagram diagram, Resource connection, IElement connectionElement, Set<BackendConnection> backendConnections) {
+ if (connectionElement == null)
+ throw new NullPointerException("null connection element");
+ this.diagram = diagram;
+ this.connection = connection;
+ this.connectionElement = connectionElement;
+ this.backendConnections = backendConnections;
+ IElement ce = getConnection0();
+ if (ce != null)
+ this.connectionElement = ce;
+ }
+
+ public IElement getConnection0() {
+ DataElementMap dem = diagram.getDiagramClass().getSingleItem(DataElementMap.class);
+ IElement connectionElement = dem.getElement(diagram, connection);
+ return connectionElement;
+ }
+
+ @Override
+ public IElement getConnection() {
+ IElement c = getConnection0();
+ if (c == null)
+ c = this.connectionElement;
+ return c;
+ }
+
+ @Override
+ public Collection<IElement> getBranchPoints(Collection<IElement> result) {
+ return result != null ? result : Collections.<IElement> emptyList();
+ }
+
+ @Override
+ public Collection<IElement> getSegments(Collection<IElement> result) {
+ return result != null ? result : Collections.<IElement> emptyList();
+ }
+
+ @Override
+ public Collection<Connection> getTerminalConnections(Collection<Connection> result) {
+ if (terminalConnections == null)
+ terminalConnections = calculateTerminalConnections();
+ if (result == null)
+ result = new ArrayList<Connection>(terminalConnections);
+ else
+ result.addAll(terminalConnections);
+ return terminalConnections;
+ }
+
+ private Set<Connection> calculateTerminalConnections() {
+ Set<Connection> result = new THashSet<Connection>(backendConnections.size());
+ DataElementMap dem = diagram.getDiagramClass().getSingleItem(DataElementMap.class);
+ IElement connectionElement = dem.getElement(diagram, connection);
+ if (connectionElement == null)
+ throw new NullPointerException("connection is not mapped");
+ ArrayList<Terminal> ts = new ArrayList<Terminal>();
+ for (BackendConnection bc : backendConnections) {
+ IElement e = dem.getElement(diagram, bc.node);
+ if (e == null)
+ continue;
+ TerminalTopology tt = e.getElementClass().getSingleItem(TerminalTopology.class);
+ ts.clear();
+ tt.getTerminals(e, ts);
+ for (Terminal t : ts) {
+ if (t instanceof ResourceTerminal) {
+ ResourceTerminal rt = (ResourceTerminal) t;
+ if (bc.terminal.equals(rt.getResource())) {
+ result.add(new Connection(connectionElement, bc.end, e, t));
+ break;
+ }
+ }
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public void setListener(ConnectionListener listener) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[resource=" + connection + ", connectionElement=" + getConnection()
+ + "]";
+ }
+
+ }
+