]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java
Avoid duplicate evaluation of procedural component type requests
[simantics/platform.git] / bundles / org.simantics.structural2 / src / org / simantics / structural2 / Functions.java
index f429fdc91d104fabcaf53d6fd6c5752bdb1699ad..8bf4e3df68b6ac62dc30b2575ddb3eb75b1b9bf2 100644 (file)
@@ -23,12 +23,14 @@ import org.simantics.db.Resource;
 import org.simantics.db.Statement;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.issue.StandardIssue;
+import org.simantics.db.common.primitiverequest.IsInstanceOf;
 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
 import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.request.PossibleIndexRoot;
 import org.simantics.db.common.request.PossibleObjectWithType;
 import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.common.request.TernaryRead;
 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.function.All;
@@ -48,12 +50,14 @@ import org.simantics.db.layer0.variable.Variable;
 import org.simantics.db.layer0.variable.VariableMap;
 import org.simantics.db.layer0.variable.VariableMapImpl;
 import org.simantics.db.layer0.variable.VariableNode;
+import org.simantics.db.layer0.variable.Variables;
 import org.simantics.db.service.CollectionSupport;
 import org.simantics.issues.common.IssueUtils;
 import org.simantics.layer0.Layer0;
 import org.simantics.scl.reflection.annotations.SCLValue;
 import org.simantics.scl.runtime.SCLContext;
 import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.tuple.Tuple2;
 import org.simantics.simulation.ontology.SimulationResource;
 import org.simantics.simulator.variable.NodeManager;
 import org.simantics.structural.stubs.StructuralResource2;
@@ -180,7 +184,7 @@ public class Functions {
                @Override
                public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {
                        StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; 
-                       return new ConnectionImpl2(context.getParent(graph), variable.property.predicate);
+                       return new ConnectionImpl(context.getParent(graph), variable.property.predicate);
                }
 
                @Override
@@ -329,10 +333,11 @@ public class Functions {
 
     public static List<SubstructureElement> getProceduralDesc(ReadGraph graph, final Variable context) throws DatabaseException {
         StructuralResource2 STR = StructuralResource2.getInstance(graph);
-        final Resource type = context.getPossibleType(graph);
+        Variable config = Variables.getConfigurationVariable(graph, context);
+        final Resource type = config.getPossibleType(graph);
         if(type != null) {
             if(graph.isInstanceOf(type, STR.ProceduralComponentType)) {
-                return graph.syncRequest(new SubstructureRequest(context));
+                return graph.syncRequest(new SubstructureRequest(config));
             }
         }
         return null;
@@ -499,31 +504,48 @@ public class Functions {
                }
 
        }
-       
+
+    private static class StructuralOverrideDataWalkRequest
+            extends TernaryRead<Variable, Resource, Resource, StructuralOverrideData> {
+
+        public StructuralOverrideDataWalkRequest(Variable component, Resource actualRepresents, Resource actualType) {
+            super(component, actualRepresents, actualType);
+        }
+
+        @Override
+        public StructuralOverrideData perform(ReadGraph graph) throws DatabaseException {
+            Variable component = parameter;
+            Resource actualRepresents = parameter2;
+            Resource actualType = parameter3;
+//            System.err.println(component.getURI(graph));
+            Resource represents = component.getPossibleRepresents(graph);
+            if (represents != null) {
+                Layer0 L0 = Layer0.getInstance(graph);
+                StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                Resource container = graph
+                        .syncRequest(new PossibleObjectWithType(represents, L0.PartOf, STR.Composite));
+                if (container != null) {
+                    Map<Resource, Resource> overrides = graph.syncRequest(new StructuralTypeOverrideMap(container), TransientCacheListener.instance());
+                    Resource override = overrides.get(actualType);
+                    if (override != null) {
+                        return new StructuralOverrideData(actualRepresents, actualType, override);
+                    }
+                }
+            }
+            Variable parent = component.getParent(graph);
+            if (parent == null)
+                return new StructuralOverrideData(actualRepresents, actualType, null);
+            else
+                return graph.syncRequest(new StructuralOverrideDataWalkRequest(parent, represents, actualType), TransientCacheListener.instance());
+        }
+
+    }
+
        public static class StructuralOverrideDataRequest extends VariableRead<StructuralOverrideData> {
 
                public StructuralOverrideDataRequest(Variable component) {
                        super(component);
                }
-
-               public StructuralOverrideData walk(ReadGraph graph, Variable component, Resource actualRepresents, Resource actualType) throws DatabaseException {
-               Resource represents = component.getPossibleRepresents(graph);
-               if(represents != null) {
-                       Layer0 L0 = Layer0.getInstance(graph);
-                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
-                       Resource container = graph.syncRequest(new PossibleObjectWithType(represents, L0.PartOf, STR.Composite));
-                       if(container != null) {
-                       Map<Resource,Resource> overrides = graph.syncRequest(new StructuralTypeOverrideMap(container));
-                       Resource override = overrides.get(actualType);
-                       if(override != null) {
-                               return new StructuralOverrideData(actualRepresents, actualType, override);
-                       }
-                       }
-               }
-               Variable parent = component.getParent(graph);
-               if(parent == null) return new StructuralOverrideData(actualRepresents, actualType, null);
-               else return walk(graph, parent, represents, actualType);
-               }
                
                @Override
                public StructuralOverrideData perform(ReadGraph graph) throws DatabaseException {
@@ -532,47 +554,82 @@ public class Functions {
                if(represents == null) {
                        String uri = variable.getPossiblePropertyValue(graph, "typeURI");
                        if(uri != null) {
-                               Resource actualType = graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.<Resource>instance()); 
-                               return walk(graph, variable, null, actualType);
+                               Resource actualType = graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.<Resource>instance());
+                               if (graph.syncRequest(new IsInstanceOf(actualType, StructuralResource2.getInstance(graph).ReplaceableDefinedComponentType), TransientCacheListener.instance()) ) {
+                                   return graph.syncRequest(new StructuralOverrideDataWalkRequest(variable, null, actualType), TransientCacheListener.instance());
+                               } else {
+                                   // can not have replaceable type 
+                                   return null;
+                               }
                        }
                        throw new DatabaseException("No type for " + variable.getURI(graph));
                } else {
-                       return walk(graph, variable, represents, graph.getPossibleType(represents, Layer0.getInstance(graph).Entity));
+                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                   Resource possibleType = graph.getPossibleType(represents, STR.Component);
+                   if (possibleType == null) {
+                       possibleType = graph.getPossibleType(represents, Layer0.getInstance(graph).Entity);
+                       if (possibleType == null)
+                               return null;
+                   }
+                   if (graph.syncRequest(new IsInstanceOf(possibleType, STR.ReplaceableDefinedComponentType), TransientCacheListener.instance()) ) {
+                       return graph.syncRequest(new StructuralOverrideDataWalkRequest(variable, represents, possibleType), TransientCacheListener.instance());
+                   } else {
+                       return null;
+                   }
                }
                        
                }
                
        }
 
-       
+
+    private static class StructureTypeAndChildMapRequest extends ResourceRead<Tuple2> {
+
+        protected StructureTypeAndChildMapRequest(Resource resource) {
+            super(resource);
+        }
+
+        @Override
+        public Tuple2 perform(ReadGraph graph) throws DatabaseException {
+            StructuralComponentClass clazz = StructuralComponentClass.get(graph, resource);
+            if (StructuralComponentClass.DEFINED.equals(clazz)) {
+                StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                Resource def = graph.getSingleObject(resource, STR.IsDefinedBy);
+                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(def), TransientCacheListener.instance());
+                return new Tuple2(clazz, children);
+            }
+            return new Tuple2(clazz, null);
+        }
+        
+    }
+
        @SCLValue(type = "VariableMap")
        public static VariableMap structuralChildDomainChildren = new VariableMapImpl() {
-       
+
                @Override
                public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
-                       
-                       Resource type = context.getPossibleType(graph);
+                       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                       Resource type = context.getPossibleType(graph, STR.Component);
                        if(type == null) return null;
+                   
+                       Tuple2 result = graph.syncRequest(new StructureTypeAndChildMapRequest(type), TransientCacheListener.instance());
+                       StructuralComponentClass clazz = (StructuralComponentClass) result.c0;
                        
-                       StructuralComponentClass clazz = StructuralComponentClass.get(graph, type);
                        if(StructuralComponentClass.PROCEDURAL.equals(clazz)) {
                    Map<String,Variable> map = graph.syncRequest(new ProceduralSubstructureRequest(context),
                         TransientCacheListener.<Map<String,Variable>>instance());
                    if(map != null) return map.get(name);
                    return null;
                        } else if (StructuralComponentClass.DEFINED.equals(clazz)) {
-                               StructuralResource2 STR = StructuralResource2.getInstance(graph);
-                               Resource def = graph.getSingleObject(type, STR.IsDefinedBy);
-                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(def));
+                           Map<String, Resource> children = (Map<String, Resource>) result.c1;
                 Resource child = children.get(name);
                 if(child == null) return null;
                 return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);
                        } else {
                                Resource represents = context.getPossibleRepresents(graph);
                                if(represents == null) return null;
-                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(represents));
+                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(represents), TransientCacheListener.instance());
                 Resource child = children.get(name);
