]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java
Cache PropertyInfoRequests in getStandardChildDomainPropertyVariables
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / function / All.java
index 1c9331069ff13f28a56013cb42eaaa514bcd7f20..4e775e08a22e12597044218f138aef3cfcaf6637 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.db.layer0.function;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -27,26 +28,32 @@ import org.simantics.db.Statement;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.issue.StandardIssue;
 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied2;
 import org.simantics.db.WriteGraph;
 import org.simantics.db.common.issue.StandardIssue;
 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied2;
+import org.simantics.db.common.primitiverequest.PossibleResource;
 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
 import org.simantics.db.common.request.IsEnumeratedValue;
 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
 import org.simantics.db.common.request.IsEnumeratedValue;
-import org.simantics.db.common.request.ObjectsWithType;
 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
 import org.simantics.db.common.utils.CommonDBUtils;
 import org.simantics.db.common.utils.Functions;
 import org.simantics.db.common.utils.ListUtils;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.common.uri.UnescapedChildMapOfResource;
 import org.simantics.db.common.utils.CommonDBUtils;
 import org.simantics.db.common.utils.Functions;
 import org.simantics.db.common.utils.ListUtils;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.common.utils.NearestOwnerFinder;
 import org.simantics.db.common.validation.L0Validations;
 import org.simantics.db.common.validation.L0Validations;
+import org.simantics.db.exception.AdaptionException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.DoesNotContainValueException;
 import org.simantics.db.exception.NoSingleResultException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.exception.DoesNotContainValueException;
 import org.simantics.db.exception.NoSingleResultException;
+import org.simantics.db.exception.RuntimeDatabaseException;
+import org.simantics.db.layer0.exception.InvalidVariableException;
+import org.simantics.db.layer0.exception.MissingVariableException;
 import org.simantics.db.layer0.exception.MissingVariableValueException;
 import org.simantics.db.layer0.exception.PendingVariableException;
 import org.simantics.db.layer0.exception.MissingVariableValueException;
 import org.simantics.db.layer0.exception.PendingVariableException;
-import org.simantics.db.layer0.exception.VariableException;
 import org.simantics.db.layer0.request.PossibleURI;
 import org.simantics.db.layer0.request.PropertyInfo;
 import org.simantics.db.layer0.request.PropertyInfoRequest;
 import org.simantics.db.layer0.request.PossibleURI;
 import org.simantics.db.layer0.request.PropertyInfo;
 import org.simantics.db.layer0.request.PropertyInfoRequest;
+import org.simantics.db.layer0.request.UnescapedAssertedPropertyMapOfResource;
+import org.simantics.db.layer0.request.UnescapedMethodMapOfResource;
 import org.simantics.db.layer0.request.UnescapedPropertyMapOfResource;
 import org.simantics.db.layer0.scl.CompileResourceValueRequest;
 import org.simantics.db.layer0.scl.CompileValueRequest;
 import org.simantics.db.layer0.request.UnescapedPropertyMapOfResource;
 import org.simantics.db.layer0.scl.CompileResourceValueRequest;
 import org.simantics.db.layer0.scl.CompileValueRequest;
@@ -56,6 +63,7 @@ import org.simantics.db.layer0.variable.AbstractVariable;
 import org.simantics.db.layer0.variable.ChildVariableMapRequest;
 import org.simantics.db.layer0.variable.ExternalSetValue;
 import org.simantics.db.layer0.variable.PropertyVariableMapRequest;
 import org.simantics.db.layer0.variable.ChildVariableMapRequest;
 import org.simantics.db.layer0.variable.ExternalSetValue;
 import org.simantics.db.layer0.variable.PropertyVariableMapRequest;
+import org.simantics.db.layer0.variable.StandardAssertedGraphPropertyVariable;
 import org.simantics.db.layer0.variable.StandardComposedProperty;
 import org.simantics.db.layer0.variable.StandardGraphChildVariable;
 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
 import org.simantics.db.layer0.variable.StandardComposedProperty;
 import org.simantics.db.layer0.variable.StandardGraphChildVariable;
 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
@@ -76,8 +84,10 @@ import org.simantics.db.service.UndoRedoSupport;
 import org.simantics.issues.ontology.IssueResource;
 import org.simantics.layer0.Layer0;
 import org.simantics.scl.reflection.annotations.SCLValue;
 import org.simantics.issues.ontology.IssueResource;
 import org.simantics.layer0.Layer0;
 import org.simantics.scl.reflection.annotations.SCLValue;
