From b19b7291bcd57e51b1a0bee8f46d8b783c0b8984 Mon Sep 17 00:00:00 2001 From: Marko Luukkainen Date: Fri, 3 Jan 2020 16:09:52 +0200 Subject: [PATCH] Support for element connections. gitlab #7 Change-Id: I6d487e39780a963f7e5835d01047cf60db0c2947 --- .../simantics/interop/diagram/Diagram.java | 14 ++ .../org/simantics/interop/diagram/Symbol.java | 170 +++++++++++++++++- 2 files changed, 178 insertions(+), 6 deletions(-) diff --git a/org.simantics.interop.diagram/src/org/simantics/interop/diagram/Diagram.java b/org.simantics.interop.diagram/src/org/simantics/interop/diagram/Diagram.java index d7f0631..365cde2 100644 --- a/org.simantics.interop.diagram/src/org/simantics/interop/diagram/Diagram.java +++ b/org.simantics.interop.diagram/src/org/simantics/interop/diagram/Diagram.java @@ -250,12 +250,19 @@ public abstract class Diagram { public Diagram 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 { + + /** * Returns diagram type from composite type * @param g @@ -400,8 +409,13 @@ public abstract class Diagram { 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); } 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 index b2f7c30..c86ca7a 100644 --- a/org.simantics.interop.diagram/src/org/simantics/interop/diagram/Symbol.java +++ b/org.simantics.interop.diagram/src/org/simantics/interop/diagram/Symbol.java @@ -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 getConnectionRel(ReadGraph g, Symbol symbolConf2, Resource componentConRel1, Resource componentConRel2, Collection matching) throws DatabaseException { return matching; } @@ -87,6 +90,24 @@ public abstract class Symbol { 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 @@ -111,8 +132,8 @@ public abstract class Symbol { } } StructuralResource2 sr = StructuralResource2.getInstance(g); - Collection connType1 = g.getObjects(componentConRel1, sr.AllowsConnectionType); - Collection connType2 = g.getObjects(componentConRel2, sr.AllowsConnectionType); + Collection connType1 = getConnectionTypes(g, componentConRel1); + Collection connType2 = getConnectionTypes(g, componentConRel2); Collection matching = new HashSet(); 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 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 @@ -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 { -- 2.47.1