1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.g2d.diagram.handler.impl;
14 import java.util.Collection;
15 import java.util.List;
19 import org.simantics.g2d.connection.EndKeyOf;
20 import org.simantics.g2d.connection.TerminalKeyOf;
21 import org.simantics.g2d.diagram.IDiagram;
22 import org.simantics.g2d.diagram.handler.ElementListener;
23 import org.simantics.g2d.diagram.handler.SubstituteElement;
24 import org.simantics.g2d.diagram.handler.Topology;
25 import org.simantics.g2d.element.ElementHints;
26 import org.simantics.g2d.element.ElementUtils;
27 import org.simantics.g2d.element.IElement;
28 import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd;
29 import org.simantics.utils.datastructures.hints.IHintContext.Key;
33 * @author Toni Kalajainen
35 public class TopologyImpl implements Topology, ElementListener {
38 public Connection getConnection(IElement edge, EdgeEnd end)
40 Key key = EndKeyOf.get(end);
41 Connection c = edge.getHint(key);
44 IDiagram d = ElementUtils.getDiagram(edge);
45 c = _updateReferences(d, c);
50 public void getConnections(IElement node, Terminal terminal, Collection<Connection> connections)
52 // FIXME: only allows single connection / terminal
53 Key key = new TerminalKeyOf(terminal, null, Connection.class);
54 Connection c = node.getHint(key);
58 IDiagram d = ElementUtils.getDiagram(node);
59 _updateReferences(d, c);
62 private Connection _updateReferences(IDiagram d, Connection c)
64 List<SubstituteElement> list = d.getDiagramClass().getItemsByClass(SubstituteElement.class);
65 if (list.size()==0) return c;
70 for (SubstituteElement se : list)
72 IElement ne = se.substitute(d, e);
73 IElement nn = se.substitute(d, n);
80 return new Connection(e, c.end, n, c.terminal);
84 public void connect(IElement edge, EdgeEnd end, IElement node, Terminal terminal) {
86 throw new NullPointerException("null edge");
88 throw new NullPointerException("null end");
90 throw new NullPointerException("null node");
92 throw new NullPointerException("null terminal");
94 IDiagram d = ElementUtils.getDiagram(edge);
95 assert( d == ElementUtils.getDiagram(node) );
97 Connection c = new Connection(edge, end, node, terminal);
99 // It is not the job of this code to check or resolve modelling issues
100 // caused by this connection.
102 // This makes it possible to have more than one connection to the same
104 Object edgeData = edge.getHint(ElementHints.KEY_OBJECT);
106 TerminalKeyOf key = new TerminalKeyOf(terminal, edgeData, Connection.class);
107 node.setHint(key, c);
108 EndKeyOf key2 = EndKeyOf.get(end);
109 edge.setHint(key2, c);
113 public void disconnect(IElement edge, EdgeEnd end, IElement node, Terminal terminal) {
115 throw new NullPointerException("null edge");
117 throw new NullPointerException("null end");
119 throw new NullPointerException("null node");
120 if (terminal == null)
121 throw new NullPointerException("null terminal");
123 IDiagram d = ElementUtils.getDiagram(edge);
124 assert( d == ElementUtils.getDiagram(node) );
126 EndKeyOf edgeKey = EndKeyOf.get(end);
127 Connection c = edge.getHint(edgeKey);
129 throw new UnsupportedOperationException("cannot disconnect, no Connection in edge " + edge);
131 for (Map.Entry<TerminalKeyOf, Object> entry : node.getHintsOfClass(TerminalKeyOf.class).entrySet()) {
132 Connection cc = (Connection) entry.getValue();
134 node.removeHint(entry.getKey());
135 edge.removeHint(edgeKey);
140 throw new UnsupportedOperationException("cannot disconnect, no connection between found between edge "
141 + edge + " and node " + node);
145 public void onElementAdded(IDiagram d, IElement e) {
149 public void onElementRemoved(IDiagram d, IElement e) {
150 Set<TerminalKeyOf> keys1 = e.getHintsOfClass(TerminalKeyOf.class).keySet();
151 for (TerminalKeyOf key : keys1)
153 for (EndKeyOf key : EndKeyOf.KEYS)