]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java
13977a0e5a4397be7e2a063c75fe9b77aba9aa7c
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / variable / StandardGraphPropertyVariable.java
1 package org.simantics.db.layer0.variable;
2
3 import java.util.Collection;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.Map;
7 import java.util.Set;
8
9 import org.simantics.databoard.Bindings;
10 import org.simantics.databoard.accessor.reference.ChildReference;
11 import org.simantics.databoard.binding.Binding;
12 import org.simantics.databoard.binding.impl.ObjectVariantBinding;
13 import org.simantics.databoard.type.Datatype;
14 import org.simantics.db.ReadGraph;
15 import org.simantics.db.Resource;
16 import org.simantics.db.WriteGraph;
17 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
18 import org.simantics.db.common.utils.Logger;
19 import org.simantics.db.common.validation.L0Validations;
20 import org.simantics.db.exception.DatabaseException;
21 import org.simantics.db.exception.ValidationException;
22 import org.simantics.db.layer0.exception.MissingVariableValueException;
23 import org.simantics.db.layer0.exception.PendingVariableException;
24 import org.simantics.db.layer0.exception.VariableException;
25 import org.simantics.db.layer0.function.All;
26 import org.simantics.db.layer0.request.PropertyInfo;
27 import org.simantics.db.layer0.request.PropertyInfoRequest;
28 import org.simantics.db.layer0.util.Layer0Utils;
29 import org.simantics.layer0.Layer0;
30 import org.simantics.utils.Development;
31 import org.simantics.utils.datastructures.Pair;
32
33 public class StandardGraphPropertyVariable extends AbstractPropertyVariable {
34
35         protected static final PropertyInfo NO_PROPERTY = new PropertyInfo(null, null,
36                         false, Collections.<String> emptySet(), null, null, null, null, null, null,
37                         Collections.<String, Pair<Resource, ChildReference>> emptyMap(),
38                         null, false);
39
40         final public Variable parent;
41         final public Resource parentResource;
42         final public PropertyInfo property;
43         final public Resource represents;
44         
45         transient private int hash = 0;
46
47         public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, VariableNode node, Resource property) throws DatabaseException {
48                 this(graph, parent, node, (Resource)parent.getPossibleRepresents(graph), getPropertyInfo(graph, property));
49         }
50         
51         public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, VariableNode node, Resource parentResource, Resource property) throws DatabaseException {
52                 this(graph, parent, node, parentResource, getPropertyInfo(graph, property));
53         }
54
55         public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, Resource property) throws DatabaseException {
56         this(graph, parent, null, (Resource)parent.getPossibleRepresents(graph), getPropertyInfo(graph, property));
57     }
58
59     public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, Resource parentResource, PropertyInfo property) throws DatabaseException {
60         this(parent, null, parentResource, property, getPossibleRepresents(graph, parentResource, property.predicate));
61     }
62     
63     public StandardGraphPropertyVariable(ReadGraph graph, Variable parent, VariableNode node, Resource parentResource, PropertyInfo property) throws DatabaseException {
64         this(parent, node, parentResource, property, getPossibleRepresents(graph, parentResource, property.predicate));
65     }
66
67     private static PropertyInfo getPropertyInfo(ReadGraph graph, Resource property) throws DatabaseException {
68             return property != null ? graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance()) : NO_PROPERTY;
69     }
70     
71     private static Resource getPossibleRepresents(ReadGraph graph, Resource parentResource, Resource predicate) throws DatabaseException {
72         if(parentResource == null || predicate == null) return null;
73         return graph.getPossibleObject(parentResource, predicate);
74     }
75     
76     public boolean isAsserted() {
77         return false;
78     }
79
80     public StandardGraphPropertyVariable(Variable parent, VariableNode node, Resource parentResource, PropertyInfo property, Resource represents) throws DatabaseException {
81         super(node);
82                 assert parent != null;
83                 this.parent = parent;
84                 this.property = property;
85                 this.parentResource = parentResource;
86                 this.represents = represents;
87         }
88
89         @Override
90         public String getName(ReadGraph graph) throws DatabaseException {
91             if(node != null) return node.support.manager.getName(node.node);
92                 return property.name;
93         }
94
95         @Override
96         public String getPossibleLabel(ReadGraph graph) throws DatabaseException {
97                 return graph.getPossibleRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING);
98         }
99
100         @Override
101         public String getLabel(ReadGraph graph) throws DatabaseException {
102                 return graph.getRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING);
103         }
104
105         @Override
106         public Variable getParent(ReadGraph graph) throws DatabaseException {
107                 return parent;
108         }
109         
110         @Override
111         public PropertyInfo getPropertyInfo(ReadGraph graph) throws DatabaseException {
112                 return property;
113         }
114
115         @SuppressWarnings("unchecked")
116         @Override
117         public <T> T getValue(ReadGraph graph) throws DatabaseException {
118                 
119                 if(Development.DEVELOPMENT) {
120                         String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
121                         if(error != null) {
122                                 Logger.defaultLogError(new ValidationException(error));
123                                 //throw new ValidationException(error);
124                         }
125                 }
126                 
127                 return (T)getValueAccessor(graph).getValue(graph, this);
128                 
129         }
130
131         @SuppressWarnings("unchecked")
132         @Override
133         public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
134                 // Fall back to the bindingless method, if the expected output is a Java object 
135                 if (binding instanceof ObjectVariantBinding)
136                         return getValue(graph);         
137
138                 if(Development.DEVELOPMENT) {
139                         String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
140                         if(error != null) {
141                                 Logger.defaultLogError(new ValidationException(error));
142                                 throw new ValidationException(error);
143                         }
144                 }
145         
146                 try {
147                         
148                         return (T)getValueAccessor(graph).getValue(graph, this, binding);
149                 } catch (PendingVariableException e) {
150                     throw e;
151                 } catch (Throwable t) {
152                         throw new MissingVariableValueException(t);
153                 }
154                 
155         }
156         
157         @Override
158         public Resource getRepresents(ReadGraph graph) throws DatabaseException {
159                 if(represents == null)
160                         throw new VariableException("Variable is not represented by any resource (URI=" + getPossibleURI(graph) + ").");
161                 return represents;
162 //              return graph.getSingleObject(parentResource, property.predicate);
163         }
164
165         @Override
166         public Resource getPossibleRepresents(ReadGraph graph) throws DatabaseException {
167 //        if(parentResource == null) return null;
168 //              return graph.getPossibleObject(parentResource, property.predicate);
169                 return represents;
170         }
171
172         @Override
173         public void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException {
174                 
175                 if(Development.DEVELOPMENT) {
176                         String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
177                         if(error != null) {
178                                 Logger.defaultLogError(new ValidationException(error));
179                                 //throw new ValidationException(error);
180                         }
181                 }
182                 
183                 getValueAccessor(graph).setValue(graph, this, value, binding);
184                 
185         }
186         
187         @Override
188         public void setValue(WriteGraph graph, Object value) throws DatabaseException {
189                 
190                 if(Development.DEVELOPMENT) {
191                         String error = L0Validations.checkValueType(graph, parentResource, property.predicate);
192                         if(error != null) {
193                                 Logger.defaultLogError(new ValidationException(error));
194                                 throw new ValidationException(error);
195                         }
196                 }
197                 
198                 getValueAccessor(graph).setValue(graph, this, value);
199                 
200         }
201
202         @Override
203         public Binding getDefaultBinding(ReadGraph graph) throws DatabaseException {
204                 return Layer0Utils.getDefaultBinding(graph, this);
205         }
206         
207         @Override
208         public Binding getPossibleDefaultBinding(ReadGraph graph) throws DatabaseException {
209                 return Layer0Utils.getPossibleDefaultBinding(graph, this);
210         }
211
212         @Override
213         public Datatype getDatatype(ReadGraph graph) throws DatabaseException {
214 //<<<<<<< .mine
215 //              
216 //      Binding binding = getPossibleDefaultBinding(graph);
217 //        if(binding != null) return binding.type();
218 //
219 //              Variant vt = getVariantValue(graph);
220 //              binding = vt.getBinding();
221 //              if(binding == null) throw new DatabaseException("No binding in Variant with value " + vt.getValue());
222 //              return binding.type();
223 //=======
224                 Datatype type;
225                 try {                   
226                         type = getValueAccessor(graph).getDatatype(graph, this);
227                 } catch (Throwable t) {
228                         throw new MissingVariableValueException(t);
229                 }
230                 
231                 if (type == null) {
232                         String uri = this.getPossibleURI(graph);
233                         if (uri != null)
234                                 throw new DatabaseException("No data type for " + uri);
235                         else
236                                 throw new DatabaseException("No data type for " + this.getIdentifier());
237                 }
238                 
239                 return type;
240 //>>>>>>> .r30794
241                 
242         }
243         
244         @Override
245         public Datatype getPossibleDatatype(ReadGraph graph) throws DatabaseException {
246
247                 try {
248                         return getDatatype(graph);
249                 } catch (DatabaseException e) {
250                         return null;
251                 }
252                 
253         }
254         
255         @Override
256         public String getUnit(ReadGraph graph) throws DatabaseException {
257                 try {
258                         return Layer0Utils.getUnit(graph, this);
259                 } catch (DatabaseException e) {
260                         return null;
261                 }
262         }
263
264         @Override
265         public Resource getPropertyResource(ReadGraph graph) {
266                 return property.predicate;
267         }
268         
269         @Override
270         public Resource getContainerResource(ReadGraph graph) throws DatabaseException {
271                 return parentResource;
272         }
273
274         @Override
275         public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
276
277                 Map<String, Variable> result = new HashMap<String, Variable>();
278                 VariableMap map = getPossibleChildVariableMap(graph);
279                 if(map != null) map.getVariables(graph, this, result);
280                 return result.values();
281                 
282         }
283         
284         @Override
285         public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
286
287                 VariableMap map = getPossibleChildVariableMap(graph);
288                 if(map == null) return null;
289                 try {
290                         return map.getVariable(graph, this, name);
291                 } catch (DatabaseException e) {
292                         return null;
293                 }
294                 
295         }
296         
297         
298         @Override
299         protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {
300
301                 VariableMap valueMap = getPossiblePropertyVariableMap(graph);
302                 if(valueMap == null) return null;
303                 try {
304                         return valueMap.getVariable(graph, this, name);
305                 } catch (DatabaseException e) {
306                         return null;
307                 } catch (Throwable t) {
308                         System.err.println("err: " + getURI(graph) + "  # " + name);
309                         return null;
310                 }
311                 
312         }
313         
314         @Override
315         public Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {
316
317                 VariableMap valueMap = getPossiblePropertyVariableMap(graph);
318                 if(valueMap == null) return properties;
319                 return valueMap.getVariables(graph, this, properties);
320                 
321         }
322         
323         @Override
324         public Variable getPredicate(ReadGraph graph) throws DatabaseException {
325                 return Variables.getVariable(graph, graph.getURI(property.predicate));
326         }
327         
328         @Override
329         public Resource getPredicateResource(ReadGraph graph) throws DatabaseException {
330                 return property.predicate;
331         }
332         
333         @Override
334         public Resource getPossiblePredicateResource(ReadGraph graph) throws DatabaseException {
335                 return property.predicate;
336         }
337
338         @Override
339         public int hashCode() {
340                 if(hash == 0) {
341                         final int prime = 31;
342                         int result = 1;
343             result = prime * result + (parent != null ? parent.hashCode() : 0);
344             result = prime * result + (node != null ? node.hashCode() : 0);
345             result = prime * result + (property.predicate != null ? property.predicate.hashCode() : 0);
346             result = prime * result + (parentResource != null ? parentResource.hashCode() : 0);
347             result = prime * result + (represents != null ? represents.hashCode() : 0);
348                         hash =result;
349                 }
350                 return hash;
351         }
352
353         @Override
354         public boolean equals(Object obj) {
355                 if (this == obj)
356                         return true;
357                 if (obj == null)
358                         return false;
359                 if (getClass() != obj.getClass())
360                         return false;
361                 StandardGraphPropertyVariable other = (StandardGraphPropertyVariable) obj;
362                 
363         if(node != null) {
364                 if(!node.equals(other.node)) return false;
365         } else if (other.node != null) return false;
366
367         if(property.predicate != null) {
368                 if(!property.predicate.equals(other.property.predicate)) return false;
369         } else if (other.property.predicate != null) return false;
370         
371         if(parentResource != null) {
372                 if(!parentResource.equals(other.parentResource)) return false;
373         } else if (other.parentResource != null) return false;
374
375         if(parent != null) {
376                 if(!parent.equals(other.parent)) return false;
377         } else if (other.parent != null) return false;
378
379         if(represents != null) {
380                 if(!represents.equals(other.represents)) return false;
381         } else if (other.represents != null) return false;
382
383         return true;
384                 
385         }
386
387         @Override
388         protected Variable getNameVariable(ReadGraph graph) throws DatabaseException {
389             throw new UnsupportedOperationException();
390         }
391         
392         protected ValueAccessor getValueAccessor(ReadGraph graph) throws DatabaseException {
393                 if((property == null || property == NO_PROPERTY) && parentResource == null) return All.standardValueAccessor;
394             ValueAccessor accessor = property.valueAccessor;
395             if(accessor != null) return accessor;
396             else {
397                 System.err.println("No value accessor for " + getURI(graph));
398                 return All.standardValueAccessor;
399             }
400         }
401
402         protected VariableMap getPossibleChildVariableMap(ReadGraph graph) throws DatabaseException {
403                 if(represents == null) return All.standardPropertyDomainChildren;
404                 return graph.getPossibleRelatedValue2(represents, Layer0.getInstance(graph).domainChildren, this);
405         }
406
407         protected VariableMap getPossiblePropertyVariableMap(ReadGraph graph) throws DatabaseException {
408         if(property == null) return All.standardPropertyDomainProperties;
409         if(property.predicate == null) return null;
410                 return graph.syncRequest(new PropertyVariableMapRequest(property.predicate), TransientCacheAsyncListener.<VariableMap>instance());
411         }
412         
413         public Set<String> getClassifications(ReadGraph graph) throws DatabaseException {
414                 return property.classifications;
415         }
416         
417         @Override
418     public Map<String, Variable> collectDomainProperties(ReadGraph graph, String classification, Map<String, Variable> properties) throws DatabaseException {
419         
420         VariableMap valueMap = getPossiblePropertyVariableMap(graph);
421                 if(valueMap == null) return properties;
422                 return valueMap.getVariables(graph, this, classification, properties);
423                 
424     }
425         
426     public Collection<Variable> getProperties(ReadGraph graph, String classification) throws DatabaseException {
427         
428         VariableMap valueMap = getPossiblePropertyVariableMap(graph);
429                 if(valueMap == null) return Collections.emptyList();
430                 Map<String,Variable> propertyMap = valueMap.getVariables(graph, this, classification, null);
431         if(propertyMap == null || propertyMap.isEmpty()) return Collections.emptyList();
432         else return propertyMap.values();
433         
434     }
435         
436 }