]> gerrit.simantics Code Review - simantics/interop.git/commitdiff
Support for element connections. 59/3759/1
authorMarko Luukkainen <marko.luukkainen@semantum.fi>
Fri, 3 Jan 2020 14:09:52 +0000 (16:09 +0200)
committerMarko Luukkainen <marko.luukkainen@semantum.fi>
Fri, 3 Jan 2020 14:09:52 +0000 (16:09 +0200)
gitlab #7

Change-Id: I6d487e39780a963f7e5835d01047cf60db0c2947

org.simantics.interop.diagram/src/org/simantics/interop/diagram/Diagram.java
org.simantics.interop.diagram/src/org/simantics/interop/diagram/Symbol.java

index d7f0631e034c53fdf81d5087ffcf604b67461d68..365cde242a5e1bea827e1fcdd8ce3612cccd6bfd 100644 (file)
@@ -250,12 +250,19 @@ public abstract class Diagram<T extends Symbol> {
        public Diagram<T> fromExisting(ReadGraph g, Resource diagram) throws DatabaseException {
                ModelingResources m = ModelingResources.getInstance(g);
                StructuralResource2 s = StructuralResource2.getInstance(g);
+               DiagramResource d = DiagramResource.getInstance(g);
                Resource composite = null;
                if (g.isInstanceOf(diagram, s.Composite)) {
                        composite = diagram;
                        diagram = g.getPossibleObject(composite, m.CompositeToDiagram);
                        if (diagram == null)
                                return null;
+               } else if (g.isInheritedFrom(diagram, d.DefinedElement)) {
+                       // TODO : Defined Element behaves differently to regular configuration diagrams; should we have separate implementation?
+                       composite = diagram;
+                       diagram = g.getPossibleObject(composite, s.IsDefinedBy);
+                       if (diagram == null)
+                               return null;
                } else {
                        composite = g.getPossibleObject(diagram, m.DiagramToComposite);
                        if (composite == null)
@@ -276,6 +283,8 @@ public abstract class Diagram<T extends Symbol> {
        
        
        
+       
+       
        /**
         * Returns diagram type from composite type
         * @param g
@@ -400,8 +409,13 @@ public abstract class Diagram<T extends Symbol> {
        public T getSymbol(ReadGraph g, Resource element) throws DatabaseException {
                ModelingResources mr = ModelingResources.getInstance(g);
                DiagramResource dr = DiagramResource.getInstance(g);
+               StructuralResource2 s = StructuralResource2.getInstance(g);
                if (g.isInstanceOf(element, dr.Element))
                        return getSymbol(g, element, g.getPossibleObject(element, mr.ElementToComponent));
+               else if (g.isSubrelationOf(element, s.IsConnectedTo)) {
+                       // TODO : Defined Element
+                       return getSymbol(g, g.getSingleObject(element, dr.HasConnectionPoint_Inverse),element);
+               }
                else
                        return getSymbol(g, g.getSingleObject(element, mr.ComponentToElement), element);
        }
index b2f7c30d05edbcdbaef33425f3b492a08ee0dbe8..c86ca7ab4159fca1c6d973efa7af1fbcf74a6884 100644 (file)
@@ -3,8 +3,10 @@ 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;
@@ -79,6 +81,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 +90,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
@@ -111,8 +132,8 @@ public abstract class Symbol {
                        }
                }
                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))
@@ -146,6 +167,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.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
@@ -206,7 +290,7 @@ public abstract class Symbol {
                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 +298,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 +320,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.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 {