-                if(child == null) return null;
                 return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, child, name);
                        }
 
@@ -600,7 +657,7 @@ public class Functions {
                        } else if (StructuralComponentClass.DEFINED.equals(clazz)) {
                                StructuralResource2 STR = StructuralResource2.getInstance(graph);
                                Resource def = graph.getSingleObject(type, STR.IsDefinedBy);
-                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(def));
+                Map<String, Resource> children = graph.syncRequest(new UnescapedChildMapOfResource(def), TransientCacheListener.instance());
                 return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map);
                        } else {
                                Resource represents = context.getPossibleRepresents(graph);
@@ -694,7 +751,7 @@ public class Functions {
 
                for(Resource req : requiredConnections) {
                        if(!connections.contains(req)) {
-                               result.add(new StandardIssue(sr.ConnectionConstraint_ErrorIssue, component, req));
+                               result.add(new StandardIssue(sr.ConnectionValidationConstraint_ErrorIssue, component, req));
                        }
                }
 
@@ -813,7 +870,7 @@ public class Functions {
                                
                        }
 
-                       final Collection<InterfaceResolution> interfaces = graph.syncRequest(new DefinedUCInterfaceMap(type));
+                       final Collection<InterfaceResolution> interfaces = graph.syncRequest(new DefinedUCInterfaceMap(type), TransientCacheListener.instance());
                        if(interfaces != null) return interfaces;
 
                }
@@ -846,12 +903,12 @@ public class Functions {
         SCLContext sclContext = SCLContext.getCurrent();
         Object oldGraph = sclContext.get("graph");
         try {
-            Function1<Variable,Object> exp = graph.syncRequest(new CompileStructuralValueRequest(graph, context) {
+            Function1<Object,Object> exp = graph.syncRequest(new CompileStructuralValueRequest(graph, context) {
                 protected String getExpressionText(ReadGraph graph) throws DatabaseException {
                     return expression;
                 }
             },
-            TransientCacheListener.<Function1<Variable,Object>>instance());
+            TransientCacheListener.instance());
             sclContext.put("graph", graph);
             return exp.apply(context);
         } catch (DatabaseException e) {