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.modeling.ModelingResources;
import org.simantics.structural.stubs.StructuralResource2;
import org.simantics.structural2.utils.StructuralUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
*/
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;
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;
}
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
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))
} 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();
}
}
+ 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
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);
// 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
// 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;
+
+ // 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.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, isConnected1, connector1);
- g.claim(diagramConnection, d.HasPlainConnector, 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;
+ Resource connectorRel2 = d.HasArrowConnector;
// connector2
Resource connector2 = g.newResource();
g.claim(connector2, b.InstanceOf, d.Connector);
- g.claim(symbolConf2.element, isConnected2, connector2);
- g.claim(diagramConnection, d.HasArrowConnector, connector2);
+ 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);
+// g.claim(moduleConnection, m.ConnectionToDiagramConnection, diagramConnection);
return new ConnectorDataImpl(diagramConnection);
}
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);
}
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);
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);
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<Statement> 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;
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.
*
}
}
- private static class PointConnectionDataImpl implements PointConnectionData {
-
- private Symbol point;
-
- public PointConnectionDataImpl(Symbol point) {
- this.point = point;
- }
-
- @Override
- public Symbol getPoint() {
- return point;
- }
- }
-
- private static class SignalConnectionDataImpl implements SignalConnectionData, DiagramConnectionData{
-
- private Resource signalComponent;
- private Resource[] connectors;
-
- public SignalConnectionDataImpl(Resource signalComponent, Resource... connectors) {
- this.signalComponent = signalComponent;
- this.connectors = connectors;
- }
-
- @Override
- public Resource getSignalComponent() {
- return signalComponent;
- }
-
- @Override
- public Resource getConnection(int index) {
- return connectors[index];
- }
-
- @Override
- public int getConnectionCount() {
- return connectors.length;
- }
-
- }
-
private static class FlagConnectionDataImpl implements FlagConnectionData, DiagramConnectionData {
private Symbol firstFlag;