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