]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.structural2/src/org/simantics/structural2/variables/StandardProceduralChildVariable.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.structural2 / src / org / simantics / structural2 / variables / StandardProceduralChildVariable.java
diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/StandardProceduralChildVariable.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/variables/StandardProceduralChildVariable.java
new file mode 100644 (file)
index 0000000..30902b2
--- /dev/null
@@ -0,0 +1,354 @@
+package org.simantics.structural2.variables;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.NoSingleResultException;\r
+import org.simantics.db.layer0.function.All;\r
+import org.simantics.db.layer0.request.ClassificationsRequest;\r
+import org.simantics.db.layer0.variable.AbstractChildVariable;\r
+import org.simantics.db.layer0.variable.NodeSupport;\r
+import org.simantics.db.layer0.variable.StandardAssertedGraphPropertyVariable;\r
+import org.simantics.db.layer0.variable.StandardConstantGraphPropertyVariable;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.VariableNode;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.simulator.variable.NodeManager;\r
+import org.simantics.structural2.Functions;\r
+import org.simantics.structural2.procedural.Connection;\r
+import org.simantics.structural2.procedural.ConnectionPoint;\r
+import org.simantics.structural2.procedural.Expression;\r
+import org.simantics.structural2.procedural.Interface;\r
+import org.simantics.structural2.procedural.Property;\r
+import org.simantics.structural2.procedural.Terminal;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+public class StandardProceduralChildVariable extends AbstractChildVariable {\r
+\r
+       /*\r
+        * Extension points\r
+        * \r
+        */\r
+       public Variable getPossibleSpecialChild(ReadGraph graph, String name) throws DatabaseException {\r
+               return null;\r
+       }\r
+\r
+       public void collectSpecialChildren(ReadGraph graph, Map<String, Variable> children) throws DatabaseException {\r
+       }\r
+\r
+       /*\r
+        * Standard implementation\r
+        * \r
+        */\r
+       \r
+       final protected String name;\r
+       final protected Variable parent;\r
+       final private Resource type;\r
+       final private Map<String, Variable> properties;\r
+       final private List<Object> propertyIdentity;\r
+       \r
+    public static class FixedConnection implements org.simantics.structural2.variables.Connection {\r
+\r
+               final public Collection<Pair<String,Resource>> cps = new ArrayList<Pair<String,Resource>>();\r
+        \r
+        final private Variable parent;\r
+        \r
+        public FixedConnection(Variable parent) {\r
+            this.parent = parent;\r
+        }\r
+        \r
+        @Override\r
+        public Collection<Variable> getConnectionPoints(ReadGraph graph, Resource relationType) throws DatabaseException {\r
+               \r
+               Set<Variable> result = new THashSet<Variable>();\r
+            for(Pair<String,Resource> cp : cps) {\r
+               Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); \r
+               Variable cp2 = component.getPossibleProperty(graph, cp.second);\r
+               if(cp2 != null)\r
+                       for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, relationType)) {\r
+                               result.add(desc.getVariable(graph));\r
+                       }\r
+                else\r
+                       System.err.println("no cp " + cp.first + " for " + component.getURI(graph));\r
+            }\r
+            return result;\r
+            \r
+        }\r
+        \r
+               @Override\r
+               public Collection<String> getConnectionPointURIs(ReadGraph graph, Resource relationType) throws DatabaseException {\r
+                       \r
+               Set<String> result = new THashSet<String>();\r
+            for(Pair<String,Resource> cp : cps) {\r
+               Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); \r
+               Variable cp2 = component.getPossibleProperty(graph, cp.second);\r
+               if(cp2 != null)\r
+                       for(VariableConnectionPointDescriptor desc : ConnectionBrowser.flatten(graph, component, cp.second, relationType)) {\r
+                               result.add(desc.getURI(graph));\r
+                       }\r
+                else\r
+                       System.err.println("no cp " + cp.first + " for " + component.getURI(graph));\r
+            }\r
+            return result;\r
+                       \r
+               }\r
+               \r
+               @Override\r
+               public Collection<VariableConnectionPointDescriptor> getConnectionPointDescriptors(ReadGraph graph, Resource relationType) throws DatabaseException {\r
+                       \r
+               Set<VariableConnectionPointDescriptor> result = new THashSet<VariableConnectionPointDescriptor>();\r
+            for(Pair<String,Resource> cp : cps) {\r
+               Variable component = cp.first == null ? parent : parent.getChild(graph, cp.first); \r
+               Variable cp2 = component.getPossibleProperty(graph, cp.second);\r
+               if(cp2 != null)\r
+                       result.addAll(ConnectionBrowser.flatten(graph, component, cp.second, relationType));\r
+                else\r
+                       System.err.println("no cp " + cp.first + " for " + component.getURI(graph));\r
+            }\r
+            return result;\r
+                       \r
+               }        \r
+\r
+        @Override\r
+               public int hashCode() {\r
+                       final int prime = 31;\r
+                       int result = 1;\r
+                       result = prime * result + ((cps == null) ? 0 : cps.hashCode());\r
+                       result = prime * result\r
+                                       + ((parent == null) ? 0 : parent.hashCode());\r
+                       return result;\r
+               }\r
+\r
+               @Override\r
+               public boolean equals(Object obj) {\r
+                       if (this == obj)\r
+                               return true;\r
+                       if (obj == null)\r
+                               return false;\r
+                       if (getClass() != obj.getClass())\r
+                               return false;\r
+                       FixedConnection other = (FixedConnection) obj;\r
+                       if (cps == null) {\r
+                               if (other.cps != null)\r
+                                       return false;\r
+                       } else if (!cps.equals(other.cps))\r
+                               return false;\r
+                       if (parent == null) {\r
+                               if (other.parent != null)\r
+                                       return false;\r
+                       } else if (!parent.equals(other.parent))\r
+                               return false;\r
+                       return true;\r
+               }\r
+\r
+    }\r
+    \r
+       public StandardProceduralChildVariable(ReadGraph graph, Variable parent, VariableNode node, String name, Resource type, List<Property> properties, Collection<Connection> conns) throws DatabaseException {\r
+               super(node);\r
+               assert name != null;\r
+        assert type != null;\r
+        this.name = name;\r
+               this.parent = parent;\r
+               this.type = type;\r
+               this.properties = new THashMap<String,Variable>();\r
+               \r
+               this.propertyIdentity = new ArrayList<Object>(properties.size()+conns.size());\r
+               propertyIdentity.addAll(properties);\r
+               propertyIdentity.addAll(conns);\r
+               \r
+               Layer0 L0 = Layer0.getInstance(graph);\r
+\r
+               Map<String,Statement> assertedProperties = new THashMap<String, Statement>();\r
+               for(Statement stm : graph.getAssertedStatements(type, L0.HasProperty)) {\r
+            String pn = graph.getRelatedValue(stm.getPredicate(), L0.HasName, Bindings.STRING);\r
+            assertedProperties.put(pn, stm);\r
+               }\r
+               \r
+        Collection<Object> nodeProperties = All.getPossibleNodeProperties(graph, (AbstractChildVariable)this);\r
+        Set<String> used = new HashSet<String>(nodeProperties.size());\r
+        for(Object nodeProperty : nodeProperties) {\r
+            @SuppressWarnings("rawtypes")\r
+            NodeSupport support = node.support;\r
+            @SuppressWarnings("rawtypes")\r
+            NodeManager manager = support.manager;\r
+            @SuppressWarnings("unchecked")\r
+            String pName = manager.getName(nodeProperty);\r
+            used.add(pName);\r
+            Statement assertedProperty = assertedProperties.get(pName); \r
+            if(assertedProperty != null) {\r
+                this.properties.put(pName, new StandardAssertedGraphPropertyVariable(graph, this, new VariableNode(support, nodeProperty), assertedProperty.getSubject(), assertedProperty.getPredicate(), assertedProperty.getObject()));\r
+            }\r
+        }\r
+        \r
+        for(Map.Entry<String, Statement> entry : assertedProperties.entrySet()) {\r
+            String pName = entry.getKey();\r
+            if(used.contains(pName)) continue;\r
+            Statement assertedProperty = entry.getValue();\r
+            this.properties.put(pName, new StandardAssertedGraphPropertyVariable(graph, this, null, assertedProperty.getSubject(), assertedProperty.getPredicate(), assertedProperty.getObject()));\r
+        }\r
+               \r
+               \r
+               for(Property p : properties) {\r
+                   String pn = graph.getRelatedValue(p.relation, L0.HasName, Bindings.STRING);\r
+                   if(p.value == null) {\r
+                       Logger.defaultLogError("StandardProceduralChildVariable " + getURI(graph) + ": null value for property " + pn);\r
+                   } else if (p.value instanceof Expression) {\r
+                       Expression expression = (Expression)p.value;\r
+                           this.properties.put(pn, new StructuralProceduralExpressionPropertyVariable(graph, this, p.relation, expression.text) );\r
+                   } else {\r
+                           this.properties.put(pn, new StandardConstantGraphPropertyVariable(graph, this, p.relation, p.value) );\r
+                   }\r
+                       \r
+                       \r
+               }\r
+           Map<Resource,FixedConnection> map = new HashMap<Resource,FixedConnection>();\r
+               for(Connection conn : conns) {\r
+                   Resource p = null;\r
+                   List<Pair<String,Resource>> cps = new ArrayList<Pair<String,Resource>>();\r
+                   for(ConnectionPoint cp : conn.connectionPoints) {\r
+                       if(cp instanceof Terminal) {\r
+                           Terminal t = (Terminal)cp;\r
+                           if(t.component.equals(name)) {\r
+                               p = t.relation;\r
+                               continue;\r
+                           }\r
+                           cps.add(Pair.make(t.component, t.relation));\r
+                       }\r
+                       if(cp instanceof Interface) {\r
+                               Interface inf = (Interface)cp;\r
+                           cps.add(new Pair<String,Resource>(null, inf.relation));\r
+                       }\r
+                   }\r
+                   if(p != null) {\r
+                       FixedConnection fc = map.get(p);\r
+                       if(fc == null) {\r
+                               fc = new FixedConnection(parent);\r
+                               map.put(p, fc);\r
+                       }\r
+                       fc.cps.addAll(cps);             \r
+                   }\r
+               }\r
+               for(Map.Entry<Resource, FixedConnection> entry : map.entrySet()) {\r
+                       Resource cp = entry.getKey();\r
+            String cpName = graph.getRelatedValue(cp, L0.HasName, Bindings.STRING);\r
+               this.properties.put(cpName, new StandardConstantGraphPropertyVariable(graph, this, cp, entry.getValue()));\r
+               }\r
+               \r
+       }\r
+\r
+       @Override\r
+       public void validate(ReadGraph graph) throws DatabaseException {\r
+       }\r
+       \r
+       @Override\r
+       public Resource getType(ReadGraph graph) throws DatabaseException {\r
+           return type;\r
+       }\r
+       \r
+       @Override\r
+       public Resource getPossibleType(ReadGraph graph) throws DatabaseException {\r
+           return type;\r
+       }\r
+       \r
+       @Override\r
+       public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException {\r
+               if (graph.isInheritedFrom(type, baseType))\r
+                       return type;\r
+               throw new NoSingleResultException("variable " + getPossibleURI(graph) + " has no type");\r
+       }\r
+       \r
+       @Override\r
+       public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException {\r
+               return graph.isInheritedFrom(type, baseType) ? type : null;\r
+       }\r
+       \r
+       @Override\r
+       protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {\r
+           return properties.get(name);\r
+       }\r
+\r
+       @Override\r
+       public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {\r
+           return Functions.structuralChildDomainChildren.getVariable(graph, this, name);\r
+       }\r
+\r
+       @Override\r
+       public Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {\r
+               if(!this.properties.isEmpty()) {\r
+                       if(properties == null) properties = new THashMap<String,Variable>(this.properties.size());\r
+                       properties.putAll(this.properties);\r
+               }\r
+               return properties;\r
+       }\r
+\r
+       @Override\r
+       public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {\r
+            Map<String,Variable> result = Functions.structuralChildDomainChildren.getVariables(graph, this, null);\r
+            if(result == null) return Collections.emptyList();\r
+            else return result.values();\r
+       }\r
+\r
+       public Set<String> getClassifications(ReadGraph graph) throws DatabaseException {\r
+               Resource type = getPossibleType(graph);\r
+               return (type != null)\r
+                               ? graph.syncRequest(new ClassificationsRequest(Collections.singleton(type)))\r
+                               : Collections.<String>emptySet();\r
+       }\r
+\r
+       @Override\r
+       public String getName(ReadGraph graph) throws DatabaseException {\r
+           return name;\r
+       }\r
+\r
+       @Override\r
+       public Variable getParent(ReadGraph graph) throws DatabaseException {\r
+               return parent;\r
+       }\r
+       \r
+       @Override\r
+       final public Resource getRepresents(ReadGraph graph) throws DatabaseException {\r
+           return null;\r
+       }\r
+\r
+       @Override\r
+       public int hashCode() {\r
+               return parent.hashCode() + 31*name.hashCode() + 41*type.hashCode() + 71*System.identityHashCode(propertyIdentity);\r
+       }\r
+\r
+       @Override\r
+       public boolean equals(Object obj) {\r
+               \r
+               if (this == obj)\r
+                       return true;\r
+               if (obj == null)\r
+                       return false;\r
+               if (getClass() != obj.getClass())\r
+                       return false;\r
+               \r
+               StandardProceduralChildVariable other = (StandardProceduralChildVariable) obj;\r
+               \r
+               if(!name.equals(other.name)) return false;\r
+               if(!type.equals(other.type)) return false;\r
+               if(!parent.equals(other.parent)) return false;\r
+               if(propertyIdentity != other.propertyIdentity) return false;\r
+                               \r
+               return true;\r
+               \r
+       }\r
+       \r
+}\r