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
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.g2d.diagram.handler.impl;
\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
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
33 * @author Toni Kalajainen
\r
35 public class TopologyImpl implements Topology, ElementListener {
\r
38 public Connection getConnection(IElement edge, EdgeEnd end)
\r
40 Key key = EndKeyOf.get(end);
\r
41 Connection c = edge.getHint(key);
\r
44 IDiagram d = ElementUtils.getDiagram(edge);
\r
45 c = _updateReferences(d, c);
\r
50 public void getConnections(IElement node, Terminal terminal, Collection<Connection> connections)
\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
58 IDiagram d = ElementUtils.getDiagram(node);
\r
59 _updateReferences(d, c);
\r
62 private Connection _updateReferences(IDiagram d, Connection c)
\r
64 List<SubstituteElement> list = d.getDiagramClass().getItemsByClass(SubstituteElement.class);
\r
65 if (list.size()==0) return c;
\r
67 IElement e = c.edge;
\r
68 IElement n = c.node;
\r
70 for (SubstituteElement se : list)
\r
72 IElement ne = se.substitute(d, e);
\r
73 IElement nn = se.substitute(d, n);
\r
80 return new Connection(e, c.end, n, c.terminal);
\r
84 public void connect(IElement edge, EdgeEnd end, IElement node, Terminal terminal) {
\r
86 throw new NullPointerException("null edge");
\r
88 throw new NullPointerException("null end");
\r
90 throw new NullPointerException("null node");
\r
91 if (terminal == null)
\r
92 throw new NullPointerException("null terminal");
\r
94 IDiagram d = ElementUtils.getDiagram(edge);
\r
95 assert( d == ElementUtils.getDiagram(node) );
\r
97 Connection c = new Connection(edge, end, node, terminal);
\r
99 // It is not the job of this code to check or resolve modelling issues
\r
100 // caused by this connection.
\r
102 // This makes it possible to have more than one connection to the same
\r
104 Object edgeData = edge.getHint(ElementHints.KEY_OBJECT);
\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
113 public void disconnect(IElement edge, EdgeEnd end, IElement node, Terminal terminal) {
\r
115 throw new NullPointerException("null edge");
\r
117 throw new NullPointerException("null end");
\r
119 throw new NullPointerException("null node");
\r
120 if (terminal == null)
\r
121 throw new NullPointerException("null terminal");
\r
123 IDiagram d = ElementUtils.getDiagram(edge);
\r
124 assert( d == ElementUtils.getDiagram(node) );
\r
126 EndKeyOf edgeKey = EndKeyOf.get(end);
\r
127 Connection c = edge.getHint(edgeKey);
\r
129 throw new UnsupportedOperationException("cannot disconnect, no Connection in edge " + edge);
\r
131 for (Map.Entry<TerminalKeyOf, Object> entry : node.getHintsOfClass(TerminalKeyOf.class).entrySet()) {
\r
132 Connection cc = (Connection) entry.getValue();
\r
134 node.removeHint(entry.getKey());
\r
135 edge.removeHint(edgeKey);
\r
140 throw new UnsupportedOperationException("cannot disconnect, no connection between found between edge "
\r
141 + edge + " and node " + node);
\r
145 public void onElementAdded(IDiagram d, IElement e) {
\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
153 for (EndKeyOf key : EndKeyOf.KEYS)
\r