1 package org.simantics.db.layer0.variable;
\r
3 import java.util.Collection;
\r
4 import java.util.Collections;
\r
5 import java.util.HashMap;
\r
6 import java.util.Map;
\r
7 import java.util.Set;
\r
9 import org.simantics.databoard.Bindings;
\r
10 import org.simantics.databoard.accessor.reference.ChildReference;
\r
11 import org.simantics.databoard.binding.Binding;
\r
12 import org.simantics.databoard.binding.impl.ObjectVariantBinding;
\r
13 import org.simantics.databoard.type.Datatype;
\r
14 import org.simantics.db.ReadGraph;
\r
15 import org.simantics.db.Resource;
\r
16 import org.simantics.db.WriteGraph;
\r
17 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
\r
18 import org.simantics.db.common.utils.Logger;
\r
19 import org.simantics.db.common.validation.L0Validations;
\r
20 import org.simantics.db.exception.DatabaseException;
\r
21 import org.simantics.db.exception.ValidationException;
\r
22 import org.simantics.db.layer0.exception.MissingVariableValueException;
\r
23 import org.simantics.db.layer0.exception.PendingVariableException;
\r
24 import org.simantics.db.layer0.exception.VariableException;
\r
25 import org.simantics.db.layer0.function.All;
\r
26 import org.simantics.db.layer0.request.PropertyInfo;
\r
27 import org.simantics.db.layer0.request.PropertyInfoRequest;
\r
28 import org.simantics.db.layer0.util.Layer0Utils;
\r
29 import org.simantics.layer0.Layer0;
\r
30 import org.simantics.utils.Development;
\r
31 import org.simantics.utils.datastructures.Pair;
\r
33 public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
\r
35 protected static final PropertyInfo NO_PROPERTY = new PropertyInfo(null, null,
\r
36 false, Collections.<String> emptySet(), null, null, null, null, null, null,
\r
37 Collections.<String, Pair<Resource, ChildReference>> emptyMap(),
\r
40 final public Variable parent;
\r
41 final public Resource parentResource;
\r
42 final public PropertyInfo property;
\r
43 final public Resource represents;
\r
45 transient private int hash = 0;
\r
47 public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, VariableNode node, Resource property) throws DatabaseException {
\r
48 this(graph, parent, node, (Resource)parent.getPossibleRepresents(graph), getPropertyInfo(graph, property));
\r
51 public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, VariableNode node, Resource parentResource, Resource property) throws DatabaseException {
\r
52 this(graph, parent, node, parentResource, getPropertyInfo(graph, property));
\r
55 public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, Resource property) throws DatabaseException {
\r
56 this(graph, parent, null, (Resource)parent.getPossibleRepresents(graph), getPropertyInfo(graph, property));
\r
59 public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, Resource parentResource, PropertyInfo property) throws DatabaseException {
\r
60 this(parent, null, parentResource, property, getPossibleRepresents(graph, parentResource, property.predicate));
\r
63 public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, VariableNode node, Resource parentResource, PropertyInfo property) throws DatabaseException {
\r
64 this(parent, node, parentResource, property, getPossibleRepresents(graph, parentResource, property.predicate));
\r
67 private static PropertyInfo getPropertyInfo(ReadGraph graph, Resource property) throws DatabaseException {
\r
68 return property != null ? graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance()) : NO_PROPERTY;
\r
71 private static Resource getPossibleRepresents(ReadGraph graph, Resource parentResource, Resource predicate) throws DatabaseException {
\r
72 if(parentResource == null || predicate == null) return null;
\r
73 return graph.getPossibleObject(parentResource, predicate);
\r
76 public boolean isAsserted() {
\r
80 public StandardGraphPropertyVariable(Variable parent, VariableNode node, Resource parentResource, PropertyInfo property, Resource represents) throws DatabaseException {
\r
82 assert parent != null;
\r
83 this.parent = parent;
\r
84 this.property = property;
\r
85 this.parentResource = parentResource;
\r
86 this.represents = represents;
\r
90 public String getName(ReadGraph graph) throws DatabaseException {
\r
91 if(node != null) return node.support.manager.getName(node.node);
\r
92 return property.name;
\r
96 public String getPossibleLabel(ReadGraph graph) throws DatabaseException {
\r
97 return graph.getPossibleRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING);
\r
101 public String getLabel(ReadGraph graph) throws DatabaseException {
\r
102 return graph.getRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING);
\r
106 public Variable getParent(ReadGraph graph) throws DatabaseException {
\r
111 public PropertyInfo getPropertyInfo(ReadGraph graph) throws DatabaseException {
\r
115 @SuppressWarnings("unchecked")
\r
117 public <T> T getValue(ReadGraph graph) throws DatabaseException {
\r
119 if(Development.DEVELOPMENT) {
\r
120 String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
\r
121 if(error != null) {
\r
122 Logger.defaultLogError(new ValidationException(error));
\r
123 //throw new ValidationException(error);
\r
127 return (T)getValueAccessor(graph).getValue(graph, this);
\r
131 @SuppressWarnings("unchecked")
\r
133 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
\r
134 // Fall back to the bindingless method, if the expected output is a Java object
\r
135 if (binding instanceof ObjectVariantBinding)
\r
136 return getValue(graph);
\r
138 if(Development.DEVELOPMENT) {
\r
139 String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
\r
140 if(error != null) {
\r
141 Logger.defaultLogError(new ValidationException(error));
\r
142 throw new ValidationException(error);
\r
148 return (T)getValueAccessor(graph).getValue(graph, this, binding);
\r
149 } catch (PendingVariableException e) {
\r
151 } catch (Throwable t) {
\r
152 throw new MissingVariableValueException(t);
\r
158 public Resource getRepresents(ReadGraph graph) throws DatabaseException {
\r
159 if(represents == null)
\r
160 throw new VariableException("Variable is not represented by any resource (URI=" + getPossibleURI(graph) + ").");
\r
162 // return graph.getSingleObject(parentResource, property.predicate);
\r
166 public Resource getPossibleRepresents(ReadGraph graph) throws DatabaseException {
\r
167 // if(parentResource == null) return null;
\r
168 // return graph.getPossibleObject(parentResource, property.predicate);
\r
173 public void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException {
\r
175 if(Development.DEVELOPMENT) {
\r
176 String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
\r
177 if(error != null) {
\r
178 Logger.defaultLogError(new ValidationException(error));
\r
179 //throw new ValidationException(error);
\r
183 getValueAccessor(graph).setValue(graph, this, value, binding);
\r
188 public void setValue(WriteGraph graph, Object value) throws DatabaseException {
\r
190 if(Development.DEVELOPMENT) {
\r
191 String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
\r
192 if(error != null) {
\r
193 Logger.defaultLogError(new ValidationException(error));
\r
194 throw new ValidationException(error);
\r
198 getValueAccessor(graph).setValue(graph, this, value);
\r
203 public Binding getDefaultBinding(ReadGraph graph) throws DatabaseException {
\r
204 return Layer0Utils.getDefaultBinding(graph, this);
\r
208 public Binding getPossibleDefaultBinding(ReadGraph graph) throws DatabaseException {
\r
209 return Layer0Utils.getPossibleDefaultBinding(graph, this);
\r
213 public Datatype getDatatype(ReadGraph graph) throws DatabaseException {
\r
216 // Binding binding = getPossibleDefaultBinding(graph);
\r
217 // if(binding != null) return binding.type();
\r
219 // Variant vt = getVariantValue(graph);
\r
220 // binding = vt.getBinding();
\r
221 // if(binding == null) throw new DatabaseException("No binding in Variant with value " + vt.getValue());
\r
222 // return binding.type();
\r
226 type = getValueAccessor(graph).getDatatype(graph, this);
\r
227 } catch (Throwable t) {
\r
228 throw new MissingVariableValueException(t);
\r
231 if (type == null) {
\r
232 String uri = this.getPossibleURI(graph);
\r
234 throw new DatabaseException("No data type for " + uri);
\r
236 throw new DatabaseException("No data type for " + this.getIdentifier());
\r
245 public Datatype getPossibleDatatype(ReadGraph graph) throws DatabaseException {
\r
248 return getDatatype(graph);
\r
249 } catch (DatabaseException e) {
\r
256 public String getUnit(ReadGraph graph) throws DatabaseException {
\r
258 return Layer0Utils.getUnit(graph, this);
\r
259 } catch (DatabaseException e) {
\r
265 public Resource getPropertyResource(ReadGraph graph) {
\r
266 return property.predicate;
\r
270 public Resource getContainerResource(ReadGraph graph) throws DatabaseException {
\r
271 return parentResource;
\r
275 public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
\r
277 Map<String, Variable> result = new HashMap<String, Variable>();
\r
278 VariableMap map = getPossibleChildVariableMap(graph);
\r
279 if(map != null) map.getVariables(graph, this, result);
\r
280 return result.values();
\r
285 public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
\r
287 VariableMap map = getPossibleChildVariableMap(graph);
\r
288 if(map == null) return null;
\r
290 return map.getVariable(graph, this, name);
\r
291 } catch (DatabaseException e) {
\r
299 protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {
\r
301 VariableMap valueMap = getPossiblePropertyVariableMap(graph);
\r
302 if(valueMap == null) return null;
\r
304 return valueMap.getVariable(graph, this, name);
\r
305 } catch (DatabaseException e) {
\r
307 } catch (Throwable t) {
\r
308 System.err.println("err: " + getURI(graph) + " # " + name);
\r
315 public Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {
\r
317 VariableMap valueMap = getPossiblePropertyVariableMap(graph);
\r
318 if(valueMap == null) return properties;
\r
319 return valueMap.getVariables(graph, this, properties);
\r
324 public Variable getPredicate(ReadGraph graph) throws DatabaseException {
\r
325 return Variables.getVariable(graph, graph.getURI(property.predicate));
\r
329 public Resource getPredicateResource(ReadGraph graph) throws DatabaseException {
\r
330 return property.predicate;
\r
334 public Resource getPossiblePredicateResource(ReadGraph graph) throws DatabaseException {
\r
335 return property.predicate;
\r
339 public int hashCode() {
\r
341 final int prime = 31;
\r
343 result = prime * result + (parent != null ? parent.hashCode() : 0);
\r
344 result = prime * result + (node != null ? node.hashCode() : 0);
\r
345 result = prime * result + (property.predicate != null ? property.predicate.hashCode() : 0);
\r
346 result = prime * result + (parentResource != null ? parentResource.hashCode() : 0);
\r
347 result = prime * result + (represents != null ? represents.hashCode() : 0);
\r
354 public boolean equals(Object obj) {
\r
359 if (getClass() != obj.getClass())
\r
361 StandardGraphPropertyVariable other = (StandardGraphPropertyVariable) obj;
\r
364 if(!node.equals(other.node)) return false;
\r
365 } else if (other.node != null) return false;
\r
367 if(property.predicate != null) {
\r
368 if(!property.predicate.equals(other.property.predicate)) return false;
\r
369 } else if (other.property.predicate != null) return false;
\r
371 if(parentResource != null) {
\r
372 if(!parentResource.equals(other.parentResource)) return false;
\r
373 } else if (other.parentResource != null) return false;
\r
375 if(parent != null) {
\r
376 if(!parent.equals(other.parent)) return false;
\r
377 } else if (other.parent != null) return false;
\r
379 if(represents != null) {
\r
380 if(!represents.equals(other.represents)) return false;
\r
381 } else if (other.represents != null) return false;
\r
388 protected Variable getNameVariable(ReadGraph graph) throws DatabaseException {
\r
389 throw new UnsupportedOperationException();
\r
392 protected ValueAccessor getValueAccessor(ReadGraph graph) throws DatabaseException {
\r
393 if((property == null || property == NO_PROPERTY) && parentResource == null) return All.standardValueAccessor;
\r
394 ValueAccessor accessor = property.valueAccessor;
\r
395 if(accessor != null) return accessor;
\r
397 System.err.println("No value accessor for " + getURI(graph));
\r
398 return All.standardValueAccessor;
\r
402 protected VariableMap getPossibleChildVariableMap(ReadGraph graph) throws DatabaseException {
\r
403 if(represents == null) return All.standardPropertyDomainChildren;
\r
404 return graph.getPossibleRelatedValue2(represents, Layer0.getInstance(graph).domainChildren, this);
\r
407 protected VariableMap getPossiblePropertyVariableMap(ReadGraph graph) throws DatabaseException {
\r
408 if(property == null) return All.standardPropertyDomainProperties;
\r
409 if(property.predicate == null) return null;
\r
410 return graph.syncRequest(new PropertyVariableMapRequest(property.predicate), TransientCacheAsyncListener.<VariableMap>instance());
\r
413 public Set<String> getClassifications(ReadGraph graph) throws DatabaseException {
\r
414 return property.classifications;
\r
418 public Map<String, Variable> collectDomainProperties(ReadGraph graph, String classification, Map<String, Variable> properties) throws DatabaseException {
\r
420 VariableMap valueMap = getPossiblePropertyVariableMap(graph);
\r
421 if(valueMap == null) return properties;
\r
422 return valueMap.getVariables(graph, this, classification, properties);
\r
426 public Collection<Variable> getProperties(ReadGraph graph, String classification) throws DatabaseException {
\r
428 VariableMap valueMap = getPossiblePropertyVariableMap(graph);
\r
429 if(valueMap == null) return Collections.emptyList();
\r
430 Map<String,Variable> propertyMap = valueMap.getVariables(graph, this, classification, null);
\r
431 if(propertyMap == null || propertyMap.isEmpty()) return Collections.emptyList();
\r
432 else return propertyMap.values();
\r