package org.simantics.interop.diagram; import java.awt.geom.AffineTransform; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; 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 getConnectionRel(ReadGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Collection matching) throws DatabaseException { return matching; } protected SymbolConnectionData customConnect(WriteGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Resource connType) throws DatabaseException { return null; } protected Set getConnectionTypes(ReadGraph g, Resource componentConRel1) throws DatabaseException { StructuralResource2 sr = StructuralResource2.getInstance(g); Set set = new HashSet(); set.addAll(g.getObjects(componentConRel1, sr.AllowsConnectionType)); return set; } protected Set getNonAssertedConnectionTypes(ReadGraph g, Resource componentConRel1) throws DatabaseException { StructuralResource2 sr = StructuralResource2.getInstance(g); Set set = new HashSet(); for (Statement s : g.getStatements(componentConRel1, sr.AllowsConnectionType)) { if (s.isAsserted(componentConRel1)) continue; set.add(s.getObject()); } return set; } /** * 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 connType1 = getConnectionTypes(g, componentConRel1); Collection connType2 = getConnectionTypes(g, componentConRel2); Collection matching = new HashSet(); 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; } } public SymbolConnectionData connectElement(WriteGraph g, Symbol symbolConf2, Resource elementConRel1, Resource elementConRel2) throws DatabaseException { StructuralResource2 sr = StructuralResource2.getInstance(g); ModelingResources mod = ModelingResources.getInstance(g); Resource componentConRel1 = g.getPossibleObject(elementConRel1, mod.DiagramConnectionRelationToConnectionRelation); Resource componentConRel2 = g.getPossibleObject(elementConRel2, mod.DiagramConnectionRelationToConnectionRelation); if (componentConRel1 != null && componentConRel2 != null) { return connect(g, symbolConf2, componentConRel1, componentConRel2); } Collection connType1 = Collections.EMPTY_LIST; Collection connType2 = Collections.EMPTY_LIST; if (componentConRel1 != null) { connType1 = getConnectionTypes(g, componentConRel1); if (connType1.size() > 1) connType1 = getNonAssertedConnectionTypes(g,componentConRel1); } else if (componentConRel2 != null) { connType2 = getConnectionTypes(g, componentConRel2); if (connType2.size() > 1) connType2 = getNonAssertedConnectionTypes(g,componentConRel2); } Resource usedConnType = null; if (connType1.size() == 1) usedConnType = connType1.iterator().next(); else if (connType2.size() == 1) usedConnType = connType2.iterator().next(); else { String err = "Cannot locate connection type for: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2; Logger.defaultLogError(err); return new ConnectionErrorImpl(err); } if (!diagram.equals(symbolConf2.diagram)) { String err = "Element connections must be done on the same diagram: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2; Logger.defaultLogError(err); return new ConnectionErrorImpl(err); } return connectElement(g, symbolConf2, elementConRel1, elementConRel2, usedConnType); } public SymbolConnectionData connectElement(WriteGraph g, Symbol symbolConf2, Resource elementConRel1, Resource elementConRel2, Resource usedConnType) throws DatabaseException { if (this.equals(symbolConf2)) { if (PREVENT_SELF_CONNECTIONS) { String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2; Logger.defaultLogError(err); return new ConnectionErrorImpl(err); } if (elementConRel1.equals(elementConRel2)) { String err = "Preventing connection to self: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2; Logger.defaultLogError(err); return new ConnectionErrorImpl(err); } } // TODO : should we have separate customConnect method for element level connections? SymbolConnectionData data = customConnect(g, symbolConf2, elementConRel1, elementConRel2, usedConnType); if (data == null) { return _connectElement(g, symbolConf2, elementConRel1, elementConRel2,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 elementConRel1 = getDiagramConnectionRelation(g, element, componentConRel1); Resource connectorRel1 = g.getPossibleObject(componentConRel1, s.HasAttachmentRelation); if (connectorRel1 == null) connectorRel1 = d.HasPlainConnector; // connector1 Resource connector1 = g.newResource(); g.claim(connector1, b.InstanceOf, d.Connector); g.claim(element, elementConRel1, connector1); g.claim(diagramConnection, connectorRel1, connector1); // Relation from element2 to connector2 Resource elementConRel2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2); Resource connectorRel2 = g.getPossibleObject(componentConRel2, s.HasAttachmentRelation); if (connectorRel2 == null) connectorRel2 = d.HasArrowConnector; // connector2 Resource connector2 = g.newResource(); g.claim(connector2, b.InstanceOf, d.Connector); g.claim(symbolConf2.element, elementConRel2, connector2); g.claim(diagramConnection, connectorRel2, connector2); // connect connectors g.claim(connector1, d.AreConnected, connector2); g.claim(moduleConnection, m.ConnectionToDiagramConnection, diagramConnection); return new ConnectorDataImpl(diagramConnection); } private SymbolConnectionData _connectElement(WriteGraph g, Symbol symbolConf2, Resource elementConRel1, Resource elementConRel2, 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(elementConRel1, b.FunctionalRelation) && getDiagramSingleConnected(g, elementConRel1) != null) { Symbol current = getDiagramSingleConnected(g, elementConRel1); if (current.component.equals(symbolConf2.component)) return new SymbolExistsImpl(); String err = "Cannot connect, terminal 1 is reserved: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2; Logger.defaultLogError(err); return new ConnectionErrorImpl(err); } if (g.isInstanceOf(elementConRel2, b.FunctionalRelation) && symbolConf2.getDiagramSingleConnected(g, elementConRel2) != null) { Symbol current = symbolConf2.getDiagramSingleConnected(g, elementConRel2); if (current.component.equals(component)) return new SymbolExistsImpl(); String err = "Cannot connect, terminal 2 is reserved: " + component + " " + NameUtils.getSafeName(g, component) + " terminals: " + g.getPossibleURI(elementConRel1) + " "+ elementConRel1 + " " + g.getPossibleURI(elementConRel2) + " "+ elementConRel2; Logger.defaultLogError(err); return new ConnectionErrorImpl(err); } // // 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 elementConRel1 = getDiagramConnectionRelation(g, element, componentConRel1); // Resource connectorRel1 = g.getPossibleObject(componentConRel1, s.HasAttachmentRelation); // if (connectorRel1 == null) // connectorRel1 = d.HasPlainConnector; Resource connectorRel1 = d.HasPlainConnector; // connector1 Resource connector1 = g.newResource(); g.claim(connector1, b.InstanceOf, d.Connector); g.claim(element, elementConRel1, connector1); g.claim(diagramConnection, connectorRel1, connector1); // Relation from element2 to connector2 // Resource elementConRel2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2); // Resource connectorRel2 = g.getPossibleObject(componentConRel2, s.HasAttachmentRelation); // if (connectorRel2 == null) // connectorRel2 = d.HasArrowConnector; Resource connectorRel2 = d.HasArrowConnector; // connector2 Resource connector2 = g.newResource(); g.claim(connector2, b.InstanceOf, d.Connector); g.claim(symbolConf2.element, elementConRel2, connector2); g.claim(diagramConnection, connectorRel2, 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 diagramConnectionRels = g.getObjects(componentConnRel, m.ConnectionRelationToDiagramConnectionRelation); if (diagramConnectionRels.size() == 1) return diagramConnectionRels.iterator().next(); if (diagramConnectionRels.size() > 1) { List matching = new ArrayList(); 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 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 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 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 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 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 result = new ArrayList(); Collection modConn1s = g.getObjects(this.component, componentConRel); for (Resource modConn1 : modConn1s) { Collection connected = g.getStatements(modConn1, sr.Connects); Collection connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy); Collection connectedComponents = new ArrayList(); 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 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 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 modConn1s = g.getObjects(this.component, componentConRel); Collection result = new ArrayList(); for (Resource modConn1 : modConn1s) { Collection connected = g.getObjects(modConn1, sr.Connects); Collection connectionJoins = g.getObjects(modConn1, sr.IsJoinedBy); Collection connectedComponents = new ArrayList(); for (Resource r : connected) { if (!r.equals(this.component)) { connectedComponents.add(r); } } for (Resource connectionJoin : connectionJoins) { Collection 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 getDiagramConnected(ReadGraph g, Resource diagramConnRel, Resource otherConnRel) throws DatabaseException { DiagramResource dr = DiagramResource.getInstance(g); Collection connectors = g.getObjects(element, diagramConnRel); Collection result = new ArrayList(); 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 result) throws DatabaseException{ StructuralResource2 sr = StructuralResource2.getInstance(g); DiagramResource dr = DiagramResource.getInstance(g); Collection 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 result) throws DatabaseException { DiagramResource dr = DiagramResource.getInstance(g); Collection 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 getDiagramConnected(ReadGraph g, Resource diagramConnRel) throws DatabaseException { return getDiagramConnected(g, diagramConnRel,null); } public Collection getDiagramInverseConnected(ReadGraph g, Resource otherConnRel) throws DatabaseException { StructuralResource2 sr = StructuralResource2.getInstance(g); return getDiagramConnected(g, sr.IsConnectedTo, otherConnRel); } public Collection 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 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 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 symbols = g.getObjects(componentType, m.ComponentTypeToSymbol); if (symbols.size() == 0) return null; return symbols.iterator().next(); } public void remove(WriteGraph g) throws DatabaseException{ Layer0 L0 = Layer0.getInstance(g); StructuralResource2 STR = StructuralResource2.getInstance(g); DiagramResource DIA = DiagramResource.getInstance(g); OrderedSetUtils.remove(g, diagram.getDiagram(), element); if (component != null) g.deny(component, L0.PartOf); Collection statements = g.getStatements(element, STR.IsConnectedTo); for (Statement s : statements) { if (g.isInstanceOf(s.getObject(),DIA.Connector)) { Resource connectedConnector = g.getPossibleObject(s.getObject(), DIA.AreConnected); if (connectedConnector != null) g.deny(connectedConnector); g.deny(s.getObject()); } } if (component != null) { statements = g.getStatements(component, STR.IsConnectedTo); for (Statement s : statements) { if (g.isInstanceOf(s.getObject(),STR.Connection)) { g.deny(s.getObject()); } } } g.deny(element); if (component != null) g.deny(component); } 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 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); } } }