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