]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / function / All.java
diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java
new file mode 100644 (file)
index 0000000..501e85f
--- /dev/null
@@ -0,0 +1,1535 @@
+package org.simantics.db.layer0.function;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.List;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.concurrent.atomic.AtomicReference;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.accessor.reference.ChildReference;\r
+import org.simantics.databoard.accessor.reference.IndexReference;\r
+import org.simantics.databoard.adapter.AdaptException;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.binding.error.BindingConstructionException;\r
+import org.simantics.databoard.binding.error.BindingException;\r
+import org.simantics.databoard.binding.mutable.Variant;\r
+import org.simantics.databoard.type.ArrayType;\r
+import org.simantics.databoard.type.Datatype;\r
+import org.simantics.databoard.type.NumberType;\r
+import org.simantics.databoard.util.Range;\r
+import org.simantics.db.Issue;\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.issue.StandardIssue;\r
+import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied2;\r
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
+import org.simantics.db.common.request.IsEnumeratedValue;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.uri.UnescapedChildMapOfResource;\r
+import org.simantics.db.common.utils.CommonDBUtils;\r
+import org.simantics.db.common.utils.Functions;\r
+import org.simantics.db.common.utils.ListUtils;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.common.validation.L0Validations;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.DoesNotContainValueException;\r
+import org.simantics.db.exception.NoSingleResultException;\r
+import org.simantics.db.layer0.exception.MissingVariableValueException;\r
+import org.simantics.db.layer0.exception.PendingVariableException;\r
+import org.simantics.db.layer0.exception.VariableException;\r
+import org.simantics.db.layer0.request.PossibleURI;\r
+import org.simantics.db.layer0.request.PropertyInfo;\r
+import org.simantics.db.layer0.request.PropertyInfoRequest;\r
+import org.simantics.db.layer0.request.UnescapedPropertyMapOfResource;\r
+import org.simantics.db.layer0.scl.CompileResourceValueRequest;\r
+import org.simantics.db.layer0.scl.CompileValueRequest;\r
+import org.simantics.db.layer0.util.Layer0Utils;\r
+import org.simantics.db.layer0.util.PrimitiveValueParser;\r
+import org.simantics.db.layer0.variable.AbstractVariable;\r
+import org.simantics.db.layer0.variable.ChildVariableMapRequest;\r
+import org.simantics.db.layer0.variable.ExternalSetValue;\r
+import org.simantics.db.layer0.variable.PropertyVariableMapRequest;\r
+import org.simantics.db.layer0.variable.StandardComposedProperty;\r
+import org.simantics.db.layer0.variable.StandardGraphChildVariable;\r
+import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;\r
+import org.simantics.db.layer0.variable.SubliteralPropertyVariable;\r
+import org.simantics.db.layer0.variable.SubliteralPropertyVariableDeprecated;\r
+import org.simantics.db.layer0.variable.ValueAccessor;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.VariableBuilder;\r
+import org.simantics.db.layer0.variable.VariableMap;\r
+import org.simantics.db.layer0.variable.VariableMapImpl;\r
+import org.simantics.db.layer0.variable.VariableNode;\r
+import org.simantics.db.layer0.variable.VariableNodeReadRunnable;\r
+import org.simantics.db.layer0.variable.VariableUtils;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.layer0.variable.Variables.NodeStructure;\r
+import org.simantics.db.service.ClusteringSupport;\r
+import org.simantics.db.service.UndoRedoSupport;\r
+import org.simantics.issues.ontology.IssueResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.scl.reflection.annotations.SCLValue;\r
+import org.simantics.scl.runtime.function.Function4;\r
+import org.simantics.scl.runtime.function.FunctionImpl1;\r
+import org.simantics.simulator.variable.exceptions.NodeManagerException;\r
+import org.simantics.utils.Development;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.strings.StringInputValidator;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+public class All {\r
+\r
+       public static Object standardGetValue1(ReadGraph graph, Variable context) throws DatabaseException {\r
+\r
+               StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
+\r
+        // First from node\r
+        if(variable.node != null) {\r
+            Variant value = Variables.requestNodeValue(graph, variable.node);\r
+            if(Variables.PENDING_NODE_VALUE == value) throw new PendingVariableException("");\r
+            return value.getValue();\r
+        }\r
+               \r
+               try {\r
+\r
+            if(variable.property.hasEnumerationRange) {\r
+                       Resource object = variable.getRepresents(graph);\r
+                               if(graph.sync(new IsEnumeratedValue(object))) {\r
+                           Layer0 L0 = Layer0.getInstance(graph);\r
+                                       if(graph.isInstanceOf(object, L0.Literal)) {\r
+                                               return graph.getValue(object);\r
+                                       } else {\r
+                                               String label = graph.getPossibleRelatedValue2(variable.getRepresents(graph), L0.HasLabel, Bindings.STRING);\r
+                                               if(label == null) label = graph.getPossibleRelatedValue(variable.getRepresents(graph), L0.HasName, Bindings.STRING);\r
+                                               if(label == null) label = "<no label>";\r
+                                               return label;\r
+                                       }\r
+                               }\r
+            }\r
+                       \r
+            if (variable.isAsserted()) {\r
+                               if (variable.parentResource != null) {\r
+                           Layer0 L0 = Layer0.getInstance(graph);\r
+                                       for(Resource assertion : graph.syncRequest(new ObjectsWithType(variable.parentResource, L0.Asserts, L0.Assertion))) {\r
+                                               if(variable.property.predicate.equals(graph.getSingleObject(assertion, L0.HasPredicate))) {\r
+                                                       return graph.getRelatedValue2(assertion, L0.HasObject, variable);\r
+                                               }\r
+                                       }\r
+                               }\r
+            }\r
+                \r
+                       return graph.getValue2(variable.getRepresents(graph), variable);\r
+                       \r
+               } catch (NoSingleResultException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph), e);\r
+               } catch (DoesNotContainValueException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph), e);\r
+               } catch (DatabaseException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph), e);\r
+               }\r
+\r
+       }\r
+       \r
+       public static Object standardGetValue2(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {           \r
+               StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
+\r
+        // First from node\r
+        if(variable.node != null) {\r
+            try {\r
+                Variant value = Variables.requestNodeValue(graph, variable.node, binding);\r
+                if(Variables.PENDING_NODE_VALUE == value) throw new PendingVariableException("");\r
+                if(value == null) throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
+                return value.getValue(binding);\r
+            } catch (AdaptException e) {\r
+                throw new DatabaseException(e);\r
+            }\r
+        }\r
+               \r
+       try {\r
+                       \r
+               Layer0 L0 = Layer0.getInstance(graph);\r
+               \r
+               if(variable.property.hasEnumerationRange) {\r
+               Resource object = variable.getRepresents(graph);\r
+               if(graph.sync(new IsEnumeratedValue(object))) {\r
+                       if(graph.isInstanceOf(object, L0.Literal)) {\r
+                               return graph.getValue(object);\r
+                       } else {\r
+                               return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel, binding);\r
+                       }\r
+               }\r
+            }\r
+                       \r
+               if (variable.isAsserted()) {\r
+                       if (variable.parentResource != null) {\r
+                               for(Resource assertion : graph.syncRequest(new ObjectsWithType(variable.parentResource, L0.Asserts, L0.Assertion))) {\r
+                                       if(variable.property.predicate.equals(graph.getSingleObject(assertion, L0.HasPredicate))) {\r
+                                               return graph.getRelatedValue2(assertion, L0.HasObject, context);\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+                       \r
+                       return graph.getValue2(variable.getRepresents(graph), context, binding);\r
+                       \r
+               } catch (NoSingleResultException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
+               } catch (DoesNotContainValueException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
+               } catch (DatabaseException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph), e);\r
+               }\r
+\r
+       }\r
+\r
+       public static void standardSetValue2(WriteGraph graph, Variable context, final Object value) throws DatabaseException {\r
+               \r
+           if(context instanceof StandardGraphPropertyVariable) {\r
+\r
+               final StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; \r
+               \r
+               // First from node\r
+            if(variable.node != null) {\r
+\r
+                final Binding binding = Layer0Utils.getDefaultBinding(graph, variable);\r
+\r
+                final AtomicReference<Object> oldValueRef = new AtomicReference<Object>();\r
+                try {\r
+                    variable.node.support.manager.getRealm().syncExec(new Runnable() {\r
+                        @Override\r
+                        public void run() {\r
+                            try {\r
+                                oldValueRef.set(getNodeValue(variable, binding));\r
+                                setNodeValue(variable, value, binding);\r
+                            } catch (NodeManagerException e) {\r
+                                throw new RuntimeException(e);\r
+                            } catch (BindingException e) {\r
+                                   throw new RuntimeException(e);\r
+                               }\r
+                        }\r
+                    });\r
+                } catch(RuntimeException e) {\r
+                    if(e.getCause() instanceof NodeManagerException || e.getCause() instanceof BindingException)\r
+                        throw new DatabaseException(e.getCause());\r
+                    else\r
+                        throw e;\r
+                } catch (InterruptedException e) {\r
+                    throw new DatabaseException(e);\r
+                }\r
+\r
+                ExternalSetValue ext = new ExternalSetValue(variable.node.support.manager, variable.node.node,\r
+                        oldValueRef.get(), value, binding);\r
+                graph.getService(UndoRedoSupport.class).addExternalOperation(graph, ext);\r
+\r
+                return;\r
+            }\r
+               \r
+           }\r
+           \r
+               Function4<WriteGraph, Variable, Object, Object, String> modifier = context.getPossiblePropertyValue(graph, Variables.INPUT_MODIFIER);\r
+               if(modifier == null) modifier = VariableUtils.defaultInputModifier; \r
+               try {\r
+                       modifier.apply(graph, context, value, Bindings.getBinding(value.getClass()));\r
+               } catch (BindingConstructionException e) {\r
+                       throw new DatabaseException(e);\r
+               }\r
+\r
+       }\r
+\r
+       public static void standardSetValue3(final WriteGraph graph, Variable context, final Object value, final Binding binding) throws DatabaseException {\r
+\r
+        // First from node\r
+        if(context instanceof StandardGraphPropertyVariable) {\r
+\r
+            final StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; \r
+            \r
+            // First from node\r
+            if(variable.node != null) {\r
+                \r
+                try {\r
+                    \r
+                    variable.node.support.manager.getRealm().syncExec(new Runnable() {\r
+\r
+                        @Override\r
+                        public void run() {\r
+                            try {\r
+                                Object oldValue = getNodeValue(variable, binding);\r
+                                setNodeValue(variable, value, binding);\r
+                                ExternalSetValue ext = new ExternalSetValue(variable.node.support.manager, variable.node.node, oldValue, value, binding);\r
+                                graph.getService(UndoRedoSupport.class).addExternalOperation(graph, ext);\r
+                            } catch (NodeManagerException | BindingException e) {\r
+                                Logger.defaultLogError(e);\r
+                            }\r
+                        }\r
+\r
+                        \r
+                    });\r
+                    \r
+                    return;\r
+                    \r
+                } catch (InterruptedException e) {\r
+                    throw new DatabaseException(e);\r
+                }\r
+                \r
+            }\r
+            \r
+        }\r
+           \r
+               Function4<WriteGraph, Variable, Object, Object, String> modifier = context.getPossiblePropertyValue(graph, Variables.INPUT_MODIFIER);\r
+               if(modifier == null) modifier = VariableUtils.defaultInputModifier; \r
+               modifier.apply(graph, context, value, binding);\r
+\r
+       }\r
+\r
+       public static Datatype getDatatypeFromValue(ReadGraph graph, Variable context) throws DatabaseException {\r
+               if (context instanceof AbstractVariable) {\r
+                       Binding defaultBinding = ((AbstractVariable)context).getPossibleDefaultBinding(graph);\r
+                       if (defaultBinding != null)\r
+                               return defaultBinding.type();\r
+               }\r
+                       \r
+       Variant value = context.getVariantValue(graph);\r
+       if (value.getBinding() == null)\r
+               throw new DatabaseException("No value binding for " + context.getURI(graph));\r
+       \r
+       return value.getBinding().type();\r
+       }\r
+\r
+    @SuppressWarnings("rawtypes")\r
+    private static class DatatypeGetter implements VariableNodeReadRunnable {\r
+        final VariableNode node;\r
+        Datatype type;\r
+        Exception exception;\r
+\r
+        public DatatypeGetter(VariableNode node) {\r
+            this.node = node;\r
+        }\r
+\r
+        @SuppressWarnings("unchecked")\r
+        @Override\r
+        public void run() {\r
+            try {\r
+                type = node.support.manager.getDatatype(node.node);\r
+            } catch (NodeManagerException e) {\r
+                exception = e;\r
+            }\r
+        }\r
+        @Override\r
+        public String toString() {\r
+            return "DatatypeGetter(" + node.node + ")";\r
+        }\r
+    }\r
+\r
+    public static Datatype standardGetDatatype(ReadGraph graph, Variable context) throws DatabaseException {\r
+       if (context instanceof AbstractVariable) {\r
+               final AbstractVariable variable = (AbstractVariable)context;\r
+               if (variable.node != null) {\r
+                       try {\r
+                               DatatypeGetter request = new DatatypeGetter(variable.node);\r
+                               \r
+                                       variable.node.support.manager.getRealm().syncExec(request);\r
+                                       \r
+                                       if (request.exception != null)\r
+                                               throw new DatabaseException(request.exception);\r
+                                       \r
+                                       return request.type;\r
+                               } catch (InterruptedException e) {\r
+                               }\r
+               }\r
+       }\r
+       \r
+       return getDatatypeFromValue(graph, context);\r
+       }\r
+\r
+//     @SCLValue(type = "ValueAccessor")\r
+//     public static ValueAccessor standardValueAccessor = new ValueAccessor() {\r
+//\r
+//             @Override\r
+//             public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
+//                     return standardGetValue(graph, (StandardGraphPropertyVariable)context);\r
+//             }\r
+//\r
+//             @Override\r
+//             public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
+//                     return standardGetValue(graph, context, binding);\r
+//             }\r
+//\r
+//             @Override\r
+//             public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
+//                     standardSetValue(graph, context, value);\r
+//             }\r
+//\r
+//             @Override\r
+//             public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
+//                     standardSetValue(graph, context, value, binding);\r
+//             }\r
+//\r
+//             @Override\r
+//             public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {\r
+//                     return standardGetDatatype(graph, context);\r
+//             }\r
+//             \r
+//     };\r
+       \r
+       @SCLValue(type = "ValueAccessor")\r
+       public static ValueAccessor standardValueAccessor = new ValueAccessor() {\r
+\r
+               @Override\r
+               public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
+                       ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
+                       if(accessor != null) return accessor.getValue(graph, context);\r
+                       else \r
+                               return standardGetValue1(graph, context);\r
+               }\r
+\r
+               @Override\r
+               public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
+                       ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
+                       if(accessor != null) return accessor.getValue(graph, context, binding);\r
+                       else \r
+                               return standardGetValue2(graph, context, binding);\r
+               }\r
+\r
+               @Override\r
+               public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
+                       ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
+                       if(accessor != null) accessor.setValue(graph, context, value);\r
+                       else \r
+                               standardSetValue2(graph, context, value);\r
+               }\r
+\r
+               @Override\r
+               public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
+                       ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
+                       if(accessor != null) accessor.setValue(graph, context, value, binding);\r
+                       else \r
+                               standardSetValue3(graph, context, value, binding);\r
+               }\r
+\r
+               @Override\r
+               public Datatype getDatatype(ReadGraph graph, Variable context)\r
+                               throws DatabaseException {\r
+                       ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
+                       if(accessor != null) return accessor.getDatatype(graph, context);\r
+                       else \r
+                               return standardGetDatatype(graph, context);\r
+               }\r
+               \r
+       };\r
+\r
+       public static Variable getStandardChildDomainPropertyVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+        StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
+        PropertyInfo graphProperty = getPossiblePropertyInfoFromContext(graph, variable, variable.resource, name);\r
+        return getStandardChildDomainPropertyVariable(graph, context, graphProperty, name);\r
+    }\r
+\r
+    public static Resource getPossiblePropertyResource(ReadGraph graph, AbstractVariable parent, Object node) throws DatabaseException {\r
+        if(parent != null && parent.node != null && parent.node.node != null && parent.node.support != null) {\r
+            String propertyURI = getPossiblePropertyURI(parent, node);\r
+            if(propertyURI != null)\r
+                return graph.getPossibleResource(propertyURI);\r
+        }\r
+        return null;\r
+    }\r
+\r
+       public static Variable getStandardChildDomainPropertyVariable(ReadGraph graph, Variable context, PropertyInfo graphProperty, String name) throws DatabaseException {\r
+        StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
+        Object propertyNode = getPossibleNodeProperty(graph, variable, name, true);\r
+        if(graphProperty != null && graphProperty.builder != null)\r
+            return buildPropertyVariable(graph, variable, variable.resource, graphProperty, propertyNode);\r
+        if(propertyNode != null) {\r
+            // Fallback: try to ask property resource uri from NodeManager\r
+            return createStandardGraphPropertyVariable(graph, variable, propertyNode);\r
+        }\r
+        return null;\r
+    }\r
+\r
+    public static Map<String, Variable> getStandardChildDomainPropertyVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+       // Get properties with null identification\r
+        return getStandardChildDomainPropertyVariables(graph, context, null, map);\r
+    }\r
+\r
+    public static Map<String, Variable> getStandardChildDomainPropertyVariables(ReadGraph graph, Variable context, String classification, Map<String, Variable> map) throws DatabaseException {\r
+       \r
+        StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
+        \r
+        Collection<Object> nodeProperties = getPossibleNodeProperties(graph, variable);\r
+        if(!nodeProperties.isEmpty()) {\r
+\r
+            // Get variables for properties read from the graph\r
+            Map<String,PropertyInfo> graphProperties = collectPropertyInfosFromContext(graph, variable, variable.resource);\r
+            \r
+            Set<String> used = new THashSet<String>(nodeProperties.size());\r
+            \r
+            map = ensureVariableMap(map, graphProperties.size() + nodeProperties.size());\r
+            \r
+            // Process NodeManager property nodes\r
+            for(Object nodeProperty : nodeProperties) {\r
+               String name = getNodeName(variable, nodeProperty);\r
+                used.add(name);\r
+                \r
+                PropertyInfo graphProperty = graphProperties.get(name); \r
+                if(graphProperty != null && graphProperty.builder != null) {\r
+                    if (classification != null && !graphProperty.hasClassification(classification)) continue;\r
+                    \r
+                    // Combine with identically named graph property\r
+                    map.put(name, buildPropertyVariable(graph, variable, variable.resource, graphProperty, nodeProperty));\r
+                    continue;\r
+                }\r
+                \r
+                map.put(name, createStandardGraphPropertyVariable(graph, variable, nodeProperty));\r
+            }\r
+            \r
+            // Process graph properties\r
+            for(PropertyInfo info : graphProperties.values()) {\r
+                String name = info.name;\r
+                if(used != null && used.contains(name)) continue;\r
+                if (classification != null && !info.hasClassification(classification)) continue;\r
+                if (info.builder != null) {\r
+                    map.put(name, buildPropertyVariable(graph, variable, variable.resource, info, null));\r
+                }\r
+            }\r
+            return map;\r
+               \r
+        } else {\r
+\r
+               if(variable.resource == null) return map;\r
+\r
+               // Only graph properties\r
+               Collection<Resource> predicates = graph.getPredicates(variable.resource);\r
+               if(predicates.isEmpty()) return map;\r
+               \r
+               map = ensureVariableMap(map, predicates.size());\r
+               \r
+            // Process graph properties\r
+            for(Resource predicate : predicates) {\r
+               \r
+                       PropertyInfo info = graph.isImmutable(predicate) ?\r
+                                       graph.syncRequest(new PropertyInfoRequest(predicate), TransientCacheAsyncListener.<PropertyInfo>instance()) :\r
+                                               graph.syncRequest(new PropertyInfoRequest(predicate));\r
+\r
+                       if(!info.isHasProperty) continue;\r
+                                       \r
+                if (classification != null && !info.hasClassification(classification)) continue;\r
+                if (info.builder != null) {\r
+                    map.put(info.name, buildPropertyVariable(graph, variable, variable.resource, info, null));\r
+                }\r
+                \r
+            }\r
+            \r
+            return map;\r
+               \r
+        }\r
+        \r
+     }\r
+       \r
+    @SCLValue(type = "VariableMap")\r
+       public static VariableMap standardChildDomainProperties = new VariableMapImpl() {\r
+       \r
+               @Override\r
+               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+               return getStandardChildDomainPropertyVariable(graph, context, name);\r
+               }\r
+\r
+               @Override\r
+               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+                   return getStandardChildDomainPropertyVariables(graph, context, map);\r
+               }\r
+               \r
+       };\r
+       \r
+       public static Variable getStandardPropertyDomainPropertyVariableFromValue(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+\r
+               if(context instanceof StandardGraphPropertyVariable) {\r
+               StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
+               Resource literal = variable.getPossibleRepresents(graph);\r
+               Object propertyNode = getPossibleNodeProperty(graph, variable, name, false);\r
+\r
+               if(literal != null) {\r
+                       Variable result = getPossiblePropertyFromContext(graph, variable, literal, name, propertyNode);\r
+                       if(result != null) return result;\r
+               }\r
+               \r
+               Variable result = getPossibleSubliteralPropertyFromContext(graph, variable, name);\r
+               if(result != null) return result;\r
+               result = getPossiblePropertyFromContext(graph, variable, variable.property.predicate, name, propertyNode);\r
+               if (result != null) return result;\r
+               \r
+               // Get possible property from NodeManager\r
+               if (propertyNode != null)\r
+                       return createStandardGraphPropertyVariable(graph, variable, propertyNode);\r
+               return null;\r
+               } else if (context instanceof StandardGraphChildVariable) {\r
+                       return standardChildDomainProperties.getVariable(graph, context, name);\r
+               } else {\r
+                       throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
+               }                       \r
+               \r
+       }\r
+       \r
+       public static Map<String, Variable> getStandardPropertyDomainPropertyVariablesFromValue(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+\r
+               if(context instanceof StandardGraphPropertyVariable) {\r
+                       StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
+                       map = collectPropertiesFromContext(graph, variable, variable.property.predicate, map);\r
+                       if (variable.parentResource != null) {\r
+                               Resource literal = graph.getPossibleObject(variable.parentResource, variable.property.predicate);\r
+                               if(literal != null) map=collectPropertiesFromContext(graph, variable, literal, map);\r
+                               map=collectSubliteralProperties(graph, variable, map);\r
+                       }\r
+\r
+                       // Get properties from VariableNode\r
+                       map = getStandardNodePropertyVariables(graph, context, map);\r
+                       return map;\r
+               } else if (context instanceof StandardGraphChildVariable) {\r
+                       return standardChildDomainProperties.getVariables(graph, context, map);\r
+               } else {\r
+                       throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
+               }\r
+               \r
+       }\r
+       \r
+       public static Map<String, Variable> getStandardPropertyDomainPropertyVariablesFromValue(ReadGraph graph, Variable context, String classification, Map<String, Variable> map) throws DatabaseException {\r
+\r
+               if(context instanceof StandardGraphPropertyVariable) {\r
+                       StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
+                       map = collectPropertiesFromContext(graph, variable, variable.property.predicate, classification, map);\r
+                       if (variable.parentResource != null) {\r
+                               Resource literal = graph.getPossibleObject(variable.parentResource, variable.property.predicate);\r
+                               if(literal != null) map=collectPropertiesFromContext(graph, variable, literal, classification, map);\r
+                       }\r
+                       \r
+                       // Get properties from VariableNode\r
+                       map = getStandardNodePropertyVariables(graph, context, map);\r
+                       return map;\r
+               } else if (context instanceof StandardGraphChildVariable) {\r
+                       return standardChildDomainProperties.getVariables(graph, context, map);\r
+               } else {\r
+                       throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
+               }       \r
+               \r
+       }       \r
+       \r
+    @SCLValue(type = "VariableMap")\r
+       public static VariableMap standardPropertyDomainProperties = new VariableMapImpl() {\r
+\r
+       VariableMap getValueVariableMap(ReadGraph graph, Variable context) throws DatabaseException {\r
+               Resource represents = context.getPossibleRepresents(graph);\r
+               if(represents == null) return null;\r
+               \r
+               VariableMap map = graph.isImmutable(represents) ?\r
+                               graph.syncRequest(new PropertyVariableMapRequest(represents), TransientCacheListener.<VariableMap>instance()) :\r
+                                       (VariableMap)graph.getPossibleRelatedValue2(represents, Layer0.getInstance(graph).domainProperties, represents);\r
+               \r
+               if(map == standardPropertyDomainProperties) return null;\r
+               else return map;\r
+               \r
+       }\r
+       \r
+               @Override\r
+               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+                       VariableMap valueMap = getValueVariableMap(graph, context);\r
+                       if(valueMap != null) return valueMap.getVariable(graph, context, name);\r
+                       return getStandardPropertyDomainPropertyVariableFromValue(graph, context, name);\r
+               }\r
+\r
+               @Override\r
+               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+                       VariableMap valueMap = getValueVariableMap(graph, context);\r
+                       if(valueMap != null) return valueMap.getVariables(graph, context, map);\r
+                       else return getStandardPropertyDomainPropertyVariablesFromValue(graph, context, map);\r
+               }\r
+               \r
+               @Override\r
+               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, String classification, Map<String, Variable> map) throws DatabaseException {\r
+                       VariableMap valueMap = getValueVariableMap(graph, context);\r
+                       if(valueMap != null) return valueMap.getVariables(graph, context, classification, map);\r
+                       else return getStandardPropertyDomainPropertyVariablesFromValue(graph, context, classification, map);\r
+               }\r
+               \r
+       };\r
+\r
+    public static Resource getPossibleGraphChild(ReadGraph graph, Variable variable, String name) throws DatabaseException {\r
+       Resource resource = variable.getPossibleRepresents(graph);\r
+        if(resource == null) return null;\r
+        Map<String, Resource> graphChildren = graph.syncRequest(new UnescapedChildMapOfResource(resource));\r
+        return graphChildren.get(name);\r
+    }\r
+\r
+    public static Map<String,Resource> getPossibleGraphChildren(ReadGraph graph, Variable variable) throws DatabaseException {\r
+       Resource resource = variable.getPossibleRepresents(graph);\r
+        if(resource == null) return Collections.emptyMap();\r
+        return graph.syncRequest(new UnescapedChildMapOfResource(resource));\r
+    }\r
+\r
+    public static Object getPossibleNodeChild(ReadGraph graph, Variable variable, String name) throws DatabaseException {\r
+       if (!(variable instanceof AbstractVariable)) return null;\r
+       VariableNode<?> node = ((AbstractVariable)variable).node;\r
+        if(node == null) return null;\r
+        NodeStructure structure = Variables.requestNodeStructure(graph, node);\r
+        if(Variables.PENDING_NODE_STRUCTURE == structure) throw new PendingVariableException("");\r
+        return structure.children.get(name);\r
+       }\r
+       \r
+    public static Collection<Object> getPossibleNodeChildren(ReadGraph graph, Variable variable) throws DatabaseException {\r
+       if (!(variable instanceof AbstractVariable)) return null;\r
+       VariableNode<?> node = ((AbstractVariable)variable).node;\r
+        if(node == null) return Collections.emptyList();\r
+        NodeStructure structure = Variables.requestNodeStructure(graph, node);\r
+        if(Variables.PENDING_NODE_STRUCTURE == structure) throw new PendingVariableException("");\r
+        return structure.children.values();\r
+    }\r
+    \r
+    public static Object getPossibleNodeProperty(ReadGraph graph, Variable variable, String name, boolean throwPending) throws DatabaseException {\r
+       if (!(variable instanceof AbstractVariable)) return null;\r
+       VariableNode<?> node = ((AbstractVariable)variable).node;\r
+        if(node == null) return null;\r
+        NodeStructure structure = Variables.requestNodeStructure(graph, node);\r
+        if(throwPending && Variables.PENDING_NODE_STRUCTURE == structure) throw new PendingVariableException("");\r
+        return structure.properties.get(name);\r
+    }\r
+    \r
+    public static Collection<Object> getPossibleNodeProperties(ReadGraph graph, Variable variable) throws DatabaseException {\r
+       if (!(variable instanceof AbstractVariable)) return null;\r
+       VariableNode<?> node = ((AbstractVariable)variable).node;\r
+        if(node == null) return Collections.emptyList();\r
+        NodeStructure structure = Variables.requestNodeStructure(graph, node);\r
+        if(Variables.PENDING_NODE_STRUCTURE == structure) throw new PendingVariableException("");\r
+        return structure.properties.values();\r
+    }\r
+\r
+    @SuppressWarnings({ "rawtypes", "unchecked" })\r
+    public static VariableNode build(VariableNode parent, Object node) {\r
+        if(node == null) return null;\r
+        return new VariableNode(parent.support, node);\r
+    }\r
+\r
+    @Deprecated\r
+    public static Variable getStandardChildDomainChildVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+       return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, name);\r
+    }\r
+\r
+    @Deprecated\r
+    public static Variable getStandardChildDomainChildVariable(ReadGraph graph, Variable context, Resource graphChild, String name) throws DatabaseException {\r
+       return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, graphChild, name);\r
+    }\r
+       \r
+    @Deprecated\r
+    public static Map<String, Variable> getStandardChildDomainChildVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+       return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, map);\r
+    }\r
+\r
+    @Deprecated\r
+    public static Map<String, Variable> getStandardChildDomainChildVariables(ReadGraph graph, Variable context, Map<String,Resource> graphChildren, Map<String, Variable> map) throws DatabaseException {\r
+       return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, graphChildren, map);\r
+    }\r
+    \r
+    /**\r
+     * Get a map of child Variables from a node manager-based Variable, combined with the existing variables in #map.\r
+     * @param graph  The read graph.\r
+     * @param context  The parent Variable.\r
+     * @param map  A map of variables into which the new variables are merged.\r
+     * @return  A map from variable names to instances\r
+     * @throws DatabaseException\r
+     */\r
+    public static Map<String, Variable> getStandardNodeChildVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+       AbstractVariable variable = (AbstractVariable)context;\r
+       if (variable.node == null) return map;\r
+        \r
+        Collection<Object> nodeChildren = getPossibleNodeChildren(graph, variable);\r
+        if (nodeChildren.isEmpty()) return map;\r
+        \r
+        map = ensureVariableMap(map, nodeChildren.size());\r
+\r
+        for(Object nodeChild : nodeChildren) {\r
+            String name = getNodeName(variable, nodeChild);\r
+            if (!map.containsKey(name))\r
+               map.put(name, createStandardGraphChildVariable(variable, nodeChild));\r
+        }\r
+\r
+        return map;\r
+    }\r
+\r
+    /**\r
+     * Get a map of property Variables from a node manager-based Variable, combined with the existing variables in #map.\r
+     * @param graph  The read graph.\r
+     * @param context  The parent Variable.\r
+     * @param map  A map of variables into which the new variables are merged.\r
+     * @return  A map from variable names to instances\r
+     * @throws DatabaseException\r
+     */\r
+    public static Map<String, Variable> getStandardNodePropertyVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+       AbstractVariable variable = (AbstractVariable)context;\r
+       if (variable.node == null) return map;\r
+        \r
+        Collection<Object> nodeProperties = getPossibleNodeProperties(graph, variable);\r
+        if (nodeProperties.isEmpty()) return map;\r
+        \r
+        map = ensureVariableMap(map, nodeProperties.size());\r
+\r
+        for(Object nodeProperty : nodeProperties) {\r
+            String name = getNodeName(variable, nodeProperty);\r
+            if (!map.containsKey(name)) {\r
+               map.put(name, createStandardGraphPropertyVariable(graph, variable, nodeProperty));\r
+            }\r
+        }\r
+\r
+        return map;\r
+    }    \r
+\r
+       @SCLValue(type = "VariableMap")\r
+       public static VariableMap standardChildDomainChildren = new VariableMapImpl() {\r
+\r
+               @Override\r
+               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+                       return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, name);\r
+               }\r
+\r
+               @Override\r
+               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+                   return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, map);\r
+               }\r
+               \r
+       };\r
+\r
+    @SCLValue(type = "VariableMap")\r
+       public static VariableMap standardPropertyDomainChildren = new VariableMapImpl() {\r
+\r
+       /**\r
+        * Get a possible non-standard VariableMap defined in the graph.\r
+        * @param graph  The graph\r
+        * @param context  The context node\r
+        * @return  A non-standard VariableMap instance for the context node,\r
+        *          or null, if not defined or defined as this instance.\r
+        * @throws DatabaseException\r
+        */\r
+       VariableMap getValueVariableMap(ReadGraph graph, Variable context) throws DatabaseException {\r
+               Resource represents = context.getPossibleRepresents(graph);\r
+               if(represents == null) return null;\r
+                       VariableMap map = graph.syncRequest(new ChildVariableMapRequest(represents));\r
+               if(map == standardPropertyDomainChildren) return null;\r
+               else return map;\r
+       }\r
+       \r
+               @Override\r
+               public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
+                       // Delegate call to a non-standard variable map?\r
+                       VariableMap valueMap = getValueVariableMap(graph, context);\r
+                       if(valueMap != null) return valueMap.getVariable(graph, context, name);\r
+                       \r
+                       if(context instanceof StandardGraphPropertyVariable) {\r
+                               StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
+                               Datatype dt = variable.getDatatype(graph);\r
+                               if (dt instanceof ArrayType) {\r
+                                       ChildReference ref = getPossibleIndexReference(name);\r
+                                       if (ref != null)\r
+                                               return new SubliteralPropertyVariableDeprecated(variable, ref);\r
+                               }\r
+                               \r
+                               // Check for a child node provided by the NodeManager\r
+                               if (variable.node != null) {\r
+                                       Object childNode = getPossibleNodeChild(graph, variable, name);\r
+                                       if (childNode != null)\r
+                                               return createStandardGraphChildVariable(variable, childNode);\r
+                               }\r
+                               return standardChildDomainChildren.getVariable(graph, context, name);\r
+                       } else if (context instanceof StandardGraphChildVariable) {\r
+                               return standardChildDomainChildren.getVariable(graph, context, name);\r
+                       } else {\r
+                               throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
+                       }\r
+               }\r
+\r
+               @Override\r
+               public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
+                       // Delegate call to a non-standard variable map?\r
+                       VariableMap valueMap = getValueVariableMap(graph, context);\r
+                       if(valueMap != null) return valueMap.getVariables(graph, context, map);\r
+                       \r
+                       if(context instanceof StandardGraphPropertyVariable) {\r
+                               // Get child variables provided by the NodeManager\r
+                               Map<String, Variable> result = getStandardNodeChildVariables(graph, context, map); \r
+                               return standardChildDomainChildren.getVariables(graph, context, result);\r
+                       } else if (context instanceof StandardGraphChildVariable) {\r
+                               return standardChildDomainChildren.getVariables(graph, context, map);\r
+                       } else {\r
+                               throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
+                       }       \r
+               }\r
+               \r
+       };\r
+       \r
+       protected static ChildReference getPossibleIndexReference(String name) {\r
+               if (name.startsWith("i-")) {\r
+                   try {\r
+                       int index = Integer.parseInt(name.substring(2));\r
+                       return new IndexReference(index);\r
+                   } catch (NumberFormatException e) {}\r
+               }\r
+               return null;\r
+       }\r
+\r
+       protected static ValueAccessor getPossiblePropertyValueAccessor(ReadGraph graph, StandardGraphPropertyVariable variable) throws DatabaseException {\r
+           if(variable.property == null) return null;\r
+           return variable.property.valueAccessor;\r
+//        return graph.syncRequest(new PropertyValueAccessorRequest(variable.property), TransientCacheAsyncListener.<ValueAccessor>instance());\r
+//             return graph.syncRequest(new PossibleRelatedValueImplied2<ValueAccessor>(variable.property, Layer0.getInstance(graph).valueAccessor));\r
+       }\r
+\r
+       public static ValueAccessor getPossibleValueValueAccessor(ReadGraph graph, Variable variable) throws DatabaseException {\r
+           Resource value = variable.getPossibleRepresents(graph);\r
+           if(value == null) return null;\r
+           //return graph.syncRequest(new PropertyValueAccessorRequest(value));\r
+               return graph.syncRequest(new PossibleRelatedValueImplied2<ValueAccessor>(value, Layer0.getInstance(graph).valueAccessor));      \r
+       }\r
+       \r
+       public static PropertyInfo getPossiblePropertyInfoFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException {\r
+           if(context == null) return null;\r
+               Map<String, PropertyInfo> predicates = graph.syncRequest(new UnescapedPropertyMapOfResource(context));\r
+               return predicates.get(name);\r
+       }\r
+\r
+    public static Variable getPossiblePropertyFromContext(ReadGraph graph, Variable variable, Resource context, String name, Object propertyNode) throws DatabaseException {\r
+        PropertyInfo info = getPossiblePropertyInfoFromContext(graph, variable, context, name);\r
+        if(info == null || info.builder == null) return null;\r
+        return buildPropertyVariable(graph, variable, context, info, propertyNode);\r
+    }\r
+    \r
+    public static Variable getPossibleSubliteralPropertyFromContext(ReadGraph graph, StandardGraphPropertyVariable variable, String name) throws DatabaseException {\r
+       \r
+               Resource predicate = variable.property.predicate;\r
+               if(predicate == null) return null;\r
+\r
+       PropertyInfo info = getPropertyInfo(graph, predicate);\r
+       Pair<Resource, ChildReference> p = info.subliteralPredicates.get(name);\r
+       if(p == null) return null;\r
+       \r
+               return new SubliteralPropertyVariable(graph, variable, p.first, p.second);\r
+       \r
+    }\r
+\r
+    public static Map<String, PropertyInfo> collectPropertyInfosFromContext(ReadGraph graph, Variable variable, Resource context) throws DatabaseException {\r
+        if(context == null) return Collections.emptyMap();\r
+               return graph.isImmutable(context) ?\r
+                               graph.syncRequest(new UnescapedPropertyMapOfResource(context), TransientCacheAsyncListener.<Map<String,PropertyInfo>>instance()) :\r
+                               graph.syncRequest(new UnescapedPropertyMapOfResource(context));\r
+    }\r
+\r
+       public static Map<String, Variable> collectPropertiesFromContext(ReadGraph graph, Variable variable, Resource context, Map<String, Variable> map) throws DatabaseException {\r
+\r
+               Map<String,PropertyInfo> properties = graph.isImmutable(context) ?\r
+                               graph.syncRequest(new UnescapedPropertyMapOfResource(context), TransientCacheAsyncListener.<Map<String,PropertyInfo>>instance()) :\r
+                               graph.syncRequest(new UnescapedPropertyMapOfResource(context));\r
+                               \r
+               if(properties.isEmpty()) return map;\r
+               \r
+               map = ensureVariableMap(map, properties.size());\r
+               \r
+               for(PropertyInfo info : properties.values()) {\r
+                       String name = info.name;\r
+                       if (info.builder != null) {\r
+                               Variable v = info.builder.buildProperty(graph, variable, null, context, info.predicate);\r
+                               map.put(name, v);\r
+                       }\r
+               }\r
+               \r
+               return map;\r
+               \r
+       }\r
+\r
+       public static Map<String, Variable> collectSubliteralProperties(ReadGraph graph, StandardGraphPropertyVariable variable, Map<String, Variable> map) throws DatabaseException {\r
+\r
+               Resource predicate = variable.property.predicate;\r
+               if(predicate == null) return map;\r
+               \r
+               PropertyInfo info = getPropertyInfo(graph, predicate);\r
+               if(info.subliteralPredicates.isEmpty()) return map;\r
+               \r
+               map = ensureVariableMap(map, info.subliteralPredicates.size());\r
+               \r
+               for(Map.Entry<String, Pair<Resource, ChildReference>> entry : info.subliteralPredicates.entrySet()) {\r
+                       String key = entry.getKey();\r
+                       Pair<Resource, ChildReference> p = entry.getValue();\r
+                       if(map == null) map = new THashMap<String,Variable>();\r
+                       map.put(key, new SubliteralPropertyVariable(graph, variable, p.first, p.second));\r
+               }\r
+       \r
+       return map;\r
+               \r
+       }\r
+\r
+       public static Map<String, Variable> collectPropertiesFromContext(ReadGraph graph, Variable variable, Resource context, String classification, Map<String, Variable> map) throws DatabaseException {\r
+\r
+               if(graph.isImmutable(context)) {\r
+\r
+                       Map<String,PropertyInfo> properties = graph.syncRequest(new UnescapedPropertyMapOfResource(context), TransientCacheAsyncListener.<Map<String,PropertyInfo>>instance());\r
+                       for(PropertyInfo info : properties.values()) {\r
+\r
+                               if(info.classifications.contains(classification) && info.builder != null) {\r
+                                       String name = info.name;\r
+                                       Variable v = info.builder.buildProperty(graph, variable, null, context, info.predicate);\r
+                                       if(map == null) map = new THashMap<String,Variable>();\r
+                                       map.put(name, v);\r
+                               }\r
+\r
+                       }\r
+\r
+               } else {\r
+                               \r
+                       Collection<Resource> predicates = graph.getPredicates(context);\r
+                                       \r
+                       if(predicates.isEmpty()) return map;\r
+                       \r
+                       map = ensureVariableMap(map, predicates.size());\r
+               \r
+                       for(Resource predicate : predicates) {\r
+                               \r
+                               PropertyInfo info = graph.isImmutable(predicate) ?\r
+                                               graph.syncRequest(new PropertyInfoRequest(predicate), TransientCacheAsyncListener.<PropertyInfo>instance()) :\r
+                                                       graph.syncRequest(new PropertyInfoRequest(predicate));\r
+                                               \r
+                               if(!info.isHasProperty) continue;\r
+       \r
+                               if(info.classifications.contains(classification) && info.builder != null) {\r
+                                       String name = info.name;\r
+                                       Variable v = info.builder.buildProperty(graph, variable, null, context, info.predicate);\r
+                                       if(map == null) map = new THashMap<String,Variable>();\r
+                                       map.put(name, v);\r
+                               }\r
+                               \r
+                       }\r
+                       \r
+               }\r
+               \r
+               return map;\r
+               \r
+       }       \r
+       \r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> String")\r
+    public static String entityLabel(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+       if(context instanceof Resource) {\r
+               return NameUtils.getSafeLabel(graph, ((Resource)context));      \r
+       } else if (context instanceof Variable) {\r
+               Variable parent = ((Variable)context).getParent(graph);\r
+               Resource represents = parent.getRepresents(graph);\r
+               return NameUtils.getSafeLabel(graph, represents);\r
+       } else {\r
+               throw new DatabaseException("Unknown context " + context);\r
+       }\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+    public static Object listResources(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+       return ListUtils.toList(graph, resource);\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> [String]")\r
+    public static List<String> standardClassifications(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
+       ArrayList<String> result = new ArrayList<String>();\r
+       Resource predicate = context.getParent(graph).getPossiblePredicateResource(graph);\r
+       if(predicate != null) {\r
+               for(Resource type : graph.getTypes(predicate)) {\r
+                       String uri = graph.getPossibleURI(type);\r
+                       if(uri != null) result.add(uri);\r
+               }\r
+       }\r
+       return result;\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> Boolean")\r
+    public static Boolean standardValidValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+       return Boolean.TRUE;\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> StringInputValidator")\r
+    public static StringInputValidator standardValidator(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+       return StringInputValidator.PASS;\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> Boolean")\r
+    public static Boolean standardRequiredValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+       return Boolean.FALSE;\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")\r
+    public static Boolean standardDefaultValue(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
+       Variable property = context.getParent(graph);\r
+       if(property instanceof StandardGraphPropertyVariable) {\r
+               StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)property;\r
+               if (variable.parentResource != null) {\r
+                       Statement stm = graph.getPossibleStatement(variable.parentResource, variable.property.predicate);\r
+                       return stm != null && stm.isAsserted(variable.parentResource);\r
+                       }\r
+       }\r
+       return Boolean.FALSE;\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> Boolean")\r
+    public static Boolean standardReadOnlyValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+       return Boolean.FALSE;\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+    public static Object resourceAsValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+       return resource;\r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+    public static Object functionApplication(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+       return Functions.exec(graph, resource, graph, resource, context);\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+    public static Object computeExpression(ReadGraph graph, Resource converter, Object context) throws DatabaseException {\r
+       if(context instanceof Variable) {\r
+            return CompileValueRequest.compileAndEvaluate(graph, (Variable)context);\r
+       } if (context instanceof Resource) {\r
+            return CompileResourceValueRequest.compileAndEvaluate(graph, (Resource)converter);\r
+       } else {\r
+               throw new IllegalStateException("Unknown context " + context);\r
+       }\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+    public static Object composedPropertyValue(ReadGraph graph, Resource converter, Object context) throws DatabaseException {\r
+       if(context instanceof Variable) {\r
+               return new StandardComposedProperty();\r
+       } if (context instanceof Resource) {\r
+               return new StandardComposedProperty();\r
+       } else {\r
+               throw new IllegalStateException("Unknown context " + context);\r
+       }\r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+    public static Object numberInputValidator(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+        \r
+        class Validator extends FunctionImpl1<String, String> {\r
+\r
+            private final Datatype datatype;\r
+            \r
+            public Validator(Datatype datatype) {\r
+                this.datatype = datatype;\r
+            }\r
+            \r
+            @Override\r
+            public String apply(String input) {\r
+                \r
+                if(datatype == null) return null;\r
+                \r
+                try {\r
+\r
+                    if(datatype instanceof NumberType) {\r
+                        \r
+                        Number number = (Number)PrimitiveValueParser.parse(input, datatype);\r
+                        NumberType nt = (NumberType)datatype;\r
+                        Range r = nt.getRange();\r
+                        if(r != null) {\r
+                            if(!r.contains(number)) return "Value is out of valid range";\r
+                        }\r
+                    }\r
+                    return null;\r
+                    \r
+                } catch (NumberFormatException e) {\r
+                    return "Not a valid floating-point number";\r
+                } catch (IllegalArgumentException e) {\r
+                    return "Not a valid floating-point number";\r
+                }\r
+                \r
+            }\r
+            \r
+        }\r
+\r
+        if(context instanceof Variable) {\r
+            \r
+            Variable variable = (Variable)context;\r
+            Variable property = variable.getParent(graph);\r
+            Datatype datatype = property.getPossibleDatatype(graph);\r
+            return new Validator(datatype);\r
+            \r
+        } else if (context instanceof Resource) {\r
+\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            Resource literal = (Resource)context;\r
+            Datatype datatype = graph.getRelatedValue(literal, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class));\r
+            return new Validator(datatype);\r
+            \r
+        } else {\r
+            \r
+            return new Validator(null);\r
+            \r
+        }\r
+        \r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
+    public static Object booleanInputValidator(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
+        \r
+        return new FunctionImpl1<String, String>() {\r
+\r
+            @Override\r
+            public String apply(String input) {\r
+                \r
+               String lower = input.toLowerCase();\r
+               if("true".equals(lower) || "false".equals(lower)) return null;\r
+\r
+               return "Not a valid boolean: " + input;\r
+                \r
+            }\r
+            \r
+        };\r
+        \r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> Resource")\r
+    public static Resource hasStandardResource(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
+       Variable parent = context.getParent(graph);\r
+       if(parent instanceof StandardGraphChildVariable) {\r
+               StandardGraphChildVariable variable = (StandardGraphChildVariable)parent;\r
+               return variable.resource;\r
+       }\r
+       return null;\r
+    }\r
+\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
+       public static Object valueWithoutBinding(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {\r
+\r
+       StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
+               \r
+               if(graph.sync(new IsEnumeratedValue(variable.getRepresents(graph)))) {\r
+                       Layer0 L0 = Layer0.getInstance(graph);\r
+                       return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel);\r
+               }\r
+\r
+               if (variable.parentResource == null)\r
+                       throw new VariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").");\r
+\r
+               try {\r
+                       return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);\r
+               } catch (NoSingleResultException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
+               } catch (DoesNotContainValueException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
+               }\r
+               \r
+       }\r
+\r
+    @SCLValue(type = "ReadGraph -> Variable -> Binding -> a")\r
+       public static Object valueWithBinding(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
+\r
+       StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
+               \r
+               if(graph.sync(new IsEnumeratedValue(variable.getRepresents(graph)))) {\r
+                       Layer0 L0 = Layer0.getInstance(graph);\r
+                       return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel, binding);\r
+               }\r
+\r
+               if (variable.parentResource == null)\r
+                       throw new VariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").");\r
+\r
+               try {\r
+                       return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);\r
+               } catch (NoSingleResultException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
+               } catch (DoesNotContainValueException e) {\r
+                       throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
+               }\r
+               \r
+       }\r
+\r
+    @SCLValue(type = "WriteGraph -> Variable -> a -> Binding -> b")\r
+       public static Object valueSetterWithBinding(WriteGraph graph, Variable variable, Object value, Binding binding) throws DatabaseException {\r
+               \r
+               Function4<WriteGraph, Variable, Object, Object, String> modifier = variable.getPossiblePropertyValue(graph, Variables.INPUT_MODIFIER);\r
+               if(modifier == null) modifier = VariableUtils.defaultInputModifier; \r
+               modifier.apply(graph, variable, value, binding);\r
+               return null;\r
+               \r
+       }\r
+    \r
+    static class L0Issue extends StandardIssue {\r
+        \r
+        private final String description;\r
+        \r
+        public L0Issue(String description, Resource type, Resource ... contexts) {\r
+            super(type, contexts);\r
+            this.description = description;\r
+        }\r
+\r
+        @Override\r
+        public Resource write(WriteGraph graph, Resource source) throws DatabaseException {\r
+            Layer0 L0 = Layer0.getInstance(graph);\r
+            IssueResource IR = IssueResource.getInstance(graph);\r
+            Resource issue = super.write(graph, source);\r
+            graph.claim(issue, IR.Issue_HasSeverity, IR.Severity_Fatal);\r
+            graph.addLiteral(issue, L0.HasDescription, L0.HasDescription_Inverse, description, Bindings.STRING);\r
+            return issue;\r
+        }\r
+        \r
+    }\r
+    \r
+       private static List<Issue> reportInconsistency(ReadGraph graph, Resource subject, String description, List<Issue> issues) throws DatabaseException {\r
+           if(issues == null) issues = new ArrayList<Issue>();\r
+               System.err.println("Change set validation reports the following issue: " + NameUtils.getSafeName(graph, subject, true) + ": " + description);\r
+               IssueResource IR = IssueResource.getInstance(graph);\r
+               issues.add(new L0Issue(description, IR.Issue, subject));\r
+               return issues;\r
+       }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> relationValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
+\r
+       Layer0 L0 = Layer0.getInstance(graph);\r
+\r
+       List<Issue> issues = null;\r
+       \r
+       for(Statement stm : graph.getStatements(resource, L0.IsWeaklyRelatedTo)) {\r
+               Resource predicate = stm.getPredicate();\r
+               Resource object = stm.getObject();\r
+               if(!isRelation(graph, L0, predicate)) {\r
+                       issues = reportInconsistency(graph, resource, "The predicate of a statement must be a relation: " + NameUtils.toString(graph, stm), issues);\r
+               }\r
+               if(graph.isInstanceOf(predicate, L0.FunctionalRelation)) {\r
+                       if(graph.getObjects(resource, predicate).size() > 1)\r
+                               issues = reportInconsistency(graph, resource, \r
+                                               "Relation " +\r
+                                                               NameUtils.getSafeName(graph, predicate)\r
+                                                               + " is functional.", issues);\r
+               }\r
+               {\r
+                       Collection<Resource> domain = graph.getObjects(predicate, L0.HasDomain);\r
+                       if (!isInstanceOfAny(graph, resource, domain, true)) {\r
+                               StringBuilder sb = new StringBuilder()\r
+                               .append("The domain of ")\r
+                               .append(NameUtils.getSafeName(graph, predicate))\r
+                               .append(" relation is ");\r
+                               orString(graph, sb, domain).append(".");\r
+                               issues = reportInconsistency(graph, resource, sb.toString(), issues);\r
+                       }\r
+               }\r
+               {\r
+                       Collection<Resource> range = graph.getObjects(predicate, L0.HasRange);\r
+                       if (!isInstanceOfAny(graph, object, range, true) && !graph.isInstanceOf(object, L0.SCLValue)) {\r
+                               StringBuilder sb = new StringBuilder()\r
+                               .append("The range of ")\r
+                               .append(NameUtils.getSafeName(graph, predicate))\r
+                               .append(" relation is ");\r
+                               orString(graph, sb, range).append(" but current object is ")\r
+                               .append(NameUtils.getSafeName(graph, object)).append(".");\r
+                               issues = reportInconsistency(graph, resource, sb.toString(), issues);\r
+                       }\r
+               }               \r
+       }\r
+               \r
+               return issues != null ? issues : Collections.<Issue>emptyList();\r
+\r
+    }\r
+\r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> propertyValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
+\r
+        List<Issue> issues = null;\r
+\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+       for(Statement stm : graph.getStatements(resource, L0.HasProperty)) {\r
+               Resource subject = stm.getSubject();\r
+               Resource predicate = stm.getPredicate();\r
+               String error = L0Validations.checkValueType(graph, subject, predicate);\r
+               if(error != null) issues = reportInconsistency(graph, subject, error, issues);\r
+       }\r
+               \r
+        return issues != null ? issues : Collections.<Issue>emptyList();\r
+\r
+    }\r
+    \r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> valueValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
+\r
+        List<Issue> issues = null;\r
+\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+       if(graph.hasValue(resource)) {\r
+               if(!graph.isInstanceOf(resource, L0.Literal)) {\r
+                       issues = reportInconsistency(graph, resource, \r
+                                       "Resource has a value but it is not a literal.", issues);\r
+               }\r
+               else {\r
+                       // TODO check that the value is valid for the data type\r
+               }\r
+       }\r
+       else {\r
+               if(graph.isInstanceOf(resource, L0.Literal)) {\r
+                       issues = reportInconsistency(graph, resource, \r
+                                       "Resource is a literal but it does not have a value.", issues);\r
+               }\r
+       }\r
+       \r
+        return issues != null ? issues : Collections.<Issue>emptyList();\r
+       \r
+    }\r
+\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> uriValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
+       \r
+        List<Issue> issues = null;\r
+\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        Resource parent = graph.getPossibleObject(resource, L0.PartOf);\r
+       if(parent != null) {\r
+           String parentURI = graph.syncRequest(new PossibleURI(parent));\r
+           if(parentURI != null) {\r
+                       String name = graph.getPossibleRelatedValue(resource, L0.HasName);\r
+                       if(name == null) {\r
+                               issues = reportInconsistency(graph, resource, "Resource has a parent with URI but has no valid HasName.", issues);\r
+                       }\r
+           }\r
+       }\r
+\r
+        return issues != null ? issues : Collections.<Issue>emptyList();\r
+       \r
+    }\r
+    \r
+    private static Resource getPossibleNearestClusterSet(ReadGraph graph, Resource base, Resource resource) throws DatabaseException {\r
+\r
+        ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
+        if(cs.isClusterSet(resource) && !base.equals(resource)) return resource;\r
+        \r
+        Resource nearest = CommonDBUtils.getNearestOwner(graph, Collections.singletonList(resource));\r
+        if(nearest == null) return null;\r
+        \r
+        return getPossibleNearestClusterSet(graph, base, nearest);\r
+\r
+    }\r
+\r
+    private static boolean quirks(ReadGraph graph, Resource resource) throws DatabaseException {\r
+\r
+       if(!resource.isPersistent()) return true;\r
+       if(graph.isImmutable(resource)) return true;\r
+       if(resource.getResourceId() < 0x2000) return true;\r
+\r
+       return false;\r
+       \r
+    }\r
+    \r
+    @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
+    public static List<Issue> clusterValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
+\r
+       if(!Development.DEVELOPMENT) return Collections.<Issue>emptyList();\r
+       \r
+       if(quirks(graph, resource)) return Collections.<Issue>emptyList();\r
+       \r
+        List<Issue> issues = null;\r
+\r
+        ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
+        Resource set = cs.getClusterSetOfCluster(resource);\r
+        \r
+        if(set == null) return reportInconsistency(graph, resource, "Resource cluster is not part of any cluster set", issues);\r
+        \r
+        Resource nearestSet = getPossibleNearestClusterSet(graph, resource, resource);\r
+        if(nearestSet == null) {\r
+               // This means that there is no owner since RootLibrary is a cluster set\r
+               return Collections.<Issue>emptyList();\r
+        }\r
+        \r
+        if(!set.equals(nearestSet)) return reportInconsistency(graph, resource, "The cluster set of a resource is not the nearest owner set", issues);\r
+\r
+        return Collections.<Issue>emptyList();\r
+       \r
+    }\r
+\r
+    private static boolean isInstanceOfAny(ReadGraph graph, Resource r, Collection<Resource> types, boolean ifEmpty) throws DatabaseException {\r
+               if (types.isEmpty())\r
+                       return ifEmpty;\r
+               for (Resource type : types) {\r
+                       if (graph.isInstanceOf(r, type)) {\r
+                               return true;\r
+                       }\r
+               }\r
+               return false;\r
+       }\r
+\r
+       private static StringBuilder orString(ReadGraph graph, StringBuilder sb, Collection<Resource> rs) throws DatabaseException {\r
+               sb.append("(");\r
+               boolean first = true;\r
+               for (Resource r : rs) {\r
+                       if (!first)\r
+                               sb.append(" | ");\r
+                       first = false;\r
+                       sb.append(NameUtils.getSafeName(graph, r));\r
+               }\r
+               sb.append(")");\r
+               return sb;\r
+       }\r
+\r
+    public static boolean isRelation(ReadGraph g, Layer0 l0, Resource relation) throws DatabaseException {\r
+               return g.hasStatement(relation, l0.SubrelationOf) || relation == l0.IsWeaklyRelatedTo;\r
+       }\r
+       \r
+       public static boolean isType(ReadGraph g, Layer0 l0, Resource type) throws DatabaseException {\r
+               return g.hasStatement(type, l0.Inherits) || type == l0.Entity;\r
+       }\r
+       \r
+    public static Variable buildChildVariable(ReadGraph graph, Variable context, Resource graphChild, Object nodeChild) throws DatabaseException {\r
+        VariableBuilder builder = graph.adapt(graphChild, VariableBuilder.class);\r
+       return builder.buildChild(graph, context, build(((AbstractVariable)context).node, nodeChild), graphChild);\r
+       }\r
+\r
+       private static Variable buildPropertyVariable(ReadGraph graph, Variable variable, Resource parentResource, PropertyInfo graphProperty, Object propertyNode) throws DatabaseException {\r
+               VariableNode<?> node = variable instanceof AbstractVariable ? build(((AbstractVariable)variable).node, propertyNode) : null;\r
+               return graphProperty.builder.buildProperty(graph, variable, node, parentResource, graphProperty.predicate);\r
+       }\r
+       \r
+       static StandardGraphChildVariable createStandardGraphChildVariable(\r
+                       AbstractVariable parent, Object child) {\r
+               return new StandardGraphChildVariable(parent, build(parent.node, child), null);\r
+       }\r
+\r
+       private static StandardGraphPropertyVariable createStandardGraphPropertyVariable(\r
+                       ReadGraph graph, AbstractVariable variable, Object nodeProperty) throws DatabaseException {\r
+        Resource propertyResource = getPossiblePropertyResource(graph, variable, nodeProperty);\r
+        return new StandardGraphPropertyVariable(graph, variable, build(variable.node, nodeProperty), null, propertyResource);\r
+       }\r
+        \r
+       static Map<String, Variable> ensureVariableMap(\r
+                       Map<String, Variable> map, int size) {\r
+               if(map == null) map = new THashMap<String,Variable>(size);\r
+               return map;\r
+       }\r
+\r
+       private static PropertyInfo getPropertyInfo(ReadGraph graph, Resource predicate) throws DatabaseException {\r
+               return graph.syncRequest(new PropertyInfoRequest(predicate));\r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       static String getNodeName(AbstractVariable parent, Object child) {\r
+               return parent.node.support.manager.getName(child);\r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       private static Object getNodeValue(final AbstractVariable variable, final Binding binding) throws NodeManagerException, BindingException {\r
+               return variable.node.support.manager.getValue(variable.node.node, binding);\r
+       }\r
+\r
+       @SuppressWarnings("unchecked")\r
+       private static void setNodeValue(final AbstractVariable variable, final Object value, final Binding binding) throws NodeManagerException, BindingException {\r
+               variable.node.support.manager.setValue(variable.node.node, value, binding);\r
+       }\r
+       \r
+       @SuppressWarnings("unchecked")\r
+       private static String getPossiblePropertyURI(AbstractVariable parent, Object node) {\r
+               return parent.node.support.manager.getPropertyURI(parent.node.node, node);\r
+       }\r
+    \r
+}
\ No newline at end of file