]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop.diagram/src/org/simantics/interop/diagram/Symbol.java
Diagram API fixes.
[simantics/interop.git] / org.simantics.interop.diagram / src / org / simantics / interop / diagram / Symbol.java
1 package org.simantics.interop.diagram;
2
3 import java.awt.geom.AffineTransform;
4 import java.util.ArrayList;
5 import java.util.Collection;
6 import java.util.Collections;
7 import java.util.HashSet;
8 import java.util.List;
9 import java.util.Set;
10
11 import org.simantics.databoard.Bindings;
12 import org.simantics.db.ReadGraph;
13 import org.simantics.db.Resource;
14 import org.simantics.db.Statement;
15 import org.simantics.db.WriteGraph;
16 import org.simantics.db.common.utils.NameUtils;
17 import org.simantics.db.common.utils.OrderedSetUtils;
18 import org.simantics.db.exception.DatabaseException;
19 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
20 import org.simantics.db.exception.NoSingleResultException;
21 import org.simantics.db.exception.ServiceException;
22 import org.simantics.db.exception.ValidationException;
23 import org.simantics.diagram.stubs.DiagramResource;
24 import org.simantics.diagram.stubs.G2DResource;
25 import org.simantics.layer0.Layer0;
26 import org.simantics.modeling.ModelingResources;
27 import org.simantics.structural.stubs.StructuralResource2;
28 import org.simantics.structural2.utils.StructuralUtils;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32
33
34
35 /**
36  * @author Marko Luukkainen
37  */
38 public abstract class Symbol {
39         
40         private static Logger Logger = LoggerFactory.getLogger(Symbol.class);
41         
42         private static boolean USE_UNRELIABLE_CONNECT = false;
43         private static boolean PREVENT_SELF_CONNECTIONS = false;
44         
45         private Diagram diagram;
46         Resource element;
47         Resource component;
48         
49         /**
50          * Use Diagram.getSymbol() to get Symbols.
51          * @param diagram
52          * @param element
53          * @param component
54          */
55         public Symbol(Diagram diagram, Resource element, Resource component) {
56                 assert(diagram != null);
57                 assert(element != null);
58                 this.diagram = diagram;
59                 this.element = element;
60                 this.component = component;
61         }
62         
63         public Diagram getDiagram() {
64                 return diagram;
65         }
66         
67         public Resource getComponent() {
68                 return component;
69         }
70         
71         public Resource getElement() {
72                 return element;
73         }
74         
75         /**
76          * Connects two Symbols, chooses connection type automatically.
77          * @param g
78          * @param symbolConf2 other symbol.
79          * @param componentConRel1 symbol's terminal relation.
80          * @param componentConRel2 other symbol's terminal relation.
81          * @return SymbolConnetionData instance describing the connection. Return value is never null.
82          * @throws DatabaseException on database failure.
83          */
84         public SymbolConnectionData connect(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2) throws DatabaseException {
85                 return connect(g, symbolConf2, componentConRel1, componentConRel2, false);
86         }
87         
88         
89         protected Collection<Resource> getConnectionRel(ReadGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Collection<Resource> matching) throws DatabaseException {
90                 return matching;
91         }
92         
93         protected  SymbolConnectionData customConnect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connType) throws DatabaseException {
94                 return null;
95         }
96         
97         protected Set<Resource> getConnectionTypes(ReadGraph g, Resource componentConRel1) throws DatabaseException {
98                 StructuralResource2 sr = StructuralResource2.getInstance(g);
99                 Set<Resource> set = new HashSet<Resource>();
100                 set.addAll(g.getObjects(componentConRel1, sr.AllowsConnectionType));
101                 return set;
102         }
103         
104         protected Set<Resource> getNonAssertedConnectionTypes(ReadGraph g, Resource componentConRel1) throws DatabaseException {
105                 StructuralResource2 sr = StructuralResource2.getInstance(g);
106                 Set<Resource> set = new HashSet<Resource>();
107                 for (Statement s : g.getStatements(componentConRel1, sr.AllowsConnectionType)) {
108                         if (s.isAsserted(componentConRel1))
109                                 continue;
110                         set.add(s.getObject());
111                 }
112                 return set;
113         }
114         
115         /**
116          * Connects two Symbols, chooses connection type automatically.
117          * @param g
118          * @param symbolConf2 other symbol.
119          * @param componentConRel1 symbol's terminal relation.
120          * @param componentConRel2 other symbol's terminal relation.
121          * @param forceFlag creates flag connection even if symbols are on the same diagram.
122          * @return SymbolConnetionData instance describing the connection. Return value is never null.
123          * @throws DatabaseException on database failure.
124          */
125         public SymbolConnectionData connect(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, boolean forceFlag) throws DatabaseException {
126                 if (this.equals(symbolConf2)) {
127                         if (PREVENT_SELF_CONNECTIONS) {
128                                 String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(componentConRel1) + " "+ componentConRel1 + " " + g.getPossibleURI(componentConRel2) + " "+ componentConRel2;
129                                 Logger.error(err);
130                                 return new ConnectionErrorImpl(err);
131                         }
132                         if (componentConRel1.equals(componentConRel2)) {
133                                 String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(componentConRel1) + " "+ componentConRel1 + " " + g.getPossibleURI(componentConRel2) + " "+ componentConRel2;
134                                 Logger.error(err);
135                                 return new ConnectionErrorImpl(err);
136                         }
137                 }
138                 StructuralResource2 sr = StructuralResource2.getInstance(g);
139                 Collection<Resource> connType1 = getConnectionTypes(g, componentConRel1);
140                 Collection<Resource> connType2 = getConnectionTypes(g, componentConRel2);
141                 Collection<Resource> matching = new HashSet<Resource>();
142                 for (Resource r : connType2) {
143                         if (connType1.contains(r))
144                                 matching.add(r);
145                 }
146                 if (matching.size() > 1) {
147                         matching = getConnectionRel(g, symbolConf2, componentConRel1, componentConRel2, matching);
148                 }
149                 Resource usedConnType = null;
150                 if (matching.size() != 1) {
151                         String err;
152                         if (USE_UNRELIABLE_CONNECT) {
153                                 err = "Unreliable connect " + component + " " + NameUtils.getSafeName(g, component) + " to " + symbolConf2.component + " " + NameUtils.getSafeName(g, symbolConf2.component) + " cannot find proper connection type, using Name Reference";
154                         } else {
155                                 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;
156                         }
157                         Logger.info(err);
158                         return new ConnectionErrorImpl(err);
159                 } else {
160                         usedConnType = matching.iterator().next();
161                 }
162                 
163                 SymbolConnectionData data = customConnect(g, symbolConf2, componentConRel1, componentConRel2, usedConnType);
164                 if (data == null) {
165                         if (!forceFlag && diagram.equals(symbolConf2.diagram))
166                                 return _connect(g, symbolConf2, componentConRel1, componentConRel2,usedConnType);
167                         else
168                                 return connectWithFlag(g,  symbolConf2, componentConRel1, componentConRel2,usedConnType);
169                 } else {
170                         return data;
171                 }
172         }
173         
174         public SymbolConnectionData connectElement(WriteGraph g,  Symbol symbolConf2, Resource elementConRel1, Resource elementConRel2) throws DatabaseException {
175                 
176                 StructuralResource2 sr = StructuralResource2.getInstance(g);
177                 ModelingResources mod = ModelingResources.getInstance(g);
178                 
179                 Resource componentConRel1 = g.getPossibleObject(elementConRel1, mod.DiagramConnectionRelationToConnectionRelation);
180                 Resource componentConRel2 = g.getPossibleObject(elementConRel2, mod.DiagramConnectionRelationToConnectionRelation);
181                 
182                 if (componentConRel1 != null && componentConRel2 != null) {
183                         return connect(g, symbolConf2, componentConRel1, componentConRel2);
184                 }
185
186                 Collection<Resource> connType1 = Collections.EMPTY_LIST;
187                 Collection<Resource> connType2 = Collections.EMPTY_LIST;
188                 if (componentConRel1 != null) {
189                         connType1 = getConnectionTypes(g, componentConRel1);
190                         if (connType1.size() > 1)
191                                 connType1 = getNonAssertedConnectionTypes(g,componentConRel1);
192                 } else if (componentConRel2 != null) {
193                         connType2 = getConnectionTypes(g, componentConRel2);
194                         if (connType2.size() > 1)
195                                 connType2 = getNonAssertedConnectionTypes(g,componentConRel2);
196                 }
197                 Resource usedConnType = null;
198                 if (connType1.size() == 1)
199                         usedConnType = connType1.iterator().next();
200                 else if (connType2.size() == 1)
201                         usedConnType = connType2.iterator().next();
202                 else {
203                         String err = "Cannot locate connection type for: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2;
204                         Logger.error(err);
205                         return new ConnectionErrorImpl(err);
206                 }
207                 if (!diagram.equals(symbolConf2.diagram)) {
208                         String err = "Element connections must be done on the same diagram: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2;
209                         Logger.error(err);
210                         return new ConnectionErrorImpl(err);
211                 }
212                 return connectElement(g, symbolConf2, elementConRel1, elementConRel2, usedConnType);
213         }
214         
215         public SymbolConnectionData connectElement(WriteGraph g,  Symbol symbolConf2, Resource elementConRel1, Resource elementConRel2, Resource usedConnType) throws DatabaseException {
216                 if (this.equals(symbolConf2)) {
217                         if (PREVENT_SELF_CONNECTIONS) {
218                                 String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2;
219                                 Logger.error(err);
220                                 return new ConnectionErrorImpl(err);
221                         }
222                         if (elementConRel1.equals(elementConRel2)) {
223                                 String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2;
224                                 Logger.error(err);
225                                 return new ConnectionErrorImpl(err);
226                         }
227                 }
228                 // TODO : should we have separate customConnect method for element level connections?
229                 SymbolConnectionData data = customConnect(g, symbolConf2, elementConRel1, elementConRel2, usedConnType);
230                 if (data == null) {
231                         return _connectElement(g, symbolConf2, elementConRel1, elementConRel2,usedConnType);
232                 } else {
233                         return data;
234                 }
235         }
236         
237         /**
238          * Connects two symbols with chosen connection type. Does not work with signal connections. 
239          * @param g
240          * @param symbolConf2 other symbol.
241          * @param componentConRel1 symbol's terminal relation.
242          * @param componentConRel2 other symbol's terminal relation.
243          * @param connectionType used connection type.
244          * @return SymbolConnetionData instance describing the connection. Return value is never null.
245          * @throws DatabaseException on database failure.
246          */
247         public SymbolConnectionData connect(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectionType) throws DatabaseException {
248                 if (diagram.equals(symbolConf2.diagram))
249                         return _connect(g, symbolConf2, componentConRel1, componentConRel2, connectionType);
250                 else
251                         return connectWithFlag(g,  symbolConf2, componentConRel1, componentConRel2, connectionType);
252         }
253         
254         protected SymbolConnectionData connectToExisting(WriteGraph g, Symbol symbolConf2, Symbol current, Resource componentConRel1, Resource componentConRel2, Resource connectorType, boolean firstSame) throws DatabaseException {
255                 return new ConnectionErrorImpl("Symbol is already connected");
256         }
257         
258         protected Resource componentConnectionType(ReadGraph g, Resource componentConRel1, Resource componentConRel2) throws DatabaseException {
259                 StructuralResource2 s = StructuralResource2.getInstance(g);
260                 return s.Connection;
261         }
262         
263         protected Resource diagramConnectionType(ReadGraph g, Resource componentConnectionType) throws DatabaseException {
264                 ModelingResources MOD = ModelingResources.getInstance(g);
265                 if (componentConnectionType != null) {
266                         Resource ct = g.getPossibleObject(componentConnectionType, MOD.ConnectionTypeToDiagramConnectionType);
267                         if (ct != null)
268                                 return ct;
269                 }
270                 DiagramResource d = DiagramResource.getInstance(g);
271                 return d.RouteGraphConnection;
272         }
273         
274         private SymbolConnectionData _connect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectorType) throws DatabaseException {
275                 Layer0 b = Layer0.getInstance(g);
276                 StructuralResource2 s = StructuralResource2.getInstance(g);
277                 DiagramResource d = DiagramResource.getInstance(g);
278                 ModelingResources m = ModelingResources.getInstance(g);
279                 
280                 
281                 if (g.isInstanceOf(componentConRel1, b.FunctionalRelation) && getSingleConnected(g, componentConRel1) != null) {
282                         Symbol current = getSingleConnected(g, componentConRel1);
283                         if (current.component.equals(symbolConf2.component))
284                                 return new SymbolExistsImpl();
285                         
286                         return connectToExisting(g, symbolConf2, current, componentConRel1, componentConRel2, connectorType, true);
287                 }
288                 if (g.isInstanceOf(componentConRel2, b.FunctionalRelation) && symbolConf2.getSingleConnected(g, componentConRel2) != null) {
289                         Symbol current = symbolConf2.getSingleConnected(g, componentConRel2);
290                         if (current.component.equals(component))
291                                 return new SymbolExistsImpl();
292                         return connectToExisting(g, symbolConf2, current, componentConRel1, componentConRel2, connectorType, false);
293                         
294                 }
295                 
296                 // connection object in module level
297                 Resource moduleConnection = g.newResource();
298                 Resource moduleConnectionType = componentConnectionType(g, componentConRel1, componentConRel2);
299                 g.claim(moduleConnection, b.InstanceOf, moduleConnectionType);
300                 
301                 // connect the modules
302                 
303                 g.claim(component, componentConRel1, moduleConnection);
304                 g.claim(symbolConf2.component, componentConRel2, moduleConnection);
305                 
306                 // connection object in diagram level
307                 Resource diagramConnection = g.newResource();
308                 g.claim(diagramConnection, b.InstanceOf, diagramConnectionType(g, moduleConnectionType));
309                 DiagramUtils.addElementFirst(g, diagram, diagramConnection);
310                 
311                 g.claim(diagramConnection, s.HasConnectionType, connectorType);
312                 
313                 // Relation from element1 to connector1
314                 Resource elementConRel1 = getDiagramConnectionRelation(g, element, componentConRel1);
315                 Resource connectorRel1 = g.getPossibleObject(componentConRel1, s.HasAttachmentRelation);
316                 if (connectorRel1 == null)
317                         connectorRel1 = d.HasPlainConnector;
318                                 
319                 // connector1
320                 Resource connector1 = g.newResource();
321                 g.claim(connector1, b.InstanceOf, d.Connector);
322                 g.claim(element, elementConRel1, connector1);
323                 g.claim(diagramConnection, connectorRel1, connector1);
324                 
325                 // Relation from element2 to connector2
326                 Resource elementConRel2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
327                 Resource connectorRel2 = g.getPossibleObject(componentConRel2, s.HasAttachmentRelation);
328                 if (connectorRel2 == null)
329                         connectorRel2 = d.HasArrowConnector;
330                 // connector2
331                 Resource connector2 = g.newResource();
332                 g.claim(connector2, b.InstanceOf, d.Connector);
333                 g.claim(symbolConf2.element, elementConRel2, connector2);
334                 g.claim(diagramConnection, connectorRel2, connector2);
335                 
336                 // connect connectors
337                 g.claim(connector1, d.AreConnected, connector2);
338
339                 g.claim(moduleConnection, m.ConnectionToDiagramConnection, diagramConnection);
340                 
341                 return new ConnectorDataImpl(diagramConnection);
342         }
343         
344         private SymbolConnectionData _connectElement(WriteGraph g, Symbol symbolConf2, Resource elementConRel1, Resource elementConRel2, Resource connectorType) throws DatabaseException {
345                 Layer0 b = Layer0.getInstance(g);
346                 StructuralResource2 s = StructuralResource2.getInstance(g);
347                 DiagramResource d = DiagramResource.getInstance(g);
348                 ModelingResources m = ModelingResources.getInstance(g);
349                 
350                 
351                 if (g.isInstanceOf(elementConRel1, b.FunctionalRelation) && getDiagramSingleConnected(g, elementConRel1) != null) {
352                         Symbol current = getDiagramSingleConnected(g, elementConRel1);
353                         if (current.component.equals(symbolConf2.component))
354                                 return new SymbolExistsImpl();
355                         String err = "Cannot connect, terminal 1 is reserved: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2;
356                         Logger.error(err);
357                         return new ConnectionErrorImpl(err);
358                 }
359                 if (g.isInstanceOf(elementConRel2, b.FunctionalRelation) && symbolConf2.getDiagramSingleConnected(g, elementConRel2) != null) {
360                         Symbol current = symbolConf2.getDiagramSingleConnected(g, elementConRel2);
361                         if (current.component.equals(component))
362                                 return new SymbolExistsImpl();
363                         String err = "Cannot connect, terminal 2 is reserved: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2;
364                         Logger.error(err);
365                         return new ConnectionErrorImpl(err);
366                 }
367                 
368 //              // connection object in module level
369 //              Resource moduleConnection = g.newResource();
370 //              g.claim(moduleConnection, b.InstanceOf, s.Connection);
371 //              
372 //              // connect the modules
373 //              
374 //              g.claim(component, componentConRel1, moduleConnection);
375 //              g.claim(symbolConf2.component, componentConRel2, moduleConnection);
376                 
377                 // connection object in diagram level
378                 Resource diagramConnection = g.newResource();
379                 g.claim(diagramConnection, b.InstanceOf, diagramConnectionType(g, null));
380                 DiagramUtils.addElementFirst(g, diagram, diagramConnection);
381                 
382                 g.claim(diagramConnection, s.HasConnectionType, connectorType);
383                 
384                 // Relation from element1 to connector1
385 //              Resource elementConRel1 = getDiagramConnectionRelation(g, element, componentConRel1);
386 //              Resource connectorRel1 = g.getPossibleObject(componentConRel1, s.HasAttachmentRelation);
387 //              if (connectorRel1 == null)
388 //                      connectorRel1 = d.HasPlainConnector;
389                 Resource connectorRel1 = d.HasPlainConnector;
390                                 
391                 // connector1
392                 Resource connector1 = g.newResource();
393                 g.claim(connector1, b.InstanceOf, d.Connector);
394                 g.claim(element, elementConRel1, connector1);
395                 g.claim(diagramConnection, connectorRel1, connector1);
396                 
397                 // Relation from element2 to connector2
398 //              Resource elementConRel2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
399 //              Resource connectorRel2 = g.getPossibleObject(componentConRel2, s.HasAttachmentRelation);
400 //              if (connectorRel2 == null)
401 //                      connectorRel2 = d.HasArrowConnector;
402                 
403                 Resource connectorRel2 = d.HasArrowConnector;
404                 // connector2
405                 Resource connector2 = g.newResource();
406                 g.claim(connector2, b.InstanceOf, d.Connector);
407                 g.claim(symbolConf2.element, elementConRel2, connector2);
408                 g.claim(diagramConnection, connectorRel2, connector2);
409                 
410                 // connect connectors
411                 g.claim(connector1, d.AreConnected, connector2);
412
413 //              g.claim(moduleConnection, m.ConnectionToDiagramConnection, diagramConnection);
414                 
415                 return new ConnectorDataImpl(diagramConnection);
416         }
417         
418         
419         private SymbolConnectionData connectWithFlag(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectionType) throws DatabaseException {
420                 
421                 Diagram diagram2 = symbolConf2.diagram;
422                 Layer0 l0 = Layer0.getInstance(g);
423                 StructuralResource2 s = StructuralResource2.getInstance(g);
424                 DiagramResource d = DiagramResource.getInstance(g);
425                 ModelingResources m = ModelingResources.getInstance(g);
426                 
427                 if (g.isInstanceOf(componentConRel1, l0.FunctionalRelation) && getSingleConnected(g, componentConRel1) != null) {
428                         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";
429                         Logger.error(err);
430                         return new ConnectionErrorImpl(err);
431                 }
432                 if (g.isInstanceOf(componentConRel2, l0.FunctionalRelation) && symbolConf2.getSingleConnected(g, componentConRel2) != null) {
433                         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";
434                         Logger.error(err);
435                         return new ConnectionErrorImpl(err);
436                 }
437         
438                 double t = 20.0;
439                 double[] t1 =  getSymbolTranslation(g);
440                 double[] t2 =  symbolConf2.getSymbolTranslation(g);
441                 
442                 Symbol flag1 = diagram.addElement(g, d.Flag, t1[0]+t, t1[1]);
443                 Symbol flag2 = diagram2.addElement(g, d.Flag, t2[0]-t, t2[1]);
444                 
445                 Resource connectionJoin = g.newResource();
446                 g.claim(connectionJoin, l0.InstanceOf, s.ConnectionJoin);
447                 g.claim(diagram.getComposite(), s.HasConnectionJoin, connectionJoin);
448                 g.claim(diagram2.getComposite(), s.HasConnectionJoin, connectionJoin);
449                 
450                 Resource connection1 = g.newResource();
451                 Resource ct = componentConnectionType(g, componentConRel1, componentConRel2);
452                 g.claim(connection1, l0.InstanceOf, ct);
453                 
454                 Resource connection2 = g.newResource();
455                 g.claim(connection2, l0.InstanceOf, ct);
456                 
457                 g.claim(component, componentConRel1, connection1);
458                 g.claim(symbolConf2.component, componentConRel2, connection2);
459                 g.claim(connection1, s.IsJoinedBy, connectionJoin);
460                 g.claim(connection2, s.IsJoinedBy, connectionJoin);
461                 
462                 g.claim(flag1.element, d.FlagIsJoinedBy, connectionJoin);
463                 g.claim(flag2.element, d.FlagIsJoinedBy, connectionJoin);
464                 
465                 Resource diagConnection1 = g.newResource();
466                 Resource dct = diagramConnectionType(g, ct);
467                 g.claim(diagConnection1, l0.InstanceOf, dct);
468                 DiagramUtils.addElementFirst(g, diagram, diagConnection1);
469                 g.claim(diagConnection1, s.HasConnectionType, connectionType);
470
471                 Resource diagConnection2 = g.newResource();
472                 g.claim(diagConnection2, l0.InstanceOf, dct);
473                 DiagramUtils.addElementFirst(g, diagram2, diagConnection2);
474                 g.claim(diagConnection2, s.HasConnectionType, connectionType);
475                 
476                 g.claim(connection1, m.ConnectionToDiagramConnection, diagConnection1);
477                 g.claim(connection2, m.ConnectionToDiagramConnection, diagConnection2);
478                 
479                 // Relation from element1 to connector1
480                 Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
481                 
482                 // connector1
483                 Resource connector1_1 = g.newResource();
484                 g.claim(connector1_1, l0.InstanceOf, d.Connector);
485                 g.claim(element, isConnected1, connector1_1);
486                 g.claim(diagConnection1, d.HasPlainConnector, connector1_1);
487                 
488                 Resource connector1_2 = g.newResource();
489                 g.claim(connector1_2, l0.InstanceOf, d.Connector);
490                 g.claim(flag1.element, d.Flag_ConnectionPoint, connector1_2);
491                 g.claim(diagConnection1, d.HasArrowConnector, connector1_2);
492                 
493                 g.claim(connector1_1, d.AreConnected, connector1_2);
494                 
495                 // Relation from element2 to connector2
496                 Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
497                 
498                 // connector1
499                 Resource connector2_1 = g.newResource();
500                 g.claim(connector2_1, l0.InstanceOf, d.Connector);
501                 g.claim(flag2.element, d.Flag_ConnectionPoint, connector2_1);
502                 g.claim(diagConnection2, d.HasPlainConnector, connector2_1);
503                 
504                 Resource connector2_2 = g.newResource();
505                 g.claim(connector2_2, l0.InstanceOf, d.Connector);
506                 g.claim(symbolConf2.element, isConnected2, connector2_2);
507                 g.claim(diagConnection2, d.HasArrowConnector, connector2_2);
508                 
509                 g.claim(connector2_1, d.AreConnected, connector2_2);
510                 
511                 return new FlagConnectionDataImpl(flag1, flag2, diagConnection1, diagConnection2);
512         }
513         
514         /**
515          * Returns diagram connection relation for an element and its component connection relation
516          * @param g
517          * @param element
518          * @param componentConnRel
519          * @return
520          * @throws ServiceException
521          * @throws NoSingleResultException
522          * @throws ValidationException 
523          */
524         public static Resource getDiagramConnectionRelation(ReadGraph g, Resource element, Resource componentConnRel) throws DatabaseException {
525                 ModelingResources m = ModelingResources.getInstance(g);
526                 Collection<Resource> diagramConnectionRels = g.getObjects(componentConnRel, m.ConnectionRelationToDiagramConnectionRelation);
527                 if (diagramConnectionRels.size() == 1)
528                         return diagramConnectionRels.iterator().next();
529                 if (diagramConnectionRels.size() > 1) {
530                         List<Resource> matching = new ArrayList<Resource>();
531                         for (Resource r : diagramConnectionRels) {
532                                 if (g.hasStatement(element, r))
533                                         matching.add(r);
534                         }
535                         if (matching.size() == 1)
536                                 return matching.get(0);
537                 }
538                 Layer0 b = Layer0.getInstance(g);
539                 Collection<Resource> elementTypes = g.getObjects(element, b.InstanceOf);
540                 if (elementTypes.size() != 1)
541                         throw new RuntimeException("Cannot handle multi-instances " + element + " " + NameUtils.getSafeName(g, element));
542                 Resource elementType = elementTypes.iterator().next();
543                 Collection<Resource> rels = StructuralUtils.getConnectionRelations(g, elementType);
544                 if (rels.size() == 1)
545                         return rels.iterator().next();
546                 for (Resource rel : rels) {
547                         if (diagramConnectionRels.contains(rel))
548                                 return rel;
549                 }
550                 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 );
551         }
552         
553         public static Resource getComponentConnectionRelation(ReadGraph g, Resource diagraromConnRel) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
554                 ModelingResources mr = ModelingResources.getInstance(g);
555                 return g.getSingleObject(diagraromConnRel, mr.DiagramConnectionRelationToConnectionRelation);
556         }
557         
558 //      public static Resource getSymbolRelation(ReadGraph g, Symbol conf, Resource genericRel) throws DatabaseException {
559 //              Layer0 b = Layer0.getInstance(g);
560 //              if (g.isInstanceOf(conf.element, ab.CalculationLevelReferenceElement)) {
561 //                      ModelingResources m = ModelingResources.getInstance(g);
562 //                      //return g.getInverse(g.getSingleObject(conf.element, m.HasReferenceRelation));
563 //                      return g.getSingleObject(conf.element, m.HasReferenceRelation);
564 //              }
565 //              
566 //              Resource compType = g.getSingleObject(conf.getComponent(), b.InstanceOf);
567 //              
568 //              for (Resource rel : StructuralUtils.getConnectionRelations(g, compType))
569 //                  if (g.isSubrelationOf(rel, genericRel))
570 //                      return rel;
571 //              return null;
572 //      }
573         
574         /**
575          * Returns symbol where given symbol is connected using given relation. Returns null if the symbol is not connected using the relation.
576          * @param g
577          * @param componentConRel
578          * @return
579          * @throws DatabaseException 
580          */
581         public Symbol getSingleConnected(ReadGraph g, Resource componentConRel) throws DatabaseException {
582                 Collection<Symbol> symbols = getConnected(g, componentConRel);
583                 if (symbols.size() > 1)
584                         throw new NoSingleResultException("Symbol " + component + " is connected more than once using relation " + componentConRel);
585                 if (symbols.size() == 1)
586                         return symbols.iterator().next();
587                 return null;
588         }
589         
590         public Symbol getSingleConnected(ReadGraph g, Resource componentConRel, Resource otherComponentConRel) throws DatabaseException {
591                 Collection<Symbol> symbols = getConnected(g, componentConRel, otherComponentConRel);
592                 if (symbols.size() > 1)
593                         throw new NoSingleResultException("Symbol " + component + " is connected more than once using relation " + componentConRel);
594                 if (symbols.size() == 1)
595                         return symbols.iterator().next();
596                 return null;
597         }
598         
599         public Collection<Symbol> getConnected(ReadGraph g, Resource componentConRel, Resource otherComponentConRel) throws DatabaseException {
600                 assert(componentConRel != null);
601                 Layer0 l0 = Layer0.getInstance(g);
602                 StructuralResource2 sr = StructuralResource2.getInstance(g);
603                 ModelingResources mr = ModelingResources.getInstance(g);
604                 Collection<Symbol> result = new ArrayList<Symbol>();
605                 Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
606                 for (Resource modConn1 : modConn1s) {
607                 
608                         Collection<Statement> connected = g.getStatements(modConn1, sr.Connects);
609                         Collection<Resource> connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy);
610                         Collection<Resource> connectedComponents = new ArrayList<Resource>();
611                         
612                         for (Statement stm : connected) {
613                                 if (!stm.getObject().equals(this.component)) {
614                                         if (g.getInverse(stm.getPredicate()).equals(otherComponentConRel)) {
615                                                 connectedComponents.add(stm.getObject());
616                                         }
617                                 }
618                         }
619                         
620                         for (Resource connectionJoin : connectionJoins) {
621                                 Collection<Resource> joinedConns = g.getObjects(connectionJoin, sr.Joins);
622                                 for (Resource conn : joinedConns) {
623                                         if (!conn.equals(modConn1)) {
624                                                 // TODO : check ConnectionJoins?
625                                                 for (Statement stm : g.getStatements(conn, sr.Connects)) {
626                                                         if (g.getInverse(stm.getPredicate()).equals(otherComponentConRel))
627                                                                 connectedComponents.add(stm.getObject());
628                                                 }
629                                         }
630                                 }
631                         }
632                         for (Resource connectedComponent : connectedComponents) {
633                         
634                                 Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
635                                 
636                                 Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
637                                 result.add(diag.getSymbol(g, pointElem,connectedComponent));
638                         }
639                         
640                 }
641                 return result;  
642         }
643         
644         public Collection<Symbol> getConnected(ReadGraph g, Resource componentConRel) throws DatabaseException {
645                 assert(componentConRel != null);
646                 Layer0 l0 = Layer0.getInstance(g);
647                 StructuralResource2 sr = StructuralResource2.getInstance(g);
648                 ModelingResources mr = ModelingResources.getInstance(g);
649                 
650                 Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
651                 Collection<Symbol> result = new ArrayList<Symbol>();
652                 for (Resource modConn1 : modConn1s) {
653                 
654                         Collection<Resource> connected = g.getObjects(modConn1, sr.Connects);
655                         Collection<Resource> connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy);
656                         Collection<Resource> connectedComponents = new ArrayList<Resource>();
657                         
658                         for (Resource r : connected) {
659                                 if (!r.equals(this.component)) {
660                                         connectedComponents.add(r);
661                                 }
662                         }
663                         for (Resource connectionJoin : connectionJoins) {
664                                 Collection<Resource> joinedConns = g.getObjects(connectionJoin, sr.Joins);
665                                 for (Resource conn : joinedConns) {
666                                         if (!conn.equals(modConn1)) {
667                                                 // TODO : check ConnectionJoins?
668                                                 for (Resource obj : g.getObjects(conn, sr.Connects))
669                                                         connectedComponents.add(obj);
670                                         }
671                                 }
672                         }
673                         for (Resource connectedComponent : connectedComponents) {
674                         
675                                 Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
676                                 
677                                 Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
678                                 result.add(diag.getSymbol(g, pointElem,connectedComponent));
679                         }
680                 }
681                 return result;
682                 
683         }
684         
685         /**
686          * Returns connected symbols on diagram level. Searches through branchpoints.
687          * @param g
688          * @param diagramConnRel
689          * @param otherConnRel
690          * @return
691          * @throws DatabaseException
692          */
693         public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel, Resource otherConnRel) throws DatabaseException {
694                 DiagramResource dr = DiagramResource.getInstance(g);
695                 Collection<Resource> connectors = g.getObjects(element, diagramConnRel);
696                 Collection<Symbol> result = new ArrayList<Symbol>();
697                 for (Resource connector : connectors) {
698                         Resource otherConnector = g.getSingleObject(connector, dr.AreConnected);
699                         if (g.isInstanceOf(otherConnector, dr.Connector)) {
700                                 getConnectorConnectors(g, otherConnector, otherConnRel, result);
701                         } else if (g.isInstanceOf(otherConnector, dr.RouteLine)) {
702                                 getBranchPointConnectors(g, connector, otherConnector, otherConnRel, result);
703                         } else {
704                                 throw new DatabaseException("Connector " + g.getPossibleURI(otherConnector) + " " + otherConnector + " han unknown type");
705                         }
706                 }
707                 return result;
708         }
709         
710         private void getConnectorConnectors(ReadGraph g, Resource connector, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException{
711                 StructuralResource2 sr = StructuralResource2.getInstance(g);
712                 DiagramResource dr = DiagramResource.getInstance(g);
713                 Collection<Statement> stms = g.getStatements(connector, sr.Connects);
714                 Statement stm = null;
715                 for (Statement s : stms) {
716                         if (!g.isInstanceOf(s.getObject(), dr.Connection)) {
717                                 stm = s;
718                         }
719                 }
720                 if (stm == null)
721                         return;
722                 if (otherConnRel != null) {
723                         Resource rel = g.getInverse(stm.getPredicate());
724                         if (!rel.equals(otherConnRel))
725                                 return;
726                 }
727                 Resource element = stm.getObject();
728                 result.add(diagram.getSymbol(g, element));
729         }
730         
731         private void getBranchPointConnectors(ReadGraph g, Resource origin, Resource branchPoint, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException {
732                 DiagramResource dr = DiagramResource.getInstance(g);
733                 
734                 Collection<Resource> branchConnected = g.getObjects(branchPoint, dr.AreConnected);
735                 for (Resource branchConnector : branchConnected) {
736                         if (branchConnector.equals(origin))
737                                 continue;
738                         if (g.isInstanceOf(branchConnector, dr.Connector)) {
739                                 getConnectorConnectors(g, branchConnector, otherConnRel, result);
740                         } else if (g.isInstanceOf(branchConnector, dr.RouteLine)) {
741                                 getBranchPointConnectors(g, branchPoint, branchConnector, otherConnRel, result);
742                         } else {
743                                 throw new DatabaseException("Connector " + g.getPossibleURI(branchConnector) + " " + branchConnector + " han unknown type");
744                         }
745                 }
746         }
747
748         public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
749                 return getDiagramConnected(g, diagramConnRel,null);
750         }
751         
752         public Collection<Symbol> getDiagramInverseConnected(ReadGraph g,  Resource otherConnRel) throws DatabaseException {
753                 StructuralResource2 sr = StructuralResource2.getInstance(g);
754                 return getDiagramConnected(g, sr.IsConnectedTo, otherConnRel);
755                 
756         }
757         
758         public Collection<Symbol> getDiagramConnected(ReadGraph g) throws DatabaseException {
759                 StructuralResource2 sr = StructuralResource2.getInstance(g);
760                 return getDiagramConnected(g, sr.IsConnectedTo, null);
761         }
762         
763         public Symbol getDiagramSingleConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
764                 Collection<Symbol> symbols = getDiagramConnected(g, diagramConnRel);
765                 if (symbols.size() > 1) {
766                         throw new NoSingleResultException("Symbol " + element + " has more than one connection with " + diagramConnRel);
767                 } else if (symbols.size() == 1) {
768                         return symbols.iterator().next();
769                 }
770                 return null;
771         }
772         
773         public Symbol getOtherFlag(ReadGraph g) throws DatabaseException {
774                 DiagramResource dr = DiagramResource.getInstance(g);
775                 Resource connectionJoin = g.getPossibleObject(element, dr.FlagIsJoinedBy);
776                 if (connectionJoin == null)
777                         return null;
778                 Collection<Resource> flags = g.getObjects(connectionJoin, dr.JoinsFlag);
779                 Resource otherFlag = null;
780                 for (Resource f : flags) {
781                         if (!f.equals(element)) {
782                                 otherFlag = f;
783                                 break;
784                         }
785                 }
786                 
787                 if (otherFlag == null) {
788                         return null;
789                 }
790                 Resource otherDiagramR = OrderedSetUtils.getSingleOwnerList(g, otherFlag);
791                 Diagram otherDiagram = diagram.fromExisting(g, otherDiagramR);
792                 return otherDiagram.getSymbol(g, otherFlag, null);
793                 
794         }
795
796         /**
797          * Returns concatenated translation of the symbol.
798          * @param g
799          * @return
800          * @throws DatabaseException
801          */
802         public double[] getSymbolTranslation(ReadGraph g) throws DatabaseException {
803                 DiagramResource d = DiagramResource.getInstance(g);
804                 ModelingResources mr = ModelingResources.getInstance(g);
805                 
806                 Resource e = element;
807                 AffineTransform at = new AffineTransform();
808                 while (e != null) {
809                         double transform[] = g.getPossibleRelatedValue(e, d.HasTransform);
810                         if (transform == null)
811                                 break;
812                         AffineTransform at2 = new AffineTransform(transform);
813                         at.preConcatenate(at2);
814                         Resource component = g.getPossibleObject(e, mr.HasParentComponent);
815                         if (component != null) {
816                                 e = g.getPossibleObject(component, mr.ComponentToElement);
817                         } else {
818                                 e = null;
819                         }
820                 }
821
822                 return new double[]{at.getTranslateX(),at.getTranslateY()};
823         }
824         
825         /**
826          * Returns transformation of the symbol.
827          * @param g
828          * @return
829          * @throws DatabaseException
830          */
831         public double[] getSymbolTransformation(ReadGraph g) throws DatabaseException{
832                 DiagramResource d = DiagramResource.getInstance(g);
833                 double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
834                 return transform;
835         }
836         
837         /**
838          * Sets translation of symbol. The scale is set to 1.0.
839          * @param g
840          * @param x
841          * @param y
842          * @throws DatabaseException
843          */
844         public void setSymbolTranslation(WriteGraph g, double x, double y) throws DatabaseException {
845                 DiagramResource d = DiagramResource.getInstance(g);
846                 G2DResource g2d = G2DResource.getInstance(g);
847                 g.claimLiteral(element, d.HasTransform, g2d.Transform, new double[]{1.0,0.0,0.0,1.0,x,y});
848         }
849         
850         public void setSymbolTransformation(WriteGraph g, AffineTransform at) throws DatabaseException {
851                 DiagramResource d = DiagramResource.getInstance(g);
852                 G2DResource g2d = G2DResource.getInstance(g);
853                 double arr[] = new double[6];
854                 at.getMatrix(arr);
855                 g.claimLiteral(element, d.HasTransform, g2d.Transform, arr);
856         }
857         
858         /**
859          * Set the scale of symbol.
860          * @param g
861          * @param scale
862          * @throws DatabaseException
863          */
864         public void setScale(WriteGraph g, double scale) throws DatabaseException {
865                 DiagramResource d = DiagramResource.getInstance(g);
866                 double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
867                 g.claimLiteral(element, d.HasTransform, new double[]{scale,0.0,0.0,scale,transform[4],transform[5]});
868         }
869         
870         @Override
871         public boolean equals(Object o) {
872                 if (o == null)
873                         return false;
874                 if (this.getClass() != o.getClass())
875                         return false;
876                 Symbol other = (Symbol)o;
877                 return element.equals(other.element);
878         }
879         
880         @Override
881         public int hashCode() {
882                 return element.hashCode();
883         }
884         
885         
886         
887         /**
888          * Returns component type from symbol type
889          * @param g
890          * @param symbolType
891          * @return
892          * @throws NoSingleResultException
893          * @throws ManyObjectsForFunctionalRelationException
894          * @throws ServiceException
895          */
896         public static Resource getComponentTypeFromSymbolType(ReadGraph g, Resource symbolType) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
897                 ModelingResources m = ModelingResources.getInstance(g);
898                 Resource component = g.getPossibleObject(symbolType, m.SymbolToComponentType);
899                 return component;
900         }
901         
902         public static Resource getSymbolTypeFromComponentType(ReadGraph g, Resource componentType) throws NoSingleResultException, ServiceException, ManyObjectsForFunctionalRelationException {
903                 ModelingResources m = ModelingResources.getInstance(g);
904                 Collection<Resource> symbols = g.getObjects(componentType, m.ComponentTypeToSymbol);
905                 if (symbols.size() == 0)
906                         return null;
907                 return symbols.iterator().next();
908         }
909         
910         public void remove(WriteGraph g) throws DatabaseException{
911                 Layer0 L0 = Layer0.getInstance(g);
912                 StructuralResource2 STR = StructuralResource2.getInstance(g);
913                 DiagramResource DIA = DiagramResource.getInstance(g);
914                 OrderedSetUtils.remove(g, diagram.getDiagram(), element);
915                 if (component != null)
916                         g.deny(component, L0.PartOf);
917                 Collection<Statement> statements = g.getStatements(element, STR.IsConnectedTo);
918                 for (Statement s : statements) {
919                         if (g.isInstanceOf(s.getObject(),DIA.Connector)) {
920                                 Resource connectedConnector = g.getPossibleObject(s.getObject(), DIA.AreConnected);
921                                 if (connectedConnector != null)
922                                         g.deny(connectedConnector);
923                                 g.deny(s.getObject());
924                         }
925                 }
926                 if (component != null) {
927                         statements = g.getStatements(component, STR.IsConnectedTo);
928                         for (Statement s : statements) {
929                                 if (g.isInstanceOf(s.getObject(),STR.Connection)) {
930                                         g.deny(s.getObject());
931                                 }
932                         }
933                 }
934                 g.deny(element);
935                 if (component != null)
936                         g.deny(component);
937         }
938         
939         public void dispose() {
940                 diagram = null;
941                 component = null;
942                 element = null;
943         }
944
945         /**
946          * Common interface for Symbol.connect return value.
947          *
948          */
949         public interface SymbolConnectionData {
950                 
951         }
952         
953         /**
954          * Interface for returning diagram level connectors.
955          *
956          */
957         public interface DiagramConnectionData extends SymbolConnectionData {
958                 public int getConnectionCount();
959                 public Resource getConnection(int index);
960         }
961         
962         /**
963          * Interface for flag connections. 
964          *
965          */
966         public interface FlagConnectionData extends SymbolConnectionData {
967                 public Symbol getFirstFlag();
968                 public Symbol getSecondFlag();
969         }
970         
971         /**
972          * Interface for "connection" that merged the connected symbols into one symbol. 
973          *
974          */
975         public interface MergeSymbolData extends SymbolConnectionData {
976                 Symbol getResultSymbol();
977         }
978         
979         /**
980          * Return value for a connection that already exists. 
981          *
982          */
983         public interface SymbolExists extends SymbolConnectionData {
984                 
985         }
986         
987         /**
988          * Return value for an error. 
989          *
990          */
991         public interface ConnectionError extends SymbolConnectionData {
992                 String getReason();
993         }
994         
995         private static class ConnectionErrorImpl implements ConnectionError {
996                 private String error;
997                 
998                 public ConnectionErrorImpl(String error) {
999                         this.error = error;
1000                 }
1001                 
1002                 @Override
1003                 public String getReason() {
1004                         return error;
1005                 }
1006         }
1007         
1008         private static class SymbolExistsImpl implements SymbolExists {
1009                 
1010         }
1011         
1012         private static class ConnectorDataImpl implements DiagramConnectionData {
1013                 
1014                 private Resource[] connectors;
1015                 
1016                 public ConnectorDataImpl(Resource... connectors) {
1017                         this.connectors = connectors;
1018                 }
1019                 
1020                 @Override
1021                 public Resource getConnection(int index) {
1022                         return connectors[index];
1023                 }
1024                 
1025                 @Override
1026                 public int getConnectionCount() {
1027                         return connectors.length;
1028                 }
1029         }
1030         
1031         private static class FlagConnectionDataImpl implements FlagConnectionData, DiagramConnectionData {
1032                 
1033                 private Symbol firstFlag;
1034                 private Symbol secondFlag;
1035                 private Resource[] connectors;
1036                 
1037                 public FlagConnectionDataImpl(Symbol firstFlag, Symbol secondFlag, Resource... connectors) {
1038                         this.firstFlag = firstFlag;
1039                         this.secondFlag = secondFlag;
1040                         this.connectors = connectors;
1041                 }
1042                 
1043                 @Override
1044                 public Symbol getFirstFlag() {
1045                         return firstFlag;
1046                 }
1047                 
1048                 @Override
1049                 public Symbol getSecondFlag() {
1050                         return secondFlag;
1051                 }
1052                 
1053                 @Override
1054                 public Resource getConnection(int index) {
1055                         return connectors[index];
1056                 }
1057                 
1058                 @Override
1059                 public int getConnectionCount() {
1060                         return connectors.length;
1061                 }
1062         }
1063
1064         public void setComponentValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
1065                 setValue(graph, component, property, value);
1066         }
1067         
1068         public void setComponentValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
1069                 setValue(graph, component, property, value);
1070         }
1071         
1072         public void setComponentValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
1073                 setValue(graph, component, property, value);
1074         }
1075         
1076         public void setComponentValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
1077                 setValue(graph, component, property, value);
1078         }
1079         
1080         public void setComponentValue(WriteGraph graph, Resource property, String value) throws DatabaseException{
1081                 setValue(graph, component, property, value);
1082         }
1083         
1084         public void setComponentValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
1085                 setValue(graph, component, property, value);
1086         }
1087         
1088         public void setComponentValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
1089                 setValue(graph, component, property, value);
1090         }
1091         
1092         public void setComponentValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
1093                 setValue(graph, component, property, value);
1094         }
1095         
1096         public void setComponentValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
1097                 setValue(graph, component, property, value);
1098         }
1099         
1100         public void setElementValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
1101                 setValue(graph, element, property, value);
1102         }
1103         
1104         public void setElementValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
1105                 setValue(graph, element, property, value);
1106         }
1107         
1108         public void setElementValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
1109                 setValue(graph, element, property, value);
1110         }
1111         
1112         public void setElementValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
1113                 setValue(graph, element, property, value);
1114         }
1115         
1116         public void setElementValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
1117                 setValue(graph, element, property, value);
1118         }
1119         
1120         public void setElementValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
1121                 setValue(graph, element, property, value);
1122         }
1123         
1124         public void setElementValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
1125                 setValue(graph, element, property, value);
1126         }
1127         
1128         public void setElementValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
1129                 setValue(graph, element, property, value);
1130         }
1131         
1132         /**
1133          * Sets literal value. Does data conversion if required.
1134          * 
1135          * Note: This method support only some basic L0 data types.
1136          * 
1137          * @param graph
1138          * @param object
1139          * @param property
1140          * @param value
1141          * @throws DatabaseException
1142          */
1143         public static void setValue(WriteGraph graph, Resource object, Resource property, double value) throws DatabaseException{
1144                 Layer0 l0 = Layer0.getInstance(graph);
1145                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1146                 if (l0.Double.equals(range)) {
1147                         graph.claimLiteral(object, property, value, Bindings.DOUBLE);
1148                 } else if (l0.Float.equals(range)) {
1149                         graph.claimLiteral(object, property, (float)value, Bindings.FLOAT);
1150                 } else if (l0.Integer.equals(range)) {
1151                         graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
1152                 } else if (l0.Long.equals(range)) {
1153                         graph.claimLiteral(object, property, (long)value, Bindings.LONG);
1154                 } else if (l0.Boolean.equals(range)) {
1155                         graph.claimLiteral(object, property, value > 0.0, Bindings.BOOLEAN);
1156                 } else if (l0.String.equals(range)) {
1157                         graph.claimLiteral(object, property, Double.toString(value), Bindings.STRING);
1158                 } else {
1159                         graph.claimLiteral(object, property, value, Bindings.DOUBLE);
1160                 }
1161         }
1162
1163         /**
1164          * Sets literal value. Does data conversion if required.
1165          * 
1166          * Note: This method support only some basic L0 data types.
1167          * 
1168          * @param graph
1169          * @param object
1170          * @param property
1171          * @param value
1172          * @throws DatabaseException
1173          */
1174         public static void setValue(WriteGraph graph, Resource object, Resource property, float value) throws DatabaseException{
1175                 Layer0 l0 = Layer0.getInstance(graph);
1176                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1177                 if (l0.Double.equals(range)) {
1178                         graph.claimLiteral(object, property, (double)value, Bindings.DOUBLE);
1179                 } else if (l0.Float.equals(range)) {
1180                         graph.claimLiteral(object, property, value, Bindings.FLOAT);
1181                 } else if (l0.Integer.equals(range)) {
1182                         graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
1183                 } else if (l0.Long.equals(range)) {
1184                         graph.claimLiteral(object, property, (long)value, Bindings.LONG);
1185                 } else if (l0.Boolean.equals(range)) {
1186                         graph.claimLiteral(object, property, value > 0.f, Bindings.BOOLEAN);
1187                 } else if (l0.String.equals(range)) {
1188                         graph.claimLiteral(object, property, Float.toString(value), Bindings.STRING);
1189                 } else {
1190                         graph.claimLiteral(object, property, value, Bindings.FLOAT);
1191                 }
1192         }
1193         
1194         /**
1195          * Sets literal value. Does data conversion if required.
1196          * 
1197          * Note: This method support only some basic L0 data types.
1198          * 
1199          * @param graph
1200          * @param object
1201          * @param property
1202          * @param value
1203          * @throws DatabaseException
1204          */
1205         public static void setValue(WriteGraph graph, Resource object, Resource property, int value) throws DatabaseException{
1206                 Layer0 l0 = Layer0.getInstance(graph);
1207                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1208                 if (l0.Double.equals(range)) {
1209                         graph.claimLiteral(object, property, (double)value, Bindings.DOUBLE);
1210                 } else if (l0.Float.equals(range)) {
1211                         graph.claimLiteral(object, property, (float) value, Bindings.FLOAT);
1212                 } else if (l0.Integer.equals(range)) {
1213                         graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
1214                 } else if (l0.Long.equals(range)) {
1215                         graph.claimLiteral(object, property, (long)value, Bindings.LONG);
1216                 } else if (l0.Boolean.equals(range)) {
1217                         graph.claimLiteral(object, property, value > 0, Bindings.BOOLEAN);
1218                 } else if (l0.String.equals(range)) {
1219                         graph.claimLiteral(object, property, Integer.toString(value), Bindings.STRING);
1220                 } else {
1221                         graph.claimLiteral(object, property, value, Bindings.INTEGER);
1222                 }
1223         }
1224         
1225         /**
1226          * Sets literal value. Does data conversion if required.
1227          * 
1228          * @param graph
1229          * @param object
1230          * @param property
1231          * @param value
1232          * @throws DatabaseException
1233          */
1234         public static void setValue(WriteGraph graph, Resource object, Resource property, String value) throws DatabaseException{
1235                 Layer0 l0 = Layer0.getInstance(graph);
1236                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1237                 if (range == null) {
1238                         graph.claimLiteral(object, property, value, Bindings.STRING);
1239                 } else {
1240                         if (graph.isInheritedFrom(range, l0.String)) {
1241                                 graph.claimLiteral(object, property, value, Bindings.STRING);
1242                         } else if (graph.isInheritedFrom(range, l0.Double)) {
1243                                 graph.claimLiteral(object, property, Double.parseDouble(value), Bindings.DOUBLE);
1244                         } else if (graph.isInheritedFrom(range, l0.Float)) {
1245                                 graph.claimLiteral(object, property, Float.parseFloat(value), Bindings.FLOAT);
1246                         } else if (graph.isInheritedFrom(range, l0.Integer)) {
1247                                 graph.claimLiteral(object, property, Integer.parseInt(value), Bindings.INTEGER);
1248                         } else if (graph.isInheritedFrom(range, l0.Long)) {
1249                                 graph.claimLiteral(object, property, Long.parseLong(value), Bindings.LONG);
1250                         } else if (graph.isInheritedFrom(range, l0.Boolean)) {
1251                                 graph.claimLiteral(object, property, Boolean.parseBoolean(value), Bindings.BOOLEAN);
1252                         } else {
1253                                 graph.claimLiteral(object, property, value, Bindings.STRING);
1254                         } 
1255                 }
1256         }
1257
1258         /**
1259          * Sets literal value. Does data conversion if required.
1260          * 
1261          * Note: This method support only some basic L0 data types.
1262          * 
1263          * @param graph
1264          * @param object
1265          * @param property
1266          * @param value
1267          * @throws DatabaseException
1268          */
1269         public static void setValue(WriteGraph graph, Resource object, Resource property, boolean value) throws DatabaseException{
1270                 Layer0 l0 = Layer0.getInstance(graph);
1271                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1272                 if (l0.Boolean.equals(range)) {
1273                         graph.claimLiteral(object, property, value , Bindings.BOOLEAN);
1274                 } else if (l0.String.equals(range)) {
1275                         graph.claimLiteral(object, property, Boolean.toString(value), Bindings.STRING);
1276                 } else if (l0.Integer.equals(range)) {
1277                         graph.claimLiteral(object, property, value ? 1 : 0, Bindings.INTEGER);
1278                 } else {
1279                         graph.claimLiteral(object, property, value, Bindings.BOOLEAN);
1280                 }
1281         }
1282         
1283         /**
1284          * Sets literal value. Does data conversion if required.
1285          * 
1286          * Note: This method support only some basic L0 data types.
1287          * 
1288          * @param graph
1289          * @param object
1290          * @param property
1291          * @param value
1292          * @throws DatabaseException
1293          */
1294         public static void setValue(WriteGraph graph, Resource object, Resource property, double[] value) throws DatabaseException{
1295                 Layer0 l0 = Layer0.getInstance(graph);
1296                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1297                 if (l0.DoubleArray.equals(range)) {
1298                         graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
1299                 } else if (l0.FloatArray.equals(range)) {
1300                         float arr[] = new float[value.length];
1301                         for (int i = 0; i < value.length; i++)
1302                                 arr[i] = (float) value[i];
1303                         graph.claimLiteral(object, property, arr, Bindings.FLOAT_ARRAY);
1304                 } else if (l0.IntegerArray.equals(range)) {
1305                         int arr[] = new int[value.length];
1306                         for (int i = 0; i < value.length; i++)
1307                                 arr[i] = (int) value[i];
1308                         graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1309                 } else {
1310                         graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
1311                 }
1312         }
1313         
1314         /**
1315          * Sets literal value. Does data conversion if required.
1316          * 
1317          * Note: This method support only some basic L0 data types.
1318          * 
1319          * @param graph
1320          * @param object
1321          * @param property
1322          * @param value
1323          * @throws DatabaseException
1324          */
1325         public static void setValue(WriteGraph graph, Resource object, Resource property, float[] value) throws DatabaseException{
1326                 Layer0 l0 = Layer0.getInstance(graph);
1327                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1328                 if (l0.FloatArray.equals(range)) {
1329                         graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
1330                 } else if (l0.DoubleArray.equals(range)) {
1331                         double arr[] = new double[value.length];
1332                         for (int i = 0; i < value.length; i++)
1333                                 arr[i] = (double) value[i];
1334                         graph.claimLiteral(object, property, arr, Bindings.DOUBLE_ARRAY);
1335                 } else if (l0.IntegerArray.equals(range)) {
1336                         int arr[] = new int[value.length];
1337                         for (int i = 0; i < value.length; i++)
1338                                 arr[i] = (int) value[i];
1339                         graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1340                 } else {
1341                         graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
1342                 }
1343         }
1344         
1345         /**
1346          * Sets literal value. Does data conversion if required.
1347          * 
1348          * Note: This method support only some basic L0 data types.
1349          * 
1350          * @param graph
1351          * @param object
1352          * @param property
1353          * @param value
1354          * @throws DatabaseException
1355          */
1356         public static void setValue(WriteGraph graph, Resource object, Resource property, int[] value) throws DatabaseException{
1357                 Layer0 l0 = Layer0.getInstance(graph);
1358                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1359                 if (l0.IntegerArray.equals(range)) {
1360                         graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
1361                 } else if (l0.DoubleArray.equals(range)) {
1362                         double arr[] = new double[value.length];
1363                         for (int i = 0; i < value.length; i++)
1364                                 arr[i] = (double) value[i];
1365                         graph.claimLiteral(object, property, arr, Bindings.DOUBLE_ARRAY);
1366                 } else if (l0.FloatArray.equals(range)) {
1367                         float arr[] = new float[value.length];
1368                         for (int i = 0; i < value.length; i++)
1369                                 arr[i] = (float) value[i];
1370                         graph.claimLiteral(object, property, arr, Bindings.FLOAT_ARRAY);
1371                 } else {
1372                         graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
1373                 }
1374         }
1375         
1376         /**
1377          * Sets literal value. Does data conversion if required.
1378          * 
1379          * Note: This method support only some basic L0 data types.
1380          * 
1381          * @param graph
1382          * @param object
1383          * @param property
1384          * @param value
1385          * @throws DatabaseException
1386          */
1387         public static void setValue(WriteGraph graph, Resource object, Resource property, boolean[] value) throws DatabaseException{
1388                 Layer0 l0 = Layer0.getInstance(graph);
1389                 Resource range = graph.getPossibleObject(property, l0.HasRange);
1390                 if (l0.BooleanArray.equals(range)) {
1391                         graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);
1392                 } else if (l0.IntegerArray.equals(range)) {
1393                         int arr[] = new int[value.length];
1394                         for (int i = 0; i < value.length; i++)
1395                                 arr[i] =  value[i] ? 1 : 0;
1396                         graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
1397                 } else {
1398                         graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);
1399                 }
1400         }
1401         
1402 }