]> gerrit.simantics Code Review - simantics/interop.git/blobdiff - org.simantics.interop.diagram/src/org/simantics/interop/diagram/Symbol.java
Diagram API fixes.
[simantics/interop.git] / org.simantics.interop.diagram / src / org / simantics / interop / diagram / Symbol.java
index b2f7c30d05edbcdbaef33425f3b492a08ee0dbe8..1ae1c6c545d10fd495d223967f56ee581a6bfcad 100644 (file)
@@ -3,15 +3,16 @@ 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;
@@ -25,6 +26,9 @@ import org.simantics.layer0.Layer0;
 import org.simantics.modeling.ModelingResources;
 import org.simantics.structural.stubs.StructuralResource2;
 import org.simantics.structural2.utils.StructuralUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 
 
 
@@ -33,6 +37,8 @@ import org.simantics.structural2.utils.StructuralUtils;
  */
 public abstract class Symbol {
        
+       private static Logger Logger = LoggerFactory.getLogger(Symbol.class);
+       
        private static boolean USE_UNRELIABLE_CONNECT = false;
        private static boolean PREVENT_SELF_CONNECTIONS = false;
        
@@ -79,6 +85,7 @@ public abstract class Symbol {
                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;
        }
@@ -87,6 +94,24 @@ public abstract class Symbol {
                return null;
        }
        
+       protected Set<Resource> getConnectionTypes(ReadGraph g, Resource componentConRel1) throws DatabaseException {
+               StructuralResource2 sr = StructuralResource2.getInstance(g);
+               Set<Resource> set = new HashSet<Resource>();
+               set.addAll(g.getObjects(componentConRel1, sr.AllowsConnectionType));
+               return set;
+       }
+       
+       protected Set<Resource> getNonAssertedConnectionTypes(ReadGraph g, Resource componentConRel1) throws DatabaseException {
+               StructuralResource2 sr = StructuralResource2.getInstance(g);
+               Set<Resource> set = new HashSet<Resource>();
+               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
@@ -101,18 +126,18 @@ public abstract class Symbol {
                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);
+                               Logger.error(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);
+                               Logger.error(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> connType1 = getConnectionTypes(g, componentConRel1);
+               Collection<Resource> connType2 = getConnectionTypes(g, componentConRel2);
                Collection<Resource> matching = new HashSet<Resource>();
                for (Resource r : connType2) {
                        if (connType1.contains(r))
@@ -129,7 +154,7 @@ public abstract class Symbol {
                        } 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);
+                       Logger.info(err);
                        return new ConnectionErrorImpl(err);
                } else {
                        usedConnType = matching.iterator().next();
@@ -146,6 +171,69 @@ public abstract class Symbol {
                }
        }
        
+       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<Resource> connType1 = Collections.EMPTY_LIST;
+               Collection<Resource> 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.error(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.error(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.error(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.error(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
@@ -167,6 +255,22 @@ public abstract class Symbol {
                return new ConnectionErrorImpl("Symbol is already connected");
        }
        
+       protected Resource componentConnectionType(ReadGraph g, Resource componentConRel1, Resource componentConRel2) throws DatabaseException {
+               StructuralResource2 s = StructuralResource2.getInstance(g);
+               return s.Connection;
+       }
+       
+       protected Resource diagramConnectionType(ReadGraph g, Resource componentConnectionType) throws DatabaseException {
+               ModelingResources MOD = ModelingResources.getInstance(g);
+               if (componentConnectionType != null) {
+                       Resource ct = g.getPossibleObject(componentConnectionType, MOD.ConnectionTypeToDiagramConnectionType);
+                       if (ct != null)
+                               return ct;
+               }
+               DiagramResource d = DiagramResource.getInstance(g);
+               return d.RouteGraphConnection;
+       }
+       
        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);
@@ -191,7 +295,8 @@ public abstract class Symbol {
                
                // connection object in module level
                Resource moduleConnection = g.newResource();
-               g.claim(moduleConnection, b.InstanceOf, s.Connection);
+               Resource moduleConnectionType = componentConnectionType(g, componentConRel1, componentConRel2);
+               g.claim(moduleConnection, b.InstanceOf, moduleConnectionType);
                
                // connect the modules
                
@@ -200,13 +305,13 @@ public abstract class Symbol {
                
                // connection object in diagram level
                Resource diagramConnection = g.newResource();
-               g.claim(diagramConnection, b.InstanceOf, d.RouteGraphConnection);
+               g.claim(diagramConnection, b.InstanceOf, diagramConnectionType(g, moduleConnectionType));
                DiagramUtils.addElementFirst(g, diagram, diagramConnection);
                
                g.claim(diagramConnection, s.HasConnectionType, connectorType);
                
                // Relation from element1 to connector1
-               Resource isConnected1 = getDiagramConnectionRelation(g, element, componentConRel1);
+               Resource elementConRel1 = getDiagramConnectionRelation(g, element, componentConRel1);
                Resource connectorRel1 = g.getPossibleObject(componentConRel1, s.HasAttachmentRelation);
                if (connectorRel1 == null)
                        connectorRel1 = d.HasPlainConnector;
@@ -214,18 +319,18 @@ public abstract class Symbol {
                // connector1
                Resource connector1 = g.newResource();
                g.claim(connector1, b.InstanceOf, d.Connector);
-               g.claim(element, isConnected1, connector1);
+               g.claim(element, elementConRel1, connector1);
                g.claim(diagramConnection, connectorRel1, connector1);
                
                // Relation from element2 to connector2
-               Resource isConnected2 = getDiagramConnectionRelation(g, symbolConf2.element, componentConRel2);
+               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, isConnected2, connector2);
+               g.claim(symbolConf2.element, elementConRel2, connector2);
                g.claim(diagramConnection, connectorRel2, connector2);
                
                // connect connectors
@@ -236,6 +341,80 @@ public abstract class Symbol {
                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.error(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.error(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, diagramConnectionType(g, null));
+               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 {
                
@@ -247,12 +426,12 @@ public abstract class Symbol {
                
                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);
+                       Logger.error(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);
+                       Logger.error(err);
                        return new ConnectionErrorImpl(err);
                }
        
@@ -269,10 +448,11 @@ public abstract class Symbol {
                g.claim(diagram2.getComposite(), s.HasConnectionJoin, connectionJoin);
                
                Resource connection1 = g.newResource();
-               g.claim(connection1, l0.InstanceOf, s.Connection);
+               Resource ct = componentConnectionType(g, componentConRel1, componentConRel2);
+               g.claim(connection1, l0.InstanceOf, ct);
                
                Resource connection2 = g.newResource();
-               g.claim(connection2, l0.InstanceOf, s.Connection);
+               g.claim(connection2, l0.InstanceOf, ct);
                
                g.claim(component, componentConRel1, connection1);
                g.claim(symbolConf2.component, componentConRel2, connection2);
@@ -283,12 +463,13 @@ public abstract class Symbol {
                g.claim(flag2.element, d.FlagIsJoinedBy, connectionJoin);
                
                Resource diagConnection1 = g.newResource();
-               g.claim(diagConnection1, l0.InstanceOf, d.RouteGraphConnection);
+               Resource dct = diagramConnectionType(g, ct);
+               g.claim(diagConnection1, l0.InstanceOf, dct);
                DiagramUtils.addElementFirst(g, diagram, diagConnection1);
                g.claim(diagConnection1, s.HasConnectionType, connectionType);
 
                Resource diagConnection2 = g.newResource();
-               g.claim(diagConnection2, l0.InstanceOf, d.RouteGraphConnection);
+               g.claim(diagConnection2, l0.InstanceOf, dct);
                DiagramUtils.addElementFirst(g, diagram2, diagConnection2);
                g.claim(diagConnection2, s.HasConnectionType, connectionType);
                
@@ -787,23 +968,6 @@ public abstract class Symbol {
                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. 
         *