]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - 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
diff --git a/org.simantics.interop.diagram/src/org/simantics/interop/diagram/Symbol.java b/org.simantics.interop.diagram/src/org/simantics/interop/diagram/Symbol.java
new file mode 100644 (file)
index 0000000..22160aa
--- /dev/null
@@ -0,0 +1,1245 @@
+package org.simantics.interop.diagram;
+
+import java.awt.geom.AffineTransform;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Statement;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.common.utils.OrderedSetUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
+import org.simantics.db.exception.NoSingleResultException;
+import org.simantics.db.exception.ServiceException;
+import org.simantics.db.exception.ValidationException;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.stubs.G2DResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.structural2.utils.StructuralUtils;
+
+
+
+/**
+ * @author Marko Luukkainen
+ */
+public abstract class Symbol {
+       
+       private static boolean USE_UNRELIABLE_CONNECT = false;
+       private static boolean PREVENT_SELF_CONNECTIONS = false;
+       
+       private Diagram diagram;
+       Resource element;
+       Resource component;
+       
+       /**
+        * Use Diagram.getSymbol() to get Symbols.
+        * @param diagram
+        * @param element
+        * @param component
+        */
+       public Symbol(Diagram diagram, Resource element, Resource component) {
+               assert(diagram != null);
+               assert(element != null);
+               this.diagram = diagram;
+               this.element = element;
+               this.component = component;
+       }
+       
+       public Diagram getDiagram() {
+               return diagram;
+       }
+       
+       public Resource getComponent() {
+               return component;
+       }
+       
+       public Resource getElement() {
+               return element;
+       }
+       
+       /**
+        * Connects two Symbols, chooses connection type automatically.
+        * @param g
+        * @param symbolConf2 other symbol.
+        * @param componentConRel1 symbol's terminal relation.
+        * @param componentConRel2 other symbol's terminal relation.
+        * @return SymbolConnetionData instance describing the connection. Return value is never null.
+        * @throws DatabaseException on database failure.
+        */
+       public SymbolConnectionData connect(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2) throws DatabaseException {
+               return connect(g, symbolConf2, componentConRel1, componentConRel2, false);
+       }
+       
+       protected Collection<Resource> getConnectionRel(ReadGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Collection<Resource> matching) throws DatabaseException {
+               return matching;
+       }
+       
+       protected  SymbolConnectionData customConnect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connType) throws DatabaseException {
+               return null;
+       }
+       
+       /**
+        * Connects two Symbols, chooses connection type automatically.
+        * @param g
+        * @param symbolConf2 other symbol.
+        * @param componentConRel1 symbol's terminal relation.
+        * @param componentConRel2 other symbol's terminal relation.
+        * @param forceFlag creates flag connection even if symbols are on the same diagram.
+        * @return SymbolConnetionData instance describing the connection. Return value is never null.
+        * @throws DatabaseException on database failure.
+        */
+       public SymbolConnectionData connect(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, boolean forceFlag) throws DatabaseException {
+               if (this.equals(symbolConf2)) {
+                       if (PREVENT_SELF_CONNECTIONS) {
+                               String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(componentConRel1) + " "+ componentConRel1 + " " + g.getPossibleURI(componentConRel2) + " "+ componentConRel2;
+                               Logger.defaultLogError(err);
+                               return new ConnectionErrorImpl(err);
+                       }
+                       if (componentConRel1.equals(componentConRel2)) {
+                               String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(componentConRel1) + " "+ componentConRel1 + " " + g.getPossibleURI(componentConRel2) + " "+ componentConRel2;
+                               Logger.defaultLogError(err);
+                               return new ConnectionErrorImpl(err);
+                       }
+               }
+               StructuralResource2 sr = StructuralResource2.getInstance(g);
+               Collection<Resource> connType1 = g.getObjects(componentConRel1, sr.AllowsConnectionType);
+               Collection<Resource> connType2 = g.getObjects(componentConRel2, sr.AllowsConnectionType);
+               Collection<Resource> matching = new HashSet<Resource>();
+               for (Resource r : connType2) {
+                       if (connType1.contains(r))
+                               matching.add(r);
+               }
+               if (matching.size() > 1) {
+                       matching = getConnectionRel(g, symbolConf2, componentConRel1, componentConRel2, matching);
+               }
+               Resource usedConnType = null;
+               if (matching.size() != 1) {
+                       String err;
+                       if (USE_UNRELIABLE_CONNECT) {
+                               err = "Unreliable connect " + component + " " + NameUtils.getSafeName(g, component) + " to " + symbolConf2.component + " " + NameUtils.getSafeName(g, symbolConf2.component) + " cannot find proper connection type, using Name Reference";
+                       } else {
+                               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;
+                       }
+                       Logger.defaultLogInfo(err);
+                       return new ConnectionErrorImpl(err);
+               } else {
+                       usedConnType = matching.iterator().next();
+               }
+               
+               SymbolConnectionData data = customConnect(g, symbolConf2, componentConRel1, componentConRel2, usedConnType);
+               if (data == null) {
+                       if (!forceFlag && diagram.equals(symbolConf2.diagram))
+                               return _connect(g, symbolConf2, componentConRel1, componentConRel2,usedConnType);
+                       else
+                               return connectWithFlag(g,  symbolConf2, componentConRel1, componentConRel2,usedConnType);
+               } else {
+                       return data;
+               }
+       }
+       
+       /**
+        * Connects two symbols with chosen connection type. Does not work with signal connections. 
+        * @param g
+        * @param symbolConf2 other symbol.
+        * @param componentConRel1 symbol's terminal relation.
+        * @param componentConRel2 other symbol's terminal relation.
+        * @param connectionType used connection type.
+        * @return SymbolConnetionData instance describing the connection. Return value is never null.
+        * @throws DatabaseException on database failure.
+        */
+       public SymbolConnectionData connect(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectionType) throws DatabaseException {
+               if (diagram.equals(symbolConf2.diagram))
+                       return _connect(g, symbolConf2, componentConRel1, componentConRel2, connectionType);
+               else
+                       return connectWithFlag(g,  symbolConf2, componentConRel1, componentConRel2, connectionType);
+       }
+       
+       protected SymbolConnectionData connectToExisting(WriteGraph g, Symbol symbolConf2, Symbol current, Resource componentConRel1, Resource componentConRel2, Resource connectorType, boolean firstSame) throws DatabaseException {
+               return new ConnectionErrorImpl("Symbol is already connected");
+       }
+       
+       private SymbolConnectionData _connect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectorType) throws DatabaseException {
+               Layer0 b = Layer0.getInstance(g);
+               StructuralResource2 s = StructuralResource2.getInstance(g);
+               DiagramResource d = DiagramResource.getInstance(g);
+               ModelingResources m = ModelingResources.getInstance(g);
+               
+               
+               if (g.isInstanceOf(componentConRel1, b.FunctionalRelation) && getSingleConnected(g, componentConRel1) != null) {
+                       Symbol current = getSingleConnected(g, componentConRel1);
+                       if (current.component.equals(symbolConf2.component))
+                               return new SymbolExistsImpl();
+                       
+                       return connectToExisting(g, symbolConf2, current, componentConRel1, componentConRel2, connectorType, true);
+               }
+               if (g.isInstanceOf(componentConRel2, b.FunctionalRelation) && symbolConf2.getSingleConnected(g, componentConRel2) != null) {
+                       Symbol current = symbolConf2.getSingleConnected(g, componentConRel2);
+                       if (current.component.equals(component))
+                               return new SymbolExistsImpl();
+                       return connectToExisting(g, symbolConf2, current, componentConRel1, componentConRel2, connectorType, false);
+                       
+               }
+               
+               // connection object in module level
+               Resource moduleConnection = g.newResource();
+               g.claim(moduleConnection, b.InstanceOf, s.Connection);
+               
+               // connect the modules
+               
+               g.claim(component, componentConRel1, moduleConnection);
+               g.claim(symbolConf2.component, componentConRel2, moduleConnection);
+               
+               // connection object in diagram level
+               Resource diagramConnection = g.newResource();
+               g.claim(diagramConnection, b.InstanceOf, d.RouteGraphConnection);
+               DiagramUtils.addElementFirst(g, diagram, diagramConnection);
+               
+               g.claim(diagramConnection, s.HasConnectionType, connectorType);
+               
+               // Relation from element1 to connector1
+               Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
+               
+               // connector1
+               Resource connector1 = g.newResource();
+               g.claim(connector1, b.InstanceOf, d.Connector);
+               g.claim(element, isConnected1, connector1);
+               g.claim(diagramConnection, d.HasPlainConnector, connector1);
+               
+               // Relation from element2 to connector2
+               Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
+               
+               // connector2
+               Resource connector2 = g.newResource();
+               g.claim(connector2, b.InstanceOf, d.Connector);
+               g.claim(symbolConf2.element, isConnected2, connector2);
+               g.claim(diagramConnection, d.HasArrowConnector, connector2);
+               
+               // connect connectors
+               g.claim(connector1, d.AreConnected, connector2);
+
+               g.claim(moduleConnection, m.ConnectionToDiagramConnection, diagramConnection);
+               
+               return new ConnectorDataImpl(diagramConnection);
+       }
+       
+       
+       private SymbolConnectionData connectWithFlag(WriteGraph g,  Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connectionType) throws DatabaseException {
+               
+               Diagram diagram2 = symbolConf2.diagram;
+               Layer0 l0 = Layer0.getInstance(g);
+               StructuralResource2 s = StructuralResource2.getInstance(g);
+               DiagramResource d = DiagramResource.getInstance(g);
+               ModelingResources m = ModelingResources.getInstance(g);
+               
+               if (g.isInstanceOf(componentConRel1, l0.FunctionalRelation) && getSingleConnected(g, componentConRel1) != null) {
+                       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";
+                       Logger.defaultLogError(err);
+                       return new ConnectionErrorImpl(err);
+               }
+               if (g.isInstanceOf(componentConRel2, l0.FunctionalRelation) && symbolConf2.getSingleConnected(g, componentConRel2) != null) {
+                       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";
+                       Logger.defaultLogError(err);
+                       return new ConnectionErrorImpl(err);
+               }
+       
+               double t = 20.0;
+               double[] t1 =  getSymbolTranslation(g);
+               double[] t2 =  symbolConf2.getSymbolTranslation(g);
+               
+               Symbol flag1 = diagram.addElement(g, d.Flag, t1[0]+t, t1[1]);
+               Symbol flag2 = diagram2.addElement(g, d.Flag, t2[0]-t, t2[1]);
+               
+               Resource connectionJoin = g.newResource();
+               g.claim(connectionJoin, l0.InstanceOf, s.ConnectionJoin);
+               g.claim(diagram.getComposite(), s.HasConnectionJoin, connectionJoin);
+               g.claim(diagram2.getComposite(), s.HasConnectionJoin, connectionJoin);
+               
+               Resource connection1 = g.newResource();
+               g.claim(connection1, l0.InstanceOf, s.Connection);
+               
+               Resource connection2 = g.newResource();
+               g.claim(connection2, l0.InstanceOf, s.Connection);
+               
+               g.claim(component, componentConRel1, connection1);
+               g.claim(symbolConf2.component, componentConRel2, connection2);
+               g.claim(connection1, s.IsJoinedBy, connectionJoin);
+               g.claim(connection2, s.IsJoinedBy, connectionJoin);
+               
+               g.claim(flag1.element, d.FlagIsJoinedBy, connectionJoin);
+               g.claim(flag2.element, d.FlagIsJoinedBy, connectionJoin);
+               
+               Resource diagConnection1 = g.newResource();
+               g.claim(diagConnection1, l0.InstanceOf, d.RouteGraphConnection);
+               DiagramUtils.addElementFirst(g, diagram, diagConnection1);
+               g.claim(diagConnection1, s.HasConnectionType, connectionType);
+
+               Resource diagConnection2 = g.newResource();
+               g.claim(diagConnection2, l0.InstanceOf, d.RouteGraphConnection);
+               DiagramUtils.addElementFirst(g, diagram2, diagConnection2);
+               g.claim(diagConnection2, s.HasConnectionType, connectionType);
+               
+               g.claim(connection1, m.ConnectionToDiagramConnection, diagConnection1);
+               g.claim(connection2, m.ConnectionToDiagramConnection, diagConnection2);
+               
+               // Relation from element1 to connector1
+               Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
+               
+               // connector1
+               Resource connector1_1 = g.newResource();
+               g.claim(connector1_1, l0.InstanceOf, d.Connector);
+               g.claim(element, isConnected1, connector1_1);
+               g.claim(diagConnection1, d.HasPlainConnector, connector1_1);
+               
+               Resource connector1_2 = g.newResource();
+               g.claim(connector1_2, l0.InstanceOf, d.Connector);
+               g.claim(flag1.element, d.Flag_ConnectionPoint, connector1_2);
+               g.claim(diagConnection1, d.HasArrowConnector, connector1_2);
+               
+               g.claim(connector1_1, d.AreConnected, connector1_2);
+               
+               // Relation from element2 to connector2
+               Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
+               
+               // connector1
+               Resource connector2_1 = g.newResource();
+               g.claim(connector2_1, l0.InstanceOf, d.Connector);
+               g.claim(flag2.element, d.Flag_ConnectionPoint, connector2_1);
+               g.claim(diagConnection2, d.HasPlainConnector, connector2_1);
+               
+               Resource connector2_2 = g.newResource();
+               g.claim(connector2_2, l0.InstanceOf, d.Connector);
+               g.claim(symbolConf2.element, isConnected2, connector2_2);
+               g.claim(diagConnection2, d.HasArrowConnector, connector2_2);
+               
+               g.claim(connector2_1, d.AreConnected, connector2_2);
+               
+               return new FlagConnectionDataImpl(flag1, flag2, diagConnection1, diagConnection2);
+       }
+       
+       /**
+        * Returns diagram connection relation for an element and its component connection relation
+        * @param g
+        * @param element
+        * @param componentConnRel
+        * @return
+        * @throws ServiceException
+        * @throws NoSingleResultException
+        * @throws ValidationException 
+        */
+       public static Resource getDiagramConnectionRelation(ReadGraph g, Resource element, Resource componentConnRel) throws DatabaseException {
+               ModelingResources m = ModelingResources.getInstance(g);
+               Collection<Resource> diagramConnectionRels = g.getObjects(componentConnRel, m.ConnectionRelationToDiagramConnectionRelation);
+               if (diagramConnectionRels.size() == 1)
+                       return diagramConnectionRels.iterator().next();
+               if (diagramConnectionRels.size() > 1) {
+                       List<Resource> matching = new ArrayList<Resource>();
+                       for (Resource r : diagramConnectionRels) {
+                               if (g.hasStatement(element, r))
+                                       matching.add(r);
+                       }
+                       if (matching.size() == 1)
+                               return matching.get(0);
+               }
+               Layer0 b = Layer0.getInstance(g);
+               Collection<Resource> elementTypes = g.getObjects(element, b.InstanceOf);
+               if (elementTypes.size() != 1)
+                       throw new RuntimeException("Cannot handle multi-instances " + element + " " + NameUtils.getSafeName(g, element));
+               Resource elementType = elementTypes.iterator().next();
+               Collection<Resource> rels = StructuralUtils.getConnectionRelations(g, elementType);
+               if (rels.size() == 1)
+                       return rels.iterator().next();
+               for (Resource rel : rels) {
+                       if (diagramConnectionRels.contains(rel))
+                               return rel;
+               }
+               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 );
+       }
+       
+       public static Resource getComponentConnectionRelation(ReadGraph g, Resource diagraromConnRel) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
+               ModelingResources mr = ModelingResources.getInstance(g);
+               return g.getSingleObject(diagraromConnRel, mr.DiagramConnectionRelationToConnectionRelation);
+       }
+       
+//     public static Resource getSymbolRelation(ReadGraph g, Symbol conf, Resource genericRel) throws DatabaseException {
+//             Layer0 b = Layer0.getInstance(g);
+//             if (g.isInstanceOf(conf.element, ab.CalculationLevelReferenceElement)) {
+//                     ModelingResources m = ModelingResources.getInstance(g);
+//                     //return g.getInverse(g.getSingleObject(conf.element, m.HasReferenceRelation));
+//                     return g.getSingleObject(conf.element, m.HasReferenceRelation);
+//             }
+//             
+//             Resource compType = g.getSingleObject(conf.getComponent(), b.InstanceOf);
+//             
+//             for (Resource rel : StructuralUtils.getConnectionRelations(g, compType))
+//                 if (g.isSubrelationOf(rel, genericRel))
+//                     return rel;
+//             return null;
+//     }
+       
+       /**
+        * Returns symbol where given symbol is connected using given relation. Returns null if the symbol is not connected using the relation.
+        * @param g
+        * @param componentConRel
+        * @return
+        * @throws DatabaseException 
+        */
+       public Symbol getSingleConnected(ReadGraph g, Resource componentConRel) throws DatabaseException {
+               Collection<Symbol> symbols = getConnected(g, componentConRel);
+               if (symbols.size() > 1)
+                       throw new NoSingleResultException("Symbol " + component + " is connected more than once using relation " + componentConRel);
+               if (symbols.size() == 1)
+                       return symbols.iterator().next();
+               return null;
+       }
+       
+       public Symbol getSingleConnected(ReadGraph g, Resource componentConRel, Resource otherComponentConRel) throws DatabaseException {
+               Collection<Symbol> symbols = getConnected(g, componentConRel, otherComponentConRel);
+               if (symbols.size() > 1)
+                       throw new NoSingleResultException("Symbol " + component + " is connected more than once using relation " + componentConRel);
+               if (symbols.size() == 1)
+                       return symbols.iterator().next();
+               return null;
+       }
+       
+       public Collection<Symbol> getConnected(ReadGraph g, Resource componentConRel, Resource otherComponentConRel) throws DatabaseException {
+               assert(componentConRel != null);
+               Layer0 l0 = Layer0.getInstance(g);
+               StructuralResource2 sr = StructuralResource2.getInstance(g);
+               ModelingResources mr = ModelingResources.getInstance(g);
+               Collection<Symbol> result = new ArrayList<Symbol>();
+               Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
+               for (Resource modConn1 : modConn1s) {
+               
+                       Collection<Statement> connected = g.getStatements(modConn1, sr.Connects);
+                       Collection<Resource> connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy);
+                       Collection<Resource> connectedComponents = new ArrayList<Resource>();
+                       
+                       for (Statement stm : connected) {
+                               if (!stm.getObject().equals(this.component)) {
+                                       if (g.getInverse(stm.getPredicate()).equals(otherComponentConRel)) {
+                                               connectedComponents.add(stm.getObject());
+                                       }
+                               }
+                       }
+                       
+                       for (Resource connectionJoin : connectionJoins) {
+                               Collection<Resource> joinedConns = g.getObjects(connectionJoin, sr.Joins);
+                               for (Resource conn : joinedConns) {
+                                       if (!conn.equals(modConn1)) {
+                                               // TODO : check ConnectionJoins?
+                                               for (Statement stm : g.getStatements(conn, sr.Connects)) {
+                                                       if (g.getInverse(stm.getPredicate()).equals(otherComponentConRel))
+                                                               connectedComponents.add(stm.getObject());
+                                               }
+                                       }
+                               }
+                       }
+                       for (Resource connectedComponent : connectedComponents) {
+                       
+                               Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
+                               
+                               Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
+                               result.add(diag.getSymbol(g, pointElem,connectedComponent));
+                       }
+                       
+               }
+               return result;  
+       }
+       
+       public Collection<Symbol> getConnected(ReadGraph g, Resource componentConRel) throws DatabaseException {
+               assert(componentConRel != null);
+               Layer0 l0 = Layer0.getInstance(g);
+               StructuralResource2 sr = StructuralResource2.getInstance(g);
+               ModelingResources mr = ModelingResources.getInstance(g);
+               
+               Collection<Resource> modConn1s = g.getObjects(this.component, componentConRel);
+               Collection<Symbol> result = new ArrayList<Symbol>();
+               for (Resource modConn1 : modConn1s) {
+               
+                       Collection<Resource> connected = g.getObjects(modConn1, sr.Connects);
+                       Collection<Resource> connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy);
+                       Collection<Resource> connectedComponents = new ArrayList<Resource>();
+                       
+                       for (Resource r : connected) {
+                               if (!r.equals(this.component)) {
+                                       connectedComponents.add(r);
+                               }
+                       }
+                       for (Resource connectionJoin : connectionJoins) {
+                               Collection<Resource> joinedConns = g.getObjects(connectionJoin, sr.Joins);
+                               for (Resource conn : joinedConns) {
+                                       if (!conn.equals(modConn1)) {
+                                               // TODO : check ConnectionJoins?
+                                               for (Resource obj : g.getObjects(conn, sr.Connects))
+                                                       connectedComponents.add(obj);
+                                       }
+                               }
+                       }
+                       for (Resource connectedComponent : connectedComponents) {
+                       
+                               Resource pointElem = g.getSingleObject(connectedComponent, mr.ComponentToElement);
+                               
+                               Diagram diag = diagram.fromExisting(g, g.getSingleObject(connectedComponent, l0.PartOf));
+                               result.add(diag.getSymbol(g, pointElem,connectedComponent));
+                       }
+               }
+               return result;
+               
+       }
+       
+       /**
+        * Returns connected symbols on diagram level. Searches through branchpoints.
+        * @param g
+        * @param diagramConnRel
+        * @param otherConnRel
+        * @return
+        * @throws DatabaseException
+        */
+       public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel, Resource otherConnRel) throws DatabaseException {
+               DiagramResource dr = DiagramResource.getInstance(g);
+               Collection<Resource> connectors = g.getObjects(element, diagramConnRel);
+               Collection<Symbol> result = new ArrayList<Symbol>();
+               for (Resource connector : connectors) {
+                       Resource otherConnector = g.getSingleObject(connector, dr.AreConnected);
+                       if (g.isInstanceOf(otherConnector, dr.Connector)) {
+                               getConnectorConnectors(g, otherConnector, otherConnRel, result);
+                       } else if (g.isInstanceOf(otherConnector, dr.RouteLine)) {
+                               getBranchPointConnectors(g, connector, otherConnector, otherConnRel, result);
+                       } else {
+                               throw new DatabaseException("Connector " + g.getPossibleURI(otherConnector) + " " + otherConnector + " han unknown type");
+                       }
+               }
+               return result;
+       }
+       
+       private void getConnectorConnectors(ReadGraph g, Resource connector, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException{
+               StructuralResource2 sr = StructuralResource2.getInstance(g);
+               DiagramResource dr = DiagramResource.getInstance(g);
+               Collection<Statement> stms = g.getStatements(connector, sr.Connects);
+               Statement stm = null;
+               for (Statement s : stms) {
+                       if (!g.isInstanceOf(s.getObject(), dr.Connection)) {
+                               stm = s;
+                       }
+               }
+               if (stm == null)
+                       return;
+               if (otherConnRel != null) {
+                       Resource rel = g.getInverse(stm.getPredicate());
+                       if (!rel.equals(otherConnRel))
+                               return;
+               }
+               Resource element = stm.getObject();
+               result.add(diagram.getSymbol(g, element));
+       }
+       
+       private void getBranchPointConnectors(ReadGraph g, Resource origin, Resource branchPoint, Resource otherConnRel, Collection<Symbol> result) throws DatabaseException {
+               DiagramResource dr = DiagramResource.getInstance(g);
+               
+               Collection<Resource> branchConnected = g.getObjects(branchPoint, dr.AreConnected);
+               for (Resource branchConnector : branchConnected) {
+                       if (branchConnector.equals(origin))
+                               continue;
+                       if (g.isInstanceOf(branchConnector, dr.Connector)) {
+                               getConnectorConnectors(g, branchConnector, otherConnRel, result);
+                       } else if (g.isInstanceOf(branchConnector, dr.RouteLine)) {
+                               getBranchPointConnectors(g, branchPoint, branchConnector, otherConnRel, result);
+                       } else {
+                               throw new DatabaseException("Connector " + g.getPossibleURI(branchConnector) + " " + branchConnector + " han unknown type");
+                       }
+               }
+       }
+
+       public Collection<Symbol> getDiagramConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
+               return getDiagramConnected(g, diagramConnRel,null);
+       }
+       
+       public Collection<Symbol> getDiagramInverseConnected(ReadGraph g,  Resource otherConnRel) throws DatabaseException {
+               StructuralResource2 sr = StructuralResource2.getInstance(g);
+               return getDiagramConnected(g, sr.IsConnectedTo, otherConnRel);
+               
+       }
+       
+       public Collection<Symbol> getDiagramConnected(ReadGraph g) throws DatabaseException {
+               StructuralResource2 sr = StructuralResource2.getInstance(g);
+               return getDiagramConnected(g, sr.IsConnectedTo, null);
+       }
+       
+       public Symbol getDiagramSingleConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException {
+               Collection<Symbol> symbols = getDiagramConnected(g, diagramConnRel);
+               if (symbols.size() > 1) {
+                       throw new NoSingleResultException("Symbol " + element + " has more than one connection with " + diagramConnRel);
+               } else if (symbols.size() == 1) {
+                       return symbols.iterator().next();
+               }
+               return null;
+       }
+       
+       public Symbol getOtherFlag(ReadGraph g) throws DatabaseException {
+               DiagramResource dr = DiagramResource.getInstance(g);
+               Resource connectionJoin = g.getPossibleObject(element, dr.FlagIsJoinedBy);
+               if (connectionJoin == null)
+                       return null;
+               Collection<Resource> flags = g.getObjects(connectionJoin, dr.JoinsFlag);
+               Resource otherFlag = null;
+               for (Resource f : flags) {
+                       if (!f.equals(element)) {
+                               otherFlag = f;
+                               break;
+                       }
+               }
+               
+               if (otherFlag == null) {
+                       return null;
+               }
+               Resource otherDiagramR = OrderedSetUtils.getSingleOwnerList(g, otherFlag);
+               Diagram otherDiagram = diagram.fromExisting(g, otherDiagramR);
+               return otherDiagram.getSymbol(g, otherFlag, null);
+               
+       }
+
+       /**
+        * Returns concatenated translation of the symbol.
+        * @param g
+        * @return
+        * @throws DatabaseException
+        */
+       public double[] getSymbolTranslation(ReadGraph g) throws DatabaseException {
+               DiagramResource d = DiagramResource.getInstance(g);
+               ModelingResources mr = ModelingResources.getInstance(g);
+               
+               Resource e = element;
+               AffineTransform at = new AffineTransform();
+               while (e != null) {
+                       double transform[] = g.getPossibleRelatedValue(e, d.HasTransform);
+                       if (transform == null)
+                               break;
+                       AffineTransform at2 = new AffineTransform(transform);
+                       at.preConcatenate(at2);
+                       Resource component = g.getPossibleObject(e, mr.HasParentComponent);
+                       if (component != null) {
+                               e = g.getPossibleObject(component, mr.ComponentToElement);
+                       } else {
+                               e = null;
+                       }
+               }
+
+               return new double[]{at.getTranslateX(),at.getTranslateY()};
+       }
+       
+       /**
+        * Returns transformation of the symbol.
+        * @param g
+        * @return
+        * @throws DatabaseException
+        */
+       public double[] getSymbolTransformation(ReadGraph g) throws DatabaseException{
+               DiagramResource d = DiagramResource.getInstance(g);
+               double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
+               return transform;
+       }
+       
+       /**
+        * Sets translation of symbol. The scale is set to 1.0.
+        * @param g
+        * @param x
+        * @param y
+        * @throws DatabaseException
+        */
+       public void setSymbolTranslation(WriteGraph g, double x, double y) throws DatabaseException {
+               DiagramResource d = DiagramResource.getInstance(g);
+               G2DResource g2d = G2DResource.getInstance(g);
+               g.claimLiteral(element, d.HasTransform, g2d.Transform, new double[]{1.0,0.0,0.0,1.0,x,y});
+       }
+       
+       public void setSymbolTransformation(WriteGraph g, AffineTransform at) throws DatabaseException {
+               DiagramResource d = DiagramResource.getInstance(g);
+               G2DResource g2d = G2DResource.getInstance(g);
+               double arr[] = new double[6];
+               at.getMatrix(arr);
+               g.claimLiteral(element, d.HasTransform, g2d.Transform, arr);
+       }
+       
+       /**
+        * Set the scale of symbol.
+        * @param g
+        * @param scale
+        * @throws DatabaseException
+        */
+       public void setScale(WriteGraph g, double scale) throws DatabaseException {
+               DiagramResource d = DiagramResource.getInstance(g);
+               double transform[] = g.getPossibleRelatedValue(element, d.HasTransform);
+               g.claimLiteral(element, d.HasTransform, new double[]{scale,0.0,0.0,scale,transform[4],transform[5]});
+       }
+       
+       @Override
+       public boolean equals(Object o) {
+               if (o == null)
+                       return false;
+               if (this.getClass() != o.getClass())
+                       return false;
+               Symbol other = (Symbol)o;
+               return element.equals(other.element);
+       }
+       
+       @Override
+       public int hashCode() {
+               return element.hashCode();
+       }
+       
+       
+       
+       /**
+        * Returns component type from symbol type
+        * @param g
+        * @param symbolType
+        * @return
+        * @throws NoSingleResultException
+        * @throws ManyObjectsForFunctionalRelationException
+        * @throws ServiceException
+        */
+       public static Resource getComponentTypeFromSymbolType(ReadGraph g, Resource symbolType) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
+               ModelingResources m = ModelingResources.getInstance(g);
+               Resource component = g.getPossibleObject(symbolType, m.SymbolToComponentType);
+               return component;
+       }
+       
+       public static Resource getSymbolTypeFromComponentType(ReadGraph g, Resource componentType) throws NoSingleResultException, ServiceException, ManyObjectsForFunctionalRelationException {
+               ModelingResources m = ModelingResources.getInstance(g);
+               Collection<Resource> symbols = g.getObjects(componentType, m.ComponentTypeToSymbol);
+               if (symbols.size() == 0)
+                       return null;
+               return symbols.iterator().next();
+       }
+       
+       public void dispose() {
+               diagram = null;
+               component = null;
+               element = null;
+       }
+
+       /**
+        * Common interface for Symbol.connect return value.
+        *
+        */
+       public interface SymbolConnectionData {
+               
+       }
+       
+       /**
+        * Interface for returning diagram level connectors.
+        *
+        */
+       public interface DiagramConnectionData extends SymbolConnectionData {
+               public int getConnectionCount();
+               public Resource getConnection(int index);
+       }
+       
+       /**
+        * Interface for flag connections. 
+        *
+        */
+       public interface FlagConnectionData extends SymbolConnectionData {
+               public Symbol getFirstFlag();
+               public Symbol getSecondFlag();
+       }
+       
+       
+       /**
+        * Interface for signal connections. 
+        *
+        */
+       public interface SignalConnectionData extends SymbolConnectionData {
+               public Resource getSignalComponent();
+       }
+       
+       /**
+        * Interface for Point connections. 
+        *
+        */
+       public interface PointConnectionData extends SymbolConnectionData {
+               Symbol getPoint();
+       }
+       
+       /**
+        * Interface for "connection" that merged the connected symbols into one symbol. 
+        *
+        */
+       public interface MergeSymbolData extends SymbolConnectionData {
+               Symbol getResultSymbol();
+       }
+       
+       /**
+        * Return value for a connection that already exists. 
+        *
+        */
+       public interface SymbolExists extends SymbolConnectionData {
+               
+       }
+       
+       /**
+        * Return value for an error. 
+        *
+        */
+       public interface ConnectionError extends SymbolConnectionData {
+               String getReason();
+       }
+       
+       private static class ConnectionErrorImpl implements ConnectionError {
+               private String error;
+               
+               public ConnectionErrorImpl(String error) {
+                       this.error = error;
+               }
+               
+               @Override
+               public String getReason() {
+                       return error;
+               }
+       }
+       
+       private static class SymbolExistsImpl implements SymbolExists {
+               
+       }
+       
+       private static class ConnectorDataImpl implements DiagramConnectionData {
+               
+               private Resource[] connectors;
+               
+               public ConnectorDataImpl(Resource... connectors) {
+                       this.connectors = connectors;
+               }
+               
+               @Override
+               public Resource getConnection(int index) {
+                       return connectors[index];
+               }
+               
+               @Override
+               public int getConnectionCount() {
+                       return connectors.length;
+               }
+       }
+       
+       private static class PointConnectionDataImpl implements PointConnectionData {
+               
+               private Symbol point;
+               
+               public PointConnectionDataImpl(Symbol point) {
+                       this.point = point;
+               }
+               
+               @Override
+               public Symbol getPoint() {
+                       return point;
+               }
+       }
+       
+       private static class SignalConnectionDataImpl implements SignalConnectionData, DiagramConnectionData{
+               
+               private Resource signalComponent;
+               private Resource[] connectors;
+               
+               public SignalConnectionDataImpl(Resource signalComponent, Resource... connectors) {
+                       this.signalComponent = signalComponent;
+                       this.connectors = connectors;
+               }
+               
+               @Override
+               public Resource getSignalComponent() {
+                       return signalComponent;
+               }
+               
+               @Override
+               public Resource getConnection(int index) {
+                       return connectors[index];
+               }
+               
+               @Override
+               public int getConnectionCount() {
+                       return connectors.length;
+               }
+               
+       }
+       
+       private static class FlagConnectionDataImpl implements FlagConnectionData, DiagramConnectionData {
+               
+               private Symbol firstFlag;
+               private Symbol secondFlag;
+               private Resource[] connectors;
+               
+               public FlagConnectionDataImpl(Symbol firstFlag, Symbol secondFlag, Resource... connectors) {
+                       this.firstFlag = firstFlag;
+                       this.secondFlag = secondFlag;
+                       this.connectors = connectors;
+               }
+               
+               @Override
+               public Symbol getFirstFlag() {
+                       return firstFlag;
+               }
+               
+               @Override
+               public Symbol getSecondFlag() {
+                       return secondFlag;
+               }
+               
+               @Override
+               public Resource getConnection(int index) {
+                       return connectors[index];
+               }
+               
+               @Override
+               public int getConnectionCount() {
+                       return connectors.length;
+               }
+       }
+
+       public void setComponentValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setComponentValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setComponentValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setComponentValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setComponentValue(WriteGraph graph, Resource property, String value) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setComponentValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setComponentValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setComponentValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setComponentValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
+               setValue(graph, component, property, value);
+       }
+       
+       public void setElementValue(WriteGraph graph, Resource property, double value) throws DatabaseException{
+               setValue(graph, element, property, value);
+       }
+       
+       public void setElementValue(WriteGraph graph, Resource property, float value) throws DatabaseException{
+               setValue(graph, element, property, value);
+       }
+       
+       public void setElementValue(WriteGraph graph, Resource property, boolean value) throws DatabaseException{
+               setValue(graph, element, property, value);
+       }
+       
+       public void setElementValue(WriteGraph graph, Resource property, int value) throws DatabaseException{
+               setValue(graph, element, property, value);
+       }
+       
+       public void setElementValue(WriteGraph graph, Resource property, double value[]) throws DatabaseException{
+               setValue(graph, element, property, value);
+       }
+       
+       public void setElementValue(WriteGraph graph, Resource property, float value[]) throws DatabaseException{
+               setValue(graph, element, property, value);
+       }
+       
+       public void setElementValue(WriteGraph graph, Resource property, int value[]) throws DatabaseException{
+               setValue(graph, element, property, value);
+       }
+       
+       public void setElementValue(WriteGraph graph, Resource property, boolean value[]) throws DatabaseException{
+               setValue(graph, element, property, value);
+       }
+       
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * Note: This method support only some basic L0 data types.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, double value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (l0.Double.equals(range)) {
+                       graph.claimLiteral(object, property, value, Bindings.DOUBLE);
+               } else if (l0.Float.equals(range)) {
+                       graph.claimLiteral(object, property, (float)value, Bindings.FLOAT);
+               } else if (l0.Integer.equals(range)) {
+                       graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
+               } else if (l0.Long.equals(range)) {
+                       graph.claimLiteral(object, property, (long)value, Bindings.LONG);
+               } else if (l0.Boolean.equals(range)) {
+                       graph.claimLiteral(object, property, value > 0.0, Bindings.BOOLEAN);
+               } else if (l0.String.equals(range)) {
+                       graph.claimLiteral(object, property, Double.toString(value), Bindings.STRING);
+               } else {
+                       graph.claimLiteral(object, property, value, Bindings.DOUBLE);
+               }
+       }
+
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * Note: This method support only some basic L0 data types.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, float value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (l0.Double.equals(range)) {
+                       graph.claimLiteral(object, property, (double)value, Bindings.DOUBLE);
+               } else if (l0.Float.equals(range)) {
+                       graph.claimLiteral(object, property, value, Bindings.FLOAT);
+               } else if (l0.Integer.equals(range)) {
+                       graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
+               } else if (l0.Long.equals(range)) {
+                       graph.claimLiteral(object, property, (long)value, Bindings.LONG);
+               } else if (l0.Boolean.equals(range)) {
+                       graph.claimLiteral(object, property, value > 0.f, Bindings.BOOLEAN);
+               } else if (l0.String.equals(range)) {
+                       graph.claimLiteral(object, property, Float.toString(value), Bindings.STRING);
+               } else {
+                       graph.claimLiteral(object, property, value, Bindings.FLOAT);
+               }
+       }
+       
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * Note: This method support only some basic L0 data types.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, int value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (l0.Double.equals(range)) {
+                       graph.claimLiteral(object, property, (double)value, Bindings.DOUBLE);
+               } else if (l0.Float.equals(range)) {
+                       graph.claimLiteral(object, property, (float) value, Bindings.FLOAT);
+               } else if (l0.Integer.equals(range)) {
+                       graph.claimLiteral(object, property, (int)value, Bindings.INTEGER);
+               } else if (l0.Long.equals(range)) {
+                       graph.claimLiteral(object, property, (long)value, Bindings.LONG);
+               } else if (l0.Boolean.equals(range)) {
+                       graph.claimLiteral(object, property, value > 0, Bindings.BOOLEAN);
+               } else if (l0.String.equals(range)) {
+                       graph.claimLiteral(object, property, Integer.toString(value), Bindings.STRING);
+               } else {
+                       graph.claimLiteral(object, property, value, Bindings.INTEGER);
+               }
+       }
+       
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, String value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (range == null) {
+                       graph.claimLiteral(object, property, value, Bindings.STRING);
+               } else {
+                       if (graph.isInheritedFrom(range, l0.String)) {
+                               graph.claimLiteral(object, property, value, Bindings.STRING);
+                       } else if (graph.isInheritedFrom(range, l0.Double)) {
+                               graph.claimLiteral(object, property, Double.parseDouble(value), Bindings.DOUBLE);
+                       } else if (graph.isInheritedFrom(range, l0.Float)) {
+                               graph.claimLiteral(object, property, Float.parseFloat(value), Bindings.FLOAT);
+                       } else if (graph.isInheritedFrom(range, l0.Integer)) {
+                               graph.claimLiteral(object, property, Integer.parseInt(value), Bindings.INTEGER);
+                       } else if (graph.isInheritedFrom(range, l0.Long)) {
+                               graph.claimLiteral(object, property, Long.parseLong(value), Bindings.LONG);
+                       } else if (graph.isInheritedFrom(range, l0.Boolean)) {
+                               graph.claimLiteral(object, property, Boolean.parseBoolean(value), Bindings.BOOLEAN);
+                       } else {
+                               graph.claimLiteral(object, property, value, Bindings.STRING);
+                       } 
+               }
+       }
+
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * Note: This method support only some basic L0 data types.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, boolean value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (l0.Boolean.equals(range)) {
+                       graph.claimLiteral(object, property, value , Bindings.BOOLEAN);
+               } else if (l0.String.equals(range)) {
+                       graph.claimLiteral(object, property, Boolean.toString(value), Bindings.STRING);
+               } else if (l0.Integer.equals(range)) {
+                       graph.claimLiteral(object, property, value ? 1 : 0, Bindings.INTEGER);
+               } else {
+                       graph.claimLiteral(object, property, value, Bindings.BOOLEAN);
+               }
+       }
+       
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * Note: This method support only some basic L0 data types.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, double[] value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (l0.DoubleArray.equals(range)) {
+                       graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
+               } else if (l0.FloatArray.equals(range)) {
+                       float arr[] = new float[value.length];
+                       for (int i = 0; i < value.length; i++)
+                               arr[i] = (float) value[i];
+                       graph.claimLiteral(object, property, arr, Bindings.FLOAT_ARRAY);
+               } else if (l0.IntegerArray.equals(range)) {
+                       int arr[] = new int[value.length];
+                       for (int i = 0; i < value.length; i++)
+                               arr[i] = (int) value[i];
+                       graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
+               } else {
+                       graph.claimLiteral(object, property, value, Bindings.DOUBLE_ARRAY);
+               }
+       }
+       
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * Note: This method support only some basic L0 data types.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, float[] value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (l0.FloatArray.equals(range)) {
+                       graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
+               } else if (l0.DoubleArray.equals(range)) {
+                       double arr[] = new double[value.length];
+                       for (int i = 0; i < value.length; i++)
+                               arr[i] = (double) value[i];
+                       graph.claimLiteral(object, property, arr, Bindings.DOUBLE_ARRAY);
+               } else if (l0.IntegerArray.equals(range)) {
+                       int arr[] = new int[value.length];
+                       for (int i = 0; i < value.length; i++)
+                               arr[i] = (int) value[i];
+                       graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
+               } else {
+                       graph.claimLiteral(object, property, value, Bindings.FLOAT_ARRAY);
+               }
+       }
+       
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * Note: This method support only some basic L0 data types.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, int[] value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (l0.IntegerArray.equals(range)) {
+                       graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
+               } else if (l0.DoubleArray.equals(range)) {
+                       double arr[] = new double[value.length];
+                       for (int i = 0; i < value.length; i++)
+                               arr[i] = (double) value[i];
+                       graph.claimLiteral(object, property, arr, Bindings.DOUBLE_ARRAY);
+               } else if (l0.FloatArray.equals(range)) {
+                       float arr[] = new float[value.length];
+                       for (int i = 0; i < value.length; i++)
+                               arr[i] = (float) value[i];
+                       graph.claimLiteral(object, property, arr, Bindings.FLOAT_ARRAY);
+               } else {
+                       graph.claimLiteral(object, property, value, Bindings.INT_ARRAY);
+               }
+       }
+       
+       /**
+        * Sets literal value. Does data conversion if required.
+        * 
+        * Note: This method support only some basic L0 data types.
+        * 
+        * @param graph
+        * @param object
+        * @param property
+        * @param value
+        * @throws DatabaseException
+        */
+       public static void setValue(WriteGraph graph, Resource object, Resource property, boolean[] value) throws DatabaseException{
+               Layer0 l0 = Layer0.getInstance(graph);
+               Resource range = graph.getPossibleObject(property, l0.HasRange);
+               if (l0.BooleanArray.equals(range)) {
+                       graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);
+               } else if (l0.IntegerArray.equals(range)) {
+                       int arr[] = new int[value.length];
+                       for (int i = 0; i < value.length; i++)
+                               arr[i] =  value[i] ? 1 : 0;
+                       graph.claimLiteral(object, property, arr, Bindings.INT_ARRAY);
+               } else {
+                       graph.claimLiteral(object, property, value, Bindings.BOOLEAN_ARRAY);
+               }
+       }
+       
+}
\ No newline at end of file