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);
212 Resource connector1 = g.newResource();
213 g.claim(connector1, b.InstanceOf, d.Connector);
214 g.claim(element, isConnected1, connector1);
215 g.claim(diagramConnection, d.HasPlainConnector, connector1);
217 // Relation from element2 to connector2
218 Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
221 Resource connector2 = g.newResource();
222 g.claim(connector2, b.InstanceOf, d.Connector);
223 g.claim(symbolConf2.element, isConnected2, connector2);
224 g.claim(diagramConnection, d.HasArrowConnector, connector2);
226 // connect connectors
227 g.claim(connector1, d.AreConnected, connector2);
229 g.claim(moduleConnection, m.ConnectionToDiagramConnection, diagramConnection);
231 return new ConnectorDataImpl(diagramConnection);
235 private SymbolConnectionData connectWithFlag(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectionType) throws DatabaseException {
237 Diagram diagram2 = symbolConf2.diagram;
238 Layer0 l0 = Layer0.getInstance(g);
239 StructuralResource2 s = StructuralResource2.getInstance(g);
240 DiagramResource d = DiagramResource.getInstance(g);
241 ModelingResources m = ModelingResources.getInstance(g);
243 if (g.isInstanceOf(componentConRel1, l0.FunctionalRelation) && getSingleConnected(g, componentConRel1) != null) {
244 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";
245 Logger.defaultLogError(err);
246 return new ConnectionErrorImpl(err);
248 if (g.isInstanceOf(componentConRel2, l0.FunctionalRelation) && symbolConf2.getSingleConnected(g, componentConRel2) != null) {
249 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";
250 Logger.defaultLogError(err);
251 return new ConnectionErrorImpl(err);
255 double[] t1 = getSymbolTranslation(g);
256 double[] t2 = symbolConf2.getSymbolTranslation(g);
258 Symbol flag1 = diagram.addElement(g, d.Flag, t1[0]+t, t1[1]);
259 Symbol flag2 = diagram2.addElement(g, d.Flag, t2[0]-t, t2[1]);
261 Resource connectionJoin = g.newResource();
262 g.claim(connectionJoin, l0.InstanceOf, s.ConnectionJoin);
263 g.claim(diagram.getComposite(), s.HasConnectionJoin, connectionJoin);
264 g.claim(diagram2.getComposite(), s.HasConnectionJoin, connectionJoin);
266 Resource connection1 = g.newResource();
267 g.claim(connection1, l0.InstanceOf, s.Connection);
269 Resource connection2 = g.newResource();
270 g.claim(connection2, l0.InstanceOf, s.Connection);
272 g.claim(component, componentConRel1, connection1);
273 g.claim(symbolConf2.component, componentConRel2, connection2);
274 g.claim(connection1, s.IsJoinedBy, connectionJoin);
275 g.claim(connection2, s.IsJoinedBy, connectionJoin);
277 g.claim(flag1.element, d.FlagIsJoinedBy, connectionJoin);
278 g.claim(flag2.element, d.FlagIsJoinedBy, connectionJoin);
280 Resource diagConnection1 = g.newResource();
281 g.claim(diagConnection1, l0.InstanceOf, d.RouteGraphConnection);
282 DiagramUtils.addElementFirst(g, diagram, diagConnection1);
283 g.claim(diagConnection1, s.HasConnectionType, connectionType);
285 Resource diagConnection2 = g.newResource();
286 g.claim(diagConnection2, l0.InstanceOf, d.RouteGraphConnection);
287 DiagramUtils.addElementFirst(g, diagram2, diagConnection2);
288 g.claim(diagConnection2, s.HasConnectionType, connectionType);
290 g.claim(connection1, m.ConnectionToDiagramConnection, diagConnection1);
291 g.claim(connection2, m.ConnectionToDiagramConnection, diagConnection2);
293 // Relation from element1 to connector1
294 Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
297 Resource connector1_1 = g.newResource();
298 g.claim(connector1_1, l0.InstanceOf, d.Connector);
299 g.claim(element, isConnected1, connector1_1);
300 g.claim(diagConnection1, d.HasPlainConnector, connector1_1);
302 Resource connector1_2 = g.newResource();
303 g.claim(connector1_2, l0.InstanceOf, d.Connector);
304 g.claim(flag1.element, d.Flag_ConnectionPoint, connector1_2);
305 g.claim(diagConnection1, d.HasArrowConnector, connector1_2);
307 g.claim(connector1_1, d.AreConnected, connector1_2);
309 // Relation from element2 to connector2
310 Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
313 Resource connector2_1 = g.newResource();
314 g.claim(connector2_1, l0.InstanceOf, d.Connector);
315 g.claim(flag2.element, d.Flag_ConnectionPoint, connector2_1);
316 g.claim(diagConnection2, d.HasPlainConnector, connector2_1);
318 Resource connector2_2 = g.newResource();
319 g.claim(connector2_2, l0.InstanceOf, d.Connector);
320 g.claim(symbolConf2.element, isConnected2, connector2_2);
321 g.claim(diagConnection2, d.HasArrowConnector, connector2_2);
323 g.claim(connector2_1, d.AreConnected, connector2_2);
325 return new FlagConnectionDataImpl(flag1, flag2, diagConnection1, diagConnection2);
329 * Returns diagram connection relation for an element and its component connection relation
332 * @param componentConnRel
334 * @throws ServiceException
335 * @throws NoSingleResultException
336 * @throws ValidationException
338 public static Resource getDiagramConnectionRelation(ReadGraph g, Resource element, Resource componentConnRel) throws DatabaseException {
339 ModelingResources m = ModelingResources.getInstance(g);
340 Collection<Resource> diagramConnectionRels = g.getObjects(componentConnRel, m.ConnectionRelationToDiagramConnectionRelation);
341 if (diagramConnectionRels.size() == 1)
342 return diagramConnectionRels.iterator().next();
343 if (diagramConnectionRels.size() > 1) {
344 List<Resource> matching = new ArrayList<Resource>();
345 for (Resource r : diagramConnectionRels) {
346 if (g.hasStatement(element, r))
349 if (matching.size() == 1)
350 return matching.get(0);
352 Layer0 b = Layer0.getInstance(g);
353 Collection<Resource> elementTypes = g.getObjects(element, b.InstanceOf);
354 if (elementTypes.size() != 1)
355 throw new RuntimeException("Cannot handle multi-instances " + element + " " + NameUtils.getSafeName(g, element));
356 Resource elementType = elementTypes.iterator().next();
357 Collection<Resource> rels = StructuralUtils.getConnectionRelations(g, elementType);
358 if (rels.size() == 1)
359 return rels.iterator().next();
360 for (Resource rel : rels) {
361 if (diagramConnectionRels.contains(rel))
364 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 );
367 public static Resource getComponentConnectionRelation(ReadGraph g, Resource diagraromConnRel) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
368 ModelingResources mr = ModelingResources.getInstance(g);
369 return g.getSingleObject(diagraromConnRel, mr.DiagramConnectionRelationToConnectionRelation);
372 // public static Resource getSymbolRelation(ReadGraph g, Symbol conf, Resource genericRel) throws DatabaseException {
373 // Layer0 b = Layer0.getInstance(g);
374 // if (g.isInstanceOf(conf.element, ab.CalculationLevelReferenceElement)) {
375 // ModelingResources m = ModelingResources.getInstance(g);
376 // //return g.getInverse(g.getSingleObject(conf.element, m.HasReferenceRelation));
377 // return g.getSingleObject(conf.element, m.HasReferenceRelation);
380 // Resource compType = g.getSingleObject(conf.getComponent(), b.InstanceOf);
382 // for (Resource rel : StructuralUtils.getConnectionRelations(g, compType))
383 // if (g.isSubrelationOf(rel, genericRel))
389 * Returns symbol where given symbol is connected using given relation. Returns null if the symbol is not connected using the relation.
391 * @param componentConRel
393 * @throws DatabaseException
395 public Symbol getSingleConnected(ReadGraph g, Resource componentConRel) throws DatabaseException {
396 Collection<Symbol> symbols = getConnected(g, componentConRel);
397 if (symbols.size() > 1)
398 throw new NoSingleResultException("Symbol " + component + " is connected more than once using relation " + componentConRel);
399 if (symbols.size() == 1)
400 return symbols.iterator().next();
404 public Symbol getSingleConnected(ReadGraph g, Resource componentConRel, Resource otherComponentConRel) throws DatabaseException {
405 Collection<Symbol> symbols = getConnected(g, componentConRel, otherComponentConRel);
406 if (symbols.size() > 1)
407 throw new NoSingleResultException("Symbol " + component + " is connected more than once using relation " + componentConRel);
408 if (symbols.size() == 1)
409 return symbols.iterator().next();
413 public Collection<Symbol> getConnected(ReadGraph g, Resource componentConRel, Resource otherComponentConRel) throws DatabaseException {
414 assert(componentConRel != null);
415 Layer0 l0 = Layer0.getInstance(g);
416 StructuralResource2 sr = StructuralResource2.getInstance(g);
417 ModelingResources mr = ModelingResources.getInstance(g);
418 Collection<Symbol> result = new ArrayList<Symbol>();
419 Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
420 for (Resource modConn1 : modConn1s) {
422 Collection<Statement> connected = g.getStatements(modConn1, sr.Connects);
423 Collection<Resource> connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy);
424 Collection<Resource> connectedComponents = new ArrayList<Resource>();
426 for (Statement stm : connected) {
427 if (!stm.getObject().equals(this.component)) {
428 if (g.getInverse(stm.getPredicate()).equals(otherComponentConRel)) {
429 connectedComponents.add(stm.getObject());
434 for (Resource connectionJoin : connectionJoins) {
435 Collection<Resource> joinedConns = g.getObjects(connectionJoin, sr.Joins);
436 for (Resource conn : joinedConns) {
437 if (!conn.equals(modConn1)) {
438 // TODO : check ConnectionJoins?
439 for (Statement stm : g.getStatements(conn, sr.Connects)) {
440 if (g.getInverse(stm.getPredicate()).equals(otherComponentConRel))
441 connectedComponents.add(stm.getObject());
446 for (Resource connectedComponent : connectedComponents) {
448 Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
450 Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
451 result.add(diag.getSymbol(g, pointElem,connectedComponent));
458 public Collection<Symbol> getConnected(ReadGraph g, Resource componentConRel) throws DatabaseException {
459 assert(componentConRel != null);
460 Layer0 l0 = Layer0.getInstance(g);
461 StructuralResource2 sr = StructuralResource2.getInstance(g);
462 ModelingResources mr = ModelingResources.getInstance(g);
464 Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
465 Collection<Symbol> result = new ArrayList<Symbol>();
466 for (Resource modConn1 : modConn1s) {
468 Collection<Resource> connected = g.getObjects(modConn1, sr.Connects);
469 Collection<Resource> connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy);
470 Collection<Resource> connectedComponents = new ArrayList<Resource>();
472 for (Resource r : connected) {
473 if (!r.equals(this.component)) {
474 connectedComponents.add(r);
477 for (Resource connectionJoin : connectionJoins) {
478 Collection<Resource> joinedConns = g.getObjects(connectionJoin, sr.Joins);
479 for (Resource conn : joinedConns) {
480 if (!conn.equals(modConn1)) {
481 // TODO : check ConnectionJoins?
482 for (Resource obj : g.getObjects(conn, sr.Connects))
483 connectedComponents.add(obj);
487 for (Resource connectedComponent : connectedComponents) {
489 Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
491 Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
492 result.add(diag.getSymbol(g, pointElem,connectedComponent));
500 * Returns connected symbols on diagram level. Searches through branchpoints.
502 * @param diagramConnRel
503 * @param otherConnRel
505 * @throws DatabaseException
507 public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel, Resource otherConnRel) throws DatabaseException {
508 DiagramResource dr = DiagramResource.getInstance(g);
509 Collection<Resource> connectors = g.getObjects(element, diagramConnRel);
510 Collection<Symbol> result = new ArrayList<Symbol>();
511 for (Resource connector : connectors) {
512 Resource otherConnector = g.getSingleObject(connector, dr.AreConnected);
513 if (g.isInstanceOf(otherConnector, dr.Connector)) {
514 getConnectorConnectors(g, otherConnector, otherConnRel, result);
515 } else if (g.isInstanceOf(otherConnector, dr.RouteLine)) {
516 getBranchPointConnectors(g, connector, otherConnector, otherConnRel, result);
518 throw new DatabaseException("Connector " + g.getPossibleURI(otherConnector) + " " + otherConnector + " han unknown type");
524 private void getConnectorConnectors(ReadGraph g, Resource connector, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException{
525 StructuralResource2 sr = StructuralResource2.getInstance(g);
526 DiagramResource dr = DiagramResource.getInstance(g);
527 Collection<Statement> stms = g.getStatements(connector, sr.Connects);
528 Statement stm = null;
529 for (Statement s : stms) {
530 if (!g.isInstanceOf(s.getObject(), dr.Connection)) {
536 if (otherConnRel != null) {
537 Resource rel = g.getInverse(stm.getPredicate());
538 if (!rel.equals(otherConnRel))
541 Resource element = stm.getObject();
542 result.add(diagram.getSymbol(g, element));
545 private void getBranchPointConnectors(ReadGraph g, Resource origin, Resource branchPoint, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException {
546 DiagramResource dr = DiagramResource.getInstance(g);
548 Collection<Resource> branchConnected = g.getObjects(branchPoint, dr.AreConnected);
549 for (Resource branchConnector : branchConnected) {
550 if (branchConnector.equals(origin))
552 if (g.isInstanceOf(branchConnector, dr.Connector)) {
553 getConnectorConnectors(g, branchConnector, otherConnRel, result);
554 } else if (g.isInstanceOf(branchConnector, dr.RouteLine)) {
555 getBranchPointConnectors(g, branchPoint, branchConnector, otherConnRel, result);
557 throw new DatabaseException("Connector " + g.getPossibleURI(branchConnector) + " " + branchConnector + " han unknown type");
562 public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
563 return getDiagramConnected(g, diagramConnRel,null);
566 public Collection<Symbol> getDiagramInverseConnected(ReadGraph g, Resource otherConnRel) throws DatabaseException {
567 StructuralResource2 sr = StructuralResource2.getInstance(g);
568 return getDiagramConnected(g, sr.IsConnectedTo, otherConnRel);
572 public Collection<Symbol> getDiagramConnected(ReadGraph g) throws DatabaseException {
573 StructuralResource2 sr = StructuralResource2.getInstance(g);
574 return getDiagramConnected(g, sr.IsConnectedTo, null);
577 public Symbol getDiagramSingleConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
578 Collection<Symbol> symbols = getDiagramConnected(g, diagramConnRel);
579 if (symbols.size() > 1) {
580 throw new NoSingleResultException("Symbol " + element + " has more than one connection with " + diagramConnRel);
581 } else if (symbols.size() == 1) {
582 return symbols.iterator().next();
587 public Symbol getOtherFlag(ReadGraph g) throws DatabaseException {
588 DiagramResource dr = DiagramResource.getInstance(g);
589 Resource connectionJoin = g.getPossibleObject(element, dr.FlagIsJoinedBy);
590 if (connectionJoin == null)
592 Collection<Resource> flags = g.getObjects(connectionJoin, dr.JoinsFlag);
593 Resource otherFlag = null;
594 for (Resource f : flags) {
595 if (!f.equals(element)) {
601 if (otherFlag == null) {
604 Resource otherDiagramR = OrderedSetUtils.getSingleOwnerList(g, otherFlag);
605 Diagram otherDiagram = diagram.fromExisting(g, otherDiagramR);
606 return otherDiagram.getSymbol(g, otherFlag, null);
611 * Returns concatenated translation of the symbol.
614 * @throws DatabaseException
616 public double[] getSymbolTranslation(ReadGraph g) throws DatabaseException {
617 DiagramResource d = DiagramResource.getInstance(g);
618 ModelingResources mr = ModelingResources.getInstance(g);
620 Resource e = element;
621 AffineTransform at = new AffineTransform();
623 double transform[] = g.getPossibleRelatedValue(e, d.HasTransform);
624 if (transform == null)
626 AffineTransform at2 = new AffineTransform(transform);
627 at.preConcatenate(at2);
628 Resource component = g.getPossibleObject(e, mr.HasParentComponent);
629 if (component != null) {
630 e = g.getPossibleObject(component, mr.ComponentToElement);
636 return new double[]{at.getTranslateX(),at.getTranslateY()};
640 * Returns transformation of the symbol.
643 * @throws DatabaseException
645 public double[] getSymbolTransformation(ReadGraph g) throws DatabaseException{
646 DiagramResource d = DiagramResource.getInstance(g);
647 double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
652 * Sets translation of symbol. The scale is set to 1.0.
656 * @throws DatabaseException
658 public void setSymbolTranslation(WriteGraph g, double x, double y) throws DatabaseException {
659 DiagramResource d = DiagramResource.getInstance(g);
660 G2DResource g2d = G2DResource.getInstance(g);
661 g.claimLiteral(element, d.HasTransform, g2d.Transform, new double[]{1.0,0.0,0.0,1.0,x,y});
664 public void setSymbolTransformation(WriteGraph g, AffineTransform at) throws DatabaseException {
665 DiagramResource d = DiagramResource.getInstance(g);
666 G2DResource g2d = G2DResource.getInstance(g);
667 double arr[] = new double[6];
669 g.claimLiteral(element, d.HasTransform, g2d.Transform, arr);
673 * Set the scale of symbol.
676 * @throws DatabaseException
678 public void setScale(WriteGraph g, double scale) throws DatabaseException {
679 DiagramResource d = DiagramResource.getInstance(g);
680 double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
681 g.claimLiteral(element, d.HasTransform, new double[]{scale,0.0,0.0,scale,transform[4],transform[5]});
685 public boolean equals(Object o) {
688 if (this.getClass() != o.getClass())
690 Symbol other = (Symbol)o;
691 return element.equals(other.element);
695 public int hashCode() {
696 return element.hashCode();
702 * Returns component type from symbol type
706 * @throws NoSingleResultException
707 * @throws ManyObjectsForFunctionalRelationException
708 * @throws ServiceException
710 public static Resource getComponentTypeFromSymbolType(ReadGraph g, Resource symbolType) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
711 ModelingResources m = ModelingResources.getInstance(g);
712 Resource component = g.getPossibleObject(symbolType, m.SymbolToComponentType);
716 public static Resource getSymbolTypeFromComponentType(ReadGraph g, Resource componentType) throws NoSingleResultException, ServiceException, ManyObjectsForFunctionalRelationException {
717 ModelingResources m = ModelingResources.getInstance(g);
718 Collection<Resource> symbols = g.getObjects(componentType, m.ComponentTypeToSymbol);
719 if (symbols.size() == 0)
721 return symbols.iterator().next();
724 public void dispose() {
731 * Common interface for Symbol.connect return value.
734 public interface SymbolConnectionData {
739 * Interface for returning diagram level connectors.
742 public interface DiagramConnectionData extends SymbolConnectionData {
743 public int getConnectionCount();
744 public Resource getConnection(int index);
748 * Interface for flag connections.
751 public interface FlagConnectionData extends SymbolConnectionData {
752 public Symbol getFirstFlag();
753 public Symbol getSecondFlag();
758 * Interface for signal connections.
761 public interface SignalConnectionData extends SymbolConnectionData {
762 public Resource getSignalComponent();
766 * Interface for Point connections.
769 public interface PointConnectionData extends SymbolConnectionData {
774 * Interface for "connection" that merged the connected symbols into one symbol.
777 public interface MergeSymbolData extends SymbolConnectionData {
778 Symbol getResultSymbol();
782 * Return value for a connection that already exists.
785 public interface SymbolExists extends SymbolConnectionData {
790 * Return value for an error.
793 public interface ConnectionError extends SymbolConnectionData {
797 private static class ConnectionErrorImpl implements ConnectionError {
798 private String error;
800 public ConnectionErrorImpl(String error) {
805 public String getReason() {
810 private static class SymbolExistsImpl implements SymbolExists {
814 private static class ConnectorDataImpl implements DiagramConnectionData {
816 private Resource[] connectors;
818 public ConnectorDataImpl(Resource... connectors) {
819 this.connectors = connectors;
823 public Resource getConnection(int index) {
824 return connectors[index];
828 public int getConnectionCount() {
829 return connectors.length;
833 private static class PointConnectionDataImpl implements PointConnectionData {
835 private Symbol point;
837 public PointConnectionDataImpl(Symbol point) {
842 public Symbol getPoint() {
847 private static class SignalConnectionDataImpl implements SignalConnectionData, DiagramConnectionData{
849 private Resource signalComponent;
850 private Resource[] connectors;
852 public SignalConnectionDataImpl(Resource signalComponent, Resource... connectors) {
853 this.signalComponent = signalComponent;
854 this.connectors = connectors;
858 public Resource getSignalComponent() {
859 return signalComponent;
863 public Resource getConnection(int index) {
864 return connectors[index];
868 public int getConnectionCount() {
869 return connectors.length;
874 private static class FlagConnectionDataImpl implements FlagConnectionData, DiagramConnectionData {
876 private Symbol firstFlag;
877 private Symbol secondFlag;
878 private Resource[] connectors;
880 public FlagConnectionDataImpl(Symbol firstFlag, Symbol secondFlag, Resource... connectors) {
881 this.firstFlag = firstFlag;
882 this.secondFlag = secondFlag;
883 this.connectors = connectors;
887 public Symbol getFirstFlag() {
892 public Symbol getSecondFlag() {
897 public Resource getConnection(int index) {
898 return connectors[index];
902 public int getConnectionCount() {
903 return connectors.length;
907 public void setComponentValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
908 setValue(graph, component, property, value);
911 public void setComponentValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
912 setValue(graph, component, property, value);
915 public void setComponentValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
916 setValue(graph, component, property, value);
919 public void setComponentValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
920 setValue(graph, component, property, value);
923 public void setComponentValue(WriteGraph graph, Resource property, String value) throws DatabaseException{
924 setValue(graph, component, property, value);
927 public void setComponentValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
928 setValue(graph, component, property, value);
931 public void setComponentValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
932 setValue(graph, component, property, value);
935 public void setComponentValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
936 setValue(graph, component, property, value);
939 public void setComponentValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
940 setValue(graph, component, property, value);
943 public void setElementValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
944 setValue(graph, element, property, value);
947 public void setElementValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
948 setValue(graph, element, property, value);
951 public void setElementValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
952 setValue(graph, element, property, value);
955 public void setElementValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
956 setValue(graph, element, property, value);
959 public void setElementValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
960 setValue(graph, element, property, value);
963 public void setElementValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
964 setValue(graph, element, property, value);
967 public void setElementValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
968 setValue(graph, element, property, value);
971 public void setElementValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
972 setValue(graph, element, property, value);
976 * Sets literal value. Does data conversion if required.
978 * Note: This method support only some basic L0 data types.
984 * @throws DatabaseException
986 public static void setValue(WriteGraph graph, Resource object, Resource property, double value) throws DatabaseException{
987 Layer0 l0 = Layer0.getInstance(graph);
988 Resource range = graph.getPossibleObject(property, l0.HasRange);
989 if (l0.Double.equals(range)) {
990 graph.claimLiteral(object, property, value, Bindings.DOUBLE);
991 } else if (l0.Float.equals(range)) {
992 graph.claimLiteral(object, property, (float)value, Bindings.FLOAT);
993 } else if (l0.Integer.equals(range)) {
994 graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
995 } else if (l0.Long.equals(range)) {
996 graph.claimLiteral(object, property, (long)value, Bindings.LONG);
997 } else if (l0.Boolean.equals(range)) {
998 graph.claimLiteral(object, property, value > 0.0, Bindings.BOOLEAN);
999 } else if (l0.String.equals(range)) {
1000 graph.claimLiteral(object, property, Double.toString(value), Bindings.STRING);
1002 graph.claimLiteral(object, property, value, Bindings.DOUBLE);
1007 * Sets literal value. Does data conversion if required.
1009 * Note: This method support only some basic L0 data types.
1015 * @throws DatabaseException
1017 public static void setValue(WriteGraph graph, Resource object, Resource property, float value) throws DatabaseException{
1018 Layer0 l0 = Layer0.getInstance(graph);
1019 Resource range = graph.getPossibleObject(property, l0.HasRange);
1020 if (l0.Double.equals(range)) {
1021 graph.claimLiteral(object, property, (double)value, Bindings.DOUBLE);
1022 } else if (l0.Float.equals(range)) {
1023 graph.claimLiteral(object, property, value, Bindings.FLOAT);
1024 } else if (l0.Integer.equals(range)) {
1025 graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
1026 } else if (l0.Long.equals(range)) {
1027 graph.claimLiteral(object, property, (long)value, Bindings.LONG);
1028 } else if (l0.Boolean.equals(range)) {
1029 graph.claimLiteral(object, property, value > 0.f, Bindings.BOOLEAN);
1030 } else if (l0.String.equals(range)) {
1031 graph.claimLiteral(object, property, Float.toString(value), Bindings.STRING);
1033 graph.claimLiteral(object, property, value, Bindings.FLOAT);
1038 * Sets literal value. Does data conversion if required.
1040 * Note: This method support only some basic L0 data types.
1046 * @throws DatabaseException
1048 public static void setValue(WriteGraph graph, Resource object, Resource property, int value) throws DatabaseException{
1049 Layer0 l0 = Layer0.getInstance(graph);
1050 Resource range = graph.getPossibleObject(property, l0.HasRange);
1051 if (l0.Double.equals(range)) {
1052 graph.claimLiteral(object, property, (double)value, Bindings.DOUBLE);
1053 } else if (l0.Float.equals(range)) {
1054 graph.claimLiteral(object, property, (float) value, Bindings.FLOAT);
1055 } else if (l0.Integer.equals(range)) {
1056 graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
1057 } else if (l0.Long.equals(range)) {
1058 graph.claimLiteral(object, property, (long)value, Bindings.LONG);
1059 } else if (l0.Boolean.equals(range)) {
1060 graph.claimLiteral(object, property, value > 0, Bindings.BOOLEAN);
1061 } else if (l0.String.equals(range)) {
1062 graph.claimLiteral(object, property, Integer.toString(value), Bindings.STRING);
1064 graph.claimLiteral(object, property, value, Bindings.INTEGER);
1069 * Sets literal value. Does data conversion if required.
1075 * @throws DatabaseException
1077 public static void setValue(WriteGraph graph, Resource object, Resource property, String value) throws DatabaseException{
1078 Layer0 l0 = Layer0.getInstance(graph);
1079 Resource range = graph.getPossibleObject(property, l0.HasRange);
1080 if (range == null) {
1081 graph.claimLiteral(object, property, value, Bindings.STRING);
1083 if (graph.isInheritedFrom(range, l0.String)) {
1084 graph.claimLiteral(object, property, value, Bindings.STRING);
1085 } else if (graph.isInheritedFrom(range, l0.Double)) {
1086 graph.claimLiteral(object, property, Double.parseDouble(value), Bindings.DOUBLE);
1087 } else if (graph.isInheritedFrom(range, l0.Float)) {
1088 graph.claimLiteral(object, property, Float.parseFloat(value), Bindings.FLOAT);
1089 } else if (graph.isInheritedFrom(range, l0.Integer)) {
1090 graph.claimLiteral(object, property, Integer.parseInt(value), Bindings.INTEGER);
1091 } else if (graph.isInheritedFrom(range, l0.Long)) {
1092 graph.claimLiteral(object, property, Long.parseLong(value), Bindings.LONG);
1093 } else if (graph.isInheritedFrom(range, l0.Boolean)) {
1094 graph.claimLiteral(object, property, Boolean.parseBoolean(value), Bindings.BOOLEAN);
1096 graph.claimLiteral(object, property, value, Bindings.STRING);
1102 * Sets literal value. Does data conversion if required.
1104 * Note: This method support only some basic L0 data types.
1110 * @throws DatabaseException
1112 public static void setValue(WriteGraph graph, Resource object, Resource property, boolean value) throws DatabaseException{
1113 Layer0 l0 = Layer0.getInstance(graph);
1114 Resource range = graph.getPossibleObject(property, l0.HasRange);
1115 if (l0.Boolean.equals(range)) {
1116 graph.claimLiteral(object, property, value , Bindings.BOOLEAN);
1117 } else if (l0.String.equals(range)) {
1118 graph.claimLiteral(object, property, Boolean.toString(value), Bindings.STRING);
1119 } else if (l0.Integer.equals(range)) {
1120 graph.claimLiteral(object, property, value ? 1 : 0, Bindings.INTEGER);
1122 graph.claimLiteral(object, property, value, Bindings.BOOLEAN);
1127 * Sets literal value. Does data conversion if required.
1129 * Note: This method support only some basic L0 data types.
1135 * @throws DatabaseException
1137 public static void setValue(WriteGraph graph, Resource object, Resource property, double[] value) throws DatabaseException{
1138 Layer0 l0 = Layer0.getInstance(graph);
1139 Resource range = graph.getPossibleObject(property, l0.HasRange);
1140 if (l0.DoubleArray.equals(range)) {
1141 graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
1142 } else if (l0.FloatArray.equals(range)) {
1143 float arr[] = new float[value.length];
1144 for (int i = 0; i < value.length; i++)
1145 arr[i] = (float) value[i];
1146 graph.claimLiteral(object, property, arr, Bindings.FLOAT_ARRAY);
1147 } else if (l0.IntegerArray.equals(range)) {
1148 int arr[] = new int[value.length];
1149 for (int i = 0; i < value.length; i++)
1150 arr[i] = (int) value[i];
1151 graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1153 graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
1158 * Sets literal value. Does data conversion if required.
1160 * Note: This method support only some basic L0 data types.
1166 * @throws DatabaseException
1168 public static void setValue(WriteGraph graph, Resource object, Resource property, float[] value) throws DatabaseException{
1169 Layer0 l0 = Layer0.getInstance(graph);
1170 Resource range = graph.getPossibleObject(property, l0.HasRange);
1171 if (l0.FloatArray.equals(range)) {
1172 graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
1173 } else if (l0.DoubleArray.equals(range)) {
1174 double arr[] = new double[value.length];
1175 for (int i = 0; i < value.length; i++)
1176 arr[i] = (double) value[i];
1177 graph.claimLiteral(object, property, arr, Bindings.DOUBLE_ARRAY);
1178 } else if (l0.IntegerArray.equals(range)) {
1179 int arr[] = new int[value.length];
1180 for (int i = 0; i < value.length; i++)
1181 arr[i] = (int) value[i];
1182 graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1184 graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
1189 * Sets literal value. Does data conversion if required.
1191 * Note: This method support only some basic L0 data types.
1197 * @throws DatabaseException
1199 public static void setValue(WriteGraph graph, Resource object, Resource property, int[] value) throws DatabaseException{
1200 Layer0 l0 = Layer0.getInstance(graph);
1201 Resource range = graph.getPossibleObject(property, l0.HasRange);
1202 if (l0.IntegerArray.equals(range)) {
1203 graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
1204 } else if (l0.DoubleArray.equals(range)) {
1205 double arr[] = new double[value.length];
1206 for (int i = 0; i < value.length; i++)
1207 arr[i] = (double) value[i];
1208 graph.claimLiteral(object, property, arr, Bindings.DOUBLE_ARRAY);
1209 } else if (l0.FloatArray.equals(range)) {
1210 float arr[] = new float[value.length];
1211 for (int i = 0; i < value.length; i++)
1212 arr[i] = (float) value[i];
1213 graph.claimLiteral(object, property, arr, Bindings.FLOAT_ARRAY);
1215 graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
1220 * Sets literal value. Does data conversion if required.
1222 * Note: This method support only some basic L0 data types.
1228 * @throws DatabaseException
1230 public static void setValue(WriteGraph graph, Resource object, Resource property, boolean[] value) throws DatabaseException{
1231 Layer0 l0 = Layer0.getInstance(graph);
1232 Resource range = graph.getPossibleObject(property, l0.HasRange);
1233 if (l0.BooleanArray.equals(range)) {
1234 graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);
1235 } else if (l0.IntegerArray.equals(range)) {
1236 int arr[] = new int[value.length];
1237 for (int i = 0; i < value.length; i++)
1238 arr[i] = value[i] ? 1 : 0;
1239 graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1241 graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);