+import org.simantics.scl.runtime.SCLContext;
 import org.simantics.scl.runtime.function.Function4;
 import org.simantics.scl.runtime.function.FunctionImpl1;
 import org.simantics.scl.runtime.function.Function4;
 import org.simantics.scl.runtime.function.FunctionImpl1;
+import org.simantics.scl.runtime.function.FunctionImpl2;
 import org.simantics.simulator.variable.exceptions.NodeManagerException;
 import org.simantics.utils.Development;
 import org.simantics.utils.datastructures.Pair;
 import org.simantics.simulator.variable.exceptions.NodeManagerException;
 import org.simantics.utils.Development;
 import org.simantics.utils.datastructures.Pair;
@@ -118,10 +128,20 @@ public class All {
                        
             if (variable.isAsserted()) {
                                if (variable.parentResource != null) {
                        
             if (variable.isAsserted()) {
                                if (variable.parentResource != null) {
-                           Layer0 L0 = Layer0.getInstance(graph);
-                                       for(Resource assertion : graph.syncRequest(new ObjectsWithType(variable.parentResource, L0.Asserts, L0.Assertion))) {
-                                               if(variable.property.predicate.equals(graph.getSingleObject(assertion, L0.HasPredicate))) {
-                                                       return graph.getRelatedValue2(assertion, L0.HasObject, variable);
+                                       Map<String, Pair<PropertyInfo, Resource>> assertions = graph.syncRequest(
+                                                       new UnescapedAssertedPropertyMapOfResource(variable.parentResource),
+                                                       TransientCacheAsyncListener.instance());
+
+                                       // NOTE: This optimization assumes the property
+                                       // variable's representation is the asserted object.
+                                       Resource object = variable.getPossibleRepresents(graph);
+                                       if (object != null) {
+                                               return graph.getValue2(object, variable);
+                                       } else {
+                                               for (Pair<PropertyInfo, Resource> assertion : assertions.values()) {
+                                                       if (assertion.first.predicate.equals(variable.property.predicate)) {
+                                                               return graph.getValue2(assertion.second, variable);
+                                                       }
                                                }
                                        }
                                }
                                                }
                                        }
                                }
@@ -150,19 +170,18 @@ public class All {
                 if(value == null) throw new MissingVariableValueException(variable.getPossibleURI(graph));
                 return value.getValue(binding);
             } catch (AdaptException e) {
                 if(value == null) throw new MissingVariableValueException(variable.getPossibleURI(graph));
                 return value.getValue(binding);
             } catch (AdaptException e) {
-                throw new DatabaseException(e);
+                throw new AdaptionException("Could not get value for " + context.getURI(graph), e);
             }
         }
                
        try {
                        
             }
         }
                
        try {
                        
-               Layer0 L0 = Layer0.getInstance(graph);
-               
                if(variable.property.hasEnumerationRange) {
                Resource object = variable.getRepresents(graph);
                if(graph.sync(new IsEnumeratedValue(object))) {
                if(variable.property.hasEnumerationRange) {
                Resource object = variable.getRepresents(graph);
                if(graph.sync(new IsEnumeratedValue(object))) {
+                       Layer0 L0 = Layer0.getInstance(graph);
                        if(graph.isInstanceOf(object, L0.Literal)) {
                        if(graph.isInstanceOf(object, L0.Literal)) {
-                               return graph.getValue(object);
+                               return graph.getValue(object, binding);
                        } else {
                                return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel, binding);
                        }
                        } else {
                                return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel, binding);
                        }
@@ -171,11 +190,22 @@ public class All {
                        
                if (variable.isAsserted()) {
                        if (variable.parentResource != null) {
                        
                if (variable.isAsserted()) {
                        if (variable.parentResource != null) {
-                               for(Resource assertion : graph.syncRequest(new ObjectsWithType(variable.parentResource, L0.Asserts, L0.Assertion))) {
-                                       if(variable.property.predicate.equals(graph.getSingleObject(assertion, L0.HasPredicate))) {
-                                               return graph.getRelatedValue2(assertion, L0.HasObject, context);
-                                       }
-                               }
+                                       Map<String, Pair<PropertyInfo, Resource>> assertions = graph.syncRequest(
+                                                       new UnescapedAssertedPropertyMapOfResource(variable.parentResource),
+                                                       TransientCacheAsyncListener.instance());
+
+                                       // NOTE: This optimization assumes the property
+                                       // variable's representation is the asserted object.
+                                       Resource object = variable.getPossibleRepresents(graph);
+                                       if (object != null) {
+                                               return graph.getValue2(object, variable, binding);
+                                       } else {
+                                               for (Pair<PropertyInfo, Resource> assertion : assertions.values()) {
+                                                       if (assertion.first.predicate.equals(variable.property.predicate)) {
+                                                               return graph.getValue2(assertion.second, variable, binding);
+                                                       }
+                                               }
+                                       }
                        }
                }
                        
                        }
                }
                        
@@ -240,7 +270,7 @@ public class All {
                try {
                        modifier.apply(graph, context, value, Bindings.getBinding(value.getClass()));
                } catch (BindingConstructionException e) {
                try {
                        modifier.apply(graph, context, value, Bindings.getBinding(value.getClass()));
                } catch (BindingConstructionException e) {
-                       throw new DatabaseException(e);
+                       throw new org.simantics.db.exception.BindingException("",e);
                }
 
        }
                }
 
        }
@@ -450,6 +480,33 @@ public class All {
             // Fallback: try to ask property resource uri from NodeManager
             return createStandardGraphPropertyVariable(graph, variable, propertyNode);
         }
             // Fallback: try to ask property resource uri from NodeManager
             return createStandardGraphPropertyVariable(graph, variable, propertyNode);
         }
+        // Final fallback: check types corresponding to
+        // node classification(s) and look for asserted
+        // properties from the URIs specified.
+        if (variable.node != null) {
+            try {
+                @SuppressWarnings("unchecked")
+                Set<String> classifications = variable.node.support.manager.getClassifications(variable.node.node);
+                if (!classifications.isEmpty()) {
+                    for (String uri : classifications) {
+                        Resource type = graph.syncRequest(
+                                new PossibleResource(uri),
+                                TransientCacheAsyncListener.instance());
+                        if (type == null)
+                            continue;
+                        Map<String, Pair<PropertyInfo, Resource>> pm = graph.syncRequest(
+                                new UnescapedAssertedPropertyMapOfResource(type),
+                                TransientCacheAsyncListener.instance());
+                        Pair<PropertyInfo, Resource> pi = pm.get(name);
+                        if (pi != null) {
+                            return new StandardAssertedGraphPropertyVariable(graph, context, null, type, pi.first.predicate, pi.second);
+                        }
+                    }
+                }
+            } catch(NodeManagerException e) {
+                throw new DatabaseException(e);
+            }
+        }
         return null;
     }
 
         return null;
     }
 
@@ -513,9 +570,9 @@ public class All {
             // Process graph properties
             for(Resource predicate : predicates) {
                
             // Process graph properties
             for(Resource predicate : predicates) {
                
-                       PropertyInfo info = graph.isImmutable(predicate) ?
-                                       graph.syncRequest(new PropertyInfoRequest(predicate), TransientCacheAsyncListener.<PropertyInfo>instance()) :
-                                               graph.syncRequest(new PropertyInfoRequest(predicate));
+                       PropertyInfo info = //graph.isImmutable(predicate) ?
+                                       graph.syncRequest(new PropertyInfoRequest(predicate), TransientCacheAsyncListener.<PropertyInfo>instance());// :
+                                               //graph.syncRequest(new PropertyInfoRequest(predicate));
 
                        if(!info.isHasProperty) continue;
                                        
 
                        if(!info.isHasProperty) continue;
                                        
@@ -547,6 +604,47 @@ public class All {
                
        };
        
                
        };
        
+    @SCLValue(type = "VariableMap")
+       public static VariableMap methodsPropertyDomainProperties = new VariableMapImpl() {
+       
+               @Override
+               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {
+                       Variable parent = context.getParent(graph);
+                       Resource container = parent.getPossibleRepresents(graph);
+                       if(container == null)
+                               return null;
+                       Map<String,Resource> methods = graph.syncRequest(new UnescapedMethodMapOfResource(container));
+                       Resource predicate = methods.get(name);
+                       if(predicate != null) {
+                               Layer0 L0 = Layer0.getInstance(graph);
+                               PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(L0.Entity_method));
+                               Resource value = graph.getSingleObject(container, predicate);
+                               return new StandardGraphPropertyVariable(context, null, container, info, value);
+                       }
+                       return null;
+               }
+
+               @Override
+               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {
+                       Variable parent = context.getParent(graph);
+                       Resource container = parent.getPossibleRepresents(graph);
+                       if(container == null)
+                               return Collections.emptyMap();
+                       Map<String,Resource> methods = graph.syncRequest(new UnescapedMethodMapOfResource(container));
+                       for(Map.Entry<String, Resource> entry : methods.entrySet()) {
+                               String name = entry.getKey();
+                               Resource predicate = entry.getValue();
+                               Layer0 L0 = Layer0.getInstance(graph);
+                               PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(L0.Entity_method));
+                               Resource value = graph.getSingleObject(container, predicate);
+                               if(map == null) map = new HashMap<>();
+                               map.put(name, new StandardGraphPropertyVariable(context, null, container, info, value));
+                       }
+                       return map;
+               }
+               
+       };
+
        public static Variable getStandardPropertyDomainPropertyVariableFromValue(ReadGraph graph, Variable context, String name) throws DatabaseException {
 
                if(context instanceof StandardGraphPropertyVariable) {
        public static Variable getStandardPropertyDomainPropertyVariableFromValue(ReadGraph graph, Variable context, String name) throws DatabaseException {
 
                if(context instanceof StandardGraphPropertyVariable) {
@@ -894,7 +992,7 @@ public class All {
        
        public static PropertyInfo getPossiblePropertyInfoFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException {
            if(context == null) return null;
        
        public static PropertyInfo getPossiblePropertyInfoFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException {
            if(context == null) return null;
-               Map<String, PropertyInfo> predicates = graph.syncRequest(new UnescapedPropertyMapOfResource(context));
+               Map<String, PropertyInfo> predicates = graph.syncRequest(new UnescapedPropertyMapOfResource(context), TransientCacheListener.instance());
                return predicates.get(name);
        }
 
                return predicates.get(name);
        }
 
@@ -1212,14 +1310,14 @@ public class All {
                }
 
                if (variable.parentResource == null)
                }
 
                if (variable.parentResource == null)
-                       throw new VariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").");
+                       throw new InvalidVariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").");
 
                try {
                        return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);
                } catch (NoSingleResultException e) {
 
                try {
                        return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);
                } catch (NoSingleResultException e) {
-                       throw new MissingVariableValueException(variable.getPossibleURI(graph));
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph), e);
                } catch (DoesNotContainValueException e) {
                } catch (DoesNotContainValueException e) {
-                       throw new MissingVariableValueException(variable.getPossibleURI(graph));
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph), e);
                }
                
        }
                }
                
        }
