1 package org.simantics.interop.diagram;
3 import java.awt.geom.AffineTransform;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.HashSet;
9 import org.simantics.databoard.Bindings;
10 import org.simantics.db.ReadGraph;
11 import org.simantics.db.Resource;
12 import org.simantics.db.Statement;
13 import org.simantics.db.WriteGraph;
14 import org.simantics.db.common.utils.Logger;
15 import org.simantics.db.common.utils.NameUtils;
16 import org.simantics.db.common.utils.OrderedSetUtils;
17 import org.simantics.db.exception.DatabaseException;
18 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
19 import org.simantics.db.exception.NoSingleResultException;
20 import org.simantics.db.exception.ServiceException;
21 import org.simantics.db.exception.ValidationException;
22 import org.simantics.diagram.stubs.DiagramResource;
23 import org.simantics.diagram.stubs.G2DResource;
24 import org.simantics.layer0.Layer0;
25 import org.simantics.modeling.ModelingResources;
26 import org.simantics.structural.stubs.StructuralResource2;
27 import org.simantics.structural2.utils.StructuralUtils;
32 * @author Marko Luukkainen
34 public abstract class Symbol {
36 private static boolean USE_UNRELIABLE_CONNECT = false;
37 private static boolean PREVENT_SELF_CONNECTIONS = false;
39 private Diagram diagram;
44 * Use Diagram.getSymbol() to get Symbols.
49 public Symbol(Diagram diagram, Resource element, Resource component) {
50 assert(diagram != null);
51 assert(element != null);
52 this.diagram = diagram;
53 this.element = element;
54 this.component = component;
57 public Diagram getDiagram() {
61 public Resource getComponent() {
65 public Resource getElement() {
70 * Connects two Symbols, chooses connection type automatically.
72 * @param symbolConf2 other symbol.
73 * @param componentConRel1 symbol's terminal relation.
74 * @param componentConRel2 other symbol's terminal relation.
75 * @return SymbolConnetionData instance describing the connection. Return value is never null.
76 * @throws DatabaseException on database failure.
78 public SymbolConnectionData connect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2) throws DatabaseException {
79 return connect(g, symbolConf2, componentConRel1, componentConRel2, false);
82 protected Collection<Resource> getConnectionRel(ReadGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Collection<Resource> matching) throws DatabaseException {
86 protected SymbolConnectionData customConnect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connType) throws DatabaseException {
91 * Connects two Symbols, chooses connection type automatically.
93 * @param symbolConf2 other symbol.
94 * @param componentConRel1 symbol's terminal relation.
95 * @param componentConRel2 other symbol's terminal relation.
96 * @param forceFlag creates flag connection even if symbols are on the same diagram.
97 * @return SymbolConnetionData instance describing the connection. Return value is never null.
98 * @throws DatabaseException on database failure.
100 public SymbolConnectionData connect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, boolean forceFlag) throws DatabaseException {
101 if (this.equals(symbolConf2)) {
102 if (PREVENT_SELF_CONNECTIONS) {
103 String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(componentConRel1) + " "+ componentConRel1 + " " + g.getPossibleURI(componentConRel2) + " "+ componentConRel2;
104 Logger.defaultLogError(err);
105 return new ConnectionErrorImpl(err);
107 if (componentConRel1.equals(componentConRel2)) {
108 String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(componentConRel1) + " "+ componentConRel1 + " " + g.getPossibleURI(componentConRel2) + " "+ componentConRel2;
109 Logger.defaultLogError(err);
110 return new ConnectionErrorImpl(err);
113 StructuralResource2 sr = StructuralResource2.getInstance(g);
114 Collection<Resource> connType1 = g.getObjects(componentConRel1, sr.AllowsConnectionType);
115 Collection<Resource> connType2 = g.getObjects(componentConRel2, sr.AllowsConnectionType);
116 Collection<Resource> matching = new HashSet<Resource>();
117 for (Resource r : connType2) {
118 if (connType1.contains(r))
121 if (matching.size() > 1) {
122 matching = getConnectionRel(g, symbolConf2, componentConRel1, componentConRel2, matching);
124 Resource usedConnType = null;
125 if (matching.size() != 1) {
127 if (USE_UNRELIABLE_CONNECT) {
128 err = "Unreliable connect " + component + " " + NameUtils.getSafeName(g, component) + " to " + symbolConf2.component + " " + NameUtils.getSafeName(g, symbolConf2.component) + " cannot find proper connection type, using Name Reference";
130 err = "Unable to connect " + component + " " + NameUtils.getSafeName(g, component) + " to " + symbolConf2.component + " " + NameUtils.getSafeName(g, symbolConf2.component) + " cannot find proper connection type for terminals " + g.getPossibleURI(componentConRel1) + " "+ componentConRel1 + " " + g.getPossibleURI(componentConRel2) + " "+ componentConRel2;
132 Logger.defaultLogInfo(err);
133 return new ConnectionErrorImpl(err);
135 usedConnType = matching.iterator().next();
138 SymbolConnectionData data = customConnect(g, symbolConf2, componentConRel1, componentConRel2, usedConnType);
140 if (!forceFlag && diagram.equals(symbolConf2.diagram))
141 return _connect(g, symbolConf2, componentConRel1, componentConRel2,usedConnType);
143 return connectWithFlag(g, symbolConf2, componentConRel1, componentConRel2,usedConnType);
150 * Connects two symbols with chosen connection type. Does not work with signal connections.
152 * @param symbolConf2 other symbol.
153 * @param componentConRel1 symbol's terminal relation.
154 * @param componentConRel2 other symbol's terminal relation.
155 * @param connectionType used connection type.
156 * @return SymbolConnetionData instance describing the connection. Return value is never null.
157 * @throws DatabaseException on database failure.
159 public SymbolConnectionData connect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectionType) throws DatabaseException {
160 if (diagram.equals(symbolConf2.diagram))
161 return _connect(g, symbolConf2, componentConRel1, componentConRel2, connectionType);
163 return connectWithFlag(g, symbolConf2, componentConRel1, componentConRel2, connectionType);
166 protected SymbolConnectionData connectToExisting(WriteGraph g, Symbol symbolConf2, Symbol current, Resource componentConRel1, Resource componentConRel2, Resource connectorType, boolean firstSame) throws DatabaseException {
167 return new ConnectionErrorImpl("Symbol is already connected");
170 private SymbolConnectionData _connect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectorType) throws DatabaseException {
171 Layer0 b = Layer0.getInstance(g);
172 StructuralResource2 s = StructuralResource2.getInstance(g);
173 DiagramResource d = DiagramResource.getInstance(g);
174 ModelingResources m = ModelingResources.getInstance(g);
177 if (g.isInstanceOf(componentConRel1, b.FunctionalRelation) && getSingleConnected(g, componentConRel1) != null) {
178 Symbol current = getSingleConnected(g, componentConRel1);
179 if (current.component.equals(symbolConf2.component))
180 return new SymbolExistsImpl();
182 return connectToExisting(g, symbolConf2, current, componentConRel1, componentConRel2, connectorType, true);
184 if (g.isInstanceOf(componentConRel2, b.FunctionalRelation) && symbolConf2.getSingleConnected(g, componentConRel2) != null) {
185 Symbol current = symbolConf2.getSingleConnected(g, componentConRel2);
186 if (current.component.equals(component))
187 return new SymbolExistsImpl();
188 return connectToExisting(g, symbolConf2, current, componentConRel1, componentConRel2, connectorType, false);
192 // connection object in module level
193 Resource moduleConnection = g.newResource();
194 g.claim(moduleConnection, b.InstanceOf, s.Connection);
196 // connect the modules
198 g.claim(component, componentConRel1, moduleConnection);
199 g.claim(symbolConf2.component, componentConRel2, moduleConnection);
201 // connection object in diagram level
202 Resource diagramConnection = g.newResource();
203 g.claim(diagramConnection, b.InstanceOf, d.RouteGraphConnection);
204 DiagramUtils.addElementFirst(g, diagram, diagramConnection);
206 g.claim(diagramConnection, s.HasConnectionType, connectorType);
208 // Relation from element1 to connector1
209 Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
210 Resource connectorRel1 = g.getPossibleObject(componentConRel1, s.HasAttachmentRelation);
211 if (connectorRel1 == null)
212 connectorRel1 = d.HasPlainConnector;
215 Resource connector1 = g.newResource();
216 g.claim(connector1, b.InstanceOf, d.Connector);
217 g.claim(element, isConnected1, connector1);
218 g.claim(diagramConnection, connectorRel1, connector1);
220 // Relation from element2 to connector2
221 Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
222 Resource connectorRel2 = g.getPossibleObject(componentConRel2, s.HasAttachmentRelation);
223 if (connectorRel2 == null)
224 connectorRel2 = d.HasArrowConnector;
226 Resource connector2 = g.newResource();
227 g.claim(connector2, b.InstanceOf, d.Connector);
228 g.claim(symbolConf2.element, isConnected2, connector2);
229 g.claim(diagramConnection, connectorRel2, connector2);
231 // connect connectors
232 g.claim(connector1, d.AreConnected, connector2);
234 g.claim(moduleConnection, m.ConnectionToDiagramConnection, diagramConnection);
236 return new ConnectorDataImpl(diagramConnection);
240 private SymbolConnectionData connectWithFlag(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectionType) throws DatabaseException {
242 Diagram diagram2 = symbolConf2.diagram;
243 Layer0 l0 = Layer0.getInstance(g);
244 StructuralResource2 s = StructuralResource2.getInstance(g);
245 DiagramResource d = DiagramResource.getInstance(g);
246 ModelingResources m = ModelingResources.getInstance(g);
248 if (g.isInstanceOf(componentConRel1, l0.FunctionalRelation) && getSingleConnected(g, componentConRel1) != null) {
249 String err = "Cannot flag connect " + component + " " + NameUtils.getSafeName(g, component) + " to " + symbolConf2.component + " " + NameUtils.getSafeName(g, symbolConf2.component) + " since the first terminal is already reserved";
250 Logger.defaultLogError(err);
251 return new ConnectionErrorImpl(err);
253 if (g.isInstanceOf(componentConRel2, l0.FunctionalRelation) && symbolConf2.getSingleConnected(g, componentConRel2) != null) {
254 String err = "Cannot flag connect " + component + " " + NameUtils.getSafeName(g, component) + " to " + symbolConf2.component + " " + NameUtils.getSafeName(g, symbolConf2.component) + " since the second terminal is already reserved";
255 Logger.defaultLogError(err);
256 return new ConnectionErrorImpl(err);
260 double[] t1 = getSymbolTranslation(g);
261 double[] t2 = symbolConf2.getSymbolTranslation(g);
263 Symbol flag1 = diagram.addElement(g, d.Flag, t1[0]+t, t1[1]);
264 Symbol flag2 = diagram2.addElement(g, d.Flag, t2[0]-t, t2[1]);
266 Resource connectionJoin = g.newResource();
267 g.claim(connectionJoin, l0.InstanceOf, s.ConnectionJoin);
268 g.claim(diagram.getComposite(), s.HasConnectionJoin, connectionJoin);
269 g.claim(diagram2.getComposite(), s.HasConnectionJoin, connectionJoin);
271 Resource connection1 = g.newResource();
272 g.claim(connection1, l0.InstanceOf, s.Connection);
274 Resource connection2 = g.newResource();
275 g.claim(connection2, l0.InstanceOf, s.Connection);
277 g.claim(component, componentConRel1, connection1);
278 g.claim(symbolConf2.component, componentConRel2, connection2);
279 g.claim(connection1, s.IsJoinedBy, connectionJoin);
280 g.claim(connection2, s.IsJoinedBy, connectionJoin);
282 g.claim(flag1.element, d.FlagIsJoinedBy, connectionJoin);
283 g.claim(flag2.element, d.FlagIsJoinedBy, connectionJoin);
285 Resource diagConnection1 = g.newResource();
286 g.claim(diagConnection1, l0.InstanceOf, d.RouteGraphConnection);
287 DiagramUtils.addElementFirst(g, diagram, diagConnection1);
288 g.claim(diagConnection1, s.HasConnectionType, connectionType);
290 Resource diagConnection2 = g.newResource();
291 g.claim(diagConnection2, l0.InstanceOf, d.RouteGraphConnection);
292 DiagramUtils.addElementFirst(g, diagram2, diagConnection2);
293 g.claim(diagConnection2, s.HasConnectionType, connectionType);
295 g.claim(connection1, m.ConnectionToDiagramConnection, diagConnection1);
296 g.claim(connection2, m.ConnectionToDiagramConnection, diagConnection2);
298 // Relation from element1 to connector1
299 Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
302 Resource connector1_1 = g.newResource();
303 g.claim(connector1_1, l0.InstanceOf, d.Connector);
304 g.claim(element, isConnected1, connector1_1);
305 g.claim(diagConnection1, d.HasPlainConnector, connector1_1);
307 Resource connector1_2 = g.newResource();
308 g.claim(connector1_2, l0.InstanceOf, d.Connector);
309 g.claim(flag1.element, d.Flag_ConnectionPoint, connector1_2);
310 g.claim(diagConnection1, d.HasArrowConnector, connector1_2);
312 g.claim(connector1_1, d.AreConnected, connector1_2);
314 // Relation from element2 to connector2
315 Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
318 Resource connector2_1 = g.newResource();
319 g.claim(connector2_1, l0.InstanceOf, d.Connector);
320 g.claim(flag2.element, d.Flag_ConnectionPoint, connector2_1);
321 g.claim(diagConnection2, d.HasPlainConnector, connector2_1);
323 Resource connector2_2 = g.newResource();
324 g.claim(connector2_2, l0.InstanceOf, d.Connector);
325 g.claim(symbolConf2.element, isConnected2, connector2_2);
326 g.claim(diagConnection2, d.HasArrowConnector, connector2_2);
328 g.claim(connector2_1, d.AreConnected, connector2_2);
330 return new FlagConnectionDataImpl(flag1, flag2, diagConnection1, diagConnection2);
334 * Returns diagram connection relation for an element and its component connection relation
337 * @param componentConnRel
339 * @throws ServiceException
340 * @throws NoSingleResultException
341 * @throws ValidationException
343 public static Resource getDiagramConnectionRelation(ReadGraph g, Resource element, Resource componentConnRel) throws DatabaseException {
344 ModelingResources m = ModelingResources.getInstance(g);
345 Collection<Resource> diagramConnectionRels = g.getObjects(componentConnRel, m.ConnectionRelationToDiagramConnectionRelation);
346 if (diagramConnectionRels.size() == 1)
347 return diagramConnectionRels.iterator().next();
348 if (diagramConnectionRels.size() > 1) {
349 List<Resource> matching = new ArrayList<Resource>();
350 for (Resource r : diagramConnectionRels) {
351 if (g.hasStatement(element, r))
354 if (matching.size() == 1)
355 return matching.get(0);
357 Layer0 b = Layer0.getInstance(g);
358 Collection<Resource> elementTypes = g.getObjects(element, b.InstanceOf);
359 if (elementTypes.size() != 1)
360 throw new RuntimeException("Cannot handle multi-instances " + element + " " + NameUtils.getSafeName(g, element));
361 Resource elementType = elementTypes.iterator().next();
362 Collection<Resource> rels = StructuralUtils.getConnectionRelations(g, elementType);
363 if (rels.size() == 1)
364 return rels.iterator().next();
365 for (Resource rel : rels) {
366 if (diagramConnectionRels.contains(rel))
369 throw new RuntimeException("Cannot find diagram level relation for relation " + NameUtils.getSafeName(g, componentConnRel) + " " + componentConnRel + " , element " + NameUtils.getSafeName(g, element) + " " + element + " , elementType " + NameUtils.getSafeName(g, elementType) + " " + elementType );
372 public static Resource getComponentConnectionRelation(ReadGraph g, Resource diagraromConnRel) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
373 ModelingResources mr = ModelingResources.getInstance(g);
374 return g.getSingleObject(diagraromConnRel, mr.DiagramConnectionRelationToConnectionRelation);
377 // public static Resource getSymbolRelation(ReadGraph g, Symbol conf, Resource genericRel) throws DatabaseException {
378 // Layer0 b = Layer0.getInstance(g);
379 // if (g.isInstanceOf(conf.element, ab.CalculationLevelReferenceElement)) {
380 // ModelingResources m = ModelingResources.getInstance(g);
381 // //return g.getInverse(g.getSingleObject(conf.element, m.HasReferenceRelation));
382 // return g.getSingleObject(conf.element, m.HasReferenceRelation);
385 // Resource compType = g.getSingleObject(conf.getComponent(), b.InstanceOf);
387 // for (Resource rel : StructuralUtils.getConnectionRelations(g, compType))
388 // if (g.isSubrelationOf(rel, genericRel))
394 * Returns symbol where given symbol is connected using given relation. Returns null if the symbol is not connected using the relation.
396 * @param componentConRel
398 * @throws DatabaseException
400 public Symbol getSingleConnected(ReadGraph g, Resource componentConRel) throws DatabaseException {
401 Collection<Symbol> symbols = getConnected(g, componentConRel);
402 if (symbols.size() > 1)
403 throw new NoSingleResultException("Symbol " + component + " is connected more than once using relation " + componentConRel);
404 if (symbols.size() == 1)
405 return symbols.iterator().next();
409 public Symbol getSingleConnected(ReadGraph g, Resource componentConRel, Resource otherComponentConRel) throws DatabaseException {
410 Collection<Symbol> symbols = getConnected(g, componentConRel, otherComponentConRel);
411 if (symbols.size() > 1)
412 throw new NoSingleResultException("Symbol " + component + " is connected more than once using relation " + componentConRel);
413 if (symbols.size() == 1)
414 return symbols.iterator().next();
418 public Collection<Symbol> getConnected(ReadGraph g, Resource componentConRel, Resource otherComponentConRel) throws DatabaseException {
419 assert(componentConRel != null);
420 Layer0 l0 = Layer0.getInstance(g);
421 StructuralResource2 sr = StructuralResource2.getInstance(g);
422 ModelingResources mr = ModelingResources.getInstance(g);
423 Collection<Symbol> result = new ArrayList<Symbol>();
424 Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
425 for (Resource modConn1 : modConn1s) {
427 Collection<Statement> connected = g.getStatements(modConn1, sr.Connects);
428 Collection<Resource> connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy);
429 Collection<Resource> connectedComponents = new ArrayList<Resource>();
431 for (Statement stm : connected) {
432 if (!stm.getObject().equals(this.component)) {
433 if (g.getInverse(stm.getPredicate()).equals(otherComponentConRel)) {
434 connectedComponents.add(stm.getObject());
439 for (Resource connectionJoin : connectionJoins) {
440 Collection<Resource> joinedConns = g.getObjects(connectionJoin, sr.Joins);
441 for (Resource conn : joinedConns) {
442 if (!conn.equals(modConn1)) {
443 // TODO : check ConnectionJoins?
444 for (Statement stm : g.getStatements(conn, sr.Connects)) {
445 if (g.getInverse(stm.getPredicate()).equals(otherComponentConRel))
446 connectedComponents.add(stm.getObject());
451 for (Resource connectedComponent : connectedComponents) {
453 Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
455 Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
456 result.add(diag.getSymbol(g, pointElem,connectedComponent));
463 public Collection<Symbol> getConnected(ReadGraph g, Resource componentConRel) throws DatabaseException {
464 assert(componentConRel != null);
465 Layer0 l0 = Layer0.getInstance(g);
466 StructuralResource2 sr = StructuralResource2.getInstance(g);
467 ModelingResources mr = ModelingResources.getInstance(g);
469 Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
470 Collection<Symbol> result = new ArrayList<Symbol>();
471 for (Resource modConn1 : modConn1s) {
473 Collection<Resource> connected = g.getObjects(modConn1, sr.Connects);
474 Collection<Resource> connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy);
475 Collection<Resource> connectedComponents = new ArrayList<Resource>();
477 for (Resource r : connected) {
478 if (!r.equals(this.component)) {
479 connectedComponents.add(r);
482 for (Resource connectionJoin : connectionJoins) {
483 Collection<Resource> joinedConns = g.getObjects(connectionJoin, sr.Joins);
484 for (Resource conn : joinedConns) {
485 if (!conn.equals(modConn1)) {
486 // TODO : check ConnectionJoins?
487 for (Resource obj : g.getObjects(conn, sr.Connects))
488 connectedComponents.add(obj);
492 for (Resource connectedComponent : connectedComponents) {
494 Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
496 Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
497 result.add(diag.getSymbol(g, pointElem,connectedComponent));
505 * Returns connected symbols on diagram level. Searches through branchpoints.
507 * @param diagramConnRel
508 * @param otherConnRel
510 * @throws DatabaseException
512 public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel, Resource otherConnRel) throws DatabaseException {
513 DiagramResource dr = DiagramResource.getInstance(g);
514 Collection<Resource> connectors = g.getObjects(element, diagramConnRel);
515 Collection<Symbol> result = new ArrayList<Symbol>();
516 for (Resource connector : connectors) {
517 Resource otherConnector = g.getSingleObject(connector, dr.AreConnected);
518 if (g.isInstanceOf(otherConnector, dr.Connector)) {
519 getConnectorConnectors(g, otherConnector, otherConnRel, result);
520 } else if (g.isInstanceOf(otherConnector, dr.RouteLine)) {
521 getBranchPointConnectors(g, connector, otherConnector, otherConnRel, result);
523 throw new DatabaseException("Connector " + g.getPossibleURI(otherConnector) + " " + otherConnector + " han unknown type");
529 private void getConnectorConnectors(ReadGraph g, Resource connector, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException{
530 StructuralResource2 sr = StructuralResource2.getInstance(g);
531 DiagramResource dr = DiagramResource.getInstance(g);
532 Collection<Statement> stms = g.getStatements(connector, sr.Connects);
533 Statement stm = null;
534 for (Statement s : stms) {
535 if (!g.isInstanceOf(s.getObject(), dr.Connection)) {
541 if (otherConnRel != null) {
542 Resource rel = g.getInverse(stm.getPredicate());
543 if (!rel.equals(otherConnRel))
546 Resource element = stm.getObject();
547 result.add(diagram.getSymbol(g, element));
550 private void getBranchPointConnectors(ReadGraph g, Resource origin, Resource branchPoint, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException {
551 DiagramResource dr = DiagramResource.getInstance(g);
553 Collection<Resource> branchConnected = g.getObjects(branchPoint, dr.AreConnected);
554 for (Resource branchConnector : branchConnected) {
555 if (branchConnector.equals(origin))
557 if (g.isInstanceOf(branchConnector, dr.Connector)) {
558 getConnectorConnectors(g, branchConnector, otherConnRel, result);
559 } else if (g.isInstanceOf(branchConnector, dr.RouteLine)) {
560 getBranchPointConnectors(g, branchPoint, branchConnector, otherConnRel, result);
562 throw new DatabaseException("Connector " + g.getPossibleURI(branchConnector) + " " + branchConnector + " han unknown type");
567 public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
568 return getDiagramConnected(g, diagramConnRel,null);
571 public Collection<Symbol> getDiagramInverseConnected(ReadGraph g, Resource otherConnRel) throws DatabaseException {
572 StructuralResource2 sr = StructuralResource2.getInstance(g);
573 return getDiagramConnected(g, sr.IsConnectedTo, otherConnRel);
577 public Collection<Symbol> getDiagramConnected(ReadGraph g) throws DatabaseException {
578 StructuralResource2 sr = StructuralResource2.getInstance(g);
579 return getDiagramConnected(g, sr.IsConnectedTo, null);
582 public Symbol getDiagramSingleConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
583 Collection<Symbol> symbols = getDiagramConnected(g, diagramConnRel);
584 if (symbols.size() > 1) {
585 throw new NoSingleResultException("Symbol " + element + " has more than one connection with " + diagramConnRel);
586 } else if (symbols.size() == 1) {
587 return symbols.iterator().next();
592 public Symbol getOtherFlag(ReadGraph g) throws DatabaseException {
593 DiagramResource dr = DiagramResource.getInstance(g);
594 Resource connectionJoin = g.getPossibleObject(element, dr.FlagIsJoinedBy);
595 if (connectionJoin == null)
597 Collection<Resource> flags = g.getObjects(connectionJoin, dr.JoinsFlag);
598 Resource otherFlag = null;
599 for (Resource f : flags) {
600 if (!f.equals(element)) {
606 if (otherFlag == null) {
609 Resource otherDiagramR = OrderedSetUtils.getSingleOwnerList(g, otherFlag);
610 Diagram otherDiagram = diagram.fromExisting(g, otherDiagramR);
611 return otherDiagram.getSymbol(g, otherFlag, null);
616 * Returns concatenated translation of the symbol.
619 * @throws DatabaseException
621 public double[] getSymbolTranslation(ReadGraph g) throws DatabaseException {
622 DiagramResource d = DiagramResource.getInstance(g);
623 ModelingResources mr = ModelingResources.getInstance(g);
625 Resource e = element;
626 AffineTransform at = new AffineTransform();
628 double transform[] = g.getPossibleRelatedValue(e, d.HasTransform);
629 if (transform == null)
631 AffineTransform at2 = new AffineTransform(transform);
632 at.preConcatenate(at2);
633 Resource component = g.getPossibleObject(e, mr.HasParentComponent);
634 if (component != null) {
635 e = g.getPossibleObject(component, mr.ComponentToElement);
641 return new double[]{at.getTranslateX(),at.getTranslateY()};
645 * Returns transformation of the symbol.
648 * @throws DatabaseException
650 public double[] getSymbolTransformation(ReadGraph g) throws DatabaseException{
651 DiagramResource d = DiagramResource.getInstance(g);
652 double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
657 * Sets translation of symbol. The scale is set to 1.0.
661 * @throws DatabaseException
663 public void setSymbolTranslation(WriteGraph g, double x, double y) throws DatabaseException {
664 DiagramResource d = DiagramResource.getInstance(g);
665 G2DResource g2d = G2DResource.getInstance(g);
666 g.claimLiteral(element, d.HasTransform, g2d.Transform, new double[]{1.0,0.0,0.0,1.0,x,y});
669 public void setSymbolTransformation(WriteGraph g, AffineTransform at) throws DatabaseException {
670 DiagramResource d = DiagramResource.getInstance(g);
671 G2DResource g2d = G2DResource.getInstance(g);
672 double arr[] = new double[6];
674 g.claimLiteral(element, d.HasTransform, g2d.Transform, arr);
678 * Set the scale of symbol.
681 * @throws DatabaseException
683 public void setScale(WriteGraph g, double scale) throws DatabaseException {
684 DiagramResource d = DiagramResource.getInstance(g);
685 double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
686 g.claimLiteral(element, d.HasTransform, new double[]{scale,0.0,0.0,scale,transform[4],transform[5]});
690 public boolean equals(Object o) {
693 if (this.getClass() != o.getClass())
695 Symbol other = (Symbol)o;
696 return element.equals(other.element);
700 public int hashCode() {
701 return element.hashCode();
707 * Returns component type from symbol type
711 * @throws NoSingleResultException
712 * @throws ManyObjectsForFunctionalRelationException
713 * @throws ServiceException
715 public static Resource getComponentTypeFromSymbolType(ReadGraph g, Resource symbolType) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
716 ModelingResources m = ModelingResources.getInstance(g);
717 Resource component = g.getPossibleObject(symbolType, m.SymbolToComponentType);
721 public static Resource getSymbolTypeFromComponentType(ReadGraph g, Resource componentType) throws NoSingleResultException, ServiceException, ManyObjectsForFunctionalRelationException {
722 ModelingResources m = ModelingResources.getInstance(g);
723 Collection<Resource> symbols = g.getObjects(componentType, m.ComponentTypeToSymbol);
724 if (symbols.size() == 0)
726 return symbols.iterator().next();
729 public void dispose() {
736 * Common interface for Symbol.connect return value.
739 public interface SymbolConnectionData {
744 * Interface for returning diagram level connectors.
747 public interface DiagramConnectionData extends SymbolConnectionData {
748 public int getConnectionCount();
749 public Resource getConnection(int index);
753 * Interface for flag connections.
756 public interface FlagConnectionData extends SymbolConnectionData {
757 public Symbol getFirstFlag();
758 public Symbol getSecondFlag();
763 * Interface for signal connections.
766 public interface SignalConnectionData extends SymbolConnectionData {
767 public Resource getSignalComponent();
771 * Interface for Point connections.
774 public interface PointConnectionData extends SymbolConnectionData {
779 * Interface for "connection" that merged the connected symbols into one symbol.
782 public interface MergeSymbolData extends SymbolConnectionData {
783 Symbol getResultSymbol();
787 * Return value for a connection that already exists.
790 public interface SymbolExists extends SymbolConnectionData {
795 * Return value for an error.
798 public interface ConnectionError extends SymbolConnectionData {
802 private static class ConnectionErrorImpl implements ConnectionError {
803 private String error;
805 public ConnectionErrorImpl(String error) {
810 public String getReason() {
815 private static class SymbolExistsImpl implements SymbolExists {
819 private static class ConnectorDataImpl implements DiagramConnectionData {
821 private Resource[] connectors;
823 public ConnectorDataImpl(Resource... connectors) {
824 this.connectors = connectors;
828 public Resource getConnection(int index) {
829 return connectors[index];
833 public int getConnectionCount() {
834 return connectors.length;
838 private static class PointConnectionDataImpl implements PointConnectionData {
840 private Symbol point;
842 public PointConnectionDataImpl(Symbol point) {
847 public Symbol getPoint() {
852 private static class SignalConnectionDataImpl implements SignalConnectionData, DiagramConnectionData{
854 private Resource signalComponent;
855 private Resource[] connectors;
857 public SignalConnectionDataImpl(Resource signalComponent, Resource... connectors) {
858 this.signalComponent = signalComponent;
859 this.connectors = connectors;
863 public Resource getSignalComponent() {
864 return signalComponent;
868 public Resource getConnection(int index) {
869 return connectors[index];
873 public int getConnectionCount() {
874 return connectors.length;
879 private static class FlagConnectionDataImpl implements FlagConnectionData, DiagramConnectionData {
881 private Symbol firstFlag;
882 private Symbol secondFlag;
883 private Resource[] connectors;
885 public FlagConnectionDataImpl(Symbol firstFlag, Symbol secondFlag, Resource... connectors) {
886 this.firstFlag = firstFlag;
887 this.secondFlag = secondFlag;
888 this.connectors = connectors;
892 public Symbol getFirstFlag() {
897 public Symbol getSecondFlag() {
902 public Resource getConnection(int index) {
903 return connectors[index];
907 public int getConnectionCount() {
908 return connectors.length;
912 public void setComponentValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
913 setValue(graph, component, property, value);
916 public void setComponentValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
917 setValue(graph, component, property, value);
920 public void setComponentValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
921 setValue(graph, component, property, value);
924 public void setComponentValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
925 setValue(graph, component, property, value);
928 public void setComponentValue(WriteGraph graph, Resource property, String value) throws DatabaseException{
929 setValue(graph, component, property, value);
932 public void setComponentValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
933 setValue(graph, component, property, value);
936 public void setComponentValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
937 setValue(graph, component, property, value);
940 public void setComponentValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
941 setValue(graph, component, property, value);
944 public void setComponentValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
945 setValue(graph, component, property, value);
948 public void setElementValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
949 setValue(graph, element, property, value);
952 public void setElementValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
953 setValue(graph, element, property, value);
956 public void setElementValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
957 setValue(graph, element, property, value);
960 public void setElementValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
961 setValue(graph, element, property, value);
964 public void setElementValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
965 setValue(graph, element, property, value);
968 public void setElementValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
969 setValue(graph, element, property, value);
972 public void setElementValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
973 setValue(graph, element, property, value);
976 public void setElementValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
977 setValue(graph, element, property, value);
981 * Sets literal value. Does data conversion if required.
983 * Note: This method support only some basic L0 data types.
989 * @throws DatabaseException
991 public static void setValue(WriteGraph graph, Resource object, Resource property, double value) throws DatabaseException{
992 Layer0 l0 = Layer0.getInstance(graph);
993 Resource range = graph.getPossibleObject(property, l0.HasRange);
994 if (l0.Double.equals(range)) {
995 graph.claimLiteral(object, property, value, Bindings.DOUBLE);
996 } else if (l0.Float.equals(range)) {
997 graph.claimLiteral(object, property, (float)value, Bindings.FLOAT);
998 } else if (l0.Integer.equals(range)) {
999 graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
1000 } else if (l0.Long.equals(range)) {
1001 graph.claimLiteral(object, property, (long)value, Bindings.LONG);
1002 } else if (l0.Boolean.equals(range)) {
1003 graph.claimLiteral(object, property, value > 0.0, Bindings.BOOLEAN);
1004 } else if (l0.String.equals(range)) {
1005 graph.claimLiteral(object, property, Double.toString(value), Bindings.STRING);
1007 graph.claimLiteral(object, property, value, Bindings.DOUBLE);
1012 * Sets literal value. Does data conversion if required.
1014 * Note: This method support only some basic L0 data types.
1020 * @throws DatabaseException
1022 public static void setValue(WriteGraph graph, Resource object, Resource property, float value) throws DatabaseException{
1023 Layer0 l0 = Layer0.getInstance(graph);
1024 Resource range = graph.getPossibleObject(property, l0.HasRange);
1025 if (l0.Double.equals(range)) {
1026 graph.claimLiteral(object, property, (double)value, Bindings.DOUBLE);
1027 } else if (l0.Float.equals(range)) {
1028 graph.claimLiteral(object, property, value, Bindings.FLOAT);
1029 } else if (l0.Integer.equals(range)) {
1030 graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
1031 } else if (l0.Long.equals(range)) {
1032 graph.claimLiteral(object, property, (long)value, Bindings.LONG);
1033 } else if (l0.Boolean.equals(range)) {
1034 graph.claimLiteral(object, property, value > 0.f, Bindings.BOOLEAN);
1035 } else if (l0.String.equals(range)) {
1036 graph.claimLiteral(object, property, Float.toString(value), Bindings.STRING);
1038 graph.claimLiteral(object, property, value, Bindings.FLOAT);
1043 * Sets literal value. Does data conversion if required.
1045 * Note: This method support only some basic L0 data types.
1051 * @throws DatabaseException
1053 public static void setValue(WriteGraph graph, Resource object, Resource property, int value) throws DatabaseException{
1054 Layer0 l0 = Layer0.getInstance(graph);
1055 Resource range = graph.getPossibleObject(property, l0.HasRange);
1056 if (l0.Double.equals(range)) {
1057 graph.claimLiteral(object, property, (double)value, Bindings.DOUBLE);
1058 } else if (l0.Float.equals(range)) {
1059 graph.claimLiteral(object, property, (float) value, Bindings.FLOAT);
1060 } else if (l0.Integer.equals(range)) {
1061 graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
1062 } else if (l0.Long.equals(range)) {
1063 graph.claimLiteral(object, property, (long)value, Bindings.LONG);
1064 } else if (l0.Boolean.equals(range)) {
1065 graph.claimLiteral(object, property, value > 0, Bindings.BOOLEAN);
1066 } else if (l0.String.equals(range)) {
1067 graph.claimLiteral(object, property, Integer.toString(value), Bindings.STRING);
1069 graph.claimLiteral(object, property, value, Bindings.INTEGER);
1074 * Sets literal value. Does data conversion if required.
1080 * @throws DatabaseException
1082 public static void setValue(WriteGraph graph, Resource object, Resource property, String value) throws DatabaseException{
1083 Layer0 l0 = Layer0.getInstance(graph);
1084 Resource range = graph.getPossibleObject(property, l0.HasRange);
1085 if (range == null) {
1086 graph.claimLiteral(object, property, value, Bindings.STRING);
1088 if (graph.isInheritedFrom(range, l0.String)) {
1089 graph.claimLiteral(object, property, value, Bindings.STRING);
1090 } else if (graph.isInheritedFrom(range, l0.Double)) {
1091 graph.claimLiteral(object, property, Double.parseDouble(value), Bindings.DOUBLE);
1092 } else if (graph.isInheritedFrom(range, l0.Float)) {
1093 graph.claimLiteral(object, property, Float.parseFloat(value), Bindings.FLOAT);
1094 } else if (graph.isInheritedFrom(range, l0.Integer)) {
1095 graph.claimLiteral(object, property, Integer.parseInt(value), Bindings.INTEGER);
1096 } else if (graph.isInheritedFrom(range, l0.Long)) {
1097 graph.claimLiteral(object, property, Long.parseLong(value), Bindings.LONG);
1098 } else if (graph.isInheritedFrom(range, l0.Boolean)) {
1099 graph.claimLiteral(object, property, Boolean.parseBoolean(value), Bindings.BOOLEAN);
1101 graph.claimLiteral(object, property, value, Bindings.STRING);
1107 * Sets literal value. Does data conversion if required.
1109 * Note: This method support only some basic L0 data types.
1115 * @throws DatabaseException
1117 public static void setValue(WriteGraph graph, Resource object, Resource property, boolean value) throws DatabaseException{
1118 Layer0 l0 = Layer0.getInstance(graph);
1119 Resource range = graph.getPossibleObject(property, l0.HasRange);
1120 if (l0.Boolean.equals(range)) {
1121 graph.claimLiteral(object, property, value , Bindings.BOOLEAN);
1122 } else if (l0.String.equals(range)) {
1123 graph.claimLiteral(object, property, Boolean.toString(value), Bindings.STRING);
1124 } else if (l0.Integer.equals(range)) {
1125 graph.claimLiteral(object, property, value ? 1 : 0, Bindings.INTEGER);
1127 graph.claimLiteral(object, property, value, Bindings.BOOLEAN);
1132 * Sets literal value. Does data conversion if required.
1134 * Note: This method support only some basic L0 data types.
1140 * @throws DatabaseException
1142 public static void setValue(WriteGraph graph, Resource object, Resource property, double[] value) throws DatabaseException{
1143 Layer0 l0 = Layer0.getInstance(graph);
1144 Resource range = graph.getPossibleObject(property, l0.HasRange);
1145 if (l0.DoubleArray.equals(range)) {
1146 graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
1147 } else if (l0.FloatArray.equals(range)) {
1148 float arr[] = new float[value.length];
1149 for (int i = 0; i < value.length; i++)
1150 arr[i] = (float) value[i];
1151 graph.claimLiteral(object, property, arr, Bindings.FLOAT_ARRAY);
1152 } else if (l0.IntegerArray.equals(range)) {
1153 int arr[] = new int[value.length];
1154 for (int i = 0; i < value.length; i++)
1155 arr[i] = (int) value[i];
1156 graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1158 graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
1163 * Sets literal value. Does data conversion if required.
1165 * Note: This method support only some basic L0 data types.
1171 * @throws DatabaseException
1173 public static void setValue(WriteGraph graph, Resource object, Resource property, float[] value) throws DatabaseException{
1174 Layer0 l0 = Layer0.getInstance(graph);
1175 Resource range = graph.getPossibleObject(property, l0.HasRange);
1176 if (l0.FloatArray.equals(range)) {
1177 graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
1178 } else if (l0.DoubleArray.equals(range)) {
1179 double arr[] = new double[value.length];
1180 for (int i = 0; i < value.length; i++)
1181 arr[i] = (double) value[i];
1182 graph.claimLiteral(object, property, arr, Bindings.DOUBLE_ARRAY);
1183 } else if (l0.IntegerArray.equals(range)) {
1184 int arr[] = new int[value.length];
1185 for (int i = 0; i < value.length; i++)
1186 arr[i] = (int) value[i];
1187 graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1189 graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
1194 * Sets literal value. Does data conversion if required.
1196 * Note: This method support only some basic L0 data types.
1202 * @throws DatabaseException
1204 public static void setValue(WriteGraph graph, Resource object, Resource property, int[] value) throws DatabaseException{
1205 Layer0 l0 = Layer0.getInstance(graph);
1206 Resource range = graph.getPossibleObject(property, l0.HasRange);
1207 if (l0.IntegerArray.equals(range)) {
1208 graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
1209 } else if (l0.DoubleArray.equals(range)) {
1210 double arr[] = new double[value.length];
1211 for (int i = 0; i < value.length; i++)
1212 arr[i] = (double) value[i];
1213 graph.claimLiteral(object, property, arr, Bindings.DOUBLE_ARRAY);
1214 } else if (l0.FloatArray.equals(range)) {
1215 float arr[] = new float[value.length];
1216 for (int i = 0; i < value.length; i++)
1217 arr[i] = (float) value[i];
1218 graph.claimLiteral(object, property, arr, Bindings.FLOAT_ARRAY);
1220 graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
1225 * Sets literal value. Does data conversion if required.
1227 * Note: This method support only some basic L0 data types.
1233 * @throws DatabaseException
1235 public static void setValue(WriteGraph graph, Resource object, Resource property, boolean[] value) throws DatabaseException{
1236 Layer0 l0 = Layer0.getInstance(graph);
1237 Resource range = graph.getPossibleObject(property, l0.HasRange);
1238 if (l0.BooleanArray.equals(range)) {
1239 graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);
1240 } else if (l0.IntegerArray.equals(range)) {
1241 int arr[] = new int[value.length];
1242 for (int i = 0; i < value.length; i++)
1243 arr[i] = value[i] ? 1 : 0;
1244 graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1246 graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);