]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / function / All.java
1 package org.simantics.db.layer0.function;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Collection;\r
5 import java.util.Collections;\r
6 import java.util.List;\r
7 import java.util.Map;\r
8 import java.util.Set;\r
9 import java.util.concurrent.atomic.AtomicReference;\r
10 \r
11 import org.simantics.databoard.Bindings;\r
12 import org.simantics.databoard.accessor.reference.ChildReference;\r
13 import org.simantics.databoard.accessor.reference.IndexReference;\r
14 import org.simantics.databoard.adapter.AdaptException;\r
15 import org.simantics.databoard.binding.Binding;\r
16 import org.simantics.databoard.binding.error.BindingConstructionException;\r
17 import org.simantics.databoard.binding.error.BindingException;\r
18 import org.simantics.databoard.binding.mutable.Variant;\r
19 import org.simantics.databoard.type.ArrayType;\r
20 import org.simantics.databoard.type.Datatype;\r
21 import org.simantics.databoard.type.NumberType;\r
22 import org.simantics.databoard.util.Range;\r
23 import org.simantics.db.Issue;\r
24 import org.simantics.db.ReadGraph;\r
25 import org.simantics.db.Resource;\r
26 import org.simantics.db.Statement;\r
27 import org.simantics.db.WriteGraph;\r
28 import org.simantics.db.common.issue.StandardIssue;\r
29 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied2;\r
30 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
31 import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
32 import org.simantics.db.common.request.IsEnumeratedValue;\r
33 import org.simantics.db.common.request.ObjectsWithType;\r
34 import org.simantics.db.common.uri.UnescapedChildMapOfResource;\r
35 import org.simantics.db.common.utils.CommonDBUtils;\r
36 import org.simantics.db.common.utils.Functions;\r
37 import org.simantics.db.common.utils.ListUtils;\r
38 import org.simantics.db.common.utils.Logger;\r
39 import org.simantics.db.common.utils.NameUtils;\r
40 import org.simantics.db.common.validation.L0Validations;\r
41 import org.simantics.db.exception.DatabaseException;\r
42 import org.simantics.db.exception.DoesNotContainValueException;\r
43 import org.simantics.db.exception.NoSingleResultException;\r
44 import org.simantics.db.layer0.exception.MissingVariableValueException;\r
45 import org.simantics.db.layer0.exception.PendingVariableException;\r
46 import org.simantics.db.layer0.exception.VariableException;\r
47 import org.simantics.db.layer0.request.PossibleURI;\r
48 import org.simantics.db.layer0.request.PropertyInfo;\r
49 import org.simantics.db.layer0.request.PropertyInfoRequest;\r
50 import org.simantics.db.layer0.request.UnescapedPropertyMapOfResource;\r
51 import org.simantics.db.layer0.scl.CompileResourceValueRequest;\r
52 import org.simantics.db.layer0.scl.CompileValueRequest;\r
53 import org.simantics.db.layer0.util.Layer0Utils;\r
54 import org.simantics.db.layer0.util.PrimitiveValueParser;\r
55 import org.simantics.db.layer0.variable.AbstractVariable;\r
56 import org.simantics.db.layer0.variable.ChildVariableMapRequest;\r
57 import org.simantics.db.layer0.variable.ExternalSetValue;\r
58 import org.simantics.db.layer0.variable.PropertyVariableMapRequest;\r
59 import org.simantics.db.layer0.variable.StandardComposedProperty;\r
60 import org.simantics.db.layer0.variable.StandardGraphChildVariable;\r
61 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;\r
62 import org.simantics.db.layer0.variable.SubliteralPropertyVariable;\r
63 import org.simantics.db.layer0.variable.SubliteralPropertyVariableDeprecated;\r
64 import org.simantics.db.layer0.variable.ValueAccessor;\r
65 import org.simantics.db.layer0.variable.Variable;\r
66 import org.simantics.db.layer0.variable.VariableBuilder;\r
67 import org.simantics.db.layer0.variable.VariableMap;\r
68 import org.simantics.db.layer0.variable.VariableMapImpl;\r
69 import org.simantics.db.layer0.variable.VariableNode;\r
70 import org.simantics.db.layer0.variable.VariableNodeReadRunnable;\r
71 import org.simantics.db.layer0.variable.VariableUtils;\r
72 import org.simantics.db.layer0.variable.Variables;\r
73 import org.simantics.db.layer0.variable.Variables.NodeStructure;\r
74 import org.simantics.db.service.ClusteringSupport;\r
75 import org.simantics.db.service.UndoRedoSupport;\r
76 import org.simantics.issues.ontology.IssueResource;\r
77 import org.simantics.layer0.Layer0;\r
78 import org.simantics.scl.reflection.annotations.SCLValue;\r
79 import org.simantics.scl.runtime.function.Function4;\r
80 import org.simantics.scl.runtime.function.FunctionImpl1;\r
81 import org.simantics.simulator.variable.exceptions.NodeManagerException;\r
82 import org.simantics.utils.Development;\r
83 import org.simantics.utils.datastructures.Pair;\r
84 import org.simantics.utils.strings.StringInputValidator;\r
85 \r
86 import gnu.trove.map.hash.THashMap;\r
87 import gnu.trove.set.hash.THashSet;\r
88 \r
89 public class All {\r
90 \r
91         public static Object standardGetValue1(ReadGraph graph, Variable context) throws DatabaseException {\r
92 \r
93                 StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
94 \r
95         // First from node\r
96         if(variable.node != null) {\r
97             Variant value = Variables.requestNodeValue(graph, variable.node);\r
98             if(Variables.PENDING_NODE_VALUE == value) throw new PendingVariableException("");\r
99             return value.getValue();\r
100         }\r
101                 \r
102                 try {\r
103 \r
104             if(variable.property.hasEnumerationRange) {\r
105                         Resource object = variable.getRepresents(graph);\r
106                                 if(graph.sync(new IsEnumeratedValue(object))) {\r
107                             Layer0 L0 = Layer0.getInstance(graph);\r
108                                         if(graph.isInstanceOf(object, L0.Literal)) {\r
109                                                 return graph.getValue(object);\r
110                                         } else {\r
111                                                 String label = graph.getPossibleRelatedValue2(variable.getRepresents(graph), L0.HasLabel, Bindings.STRING);\r
112                                                 if(label == null) label = graph.getPossibleRelatedValue(variable.getRepresents(graph), L0.HasName, Bindings.STRING);\r
113                                                 if(label == null) label = "<no label>";\r
114                                                 return label;\r
115                                         }\r
116                                 }\r
117             }\r
118                         \r
119             if (variable.isAsserted()) {\r
120                                 if (variable.parentResource != null) {\r
121                             Layer0 L0 = Layer0.getInstance(graph);\r
122                                         for(Resource assertion : graph.syncRequest(new ObjectsWithType(variable.parentResource, L0.Asserts, L0.Assertion))) {\r
123                                                 if(variable.property.predicate.equals(graph.getSingleObject(assertion, L0.HasPredicate))) {\r
124                                                         return graph.getRelatedValue2(assertion, L0.HasObject, variable);\r
125                                                 }\r
126                                         }\r
127                                 }\r
128             }\r
129                 \r
130                         return graph.getValue2(variable.getRepresents(graph), variable);\r
131                         \r
132                 } catch (NoSingleResultException e) {\r
133                         throw new MissingVariableValueException(variable.getPossibleURI(graph), e);\r
134                 } catch (DoesNotContainValueException e) {\r
135                         throw new MissingVariableValueException(variable.getPossibleURI(graph), e);\r
136                 } catch (DatabaseException e) {\r
137                         throw new MissingVariableValueException(variable.getPossibleURI(graph), e);\r
138                 }\r
139 \r
140         }\r
141         \r
142         public static Object standardGetValue2(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {           \r
143                 StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
144 \r
145         // First from node\r
146         if(variable.node != null) {\r
147             try {\r
148                 Variant value = Variables.requestNodeValue(graph, variable.node, binding);\r
149                 if(Variables.PENDING_NODE_VALUE == value) throw new PendingVariableException("");\r
150                 if(value == null) throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
151                 return value.getValue(binding);\r
152             } catch (AdaptException e) {\r
153                 throw new DatabaseException(e);\r
154             }\r
155         }\r
156                 \r
157         try {\r
158                         \r
159                 Layer0 L0 = Layer0.getInstance(graph);\r
160                 \r
161                 if(variable.property.hasEnumerationRange) {\r
162                 Resource object = variable.getRepresents(graph);\r
163                 if(graph.sync(new IsEnumeratedValue(object))) {\r
164                         if(graph.isInstanceOf(object, L0.Literal)) {\r
165                                 return graph.getValue(object);\r
166                         } else {\r
167                                 return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel, binding);\r
168                         }\r
169                 }\r
170             }\r
171                         \r
172                 if (variable.isAsserted()) {\r
173                         if (variable.parentResource != null) {\r
174                                 for(Resource assertion : graph.syncRequest(new ObjectsWithType(variable.parentResource, L0.Asserts, L0.Assertion))) {\r
175                                         if(variable.property.predicate.equals(graph.getSingleObject(assertion, L0.HasPredicate))) {\r
176                                                 return graph.getRelatedValue2(assertion, L0.HasObject, context);\r
177                                         }\r
178                                 }\r
179                         }\r
180                 }\r
181                         \r
182                         return graph.getValue2(variable.getRepresents(graph), context, binding);\r
183                         \r
184                 } catch (NoSingleResultException e) {\r
185                         throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
186                 } catch (DoesNotContainValueException e) {\r
187                         throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
188                 } catch (DatabaseException e) {\r
189                         throw new MissingVariableValueException(variable.getPossibleURI(graph), e);\r
190                 }\r
191 \r
192         }\r
193 \r
194         public static void standardSetValue2(WriteGraph graph, Variable context, final Object value) throws DatabaseException {\r
195                 \r
196             if(context instanceof StandardGraphPropertyVariable) {\r
197 \r
198                 final StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; \r
199                 \r
200                 // First from node\r
201             if(variable.node != null) {\r
202 \r
203                 final Binding binding = Layer0Utils.getDefaultBinding(graph, variable);\r
204 \r
205                 final AtomicReference<Object> oldValueRef = new AtomicReference<Object>();\r
206                 try {\r
207                     variable.node.support.manager.getRealm().syncExec(new Runnable() {\r
208                         @Override\r
209                         public void run() {\r
210                             try {\r
211                                 oldValueRef.set(getNodeValue(variable, binding));\r
212                                 setNodeValue(variable, value, binding);\r
213                             } catch (NodeManagerException e) {\r
214                                 throw new RuntimeException(e);\r
215                             } catch (BindingException e) {\r
216                                     throw new RuntimeException(e);\r
217                                 }\r
218                         }\r
219                     });\r
220                 } catch(RuntimeException e) {\r
221                     if(e.getCause() instanceof NodeManagerException || e.getCause() instanceof BindingException)\r
222                         throw new DatabaseException(e.getCause());\r
223                     else\r
224                         throw e;\r
225                 } catch (InterruptedException e) {\r
226                     throw new DatabaseException(e);\r
227                 }\r
228 \r
229                 ExternalSetValue ext = new ExternalSetValue(variable.node.support.manager, variable.node.node,\r
230                         oldValueRef.get(), value, binding);\r
231                 graph.getService(UndoRedoSupport.class).addExternalOperation(graph, ext);\r
232 \r
233                 return;\r
234             }\r
235                 \r
236             }\r
237             \r
238                 Function4<WriteGraph, Variable, Object, Object, String> modifier = context.getPossiblePropertyValue(graph, Variables.INPUT_MODIFIER);\r
239                 if(modifier == null) modifier = VariableUtils.defaultInputModifier; \r
240                 try {\r
241                         modifier.apply(graph, context, value, Bindings.getBinding(value.getClass()));\r
242                 } catch (BindingConstructionException e) {\r
243                         throw new DatabaseException(e);\r
244                 }\r
245 \r
246         }\r
247 \r
248         public static void standardSetValue3(final WriteGraph graph, Variable context, final Object value, final Binding binding) throws DatabaseException {\r
249 \r
250         // First from node\r
251         if(context instanceof StandardGraphPropertyVariable) {\r
252 \r
253             final StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context; \r
254             \r
255             // First from node\r
256             if(variable.node != null) {\r
257                 \r
258                 try {\r
259                     \r
260                     variable.node.support.manager.getRealm().syncExec(new Runnable() {\r
261 \r
262                         @Override\r
263                         public void run() {\r
264                             try {\r
265                                 Object oldValue = getNodeValue(variable, binding);\r
266                                 setNodeValue(variable, value, binding);\r
267                                 ExternalSetValue ext = new ExternalSetValue(variable.node.support.manager, variable.node.node, oldValue, value, binding);\r
268                                 graph.getService(UndoRedoSupport.class).addExternalOperation(graph, ext);\r
269                             } catch (NodeManagerException | BindingException e) {\r
270                                 Logger.defaultLogError(e);\r
271                             }\r
272                         }\r
273 \r
274                         \r
275                     });\r
276                     \r
277                     return;\r
278                     \r
279                 } catch (InterruptedException e) {\r
280                     throw new DatabaseException(e);\r
281                 }\r
282                 \r
283             }\r
284             \r
285         }\r
286             \r
287                 Function4<WriteGraph, Variable, Object, Object, String> modifier = context.getPossiblePropertyValue(graph, Variables.INPUT_MODIFIER);\r
288                 if(modifier == null) modifier = VariableUtils.defaultInputModifier; \r
289                 modifier.apply(graph, context, value, binding);\r
290 \r
291         }\r
292 \r
293         public static Datatype getDatatypeFromValue(ReadGraph graph, Variable context) throws DatabaseException {\r
294                 if (context instanceof AbstractVariable) {\r
295                         Binding defaultBinding = ((AbstractVariable)context).getPossibleDefaultBinding(graph);\r
296                         if (defaultBinding != null)\r
297                                 return defaultBinding.type();\r
298                 }\r
299                         \r
300         Variant value = context.getVariantValue(graph);\r
301         if (value.getBinding() == null)\r
302                 throw new DatabaseException("No value binding for " + context.getURI(graph));\r
303         \r
304         return value.getBinding().type();\r
305         }\r
306 \r
307     @SuppressWarnings("rawtypes")\r
308     private static class DatatypeGetter implements VariableNodeReadRunnable {\r
309         final VariableNode node;\r
310         Datatype type;\r
311         Exception exception;\r
312 \r
313         public DatatypeGetter(VariableNode node) {\r
314             this.node = node;\r
315         }\r
316 \r
317         @SuppressWarnings("unchecked")\r
318         @Override\r
319         public void run() {\r
320             try {\r
321                 type = node.support.manager.getDatatype(node.node);\r
322             } catch (NodeManagerException e) {\r
323                 exception = e;\r
324             }\r
325         }\r
326         @Override\r
327         public String toString() {\r
328             return "DatatypeGetter(" + node.node + ")";\r
329         }\r
330     }\r
331 \r
332     public static Datatype standardGetDatatype(ReadGraph graph, Variable context) throws DatabaseException {\r
333         if (context instanceof AbstractVariable) {\r
334                 final AbstractVariable variable = (AbstractVariable)context;\r
335                 if (variable.node != null) {\r
336                         try {\r
337                                 DatatypeGetter request = new DatatypeGetter(variable.node);\r
338                                 \r
339                                         variable.node.support.manager.getRealm().syncExec(request);\r
340                                         \r
341                                         if (request.exception != null)\r
342                                                 throw new DatabaseException(request.exception);\r
343                                         \r
344                                         return request.type;\r
345                                 } catch (InterruptedException e) {\r
346                                 }\r
347                 }\r
348         }\r
349         \r
350         return getDatatypeFromValue(graph, context);\r
351         }\r
352 \r
353 //      @SCLValue(type = "ValueAccessor")\r
354 //      public static ValueAccessor standardValueAccessor = new ValueAccessor() {\r
355 //\r
356 //              @Override\r
357 //              public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
358 //                      return standardGetValue(graph, (StandardGraphPropertyVariable)context);\r
359 //              }\r
360 //\r
361 //              @Override\r
362 //              public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
363 //                      return standardGetValue(graph, context, binding);\r
364 //              }\r
365 //\r
366 //              @Override\r
367 //              public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
368 //                      standardSetValue(graph, context, value);\r
369 //              }\r
370 //\r
371 //              @Override\r
372 //              public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
373 //                      standardSetValue(graph, context, value, binding);\r
374 //              }\r
375 //\r
376 //              @Override\r
377 //              public Datatype getDatatype(ReadGraph graph, Variable context) throws DatabaseException {\r
378 //                      return standardGetDatatype(graph, context);\r
379 //              }\r
380 //              \r
381 //      };\r
382         \r
383         @SCLValue(type = "ValueAccessor")\r
384         public static ValueAccessor standardValueAccessor = new ValueAccessor() {\r
385 \r
386                 @Override\r
387                 public Object getValue(ReadGraph graph, Variable context) throws DatabaseException {\r
388                         ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
389                         if(accessor != null) return accessor.getValue(graph, context);\r
390                         else \r
391                                 return standardGetValue1(graph, context);\r
392                 }\r
393 \r
394                 @Override\r
395                 public Object getValue(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
396                         ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
397                         if(accessor != null) return accessor.getValue(graph, context, binding);\r
398                         else \r
399                                 return standardGetValue2(graph, context, binding);\r
400                 }\r
401 \r
402                 @Override\r
403                 public void setValue(WriteGraph graph, Variable context, Object value) throws DatabaseException {\r
404                         ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
405                         if(accessor != null) accessor.setValue(graph, context, value);\r
406                         else \r
407                                 standardSetValue2(graph, context, value);\r
408                 }\r
409 \r
410                 @Override\r
411                 public void setValue(WriteGraph graph, Variable context, Object value, Binding binding) throws DatabaseException {\r
412                         ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
413                         if(accessor != null) accessor.setValue(graph, context, value, binding);\r
414                         else \r
415                                 standardSetValue3(graph, context, value, binding);\r
416                 }\r
417 \r
418                 @Override\r
419                 public Datatype getDatatype(ReadGraph graph, Variable context)\r
420                                 throws DatabaseException {\r
421                         ValueAccessor accessor = getPossibleValueValueAccessor(graph, context);\r
422                         if(accessor != null) return accessor.getDatatype(graph, context);\r
423                         else \r
424                                 return standardGetDatatype(graph, context);\r
425                 }\r
426                 \r
427         };\r
428 \r
429         public static Variable getStandardChildDomainPropertyVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
430         StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
431         PropertyInfo graphProperty = getPossiblePropertyInfoFromContext(graph, variable, variable.resource, name);\r
432         return getStandardChildDomainPropertyVariable(graph, context, graphProperty, name);\r
433     }\r
434 \r
435     public static Resource getPossiblePropertyResource(ReadGraph graph, AbstractVariable parent, Object node) throws DatabaseException {\r
436         if(parent != null && parent.node != null && parent.node.node != null && parent.node.support != null) {\r
437             String propertyURI = getPossiblePropertyURI(parent, node);\r
438             if(propertyURI != null)\r
439                 return graph.getPossibleResource(propertyURI);\r
440         }\r
441         return null;\r
442     }\r
443 \r
444         public static Variable getStandardChildDomainPropertyVariable(ReadGraph graph, Variable context, PropertyInfo graphProperty, String name) throws DatabaseException {\r
445         StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
446         Object propertyNode = getPossibleNodeProperty(graph, variable, name, true);\r
447         if(graphProperty != null && graphProperty.builder != null)\r
448             return buildPropertyVariable(graph, variable, variable.resource, graphProperty, propertyNode);\r
449         if(propertyNode != null) {\r
450             // Fallback: try to ask property resource uri from NodeManager\r
451             return createStandardGraphPropertyVariable(graph, variable, propertyNode);\r
452         }\r
453         return null;\r
454     }\r
455 \r
456     public static Map<String, Variable> getStandardChildDomainPropertyVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
457         // Get properties with null identification\r
458         return getStandardChildDomainPropertyVariables(graph, context, null, map);\r
459     }\r
460 \r
461     public static Map<String, Variable> getStandardChildDomainPropertyVariables(ReadGraph graph, Variable context, String classification, Map<String, Variable> map) throws DatabaseException {\r
462         \r
463         StandardGraphChildVariable variable = (StandardGraphChildVariable)context;\r
464         \r
465         Collection<Object> nodeProperties = getPossibleNodeProperties(graph, variable);\r
466         if(!nodeProperties.isEmpty()) {\r
467 \r
468             // Get variables for properties read from the graph\r
469             Map<String,PropertyInfo> graphProperties = collectPropertyInfosFromContext(graph, variable, variable.resource);\r
470             \r
471             Set<String> used = new THashSet<String>(nodeProperties.size());\r
472             \r
473             map = ensureVariableMap(map, graphProperties.size() + nodeProperties.size());\r
474             \r
475             // Process NodeManager property nodes\r
476             for(Object nodeProperty : nodeProperties) {\r
477                 String name = getNodeName(variable, nodeProperty);\r
478                 used.add(name);\r
479                 \r
480                 PropertyInfo graphProperty = graphProperties.get(name); \r
481                 if(graphProperty != null && graphProperty.builder != null) {\r
482                     if (classification != null && !graphProperty.hasClassification(classification)) continue;\r
483                     \r
484                     // Combine with identically named graph property\r
485                     map.put(name, buildPropertyVariable(graph, variable, variable.resource, graphProperty, nodeProperty));\r
486                     continue;\r
487                 }\r
488                 \r
489                 map.put(name, createStandardGraphPropertyVariable(graph, variable, nodeProperty));\r
490             }\r
491             \r
492             // Process graph properties\r
493             for(PropertyInfo info : graphProperties.values()) {\r
494                 String name = info.name;\r
495                 if(used != null && used.contains(name)) continue;\r
496                 if (classification != null && !info.hasClassification(classification)) continue;\r
497                 if (info.builder != null) {\r
498                     map.put(name, buildPropertyVariable(graph, variable, variable.resource, info, null));\r
499                 }\r
500             }\r
501             return map;\r
502                 \r
503         } else {\r
504 \r
505                 if(variable.resource == null) return map;\r
506 \r
507                 // Only graph properties\r
508                 Collection<Resource> predicates = graph.getPredicates(variable.resource);\r
509                 if(predicates.isEmpty()) return map;\r
510                 \r
511                 map = ensureVariableMap(map, predicates.size());\r
512                 \r
513             // Process graph properties\r
514             for(Resource predicate : predicates) {\r
515                 \r
516                         PropertyInfo info = graph.isImmutable(predicate) ?\r
517                                         graph.syncRequest(new PropertyInfoRequest(predicate), TransientCacheAsyncListener.<PropertyInfo>instance()) :\r
518                                                 graph.syncRequest(new PropertyInfoRequest(predicate));\r
519 \r
520                         if(!info.isHasProperty) continue;\r
521                                         \r
522                 if (classification != null && !info.hasClassification(classification)) continue;\r
523                 if (info.builder != null) {\r
524                     map.put(info.name, buildPropertyVariable(graph, variable, variable.resource, info, null));\r
525                 }\r
526                 \r
527             }\r
528             \r
529             return map;\r
530                 \r
531         }\r
532         \r
533      }\r
534         \r
535     @SCLValue(type = "VariableMap")\r
536         public static VariableMap standardChildDomainProperties = new VariableMapImpl() {\r
537         \r
538                 @Override\r
539                 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
540                 return getStandardChildDomainPropertyVariable(graph, context, name);\r
541                 }\r
542 \r
543                 @Override\r
544                 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
545                     return getStandardChildDomainPropertyVariables(graph, context, map);\r
546                 }\r
547                 \r
548         };\r
549         \r
550         public static Variable getStandardPropertyDomainPropertyVariableFromValue(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
551 \r
552                 if(context instanceof StandardGraphPropertyVariable) {\r
553                 StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
554                 Resource literal = variable.getPossibleRepresents(graph);\r
555                 Object propertyNode = getPossibleNodeProperty(graph, variable, name, false);\r
556 \r
557                 if(literal != null) {\r
558                         Variable result = getPossiblePropertyFromContext(graph, variable, literal, name, propertyNode);\r
559                         if(result != null) return result;\r
560                 }\r
561                 \r
562                 Variable result = getPossibleSubliteralPropertyFromContext(graph, variable, name);\r
563                 if(result != null) return result;\r
564                 result = getPossiblePropertyFromContext(graph, variable, variable.property.predicate, name, propertyNode);\r
565                 if (result != null) return result;\r
566                 \r
567                 // Get possible property from NodeManager\r
568                 if (propertyNode != null)\r
569                         return createStandardGraphPropertyVariable(graph, variable, propertyNode);\r
570                 return null;\r
571                 } else if (context instanceof StandardGraphChildVariable) {\r
572                         return standardChildDomainProperties.getVariable(graph, context, name);\r
573                 } else {\r
574                         throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
575                 }                       \r
576                 \r
577         }\r
578         \r
579         public static Map<String, Variable> getStandardPropertyDomainPropertyVariablesFromValue(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
580 \r
581                 if(context instanceof StandardGraphPropertyVariable) {\r
582                         StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
583                         map = collectPropertiesFromContext(graph, variable, variable.property.predicate, map);\r
584                         if (variable.parentResource != null) {\r
585                                 Resource literal = graph.getPossibleObject(variable.parentResource, variable.property.predicate);\r
586                                 if(literal != null) map=collectPropertiesFromContext(graph, variable, literal, map);\r
587                                 map=collectSubliteralProperties(graph, variable, map);\r
588                         }\r
589 \r
590                         // Get properties from VariableNode\r
591                         map = getStandardNodePropertyVariables(graph, context, map);\r
592                         return map;\r
593                 } else if (context instanceof StandardGraphChildVariable) {\r
594                         return standardChildDomainProperties.getVariables(graph, context, map);\r
595                 } else {\r
596                         throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
597                 }\r
598                 \r
599         }\r
600         \r
601         public static Map<String, Variable> getStandardPropertyDomainPropertyVariablesFromValue(ReadGraph graph, Variable context, String classification, Map<String, Variable> map) throws DatabaseException {\r
602 \r
603                 if(context instanceof StandardGraphPropertyVariable) {\r
604                         StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
605                         map = collectPropertiesFromContext(graph, variable, variable.property.predicate, classification, map);\r
606                         if (variable.parentResource != null) {\r
607                                 Resource literal = graph.getPossibleObject(variable.parentResource, variable.property.predicate);\r
608                                 if(literal != null) map=collectPropertiesFromContext(graph, variable, literal, classification, map);\r
609                         }\r
610                         \r
611                         // Get properties from VariableNode\r
612                         map = getStandardNodePropertyVariables(graph, context, map);\r
613                         return map;\r
614                 } else if (context instanceof StandardGraphChildVariable) {\r
615                         return standardChildDomainProperties.getVariables(graph, context, map);\r
616                 } else {\r
617                         throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
618                 }       \r
619                 \r
620         }       \r
621         \r
622     @SCLValue(type = "VariableMap")\r
623         public static VariableMap standardPropertyDomainProperties = new VariableMapImpl() {\r
624 \r
625         VariableMap getValueVariableMap(ReadGraph graph, Variable context) throws DatabaseException {\r
626                 Resource represents = context.getPossibleRepresents(graph);\r
627                 if(represents == null) return null;\r
628                 \r
629                 VariableMap map = graph.isImmutable(represents) ?\r
630                                 graph.syncRequest(new PropertyVariableMapRequest(represents), TransientCacheListener.<VariableMap>instance()) :\r
631                                         (VariableMap)graph.getPossibleRelatedValue2(represents, Layer0.getInstance(graph).domainProperties, represents);\r
632                 \r
633                 if(map == standardPropertyDomainProperties) return null;\r
634                 else return map;\r
635                 \r
636         }\r
637         \r
638                 @Override\r
639                 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
640                         VariableMap valueMap = getValueVariableMap(graph, context);\r
641                         if(valueMap != null) return valueMap.getVariable(graph, context, name);\r
642                         return getStandardPropertyDomainPropertyVariableFromValue(graph, context, name);\r
643                 }\r
644 \r
645                 @Override\r
646                 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
647                         VariableMap valueMap = getValueVariableMap(graph, context);\r
648                         if(valueMap != null) return valueMap.getVariables(graph, context, map);\r
649                         else return getStandardPropertyDomainPropertyVariablesFromValue(graph, context, map);\r
650                 }\r
651                 \r
652                 @Override\r
653                 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, String classification, Map<String, Variable> map) throws DatabaseException {\r
654                         VariableMap valueMap = getValueVariableMap(graph, context);\r
655                         if(valueMap != null) return valueMap.getVariables(graph, context, classification, map);\r
656                         else return getStandardPropertyDomainPropertyVariablesFromValue(graph, context, classification, map);\r
657                 }\r
658                 \r
659         };\r
660 \r
661     public static Resource getPossibleGraphChild(ReadGraph graph, Variable variable, String name) throws DatabaseException {\r
662         Resource resource = variable.getPossibleRepresents(graph);\r
663         if(resource == null) return null;\r
664         Map<String, Resource> graphChildren = graph.syncRequest(new UnescapedChildMapOfResource(resource));\r
665         return graphChildren.get(name);\r
666     }\r
667 \r
668     public static Map<String,Resource> getPossibleGraphChildren(ReadGraph graph, Variable variable) throws DatabaseException {\r
669         Resource resource = variable.getPossibleRepresents(graph);\r
670         if(resource == null) return Collections.emptyMap();\r
671         return graph.syncRequest(new UnescapedChildMapOfResource(resource));\r
672     }\r
673 \r
674     public static Object getPossibleNodeChild(ReadGraph graph, Variable variable, String name) throws DatabaseException {\r
675         if (!(variable instanceof AbstractVariable)) return null;\r
676         VariableNode<?> node = ((AbstractVariable)variable).node;\r
677         if(node == null) return null;\r
678         NodeStructure structure = Variables.requestNodeStructure(graph, node);\r
679         if(Variables.PENDING_NODE_STRUCTURE == structure) throw new PendingVariableException("");\r
680         return structure.children.get(name);\r
681         }\r
682         \r
683     public static Collection<Object> getPossibleNodeChildren(ReadGraph graph, Variable variable) throws DatabaseException {\r
684         if (!(variable instanceof AbstractVariable)) return null;\r
685         VariableNode<?> node = ((AbstractVariable)variable).node;\r
686         if(node == null) return Collections.emptyList();\r
687         NodeStructure structure = Variables.requestNodeStructure(graph, node);\r
688         if(Variables.PENDING_NODE_STRUCTURE == structure) throw new PendingVariableException("");\r
689         return structure.children.values();\r
690     }\r
691     \r
692     public static Object getPossibleNodeProperty(ReadGraph graph, Variable variable, String name, boolean throwPending) throws DatabaseException {\r
693         if (!(variable instanceof AbstractVariable)) return null;\r
694         VariableNode<?> node = ((AbstractVariable)variable).node;\r
695         if(node == null) return null;\r
696         NodeStructure structure = Variables.requestNodeStructure(graph, node);\r
697         if(throwPending && Variables.PENDING_NODE_STRUCTURE == structure) throw new PendingVariableException("");\r
698         return structure.properties.get(name);\r
699     }\r
700     \r
701     public static Collection<Object> getPossibleNodeProperties(ReadGraph graph, Variable variable) throws DatabaseException {\r
702         if (!(variable instanceof AbstractVariable)) return null;\r
703         VariableNode<?> node = ((AbstractVariable)variable).node;\r
704         if(node == null) return Collections.emptyList();\r
705         NodeStructure structure = Variables.requestNodeStructure(graph, node);\r
706         if(Variables.PENDING_NODE_STRUCTURE == structure) throw new PendingVariableException("");\r
707         return structure.properties.values();\r
708     }\r
709 \r
710     @SuppressWarnings({ "rawtypes", "unchecked" })\r
711     public static VariableNode build(VariableNode parent, Object node) {\r
712         if(node == null) return null;\r
713         return new VariableNode(parent.support, node);\r
714     }\r
715 \r
716     @Deprecated\r
717     public static Variable getStandardChildDomainChildVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
718         return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, name);\r
719     }\r
720 \r
721     @Deprecated\r
722     public static Variable getStandardChildDomainChildVariable(ReadGraph graph, Variable context, Resource graphChild, String name) throws DatabaseException {\r
723         return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, graphChild, name);\r
724     }\r
725         \r
726     @Deprecated\r
727     public static Map<String, Variable> getStandardChildDomainChildVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
728         return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, map);\r
729     }\r
730 \r
731     @Deprecated\r
732     public static Map<String, Variable> getStandardChildDomainChildVariables(ReadGraph graph, Variable context, Map<String,Resource> graphChildren, Map<String, Variable> map) throws DatabaseException {\r
733         return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, graphChildren, map);\r
734     }\r
735     \r
736     /**\r
737      * Get a map of child Variables from a node manager-based Variable, combined with the existing variables in #map.\r
738      * @param graph  The read graph.\r
739      * @param context  The parent Variable.\r
740      * @param map  A map of variables into which the new variables are merged.\r
741      * @return  A map from variable names to instances\r
742      * @throws DatabaseException\r
743      */\r
744     public static Map<String, Variable> getStandardNodeChildVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
745         AbstractVariable variable = (AbstractVariable)context;\r
746         if (variable.node == null) return map;\r
747         \r
748         Collection<Object> nodeChildren = getPossibleNodeChildren(graph, variable);\r
749         if (nodeChildren.isEmpty()) return map;\r
750         \r
751         map = ensureVariableMap(map, nodeChildren.size());\r
752 \r
753         for(Object nodeChild : nodeChildren) {\r
754             String name = getNodeName(variable, nodeChild);\r
755             if (!map.containsKey(name))\r
756                 map.put(name, createStandardGraphChildVariable(variable, nodeChild));\r
757         }\r
758 \r
759         return map;\r
760     }\r
761 \r
762     /**\r
763      * Get a map of property Variables from a node manager-based Variable, combined with the existing variables in #map.\r
764      * @param graph  The read graph.\r
765      * @param context  The parent Variable.\r
766      * @param map  A map of variables into which the new variables are merged.\r
767      * @return  A map from variable names to instances\r
768      * @throws DatabaseException\r
769      */\r
770     public static Map<String, Variable> getStandardNodePropertyVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
771         AbstractVariable variable = (AbstractVariable)context;\r
772         if (variable.node == null) return map;\r
773         \r
774         Collection<Object> nodeProperties = getPossibleNodeProperties(graph, variable);\r
775         if (nodeProperties.isEmpty()) return map;\r
776         \r
777         map = ensureVariableMap(map, nodeProperties.size());\r
778 \r
779         for(Object nodeProperty : nodeProperties) {\r
780             String name = getNodeName(variable, nodeProperty);\r
781             if (!map.containsKey(name)) {\r
782                 map.put(name, createStandardGraphPropertyVariable(graph, variable, nodeProperty));\r
783             }\r
784         }\r
785 \r
786         return map;\r
787     }    \r
788 \r
789         @SCLValue(type = "VariableMap")\r
790         public static VariableMap standardChildDomainChildren = new VariableMapImpl() {\r
791 \r
792                 @Override\r
793                 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
794                         return StandardChildDomainChildren.getStandardChildDomainChildVariable(graph, context, name);\r
795                 }\r
796 \r
797                 @Override\r
798                 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
799                     return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, map);\r
800                 }\r
801                 \r
802         };\r
803 \r
804     @SCLValue(type = "VariableMap")\r
805         public static VariableMap standardPropertyDomainChildren = new VariableMapImpl() {\r
806 \r
807         /**\r
808          * Get a possible non-standard VariableMap defined in the graph.\r
809          * @param graph  The graph\r
810          * @param context  The context node\r
811          * @return  A non-standard VariableMap instance for the context node,\r
812          *          or null, if not defined or defined as this instance.\r
813          * @throws DatabaseException\r
814          */\r
815         VariableMap getValueVariableMap(ReadGraph graph, Variable context) throws DatabaseException {\r
816                 Resource represents = context.getPossibleRepresents(graph);\r
817                 if(represents == null) return null;\r
818                         VariableMap map = graph.syncRequest(new ChildVariableMapRequest(represents));\r
819                 if(map == standardPropertyDomainChildren) return null;\r
820                 else return map;\r
821         }\r
822         \r
823                 @Override\r
824                 public Variable getVariable(ReadGraph graph, Variable context, String name) throws DatabaseException {\r
825                         // Delegate call to a non-standard variable map?\r
826                         VariableMap valueMap = getValueVariableMap(graph, context);\r
827                         if(valueMap != null) return valueMap.getVariable(graph, context, name);\r
828                         \r
829                         if(context instanceof StandardGraphPropertyVariable) {\r
830                                 StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
831                                 Datatype dt = variable.getDatatype(graph);\r
832                                 if (dt instanceof ArrayType) {\r
833                                         ChildReference ref = getPossibleIndexReference(name);\r
834                                         if (ref != null)\r
835                                                 return new SubliteralPropertyVariableDeprecated(variable, ref);\r
836                                 }\r
837                                 \r
838                                 // Check for a child node provided by the NodeManager\r
839                                 if (variable.node != null) {\r
840                                         Object childNode = getPossibleNodeChild(graph, variable, name);\r
841                                         if (childNode != null)\r
842                                                 return createStandardGraphChildVariable(variable, childNode);\r
843                                 }\r
844                                 return standardChildDomainChildren.getVariable(graph, context, name);\r
845                         } else if (context instanceof StandardGraphChildVariable) {\r
846                                 return standardChildDomainChildren.getVariable(graph, context, name);\r
847                         } else {\r
848                                 throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
849                         }\r
850                 }\r
851 \r
852                 @Override\r
853                 public Map<String, Variable> getVariables(ReadGraph graph, Variable context, Map<String, Variable> map) throws DatabaseException {\r
854                         // Delegate call to a non-standard variable map?\r
855                         VariableMap valueMap = getValueVariableMap(graph, context);\r
856                         if(valueMap != null) return valueMap.getVariables(graph, context, map);\r
857                         \r
858                         if(context instanceof StandardGraphPropertyVariable) {\r
859                                 // Get child variables provided by the NodeManager\r
860                                 Map<String, Variable> result = getStandardNodeChildVariables(graph, context, map); \r
861                                 return standardChildDomainChildren.getVariables(graph, context, result);\r
862                         } else if (context instanceof StandardGraphChildVariable) {\r
863                                 return standardChildDomainChildren.getVariables(graph, context, map);\r
864                         } else {\r
865                                 throw new DatabaseException("Unknown variable implementation " + context.getClass().getCanonicalName());\r
866                         }       \r
867                 }\r
868                 \r
869         };\r
870         \r
871         protected static ChildReference getPossibleIndexReference(String name) {\r
872                 if (name.startsWith("i-")) {\r
873                     try {\r
874                         int index = Integer.parseInt(name.substring(2));\r
875                         return new IndexReference(index);\r
876                     } catch (NumberFormatException e) {}\r
877                 }\r
878                 return null;\r
879         }\r
880 \r
881         protected static ValueAccessor getPossiblePropertyValueAccessor(ReadGraph graph, StandardGraphPropertyVariable variable) throws DatabaseException {\r
882             if(variable.property == null) return null;\r
883             return variable.property.valueAccessor;\r
884 //        return graph.syncRequest(new PropertyValueAccessorRequest(variable.property), TransientCacheAsyncListener.<ValueAccessor>instance());\r
885 //              return graph.syncRequest(new PossibleRelatedValueImplied2<ValueAccessor>(variable.property, Layer0.getInstance(graph).valueAccessor));\r
886         }\r
887 \r
888         public static ValueAccessor getPossibleValueValueAccessor(ReadGraph graph, Variable variable) throws DatabaseException {\r
889             Resource value = variable.getPossibleRepresents(graph);\r
890             if(value == null) return null;\r
891             //return graph.syncRequest(new PropertyValueAccessorRequest(value));\r
892                 return graph.syncRequest(new PossibleRelatedValueImplied2<ValueAccessor>(value, Layer0.getInstance(graph).valueAccessor));      \r
893         }\r
894         \r
895         public static PropertyInfo getPossiblePropertyInfoFromContext(ReadGraph graph, Variable variable, Resource context, String name) throws DatabaseException {\r
896             if(context == null) return null;\r
897                 Map<String, PropertyInfo> predicates = graph.syncRequest(new UnescapedPropertyMapOfResource(context));\r
898                 return predicates.get(name);\r
899         }\r
900 \r
901     public static Variable getPossiblePropertyFromContext(ReadGraph graph, Variable variable, Resource context, String name, Object propertyNode) throws DatabaseException {\r
902         PropertyInfo info = getPossiblePropertyInfoFromContext(graph, variable, context, name);\r
903         if(info == null || info.builder == null) return null;\r
904         return buildPropertyVariable(graph, variable, context, info, propertyNode);\r
905     }\r
906     \r
907     public static Variable getPossibleSubliteralPropertyFromContext(ReadGraph graph, StandardGraphPropertyVariable variable, String name) throws DatabaseException {\r
908         \r
909                 Resource predicate = variable.property.predicate;\r
910                 if(predicate == null) return null;\r
911 \r
912         PropertyInfo info = getPropertyInfo(graph, predicate);\r
913         Pair<Resource, ChildReference> p = info.subliteralPredicates.get(name);\r
914         if(p == null) return null;\r
915         \r
916                 return new SubliteralPropertyVariable(graph, variable, p.first, p.second);\r
917         \r
918     }\r
919 \r
920     public static Map<String, PropertyInfo> collectPropertyInfosFromContext(ReadGraph graph, Variable variable, Resource context) throws DatabaseException {\r
921         if(context == null) return Collections.emptyMap();\r
922                 return graph.isImmutable(context) ?\r
923                                 graph.syncRequest(new UnescapedPropertyMapOfResource(context), TransientCacheAsyncListener.<Map<String,PropertyInfo>>instance()) :\r
924                                 graph.syncRequest(new UnescapedPropertyMapOfResource(context));\r
925     }\r
926 \r
927         public static Map<String, Variable> collectPropertiesFromContext(ReadGraph graph, Variable variable, Resource context, Map<String, Variable> map) throws DatabaseException {\r
928 \r
929                 Map<String,PropertyInfo> properties = graph.isImmutable(context) ?\r
930                                 graph.syncRequest(new UnescapedPropertyMapOfResource(context), TransientCacheAsyncListener.<Map<String,PropertyInfo>>instance()) :\r
931                                 graph.syncRequest(new UnescapedPropertyMapOfResource(context));\r
932                                 \r
933                 if(properties.isEmpty()) return map;\r
934                 \r
935                 map = ensureVariableMap(map, properties.size());\r
936                 \r
937                 for(PropertyInfo info : properties.values()) {\r
938                         String name = info.name;\r
939                         if (info.builder != null) {\r
940                                 Variable v = info.builder.buildProperty(graph, variable, null, context, info.predicate);\r
941                                 map.put(name, v);\r
942                         }\r
943                 }\r
944                 \r
945                 return map;\r
946                 \r
947         }\r
948 \r
949         public static Map<String, Variable> collectSubliteralProperties(ReadGraph graph, StandardGraphPropertyVariable variable, Map<String, Variable> map) throws DatabaseException {\r
950 \r
951                 Resource predicate = variable.property.predicate;\r
952                 if(predicate == null) return map;\r
953                 \r
954                 PropertyInfo info = getPropertyInfo(graph, predicate);\r
955                 if(info.subliteralPredicates.isEmpty()) return map;\r
956                 \r
957                 map = ensureVariableMap(map, info.subliteralPredicates.size());\r
958                 \r
959                 for(Map.Entry<String, Pair<Resource, ChildReference>> entry : info.subliteralPredicates.entrySet()) {\r
960                         String key = entry.getKey();\r
961                         Pair<Resource, ChildReference> p = entry.getValue();\r
962                         if(map == null) map = new THashMap<String,Variable>();\r
963                         map.put(key, new SubliteralPropertyVariable(graph, variable, p.first, p.second));\r
964                 }\r
965         \r
966         return map;\r
967                 \r
968         }\r
969 \r
970         public static Map<String, Variable> collectPropertiesFromContext(ReadGraph graph, Variable variable, Resource context, String classification, Map<String, Variable> map) throws DatabaseException {\r
971 \r
972                 if(graph.isImmutable(context)) {\r
973 \r
974                         Map<String,PropertyInfo> properties = graph.syncRequest(new UnescapedPropertyMapOfResource(context), TransientCacheAsyncListener.<Map<String,PropertyInfo>>instance());\r
975                         for(PropertyInfo info : properties.values()) {\r
976 \r
977                                 if(info.classifications.contains(classification) && info.builder != null) {\r
978                                         String name = info.name;\r
979                                         Variable v = info.builder.buildProperty(graph, variable, null, context, info.predicate);\r
980                                         if(map == null) map = new THashMap<String,Variable>();\r
981                                         map.put(name, v);\r
982                                 }\r
983 \r
984                         }\r
985 \r
986                 } else {\r
987                                 \r
988                         Collection<Resource> predicates = graph.getPredicates(context);\r
989                                         \r
990                         if(predicates.isEmpty()) return map;\r
991                         \r
992                         map = ensureVariableMap(map, predicates.size());\r
993                 \r
994                         for(Resource predicate : predicates) {\r
995                                 \r
996                                 PropertyInfo info = graph.isImmutable(predicate) ?\r
997                                                 graph.syncRequest(new PropertyInfoRequest(predicate), TransientCacheAsyncListener.<PropertyInfo>instance()) :\r
998                                                         graph.syncRequest(new PropertyInfoRequest(predicate));\r
999                                                 \r
1000                                 if(!info.isHasProperty) continue;\r
1001         \r
1002                                 if(info.classifications.contains(classification) && info.builder != null) {\r
1003                                         String name = info.name;\r
1004                                         Variable v = info.builder.buildProperty(graph, variable, null, context, info.predicate);\r
1005                                         if(map == null) map = new THashMap<String,Variable>();\r
1006                                         map.put(name, v);\r
1007                                 }\r
1008                                 \r
1009                         }\r
1010                         \r
1011                 }\r
1012                 \r
1013                 return map;\r
1014                 \r
1015         }       \r
1016         \r
1017     @SCLValue(type = "ReadGraph -> Resource -> a -> String")\r
1018     public static String entityLabel(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1019         if(context instanceof Resource) {\r
1020                 return NameUtils.getSafeLabel(graph, ((Resource)context));      \r
1021         } else if (context instanceof Variable) {\r
1022                 Variable parent = ((Variable)context).getParent(graph);\r
1023                 Resource represents = parent.getRepresents(graph);\r
1024                 return NameUtils.getSafeLabel(graph, represents);\r
1025         } else {\r
1026                 throw new DatabaseException("Unknown context " + context);\r
1027         }\r
1028     }\r
1029 \r
1030     @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
1031     public static Object listResources(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1032         return ListUtils.toList(graph, resource);\r
1033     }\r
1034 \r
1035     @SCLValue(type = "ReadGraph -> Resource -> Variable -> [String]")\r
1036     public static List<String> standardClassifications(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
1037         ArrayList<String> result = new ArrayList<String>();\r
1038         Resource predicate = context.getParent(graph).getPossiblePredicateResource(graph);\r
1039         if(predicate != null) {\r
1040                 for(Resource type : graph.getTypes(predicate)) {\r
1041                         String uri = graph.getPossibleURI(type);\r
1042                         if(uri != null) result.add(uri);\r
1043                 }\r
1044         }\r
1045         return result;\r
1046     }\r
1047 \r
1048     @SCLValue(type = "ReadGraph -> Resource -> a -> Boolean")\r
1049     public static Boolean standardValidValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1050         return Boolean.TRUE;\r
1051     }\r
1052 \r
1053     @SCLValue(type = "ReadGraph -> Resource -> a -> StringInputValidator")\r
1054     public static StringInputValidator standardValidator(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1055         return StringInputValidator.PASS;\r
1056     }\r
1057 \r
1058     @SCLValue(type = "ReadGraph -> Resource -> a -> Boolean")\r
1059     public static Boolean standardRequiredValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1060         return Boolean.FALSE;\r
1061     }\r
1062 \r
1063     @SCLValue(type = "ReadGraph -> Resource -> Variable -> Boolean")\r
1064     public static Boolean standardDefaultValue(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
1065         Variable property = context.getParent(graph);\r
1066         if(property instanceof StandardGraphPropertyVariable) {\r
1067                 StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)property;\r
1068                 if (variable.parentResource != null) {\r
1069                         Statement stm = graph.getPossibleStatement(variable.parentResource, variable.property.predicate);\r
1070                         return stm != null && stm.isAsserted(variable.parentResource);\r
1071                         }\r
1072         }\r
1073         return Boolean.FALSE;\r
1074     }\r
1075 \r
1076     @SCLValue(type = "ReadGraph -> Resource -> a -> Boolean")\r
1077     public static Boolean standardReadOnlyValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1078         return Boolean.FALSE;\r
1079     }\r
1080 \r
1081     @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
1082     public static Object resourceAsValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1083         return resource;\r
1084     }\r
1085     \r
1086     @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
1087     public static Object functionApplication(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1088         return Functions.exec(graph, resource, graph, resource, context);\r
1089     }\r
1090 \r
1091     @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
1092     public static Object computeExpression(ReadGraph graph, Resource converter, Object context) throws DatabaseException {\r
1093         if(context instanceof Variable) {\r
1094             return CompileValueRequest.compileAndEvaluate(graph, (Variable)context);\r
1095         } if (context instanceof Resource) {\r
1096             return CompileResourceValueRequest.compileAndEvaluate(graph, (Resource)converter);\r
1097         } else {\r
1098                 throw new IllegalStateException("Unknown context " + context);\r
1099         }\r
1100     }\r
1101 \r
1102     @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
1103     public static Object composedPropertyValue(ReadGraph graph, Resource converter, Object context) throws DatabaseException {\r
1104         if(context instanceof Variable) {\r
1105                 return new StandardComposedProperty();\r
1106         } if (context instanceof Resource) {\r
1107                 return new StandardComposedProperty();\r
1108         } else {\r
1109                 throw new IllegalStateException("Unknown context " + context);\r
1110         }\r
1111     }\r
1112     \r
1113     @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
1114     public static Object numberInputValidator(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1115         \r
1116         class Validator extends FunctionImpl1<String, String> {\r
1117 \r
1118             private final Datatype datatype;\r
1119             \r
1120             public Validator(Datatype datatype) {\r
1121                 this.datatype = datatype;\r
1122             }\r
1123             \r
1124             @Override\r
1125             public String apply(String input) {\r
1126                 \r
1127                 if(datatype == null) return null;\r
1128                 \r
1129                 try {\r
1130 \r
1131                     if(datatype instanceof NumberType) {\r
1132                         \r
1133                         Number number = (Number)PrimitiveValueParser.parse(input, datatype);\r
1134                         NumberType nt = (NumberType)datatype;\r
1135                         Range r = nt.getRange();\r
1136                         if(r != null) {\r
1137                             if(!r.contains(number)) return "Value is out of valid range";\r
1138                         }\r
1139                     }\r
1140                     return null;\r
1141                     \r
1142                 } catch (NumberFormatException e) {\r
1143                     return "Not a valid floating-point number";\r
1144                 } catch (IllegalArgumentException e) {\r
1145                     return "Not a valid floating-point number";\r
1146                 }\r
1147                 \r
1148             }\r
1149             \r
1150         }\r
1151 \r
1152         if(context instanceof Variable) {\r
1153             \r
1154             Variable variable = (Variable)context;\r
1155             Variable property = variable.getParent(graph);\r
1156             Datatype datatype = property.getPossibleDatatype(graph);\r
1157             return new Validator(datatype);\r
1158             \r
1159         } else if (context instanceof Resource) {\r
1160 \r
1161             Layer0 L0 = Layer0.getInstance(graph);\r
1162             Resource literal = (Resource)context;\r
1163             Datatype datatype = graph.getRelatedValue(literal, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class));\r
1164             return new Validator(datatype);\r
1165             \r
1166         } else {\r
1167             \r
1168             return new Validator(null);\r
1169             \r
1170         }\r
1171         \r
1172     }\r
1173     \r
1174     @SCLValue(type = "ReadGraph -> Resource -> a -> b")\r
1175     public static Object booleanInputValidator(ReadGraph graph, Resource resource, Object context) throws DatabaseException {\r
1176         \r
1177         return new FunctionImpl1<String, String>() {\r
1178 \r
1179             @Override\r
1180             public String apply(String input) {\r
1181                 \r
1182                 String lower = input.toLowerCase();\r
1183                 if("true".equals(lower) || "false".equals(lower)) return null;\r
1184 \r
1185                 return "Not a valid boolean: " + input;\r
1186                 \r
1187             }\r
1188             \r
1189         };\r
1190         \r
1191     }\r
1192 \r
1193     @SCLValue(type = "ReadGraph -> Resource -> Variable -> Resource")\r
1194     public static Resource hasStandardResource(ReadGraph graph, Resource resource, Variable context) throws DatabaseException {\r
1195         Variable parent = context.getParent(graph);\r
1196         if(parent instanceof StandardGraphChildVariable) {\r
1197                 StandardGraphChildVariable variable = (StandardGraphChildVariable)parent;\r
1198                 return variable.resource;\r
1199         }\r
1200         return null;\r
1201     }\r
1202 \r
1203 \r
1204     @SCLValue(type = "ReadGraph -> Resource -> Variable -> a")\r
1205         public static Object valueWithoutBinding(ReadGraph graph, Resource converter, Variable context) throws DatabaseException {\r
1206 \r
1207         StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
1208                 \r
1209                 if(graph.sync(new IsEnumeratedValue(variable.getRepresents(graph)))) {\r
1210                         Layer0 L0 = Layer0.getInstance(graph);\r
1211                         return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel);\r
1212                 }\r
1213 \r
1214                 if (variable.parentResource == null)\r
1215                         throw new VariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").");\r
1216 \r
1217                 try {\r
1218                         return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);\r
1219                 } catch (NoSingleResultException e) {\r
1220                         throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
1221                 } catch (DoesNotContainValueException e) {\r
1222                         throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
1223                 }\r
1224                 \r
1225         }\r
1226 \r
1227     @SCLValue(type = "ReadGraph -> Variable -> Binding -> a")\r
1228         public static Object valueWithBinding(ReadGraph graph, Variable context, Binding binding) throws DatabaseException {\r
1229 \r
1230         StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)context;\r
1231                 \r
1232                 if(graph.sync(new IsEnumeratedValue(variable.getRepresents(graph)))) {\r
1233                         Layer0 L0 = Layer0.getInstance(graph);\r
1234                         return graph.getRelatedValue2(variable.getRepresents(graph), L0.HasLabel, binding);\r
1235                 }\r
1236 \r
1237                 if (variable.parentResource == null)\r
1238                         throw new VariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").");\r
1239 \r
1240                 try {\r
1241                         return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable);\r
1242                 } catch (NoSingleResultException e) {\r
1243                         throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
1244                 } catch (DoesNotContainValueException e) {\r
1245                         throw new MissingVariableValueException(variable.getPossibleURI(graph));\r
1246                 }\r
1247                 \r
1248         }\r
1249 \r
1250     @SCLValue(type = "WriteGraph -> Variable -> a -> Binding -> b")\r
1251         public static Object valueSetterWithBinding(WriteGraph graph, Variable variable, Object value, Binding binding) throws DatabaseException {\r
1252                 \r
1253                 Function4<WriteGraph, Variable, Object, Object, String> modifier = variable.getPossiblePropertyValue(graph, Variables.INPUT_MODIFIER);\r
1254                 if(modifier == null) modifier = VariableUtils.defaultInputModifier; \r
1255                 modifier.apply(graph, variable, value, binding);\r
1256                 return null;\r
1257                 \r
1258         }\r
1259     \r
1260     static class L0Issue extends StandardIssue {\r
1261         \r
1262         private final String description;\r
1263         \r
1264         public L0Issue(String description, Resource type, Resource ... contexts) {\r
1265             super(type, contexts);\r
1266             this.description = description;\r
1267         }\r
1268 \r
1269         @Override\r
1270         public Resource write(WriteGraph graph, Resource source) throws DatabaseException {\r
1271             Layer0 L0 = Layer0.getInstance(graph);\r
1272             IssueResource IR = IssueResource.getInstance(graph);\r
1273             Resource issue = super.write(graph, source);\r
1274             graph.claim(issue, IR.Issue_HasSeverity, IR.Severity_Fatal);\r
1275             graph.addLiteral(issue, L0.HasDescription, L0.HasDescription_Inverse, description, Bindings.STRING);\r
1276             return issue;\r
1277         }\r
1278         \r
1279     }\r
1280     \r
1281         private static List<Issue> reportInconsistency(ReadGraph graph, Resource subject, String description, List<Issue> issues) throws DatabaseException {\r
1282             if(issues == null) issues = new ArrayList<Issue>();\r
1283                 System.err.println("Change set validation reports the following issue: " + NameUtils.getSafeName(graph, subject, true) + ": " + description);\r
1284                 IssueResource IR = IssueResource.getInstance(graph);\r
1285                 issues.add(new L0Issue(description, IR.Issue, subject));\r
1286                 return issues;\r
1287         }\r
1288     \r
1289     @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
1290     public static List<Issue> relationValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
1291 \r
1292         Layer0 L0 = Layer0.getInstance(graph);\r
1293 \r
1294         List<Issue> issues = null;\r
1295         \r
1296         for(Statement stm : graph.getStatements(resource, L0.IsWeaklyRelatedTo)) {\r
1297                 Resource predicate = stm.getPredicate();\r
1298                 Resource object = stm.getObject();\r
1299                 if(!isRelation(graph, L0, predicate)) {\r
1300                         issues = reportInconsistency(graph, resource, "The predicate of a statement must be a relation: " + NameUtils.toString(graph, stm), issues);\r
1301                 }\r
1302                 if(graph.isInstanceOf(predicate, L0.FunctionalRelation)) {\r
1303                         if(graph.getObjects(resource, predicate).size() > 1)\r
1304                                 issues = reportInconsistency(graph, resource, \r
1305                                                 "Relation " +\r
1306                                                                 NameUtils.getSafeName(graph, predicate)\r
1307                                                                 + " is functional.", issues);\r
1308                 }\r
1309                 {\r
1310                         Collection<Resource> domain = graph.getObjects(predicate, L0.HasDomain);\r
1311                         if (!isInstanceOfAny(graph, resource, domain, true)) {\r
1312                                 StringBuilder sb = new StringBuilder()\r
1313                                 .append("The domain of ")\r
1314                                 .append(NameUtils.getSafeName(graph, predicate))\r
1315                                 .append(" relation is ");\r
1316                                 orString(graph, sb, domain).append(".");\r
1317                                 issues = reportInconsistency(graph, resource, sb.toString(), issues);\r
1318                         }\r
1319                 }\r
1320                 {\r
1321                         Collection<Resource> range = graph.getObjects(predicate, L0.HasRange);\r
1322                         if (!isInstanceOfAny(graph, object, range, true) && !graph.isInstanceOf(object, L0.SCLValue)) {\r
1323                                 StringBuilder sb = new StringBuilder()\r
1324                                 .append("The range of ")\r
1325                                 .append(NameUtils.getSafeName(graph, predicate))\r
1326                                 .append(" relation is ");\r
1327                                 orString(graph, sb, range).append(" but current object is ")\r
1328                                 .append(NameUtils.getSafeName(graph, object)).append(".");\r
1329                                 issues = reportInconsistency(graph, resource, sb.toString(), issues);\r
1330                         }\r
1331                 }               \r
1332         }\r
1333                 \r
1334                 return issues != null ? issues : Collections.<Issue>emptyList();\r
1335 \r
1336     }\r
1337 \r
1338     @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
1339     public static List<Issue> propertyValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
1340 \r
1341         List<Issue> issues = null;\r
1342 \r
1343         Layer0 L0 = Layer0.getInstance(graph);\r
1344         for(Statement stm : graph.getStatements(resource, L0.HasProperty)) {\r
1345                 Resource subject = stm.getSubject();\r
1346                 Resource predicate = stm.getPredicate();\r
1347                 String error = L0Validations.checkValueType(graph, subject, predicate);\r
1348                 if(error != null) issues = reportInconsistency(graph, subject, error, issues);\r
1349         }\r
1350                 \r
1351         return issues != null ? issues : Collections.<Issue>emptyList();\r
1352 \r
1353     }\r
1354     \r
1355     \r
1356     @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
1357     public static List<Issue> valueValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
1358 \r
1359         List<Issue> issues = null;\r
1360 \r
1361         Layer0 L0 = Layer0.getInstance(graph);\r
1362         if(graph.hasValue(resource)) {\r
1363                 if(!graph.isInstanceOf(resource, L0.Literal)) {\r
1364                         issues = reportInconsistency(graph, resource, \r
1365                                         "Resource has a value but it is not a literal.", issues);\r
1366                 }\r
1367                 else {\r
1368                         // TODO check that the value is valid for the data type\r
1369                 }\r
1370         }\r
1371         else {\r
1372                 if(graph.isInstanceOf(resource, L0.Literal)) {\r
1373                         issues = reportInconsistency(graph, resource, \r
1374                                         "Resource is a literal but it does not have a value.", issues);\r
1375                 }\r
1376         }\r
1377         \r
1378         return issues != null ? issues : Collections.<Issue>emptyList();\r
1379         \r
1380     }\r
1381 \r
1382     \r
1383     @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
1384     public static List<Issue> uriValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
1385         \r
1386         List<Issue> issues = null;\r
1387 \r
1388         Layer0 L0 = Layer0.getInstance(graph);\r
1389         Resource parent = graph.getPossibleObject(resource, L0.PartOf);\r
1390         if(parent != null) {\r
1391             String parentURI = graph.syncRequest(new PossibleURI(parent));\r
1392             if(parentURI != null) {\r
1393                         String name = graph.getPossibleRelatedValue(resource, L0.HasName);\r
1394                         if(name == null) {\r
1395                                 issues = reportInconsistency(graph, resource, "Resource has a parent with URI but has no valid HasName.", issues);\r
1396                         }\r
1397             }\r
1398         }\r
1399 \r
1400         return issues != null ? issues : Collections.<Issue>emptyList();\r
1401         \r
1402     }\r
1403     \r
1404     private static Resource getPossibleNearestClusterSet(ReadGraph graph, Resource base, Resource resource) throws DatabaseException {\r
1405 \r
1406         ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
1407         if(cs.isClusterSet(resource) && !base.equals(resource)) return resource;\r
1408         \r
1409         Resource nearest = CommonDBUtils.getNearestOwner(graph, Collections.singletonList(resource));\r
1410         if(nearest == null) return null;\r
1411         \r
1412         return getPossibleNearestClusterSet(graph, base, nearest);\r
1413 \r
1414     }\r
1415 \r
1416     private static boolean quirks(ReadGraph graph, Resource resource) throws DatabaseException {\r
1417 \r
1418         if(!resource.isPersistent()) return true;\r
1419         if(graph.isImmutable(resource)) return true;\r
1420         if(resource.getResourceId() < 0x2000) return true;\r
1421 \r
1422         return false;\r
1423         \r
1424     }\r
1425     \r
1426     @SCLValue(type = "ReadGraph -> Resource -> [Issue]")\r
1427     public static List<Issue> clusterValidator(ReadGraph graph, Resource resource) throws DatabaseException {\r
1428 \r
1429         if(!Development.DEVELOPMENT) return Collections.<Issue>emptyList();\r
1430         \r
1431         if(quirks(graph, resource)) return Collections.<Issue>emptyList();\r
1432         \r
1433         List<Issue> issues = null;\r
1434 \r
1435         ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
1436         Resource set = cs.getClusterSetOfCluster(resource);\r
1437         \r
1438         if(set == null) return reportInconsistency(graph, resource, "Resource cluster is not part of any cluster set", issues);\r
1439         \r
1440         Resource nearestSet = getPossibleNearestClusterSet(graph, resource, resource);\r
1441         if(nearestSet == null) {\r
1442                 // This means that there is no owner since RootLibrary is a cluster set\r
1443                 return Collections.<Issue>emptyList();\r
1444         }\r
1445         \r
1446         if(!set.equals(nearestSet)) return reportInconsistency(graph, resource, "The cluster set of a resource is not the nearest owner set", issues);\r
1447 \r
1448         return Collections.<Issue>emptyList();\r
1449         \r
1450     }\r
1451 \r
1452     private static boolean isInstanceOfAny(ReadGraph graph, Resource r, Collection<Resource> types, boolean ifEmpty) throws DatabaseException {\r
1453                 if (types.isEmpty())\r
1454                         return ifEmpty;\r
1455                 for (Resource type : types) {\r
1456                         if (graph.isInstanceOf(r, type)) {\r
1457                                 return true;\r
1458                         }\r
1459                 }\r
1460                 return false;\r
1461         }\r
1462 \r
1463         private static StringBuilder orString(ReadGraph graph, StringBuilder sb, Collection<Resource> rs) throws DatabaseException {\r
1464                 sb.append("(");\r
1465                 boolean first = true;\r
1466                 for (Resource r : rs) {\r
1467                         if (!first)\r
1468                                 sb.append(" | ");\r
1469                         first = false;\r
1470                         sb.append(NameUtils.getSafeName(graph, r));\r
1471                 }\r
1472                 sb.append(")");\r
1473                 return sb;\r
1474         }\r
1475 \r
1476     public static boolean isRelation(ReadGraph g, Layer0 l0, Resource relation) throws DatabaseException {\r
1477                 return g.hasStatement(relation, l0.SubrelationOf) || relation == l0.IsWeaklyRelatedTo;\r
1478         }\r
1479         \r
1480         public static boolean isType(ReadGraph g, Layer0 l0, Resource type) throws DatabaseException {\r
1481                 return g.hasStatement(type, l0.Inherits) || type == l0.Entity;\r
1482         }\r
1483         \r
1484     public static Variable buildChildVariable(ReadGraph graph, Variable context, Resource graphChild, Object nodeChild) throws DatabaseException {\r
1485         VariableBuilder builder = graph.adapt(graphChild, VariableBuilder.class);\r
1486         return builder.buildChild(graph, context, build(((AbstractVariable)context).node, nodeChild), graphChild);\r
1487         }\r
1488 \r
1489         private static Variable buildPropertyVariable(ReadGraph graph, Variable variable, Resource parentResource, PropertyInfo graphProperty, Object propertyNode) throws DatabaseException {\r
1490                 VariableNode<?> node = variable instanceof AbstractVariable ? build(((AbstractVariable)variable).node, propertyNode) : null;\r
1491                 return graphProperty.builder.buildProperty(graph, variable, node, parentResource, graphProperty.predicate);\r
1492         }\r
1493         \r
1494         static StandardGraphChildVariable createStandardGraphChildVariable(\r
1495                         AbstractVariable parent, Object child) {\r
1496                 return new StandardGraphChildVariable(parent, build(parent.node, child), null);\r
1497         }\r
1498 \r
1499         private static StandardGraphPropertyVariable createStandardGraphPropertyVariable(\r
1500                         ReadGraph graph, AbstractVariable variable, Object nodeProperty) throws DatabaseException {\r
1501         Resource propertyResource = getPossiblePropertyResource(graph, variable, nodeProperty);\r
1502         return new StandardGraphPropertyVariable(graph, variable, build(variable.node, nodeProperty), null, propertyResource);\r
1503         }\r
1504         \r
1505         static Map<String, Variable> ensureVariableMap(\r
1506                         Map<String, Variable> map, int size) {\r
1507                 if(map == null) map = new THashMap<String,Variable>(size);\r
1508                 return map;\r
1509         }\r
1510 \r
1511         private static PropertyInfo getPropertyInfo(ReadGraph graph, Resource predicate) throws DatabaseException {\r
1512                 return graph.syncRequest(new PropertyInfoRequest(predicate));\r
1513         }\r
1514 \r
1515         @SuppressWarnings("unchecked")\r
1516         static String getNodeName(AbstractVariable parent, Object child) {\r
1517                 return parent.node.support.manager.getName(child);\r
1518         }\r
1519 \r
1520         @SuppressWarnings("unchecked")\r
1521         private static Object getNodeValue(final AbstractVariable variable, final Binding binding) throws NodeManagerException, BindingException {\r
1522                 return variable.node.support.manager.getValue(variable.node.node, binding);\r
1523         }\r
1524 \r
1525         @SuppressWarnings("unchecked")\r
1526         private static void setNodeValue(final AbstractVariable variable, final Object value, final Binding binding) throws NodeManagerException, BindingException {\r
1527                 variable.node.support.manager.setValue(variable.node.node, value, binding);\r
1528         }\r
1529         \r
1530         @SuppressWarnings("unchecked")\r
1531         private static String getPossiblePropertyURI(AbstractVariable parent, Object node) {\r
1532                 return parent.node.support.manager.getPropertyURI(parent.node.node, node);\r
1533         }\r
1534     \r
1535 }