]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/TopologyImpl.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / diagram / handler / impl / TopologyImpl.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g2d.diagram.handler.impl;\r
13 \r
14 import java.util.Collection;\r
15 import java.util.List;\r
16 import java.util.Map;\r
17 import java.util.Set;\r
18 \r
19 import org.simantics.g2d.connection.EndKeyOf;\r
20 import org.simantics.g2d.connection.TerminalKeyOf;\r
21 import org.simantics.g2d.diagram.IDiagram;\r
22 import org.simantics.g2d.diagram.handler.ElementListener;\r
23 import org.simantics.g2d.diagram.handler.SubstituteElement;\r
24 import org.simantics.g2d.diagram.handler.Topology;\r
25 import org.simantics.g2d.element.ElementHints;\r
26 import org.simantics.g2d.element.ElementUtils;\r
27 import org.simantics.g2d.element.IElement;\r
28 import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;\r
29 import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
30 \r
31 /**\r
32  * \r
33  * @author Toni Kalajainen\r
34  */\r
35 public class TopologyImpl implements Topology, ElementListener {\r
36 \r
37     @Override\r
38     public Connection getConnection(IElement edge, EdgeEnd end)\r
39     {\r
40         Key key = EndKeyOf.get(end);\r
41         Connection c = edge.getHint(key);\r
42         if (c == null)\r
43             return null;\r
44         IDiagram d = ElementUtils.getDiagram(edge);\r
45         c = _updateReferences(d, c);\r
46         return c;\r
47     }\r
48 \r
49     @Override\r
50     public void getConnections(IElement node, Terminal terminal, Collection<Connection> connections)\r
51     {\r
52         // FIXME: only allows single connection / terminal\r
53         Key key = new TerminalKeyOf(terminal, null, Connection.class);\r
54         Connection c = node.getHint(key);\r
55         if (c != null) {\r
56             connections.add(c);\r
57         }\r
58         IDiagram d = ElementUtils.getDiagram(node);\r
59         _updateReferences(d, c);\r
60     }\r
61 \r
62     private Connection _updateReferences(IDiagram d, Connection c)\r
63     {\r
64         List<SubstituteElement> list = d.getDiagramClass().getItemsByClass(SubstituteElement.class);\r
65         if (list.size()==0) return c;\r
66 \r
67         IElement e = c.edge;\r
68         IElement n = c.node;\r
69 \r
70         for (SubstituteElement se : list)\r
71         {\r
72             IElement ne = se.substitute(d, e);\r
73             IElement nn = se.substitute(d, n);\r
74             if (ne != null)\r
75                 e = ne;\r
76             if (nn != null)\r
77                 n = nn;\r
78         }\r
79 \r
80         return new Connection(e, c.end, n, c.terminal);\r
81     }\r
82 \r
83     @Override\r
84     public void connect(IElement edge, EdgeEnd end, IElement node, Terminal terminal) {\r
85         if (edge == null)\r
86             throw new NullPointerException("null edge");\r
87         if (end == null)\r
88             throw new NullPointerException("null end");\r
89         if (node == null)\r
90             throw new NullPointerException("null node");\r
91         if (terminal == null)\r
92             throw new NullPointerException("null terminal");\r
93 \r
94         IDiagram d = ElementUtils.getDiagram(edge);\r
95         assert( d == ElementUtils.getDiagram(node) );\r
96 \r
97         Connection c = new Connection(edge, end, node, terminal);\r
98 \r
99         // It is not the job of this code to check or resolve modelling issues\r
100         // caused by this connection.\r
101 \r
102         // This makes it possible to have more than one connection to the same\r
103         // terminal.\r
104         Object edgeData = edge.getHint(ElementHints.KEY_OBJECT);\r
105 \r
106         TerminalKeyOf key = new TerminalKeyOf(terminal, edgeData, Connection.class);\r
107         node.setHint(key, c);\r
108         EndKeyOf key2 = EndKeyOf.get(end);\r
109         edge.setHint(key2, c);\r
110     }\r
111 \r
112     @Override\r
113     public void disconnect(IElement edge, EdgeEnd end, IElement node, Terminal terminal) {\r
114         if (edge == null)\r
115             throw new NullPointerException("null edge");\r
116         if (end == null)\r
117             throw new NullPointerException("null end");\r
118         if (node == null)\r
119             throw new NullPointerException("null node");\r
120         if (terminal == null)\r
121             throw new NullPointerException("null terminal");\r
122 \r
123         IDiagram d = ElementUtils.getDiagram(edge);\r
124         assert( d == ElementUtils.getDiagram(node) );\r
125 \r
126         EndKeyOf edgeKey = EndKeyOf.get(end);\r
127         Connection c = edge.getHint(edgeKey);\r
128         if (c == null)\r
129             throw new UnsupportedOperationException("cannot disconnect, no Connection in edge " + edge);\r
130 \r
131         for (Map.Entry<TerminalKeyOf, Object> entry : node.getHintsOfClass(TerminalKeyOf.class).entrySet()) {\r
132             Connection cc = (Connection) entry.getValue();\r
133             if (c == cc) {\r
134                 node.removeHint(entry.getKey());\r
135                 edge.removeHint(edgeKey);\r
136                 return;\r
137             }\r
138         }\r
139 \r
140         throw new UnsupportedOperationException("cannot disconnect, no connection between found between edge "\r
141                 + edge + " and node " + node);\r
142     }\r
143 \r
144     @Override\r
145     public void onElementAdded(IDiagram d, IElement e) {\r
146     }\r
147 \r
148     @Override\r
149     public void onElementRemoved(IDiagram d, IElement e) {\r
150         Set<TerminalKeyOf> keys1 = e.getHintsOfClass(TerminalKeyOf.class).keySet();\r
151         for (TerminalKeyOf key : keys1)\r
152             e.removeHint(key);\r
153         for (EndKeyOf key : EndKeyOf.KEYS)\r
154             e.removeHint(key);\r
155     }\r
156 \r
157 }\r