]> gerrit.simantics Code Review - simantics/interop.git/blob - org.simantics.interop.diagram/src/org/simantics/interop/diagram/Symbol.java
Java API for diagrams, work in progress
[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.HashSet;
7 import java.util.List;
8
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;
28
29
30
31 /**
32  * @author Marko Luukkainen
33  */
34 public abstract class Symbol {
35         
36         private static boolean USE_UNRELIABLE_CONNECT = false;
37         private static boolean PREVENT_SELF_CONNECTIONS = false;
38         
39         private Diagram diagram;
40         Resource element;
41         Resource component;
42         
43         /**
44          * Use Diagram.getSymbol() to get Symbols.
45          * @param diagram
46          * @param element
47          * @param component
48          */
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;
55         }
56         
57         public Diagram getDiagram() {
58                 return diagram;
59         }
60         
61         public Resource getComponent() {
62                 return component;
63         }
64         
65         public Resource getElement() {
66                 return element;
67         }
68         
69         /**
70          * Connects two Symbols, chooses connection type automatically.
71          * @param g
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.
77          */
78         public SymbolConnectionData connect(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2) throws DatabaseException {
79                 return connect(g, symbolConf2, componentConRel1, componentConRel2, false);
80         }
81         
82         protected Collection<Resource> getConnectionRel(ReadGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Collection<Resource> matching) throws DatabaseException {
83                 return matching;
84         }
85         
86         protected  SymbolConnectionData customConnect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connType) throws DatabaseException {
87                 return null;
88         }
89         
90         /**
91          * Connects two Symbols, chooses connection type automatically.
92          * @param g
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.
99          */
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);
106                         }
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);
111                         }
112                 }
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))
119                                 matching.add(r);
120                 }
121                 if (matching.size() > 1) {
122                         matching = getConnectionRel(g, symbolConf2, componentConRel1, componentConRel2, matching);
123                 }
124                 Resource usedConnType = null;
125                 if (matching.size() != 1) {
126                         String err;
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";
129                         } else {
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;
131                         }
132                         Logger.defaultLogInfo(err);
133                         return new ConnectionErrorImpl(err);
134                 } else {
135                         usedConnType = matching.iterator().next();
136                 }
137                 
138                 SymbolConnectionData data = customConnect(g, symbolConf2, componentConRel1, componentConRel2, usedConnType);
139                 if (data == null) {
140                         if (!forceFlag && diagram.equals(symbolConf2.diagram))
141                                 return _connect(g, symbolConf2, componentConRel1, componentConRel2,usedConnType);
142                         else
143                                 return connectWithFlag(g,  symbolConf2, componentConRel1, componentConRel2,usedConnType);
144                 } else {
145                         return data;
146                 }
147         }
148         
149         /**
150          * Connects two symbols with chosen connection type. Does not work with signal connections. 
151          * @param g
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.
158          */
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);
162                 else
163                         return connectWithFlag(g,  symbolConf2, componentConRel1, componentConRel2, connectionType);
164         }
165         
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");
168         }
169         
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);
175                 
176                 
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();
181                         
182                         return connectToExisting(g, symbolConf2, current, componentConRel1, componentConRel2, connectorType, true);
183                 }
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);
189                         
190                 }
191                 
192                 // connection object in module level
193                 Resource moduleConnection = g.newResource();
194                 g.claim(moduleConnection, b.InstanceOf, s.Connection);
195                 
196                 // connect the modules
197                 
198                 g.claim(component, componentConRel1, moduleConnection);
199                 g.claim(symbolConf2.component, componentConRel2, moduleConnection);
200                 
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);
205                 
206                 g.claim(diagramConnection, s.HasConnectionType, connectorType);
207                 
208                 // Relation from element1 to connector1
209                 Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
210                 
211                 // connector1
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);
216                 
217                 // Relation from element2 to connector2
218                 Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
219                 
220                 // connector2
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);
225                 
226                 // connect connectors
227                 g.claim(connector1, d.AreConnected, connector2);
228
229                 g.claim(moduleConnection, m.ConnectionToDiagramConnection, diagramConnection);
230                 
231                 return new ConnectorDataImpl(diagramConnection);
232         }
233         
234         
235         private SymbolConnectionData connectWithFlag(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectionType) throws DatabaseException {
236                 
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);
242                 
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);
247                 }
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);
252                 }
253         
254                 double t = 20.0;
255                 double[] t1 =  getSymbolTranslation(g);
256                 double[] t2 =  symbolConf2.getSymbolTranslation(g);
257                 
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]);
260                 
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);
265                 
266                 Resource connection1 = g.newResource();
267                 g.claim(connection1, l0.InstanceOf, s.Connection);
268                 
269                 Resource connection2 = g.newResource();
270                 g.claim(connection2, l0.InstanceOf, s.Connection);
271                 
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);
276                 
277                 g.claim(flag1.element, d.FlagIsJoinedBy, connectionJoin);
278                 g.claim(flag2.element, d.FlagIsJoinedBy, connectionJoin);
279                 
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);
284
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);
289                 
290                 g.claim(connection1, m.ConnectionToDiagramConnection, diagConnection1);
291                 g.claim(connection2, m.ConnectionToDiagramConnection, diagConnection2);
292                 
293                 // Relation from element1 to connector1
294                 Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
295                 
296                 // connector1
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);
301                 
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);
306                 
307                 g.claim(connector1_1, d.AreConnected, connector1_2);
308                 
309                 // Relation from element2 to connector2
310                 Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
311                 
312                 // connector1
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);
317                 
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);
322                 
323                 g.claim(connector2_1, d.AreConnected, connector2_2);
324                 
325                 return new FlagConnectionDataImpl(flag1, flag2, diagConnection1, diagConnection2);
326         }
327         
328         /**
329          * Returns diagram connection relation for an element and its component connection relation
330          * @param g
331          * @param element
332          * @param componentConnRel
333          * @return
334          * @throws ServiceException
335          * @throws NoSingleResultException
336          * @throws ValidationException 
337          */
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))
347                                         matching.add(r);
348                         }
349                         if (matching.size() == 1)
350                                 return matching.get(0);
351                 }
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))
362                                 return rel;
363                 }
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 );
365         }
366         
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);
370         }
371         
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);
378 //              }
379 //              
380 //              Resource compType = g.getSingleObject(conf.getComponent(), b.InstanceOf);
381 //              
382 //              for (Resource rel : StructuralUtils.getConnectionRelations(g, compType))
383 //                  if (g.isSubrelationOf(rel, genericRel))
384 //                      return rel;
385 //              return null;
386 //      }
387         
388         /**
389          * Returns symbol where given symbol is connected using given relation. Returns null if the symbol is not connected using the relation.
390          * @param g
391          * @param componentConRel
392          * @return
393          * @throws DatabaseException 
394          */
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();
401                 return null;
402         }
403         
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();
410                 return null;
411         }
412         
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) {
421                 
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>();
425                         
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());
430                                         }
431                                 }
432                         }
433                         
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());
442                                                 }
443                                         }
444                                 }
445                         }
446                         for (Resource connectedComponent : connectedComponents) {
447                         
448                                 Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
449                                 
450                                 Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
451                                 result.add(diag.getSymbol(g, pointElem,connectedComponent));
452                         }
453                         
454                 }
455                 return result;  
456         }
457         
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);
463                 
464                 Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
465                 Collection<Symbol> result = new ArrayList<Symbol>();
466                 for (Resource modConn1 : modConn1s) {
467                 
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>();
471                         
472                         for (Resource r : connected) {
473                                 if (!r.equals(this.component)) {
474                                         connectedComponents.add(r);
475                                 }
476                         }
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);
484                                         }
485                                 }
486                         }
487                         for (Resource connectedComponent : connectedComponents) {
488                         
489                                 Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
490                                 
491                                 Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
492                                 result.add(diag.getSymbol(g, pointElem,connectedComponent));
493                         }
494                 }
495                 return result;
496                 
497         }
498         
499         /**
500          * Returns connected symbols on diagram level. Searches through branchpoints.
501          * @param g
502          * @param diagramConnRel
503          * @param otherConnRel
504          * @return
505          * @throws DatabaseException
506          */
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);
517                         } else {
518                                 throw new DatabaseException("Connector " + g.getPossibleURI(otherConnector) + " " + otherConnector + " han unknown type");
519                         }
520                 }
521                 return result;
522         }
523         
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)) {
531                                 stm = s;
532                         }
533                 }
534                 if (stm == null)
535                         return;
536                 if (otherConnRel != null) {
537                         Resource rel = g.getInverse(stm.getPredicate());
538                         if (!rel.equals(otherConnRel))
539                                 return;
540                 }
541                 Resource element = stm.getObject();
542                 result.add(diagram.getSymbol(g, element));
543         }
544         
545         private void getBranchPointConnectors(ReadGraph g, Resource origin, Resource branchPoint, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException {
546                 DiagramResource dr = DiagramResource.getInstance(g);
547                 
548                 Collection<Resource> branchConnected = g.getObjects(branchPoint, dr.AreConnected);
549                 for (Resource branchConnector : branchConnected) {
550                         if (branchConnector.equals(origin))
551                                 continue;
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);
556                         } else {
557                                 throw new DatabaseException("Connector " + g.getPossibleURI(branchConnector) + " " + branchConnector + " han unknown type");
558                         }
559                 }
560         }
561
562         public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
563                 return getDiagramConnected(g, diagramConnRel,null);
564         }
565         
566         public Collection<Symbol> getDiagramInverseConnected(ReadGraph g,  Resource otherConnRel) throws DatabaseException {
567                 StructuralResource2 sr = StructuralResource2.getInstance(g);
568                 return getDiagramConnected(g, sr.IsConnectedTo, otherConnRel);
569                 
570         }
571         
572         public Collection<Symbol> getDiagramConnected(ReadGraph g) throws DatabaseException {
573                 StructuralResource2 sr = StructuralResource2.getInstance(g);
574                 return getDiagramConnected(g, sr.IsConnectedTo, null);
575         }
576         
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();
583                 }
584                 return null;
585         }
586         
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)
591                         return null;
592                 Collection<Resource> flags = g.getObjects(connectionJoin, dr.JoinsFlag);
593                 Resource otherFlag = null;
594                 for (Resource f : flags) {
595                         if (!f.equals(element)) {
596                                 otherFlag = f;
597                                 break;
598                         }
599                 }
600                 
601                 if (otherFlag == null) {
602                         return null;
603                 }
604                 Resource otherDiagramR = OrderedSetUtils.getSingleOwnerList(g, otherFlag);
605                 Diagram otherDiagram = diagram.fromExisting(g, otherDiagramR);
606                 return otherDiagram.getSymbol(g, otherFlag, null);
607                 
608         }
609
610         /**
611          * Returns concatenated translation of the symbol.
612          * @param g
613          * @return
614          * @throws DatabaseException
615          */
616         public double[] getSymbolTranslation(ReadGraph g) throws DatabaseException {
617                 DiagramResource d = DiagramResource.getInstance(g);
618                 ModelingResources mr = ModelingResources.getInstance(g);
619                 
620                 Resource e = element;
621                 AffineTransform at = new AffineTransform();
622                 while (e != null) {
623                         double transform[] = g.getPossibleRelatedValue(e, d.HasTransform);
624                         if (transform == null)
625                                 break;
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);
631                         } else {
632                                 e = null;
633                         }
634                 }
635
636                 return new double[]{at.getTranslateX(),at.getTranslateY()};
637         }
638         
639         /**
640          * Returns transformation of the symbol.
641          * @param g
642          * @return
643          * @throws DatabaseException
644          */
645         public double[] getSymbolTransformation(ReadGraph g) throws DatabaseException{
646                 DiagramResource d = DiagramResource.getInstance(g);
647                 double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
648                 return transform;
649         }
650         
651         /**
652          * Sets translation of symbol. The scale is set to 1.0.
653          * @param g
654          * @param x
655          * @param y
656          * @throws DatabaseException
657          */
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});
662         }
663         
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];
668                 at.getMatrix(arr);
669                 g.claimLiteral(element, d.HasTransform, g2d.Transform, arr);
670         }
671         
672         /**
673          * Set the scale of symbol.
674          * @param g
675          * @param scale
676          * @throws DatabaseException
677          */
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]});
682         }
683         
684         @Override
685         public boolean equals(Object o) {
686                 if (o == null)
687                         return false;
688                 if (this.getClass() != o.getClass())
689                         return false;
690                 Symbol other = (Symbol)o;
691                 return element.equals(other.element);
692         }
693         
694         @Override
695         public int hashCode() {
696                 return element.hashCode();
697         }
698         
699         
700         
701         /**
702          * Returns component type from symbol type
703          * @param g
704          * @param symbolType
705          * @return
706          * @throws NoSingleResultException
707          * @throws ManyObjectsForFunctionalRelationException
708          * @throws ServiceException
709          */
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);
713                 return component;
714         }
715         
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)
720                         return null;
721                 return symbols.iterator().next();
722         }
723         
724         public void dispose() {
725                 diagram = null;
726                 component = null;
727                 element = null;
728         }
729
730         /**
731          * Common interface for Symbol.connect return value.
732          *
733          */
734         public interface SymbolConnectionData {
735                 
736         }
737         
738         /**
739          * Interface for returning diagram level connectors.
740          *
741          */
742         public interface DiagramConnectionData extends SymbolConnectionData {
743                 public int getConnectionCount();
744                 public Resource getConnection(int index);
745         }
746         
747         /**
748          * Interface for flag connections. 
749          *
750          */
751         public interface FlagConnectionData extends SymbolConnectionData {
752                 public Symbol getFirstFlag();
753                 public Symbol getSecondFlag();
754         }
755         
756         
757         /**
758          * Interface for signal connections. 
759          *
760          */
761         public interface SignalConnectionData extends SymbolConnectionData {
762                 public Resource getSignalComponent();
763         }
764         
765         /**
766          * Interface for Point connections. 
767          *
768          */
769         public interface PointConnectionData extends SymbolConnectionData {
770                 Symbol getPoint();
771         }
772         
773         /**
774          * Interface for "connection" that merged the connected symbols into one symbol. 
775          *
776          */
777         public interface MergeSymbolData extends SymbolConnectionData {
778                 Symbol getResultSymbol();
779         }
780         
781         /**
782          * Return value for a connection that already exists. 
783          *
784          */
785         public interface SymbolExists extends SymbolConnectionData {
786                 
787         }
788         
789         /**
790          * Return value for an error. 
791          *
792          */
793         public interface ConnectionError extends SymbolConnectionData {
794                 String getReason();
795         }
796         
797         private static class ConnectionErrorImpl implements ConnectionError {
798                 private String error;
799                 
800                 public ConnectionErrorImpl(String error) {
801                         this.error = error;
802                 }
803                 
804                 @Override
805                 public String getReason() {
806                         return error;
807                 }
808         }
809         
810         private static class SymbolExistsImpl implements SymbolExists {
811                 
812         }
813         
814         private static class ConnectorDataImpl implements DiagramConnectionData {
815                 
816                 private Resource[] connectors;
817                 
818                 public ConnectorDataImpl(Resource... connectors) {
819                         this.connectors = connectors;
820                 }
821                 
822                 @Override
823                 public Resource getConnection(int index) {
824                         return connectors[index];
825                 }
826                 
827                 @Override
828                 public int getConnectionCount() {
829                         return connectors.length;
830                 }
831         }
832         
833         private static class PointConnectionDataImpl implements PointConnectionData {
834                 
835                 private Symbol point;
836                 
837                 public PointConnectionDataImpl(Symbol point) {
838                         this.point = point;
839                 }
840                 
841                 @Override
842                 public Symbol getPoint() {
843                         return point;
844                 }
845         }
846         
847         private static class SignalConnectionDataImpl implements SignalConnectionData, DiagramConnectionData{
848                 
849                 private Resource signalComponent;
850                 private Resource[] connectors;
851                 
852                 public SignalConnectionDataImpl(Resource signalComponent, Resource... connectors) {
853                         this.signalComponent = signalComponent;
854                         this.connectors = connectors;
855                 }
856                 
857                 @Override
858                 public Resource getSignalComponent() {
859                         return signalComponent;
860                 }
861                 
862                 @Override
863                 public Resource getConnection(int index) {
864                         return connectors[index];
865                 }
866                 
867                 @Override
868                 public int getConnectionCount() {
869                         return connectors.length;
870                 }
871                 
872         }
873         
874         private static class FlagConnectionDataImpl implements FlagConnectionData, DiagramConnectionData {
875                 
876                 private Symbol firstFlag;
877                 private Symbol secondFlag;
878                 private Resource[] connectors;
879                 
880                 public FlagConnectionDataImpl(Symbol firstFlag, Symbol secondFlag, Resource... connectors) {
881                         this.firstFlag = firstFlag;
882                         this.secondFlag = secondFlag;
883                         this.connectors = connectors;
884                 }
885                 
886                 @Override
887                 public Symbol getFirstFlag() {
888                         return firstFlag;
889                 }
890                 
891                 @Override
892                 public Symbol getSecondFlag() {
893                         return secondFlag;
894                 }
895                 
896                 @Override
897                 public Resource getConnection(int index) {
898                         return connectors[index];
899                 }
900                 
901                 @Override
902                 public int getConnectionCount() {
903                         return connectors.length;
904                 }
905         }
906
907         public void setComponentValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
908                 setValue(graph, component, property, value);
909         }
910         
911         public void setComponentValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
912                 setValue(graph, component, property, value);
913         }
914         
915         public void setComponentValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
916                 setValue(graph, component, property, value);
917         }
918         
919         public void setComponentValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
920                 setValue(graph, component, property, value);
921         }
922         
923         public void setComponentValue(WriteGraph graph, Resource property, String value) throws DatabaseException{
924                 setValue(graph, component, property, value);
925         }
926         
927         public void setComponentValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
928                 setValue(graph, component, property, value);
929         }
930         
931         public void setComponentValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
932                 setValue(graph, component, property, value);
933         }
934         
935         public void setComponentValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
936                 setValue(graph, component, property, value);
937         }
938         
939         public void setComponentValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
940                 setValue(graph, component, property, value);
941         }
942         
943         public void setElementValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
944                 setValue(graph, element, property, value);
945         }
946         
947         public void setElementValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
948                 setValue(graph, element, property, value);
949         }
950         
951         public void setElementValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
952                 setValue(graph, element, property, value);
953         }
954         
955         public void setElementValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
956                 setValue(graph, element, property, value);
957         }
958         
959         public void setElementValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
960                 setValue(graph, element, property, value);
961         }
962         
963         public void setElementValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
964                 setValue(graph, element, property, value);
965         }
966         
967         public void setElementValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
968                 setValue(graph, element, property, value);
969         }
970         
971         public void setElementValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
972                 setValue(graph, element, property, value);
973         }
974         
975         /**
976          * Sets literal value. Does data conversion if required.
977          * 
978          * Note: This method support only some basic L0 data types.
979          * 
980          * @param graph
981          * @param object
982          * @param property
983          * @param value
984          * @throws DatabaseException
985          */
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);
1001                 } else {
1002                         graph.claimLiteral(object, property, value, Bindings.DOUBLE);
1003                 }
1004         }
1005
1006         /**
1007          * Sets literal value. Does data conversion if required.
1008          * 
1009          * Note: This method support only some basic L0 data types.
1010          * 
1011          * @param graph
1012          * @param object
1013          * @param property
1014          * @param value
1015          * @throws DatabaseException
1016          */
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);
1032                 } else {
1033                         graph.claimLiteral(object, property, value, Bindings.FLOAT);
1034                 }
1035         }
1036         
1037         /**
1038          * Sets literal value. Does data conversion if required.
1039          * 
1040          * Note: This method support only some basic L0 data types.
1041          * 
1042          * @param graph
1043          * @param object
1044          * @param property
1045          * @param value
1046          * @throws DatabaseException
1047          */
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);
1063                 } else {
1064                         graph.claimLiteral(object, property, value, Bindings.INTEGER);
1065                 }
1066         }
1067         
1068         /**
1069          * Sets literal value. Does data conversion if required.
1070          * 
1071          * @param graph
1072          * @param object
1073          * @param property
1074          * @param value
1075          * @throws DatabaseException
1076          */
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);
1082                 } else {
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);
1095                         } else {
1096                                 graph.claimLiteral(object, property, value, Bindings.STRING);
1097                         } 
1098                 }
1099         }
1100
1101         /**
1102          * Sets literal value. Does data conversion if required.
1103          * 
1104          * Note: This method support only some basic L0 data types.
1105          * 
1106          * @param graph
1107          * @param object
1108          * @param property
1109          * @param value
1110          * @throws DatabaseException
1111          */
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);
1121                 } else {
1122                         graph.claimLiteral(object, property, value, Bindings.BOOLEAN);
1123                 }
1124         }
1125         
1126         /**
1127          * Sets literal value. Does data conversion if required.
1128          * 
1129          * Note: This method support only some basic L0 data types.
1130          * 
1131          * @param graph
1132          * @param object
1133          * @param property
1134          * @param value
1135          * @throws DatabaseException
1136          */
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);
1152                 } else {
1153                         graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
1154                 }
1155         }
1156         
1157         /**
1158          * Sets literal value. Does data conversion if required.
1159          * 
1160          * Note: This method support only some basic L0 data types.
1161          * 
1162          * @param graph
1163          * @param object
1164          * @param property
1165          * @param value
1166          * @throws DatabaseException
1167          */
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);
1183                 } else {
1184                         graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
1185                 }
1186         }
1187         
1188         /**
1189          * Sets literal value. Does data conversion if required.
1190          * 
1191          * Note: This method support only some basic L0 data types.
1192          * 
1193          * @param graph
1194          * @param object
1195          * @param property
1196          * @param value
1197          * @throws DatabaseException
1198          */
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);
1214                 } else {
1215                         graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
1216                 }
1217         }
1218         
1219         /**
1220          * Sets literal value. Does data conversion if required.
1221          * 
1222          * Note: This method support only some basic L0 data types.
1223          * 
1224          * @param graph
1225          * @param object
1226          * @param property
1227          * @param value
1228          * @throws DatabaseException
1229          */
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);
1240                 } else {
1241                         graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);
1242                 }
1243         }
1244         
1245 }