@@ -1235,14 +1333,14 @@ public class All {
                }
 
                if (variable.parentResource == null)
                }
 
                if (variable.parentResource == null)
-                       throw new VariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").");
+                       throw new MissingVariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").", context.getPossibleRepresents(graph));
 
                try {
                        return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);
                } catch (NoSingleResultException e) {
 
                try {
                        return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);
                } catch (NoSingleResultException e) {
-                       throw new MissingVariableValueException(variable.getPossibleURI(graph));
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph), e);
                } catch (DoesNotContainValueException e) {
                } catch (DoesNotContainValueException e) {
-                       throw new MissingVariableValueException(variable.getPossibleURI(graph));
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph), e);
                }
                
        }
                }
                
        }
@@ -1406,7 +1504,7 @@ public class All {
         ClusteringSupport cs = graph.getService(ClusteringSupport.class);
         if(cs.isClusterSet(resource) && !base.equals(resource)) return resource;
         
         ClusteringSupport cs = graph.getService(ClusteringSupport.class);
         if(cs.isClusterSet(resource) && !base.equals(resource)) return resource;
         
-        Resource nearest = CommonDBUtils.getNearestOwner(graph, Collections.singletonList(resource));
+        Resource nearest = NearestOwnerFinder.getNearestOwner(graph, resource);
         if(nearest == null) return null;
         
         return getPossibleNearestClusterSet(graph, base, nearest);
         if(nearest == null) return null;
         
         return getPossibleNearestClusterSet(graph, base, nearest);
@@ -1532,4 +1630,28 @@ public class All {
                return parent.node.support.manager.getPropertyURI(parent.node.node, node);
        }
     
                return parent.node.support.manager.getPropertyURI(parent.node.node, node);
        }
     
+
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")
+    public static Object defaultInstantiateUnder(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {
+        return new FunctionImpl2<Resource, Resource, Resource>() {
+            public Resource apply(Resource container, Resource type) {
+                try {
+                    WriteGraph graph = (WriteGraph)SCLContext.getCurrent().get("graph");
+
+                    Layer0 L0 = Layer0.getInstance(graph);
+                    CommonDBUtils.selectClusterSet(graph, container);
+                    Resource result = graph.newResource();
+                    String name = NameUtils.findFreshInstanceName(graph, type, container);
+                    graph.claim(result, L0.InstanceOf, type);
+                    graph.addLiteral(result, L0.HasName, L0.NameOf, name, Bindings.STRING);
+                    graph.claim(container, L0.ConsistsOf, L0.PartOf, result);
+
+                    return result;
+                } catch (DatabaseException e) {
+                    throw new RuntimeDatabaseException(e);
+                }
+            }
+        };
+    }
+
 }
\ No newline at end of file
 }
\ No newline at end of file