]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/rules/MappedModelingRules.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / rules / MappedModelingRules.java
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/rules/MappedModelingRules.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/rules/MappedModelingRules.java
new file mode 100644 (file)
index 0000000..edf3231
--- /dev/null
@@ -0,0 +1,246 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2014 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *     Semantum Oy - #5290\r
+ *******************************************************************************/\r
+package org.simantics.modeling.rules;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.structural2.modelingRules.AbstractModelingRules;\r
+import org.simantics.structural2.modelingRules.CPConnection;\r
+import org.simantics.structural2.modelingRules.CPConnectionJoin;\r
+import org.simantics.structural2.modelingRules.CPIgnore;\r
+import org.simantics.structural2.modelingRules.CPTerminal;\r
+import org.simantics.structural2.modelingRules.ConnectionJudgement;\r
+import org.simantics.structural2.modelingRules.IAttachmentRelationMap;\r
+import org.simantics.structural2.modelingRules.IConnectionPoint;\r
+import org.simantics.structural2.modelingRules.IModelingRules;\r
+import org.simantics.structural2.modelingRules.Policy;\r
+\r
+public class MappedModelingRules extends AbstractModelingRules {\r
+\r
+    IModelingRules baseRules;\r
+    IMapping mapping;\r
+\r
+    public MappedModelingRules(IModelingRules baseRules, IMapping mapping) {\r
+        super();\r
+        this.baseRules = baseRules;\r
+        this.mapping = mapping;\r
+    }\r
+\r
+    public MappedModelingRules(ReadGraph g, IModelingRules baseRules) throws DatabaseException {\r
+        this(baseRules, new Mapping(g));\r
+    }\r
+\r
+    @Override\r
+    public boolean canPopulate(ReadGraph g, Resource componentType)\r
+    throws DatabaseException {\r
+        Resource mappedComponentType = mapping.mapComponentType(g, componentType);\r
+        if(mappedComponentType == null)\r
+            return false;\r
+        return baseRules.canPopulate(g, mappedComponentType);\r
+    }\r
+\r
+    @Override\r
+    public void setConnectionType(WriteGraph g, Resource connection,\r
+            Resource connectionType) throws DatabaseException {\r
+        StructuralResource2 sr = StructuralResource2.getInstance(g);\r
+        DiagramResource DIA = DiagramResource.getInstance(g); \r
+        ModelingResources MOD = ModelingResources.getInstance(g);\r
+\r
+        if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
+            System.out.println("setConnectionType(" + NameUtils.getSafeName(g, connection) + ", " + NameUtils.getSafeName(g, connectionType) + ")");\r
+\r
+        RelatedDiagramConnections rdc = new RelatedDiagramConnections(g);\r
+        rdc.addConnection(connection);\r
+        for(Resource c : rdc.connections) {\r
+            g.deny(c, sr.HasConnectionType);\r
+            g.claim(c, sr.HasConnectionType, null, connectionType);\r
+        }\r
+\r
+        // Fix MOD.HasConnectionMappingSpecification in output connector(s).\r
+        if (!rdc.outputConnectors.isEmpty()) {\r
+            Resource requiredConnectionMappingSpecification = g.getPossibleObject(connectionType, MOD.ConnectionTypeToConnectionMappingSpecification);\r
+            for (Resource connector : rdc.outputConnectors) {\r
+                for (Statement connects : g.getStatements(connector, sr.Connects)) {\r
+                    if (g.isInstanceOf(connects.getObject(), DIA.Connection))\r
+                        continue;\r
+                    Resource dcp  = g.getPossibleInverse(connects.getPredicate());\r
+                    if (dcp != null) {\r
+                        Resource cp = g.getPossibleObject(dcp, MOD.DiagramConnectionRelationToConnectionRelation);\r
+                        if (cp != null) {\r
+                            g.deny(connector, MOD.HasConnectionMappingSpecification);\r
+                            if (requiredConnectionMappingSpecification != null && g.hasStatement(cp, MOD.NeedsConnectionMappingSpecification)) {\r
+                                g.claim(connector, MOD.HasConnectionMappingSpecification, requiredConnectionMappingSpecification);\r
+                            }\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    class MappedAttachmentRelationMap implements IAttachmentRelationMap {\r
+\r
+        IAttachmentRelationMap baseMap;\r
+\r
+        public MappedAttachmentRelationMap(IAttachmentRelationMap baseMap) {\r
+            this.baseMap = baseMap;\r
+        }\r
+\r
+        @Override\r
+        public Resource get(ReadGraph g, CPTerminal cp)\r
+        throws DatabaseException {\r
+            IConnectionPoint mcp = mapping.mapConnectionPoint(g, cp);\r
+            if(mcp instanceof CPTerminal)\r
+                return baseMap.get(g, (CPTerminal)mcp);\r
+            else\r
+                return null;\r
+        }\r
+\r
+    }\r
+    \r
+    private ArrayList<IConnectionPoint> getMappedConnectionPoints(ReadGraph g,\r
+               Collection<IConnectionPoint> connectionPoints)\r
+                           throws DatabaseException {\r
+\r
+        // Map connection points to configuration\r
+        ArrayList<IConnectionPoint> mappedConnectionPoints =\r
+                new ArrayList<IConnectionPoint>(connectionPoints.size());\r
+       \r
+        // Map connection points to configuration\r
+        for(IConnectionPoint cp : connectionPoints) {\r
+            if(cp == null)\r
+                throw new IllegalArgumentException("Null connection point encountered.");\r
+            if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
+                System.out.println("Mapping CP: " + cp.toString(g));\r
+            int mcps = mapping.mapToConnectionPoints(g, cp, mappedConnectionPoints);\r
+            if(mcps > 0) {\r
+                if(Policy.DEBUG_STANDARD_MODELING_RULES)\r
+                    for (IConnectionPoint mcpt : mappedConnectionPoints.subList(mappedConnectionPoints.size()-mcps, mappedConnectionPoints.size()))\r
+                        System.out.println("Mapped CP: " + mcpt.toString(g));\r
+            } else {\r
+                if(cp instanceof CPTerminal) {\r
+                    // TODO move this logic elsewhere\r
+                    CPTerminal terminal = (CPTerminal)cp;\r
+                    DiagramResource dr = DiagramResource.getInstance(g);\r
+                    if(terminal.component != null && g.isInstanceOf(terminal.component, dr.Flag)) {\r
+                        if(g.hasStatement(terminal.component, dr.Flag_ConnectionPoint))\r
+                            return null;\r
+                        for(Resource join : g.getObjects(terminal.component, dr.FlagIsJoinedBy))\r
+                            mappedConnectionPoints.add(new CPConnectionJoin(join));\r
+                        \r
+                        Resource isLiftedAs = g.getPossibleObject(terminal.component, dr.IsLiftedAs);\r
+                        if (isLiftedAs != null) {\r
+                            // This is a lifted flag in a structural configuration.\r
+                            mappedConnectionPoints.add(new CPTerminal(terminal.component, isLiftedAs));\r
+                        } else {\r
+                            // Do nothing, because the flag is not connected\r
+                        }\r
+                    }\r
+                } else if (cp instanceof CPConnection) {\r
+                    // Do nothing, because ignored connection points are not\r
+                    // meant to affect modelling rules in any way.\r
+                    //System.out.println("Non-mappable connection " + cp.toString(g));\r
+                } else if (cp instanceof CPIgnore) {\r
+                    // Do nothing, because ignored connection points are not\r
+                    // meant to affect modelling rules in any way.\r
+                    // FIXME: this is maybe a bit of a hack.\r
+                    //System.out.println("Ignoring " + cp.toString(g));\r
+                }\r
+                else\r
+                    return null;\r
+            }\r
+        }\r
+        \r
+        return mappedConnectionPoints;\r
+       \r
+    }\r
+    \r
+    @Override\r
+    public ConnectionJudgement judgeConnection(ReadGraph g, Collection<IConnectionPoint> connectionPoints)\r
+               throws DatabaseException {\r
+\r
+       ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);\r
+        if(mappedConnectionPoints == null) return ConnectionJudgement.ILLEGAL; \r
+\r
+        // Judge mapped connection\r
+        ConnectionJudgement judgement = baseRules.judgeConnection(g, mappedConnectionPoints);\r
+\r
+        // Inverse map attachment relations\r
+        if(judgement.attachmentRelations != null)\r
+            judgement.attachmentRelations =\r
+                new MappedAttachmentRelationMap(judgement.attachmentRelations);\r
+\r
+        return judgement;\r
+        \r
+    }\r
+    \r
+    @Override\r
+    public Resource computeConnectionType(ReadGraph g, Collection<IConnectionPoint> connectionPoints) throws DatabaseException {\r
+       \r
+       ArrayList<IConnectionPoint> mappedConnectionPoints = getMappedConnectionPoints(g, connectionPoints);\r
+        if(mappedConnectionPoints == null) return null;\r
+       \r
+        return baseRules.computeConnectionType(g, mappedConnectionPoints);\r
+       \r
+    }\r
+\r
+    @Override\r
+    public IAttachmentRelationMap getAttachmentRelations(ReadGraph g,\r
+            Resource connection) throws DatabaseException {\r
+        Resource mappedConnection = mapping.mapConnection(g, connection);\r
+        if(mappedConnection == null)\r
+            System.err.println("Connection mapped from " + NameUtils.getSafeName(g, connection, true) + " is null");\r
+        return new MappedAttachmentRelationMap(\r
+                baseRules.getAttachmentRelations(g, mappedConnection)\r
+        );\r
+    }\r
+    \r
+       @Override\r
+       public Set<CPTerminal> resolveTerminals(ReadGraph g, Collection<IConnectionPoint> connectionPoints) \r
+                       throws DatabaseException {\r
+               Set<CPTerminal> terminals = new HashSet<CPTerminal>();\r
+               StructuralResource2 STR = StructuralResource2.getInstance(g);\r
+               DiagramResource DIA = DiagramResource.getInstance(g);\r
+               for(IConnectionPoint cp : connectionPoints) {\r
+                       //System.out.println(this + ": translate connection point: " + cp.toString(g));\r
+                       if(cp instanceof CPTerminal)\r
+                               terminals.add((CPTerminal)cp);\r
+                       else if(cp instanceof CPConnection) {\r
+                               CPConnection connection = (CPConnection)cp;\r
+                               for (Resource connector : g.getObjects(connection.connection, DIA.HasConnector)) {\r
+                                       for (Statement stat : g.getStatements(connector, STR.Connects)) {\r
+                                               if(stat.getObject().equals(connection.connection)) continue;\r
+                                               terminals.add(new CPTerminal(stat.getObject(),\r
+                                                               g.getInverse(stat.getPredicate())));\r
+                                       }\r
+                               }\r
+                       }\r
+                       else\r
+                               throw new IllegalArgumentException("Connection point " + cp + " encountered.");\r
+               }\r
+               return terminals;\r
+       }\r
+\r
+}\r