]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphChildVariable.java
Variable optimizations for documents (Simupedia)
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / variable / StandardGraphChildVariable.java
1 package org.simantics.db.layer0.variable;
2
3 import java.util.Collection;
4 import java.util.Collections;
5 import java.util.Map;
6 import java.util.Set;
7
8 import org.simantics.databoard.Bindings;
9 import org.simantics.datatypes.literal.GUID;
10 import org.simantics.db.ReadGraph;
11 import org.simantics.db.Resource;
12 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
13 import org.simantics.db.exception.AssumptionException;
14 import org.simantics.db.exception.DatabaseException;
15 import org.simantics.db.layer0.exception.InvalidVariableException;
16 import org.simantics.db.layer0.function.All;
17 import org.simantics.db.layer0.request.ClassificationsRequest;
18 import org.simantics.db.layer0.request.VariableURI;
19 import org.simantics.db.layer0.variable.RVI.RVIPart;
20 import org.simantics.db.layer0.variable.RVI.ResourceRVIPart;
21 import org.simantics.db.layer0.variable.RVI.StringRVIPart;
22 import org.simantics.db.layer0.variable.Variables.Role;
23 import org.simantics.layer0.Layer0;
24 import org.simantics.simulator.variable.exceptions.NodeManagerException;
25
26 public class StandardGraphChildVariable extends AbstractChildVariable implements ProxyVariableSupport {
27
28         /*
29          * Extension points
30          * 
31          */
32         public Variable getPossibleSpecialChild(ReadGraph graph, String name) throws DatabaseException {
33                 return null;
34         }
35
36         public Map<String, Variable> collectSpecialChildren(ReadGraph graph, Map<String, Variable> children) throws DatabaseException {
37                 return children;
38         }
39
40         /*
41          * Standard implementation
42          * 
43          */
44         
45         final protected Variable parent;
46         final public Resource resource;
47         
48         transient private int hash;
49         
50         public StandardGraphChildVariable(Variable parent, VariableNode node, Resource resource) {
51                 super(node);
52                 this.parent = parent;
53                 this.resource = resource;
54         }
55
56         @Override
57         public void validate(ReadGraph graph) throws DatabaseException {
58                 if(!graph.hasStatement(resource)) throw new InvalidVariableException("The resource has been removed: " + resource);
59         }
60         
61         @Override
62         protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {
63                 VariableMap map = getPossiblePropertyVariableMap(graph);
64                 if(map == null) return null;
65                 try {
66                         return map.getVariable(graph, this, name);
67                 } catch (DatabaseException e) {
68                         return null;
69                 }
70         }
71
72         @Override
73         public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
74                 VariableMap map = getPossibleChildVariableMap(graph);
75                 if(map == null) return getPossibleSpecialChild(graph, name);
76                 try {
77                         Variable result = map.getVariable(graph, this, name);
78                         if(result != null) return result;
79                         else return getPossibleSpecialChild(graph, name);
80                 } catch (DatabaseException e) {
81                         return null;
82                 }
83         }
84
85         @Override
86         public Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {
87                 VariableMap map = getPossiblePropertyVariableMap(graph);
88                 if(map == null) return properties;
89                 return map.getVariables(graph, this, properties);
90         }
91
92         @Override
93         public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
94                 Map<String, Variable> result = null;
95                 VariableMap map = getPossibleChildVariableMap(graph);
96                 if(map != null) result = map.getVariables(graph, this, result);
97                 result = collectSpecialChildren(graph, result);
98                 if(result == null) return Collections.emptyList();
99                 else return result.values();
100         }
101
102         @SuppressWarnings("unchecked")
103         @Override
104         public String getName(ReadGraph graph) throws DatabaseException {
105             if(node != null) {
106                 return node.support.manager.getName(node.node);
107             }
108                 String unescapedName = graph.getPossibleRelatedValue(resource, graph.getService(Layer0.class).HasName, Bindings.STRING);
109                 if(unescapedName == null) return VariableUtils.unnamedResourceName(resource);
110                 return unescapedName;
111         }
112
113         @Override
114         public Variable getNameVariable(ReadGraph graph) throws DatabaseException {
115                 Resource resource = (Resource) getPossibleRepresents(graph);
116                 if (resource != null) {
117                         return new StandardGraphPropertyVariable(graph, this, null, resource, Layer0.getInstance(graph).HasName);
118                 }
119                 return super.getNameVariable(graph);
120         }
121         
122         
123         @Override
124         public String getLabel(ReadGraph graph) throws DatabaseException {
125             if(resource == null) return getName(graph);
126                 String label = graph.getPossibleRelatedValue2(resource, graph.getService(Layer0.class).HasLabel);
127                 return label != null ? label : getName(graph);
128         }
129
130         @Override
131         final protected Variable getLabelVariable(ReadGraph graph) throws DatabaseException {
132                 Layer0 L0 = Layer0.getInstance(graph);
133                 if(resource == null) return null;
134                 return new StandardGraphPropertyVariable(graph, this, L0.HasLabel);
135         }
136         
137 //      @Override
138 //      final public Object getSerialized(ReadGraph graph) throws DatabaseException {
139 //              Resource represents = getRepresents(graph);
140 //              if(represents != null) return represents;
141 //              else return getName(graph);
142 //      }
143
144         @Override
145         public Variable getParent(ReadGraph graph) throws DatabaseException {
146                 return parent;
147         }
148         
149         @Override
150         final public Resource getRepresents(ReadGraph graph) throws DatabaseException {
151             if(resource == null)
152                 throw new InvalidVariableException("Variable is not represented by any resource (URI=" + getPossibleURI(graph) + ").");
153             return resource;
154 //              Layer0X L0X = Layer0X.getInstance(graph);
155 //              Resource represents = graph.getPossibleObject(resource, L0X.Represents);
156 //              if(represents != null) return represents;
157 //              else return resource;
158         }
159
160         @Override
161         public Resource getPossibleRepresents(ReadGraph graph)
162                 throws DatabaseException {
163             return resource;
164         }
165         
166         @Override
167         final public String getURI(ReadGraph graph) throws DatabaseException {
168                 
169                 try {
170                         if(parent == null) return "http:/";
171                         String parentURI = graph.syncRequest(new VariableURI(parent), TransientCacheAsyncListener.<String>instance());
172                         return parentURI + Role.CHILD.getIdentifier() + encodeString(getName(graph));
173                 } catch (AssumptionException e) {
174                         throw new InvalidVariableException(e);
175                 }
176         }
177
178         /**
179          * All variables must have proper URIs, this is only for debugging purposes.
180          * 
181          * @see org.simantics.db.layer0.variable.AbstractVariable#getPossibleURI(org.simantics.db.ReadGraph)
182          */
183         @Override
184         public String getPossibleURI(ReadGraph graph) throws DatabaseException {
185         try {
186             return getURI(graph);
187         } catch (DatabaseException e) {
188             return "<no uri>";
189         }
190         }
191
192         @Override
193         public int hashCode() {
194                 if(hash == 0) {
195                         final int prime = 31;
196                         int result = 1;
197                         result = prime * result + (parent != null ? parent.hashCode() : 0);
198                         result = prime * result + (node != null ? node.hashCode() : 0);
199                         result = prime * result + (resource != null ? resource.hashCode() : 0);
200                         hash =result;
201                 }
202                 return hash;
203         }
204
205         @Override
206         public boolean equals(Object obj) {
207                 if (this == obj)
208                         return true;
209                 if (obj == null)
210                         return false;
211                 if (getClass() != obj.getClass())
212                         return false;
213                 
214                 StandardGraphChildVariable other = (StandardGraphChildVariable) obj;
215                 
216                 if(node != null) { 
217                         if(!node.equals(other.node)) return false;
218                 } else if (other.node != null) return false;
219
220         if(resource != null) {
221                 if(!resource.equals(other.resource)) return false;
222         } else if (other.resource != null) return false;
223                 
224         if(parent != null) {
225                 if(!parent.equals(other.parent)) return false;
226         } else if (other.parent != null) return false;
227         
228         return true;
229                 
230         }
231         
232         @Override
233         public <T> T adapt(ReadGraph graph, Class<T> clazz) throws DatabaseException {
234                 return graph.adapt(resource, clazz);
235         }
236
237     @Override
238     public <T> T adaptPossible(ReadGraph graph, Class<T> clazz) throws DatabaseException {
239         return graph.getPossibleAdapter(resource, clazz);
240     }
241
242         @Override
243         public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException {
244             if(resource == null) return new StringRVIPart(Role.CHILD, getName(graph));
245         Layer0 L0 = Layer0.getInstance(graph);
246         GUID id = graph.getPossibleRelatedValue(resource, L0.identifier, GUID.BINDING);
247         if(id != null)
248                 return new RVI.GuidRVIPart(Role.CHILD, resource, id.mostSignificant, id.leastSignificant);
249         else
250                 return new ResourceRVIPart(Role.CHILD, resource);
251         }
252         
253     public String getIdentifier() {
254         return getClass().getSimpleName() + "[" + resource + "]";
255     }
256         
257     protected VariableMap getPossiblePropertyVariableMap(ReadGraph graph) throws DatabaseException {
258         if(resource == null) return All.standardChildDomainProperties;
259         Resource domainProperties = Layer0.getInstance(graph).domainProperties; 
260         return graph.getPossibleRelatedValue2(resource, domainProperties, 
261             new StandardGraphPropertyVariable(graph, this, domainProperties));
262     }
263
264         protected VariableMap getPossibleChildVariableMap(ReadGraph graph) throws DatabaseException {
265             if(resource == null) return All.standardChildDomainChildren;
266             Resource domainChildren = Layer0.getInstance(graph).domainChildren;
267                 return graph.getPossibleRelatedValue2(resource, domainChildren, 
268                                 new StandardGraphPropertyVariable(graph, this, domainChildren));
269         }
270         
271         @Override
272     public Map<String, Variable> collectDomainProperties(ReadGraph graph, String classification, Map<String, Variable> properties) throws DatabaseException {
273         VariableMap valueMap = getPossiblePropertyVariableMap(graph);
274                 if(valueMap == null) return properties;
275                 return valueMap.getVariables(graph, this, classification, properties);
276     }
277         
278     @Override
279     public Variable resolve(ReadGraph graph, RVIPart part) throws DatabaseException {
280         Resource represents = getPossibleRepresents(graph);
281         if (represents == null)
282             return StandardRVIResolver.INSTANCE.getVariable(graph, this, part);
283         RVIResolver resolver = graph.adapt(represents, RVIResolver.class);
284         return resolver.getVariable(graph, this, part);
285     }    
286
287     @Override
288     public Variable resolvePossible(ReadGraph graph, RVIPart part) throws DatabaseException {
289         try {
290             return resolve(graph, part);
291         } catch (DatabaseException e) {
292             return null;
293         }
294     }
295
296     @SuppressWarnings("unchecked")
297     public Set<String> getClassifications(ReadGraph graph) throws DatabaseException {
298         Resource represents = getPossibleRepresents(graph);
299         Set<String> result = (represents != null) ? graph.syncRequest(new ClassificationsRequest(graph.getPrincipalTypes(represents))) : Collections.<String>emptySet();
300         if (result.isEmpty()) {
301                 Resource type = getPossibleType(graph);
302                 if(type != null) result = graph.syncRequest(new ClassificationsRequest(Collections.singleton(type)));
303         }
304         if (result.isEmpty() && node != null) {
305             try {
306                 result = node.support.manager.getClassifications(node.node);
307             } catch(NodeManagerException e) {
308                 throw new DatabaseException(e);
309             }
310         }
311         return result;
312     }
313
314     @Override
315     public RVI getRVI(ReadGraph graph) throws DatabaseException {
316         Resource represents = getPossibleRepresents(graph);
317         if (represents == null)
318             return StandardRVIResolver.INSTANCE.getRVI(graph, this);
319         RVIResolver resolver = graph.adapt(represents, RVIResolver.class);
320         return resolver.getRVI(graph, this);
321     }    
322     
323     @Override
324     public RVI getPossibleRVI(ReadGraph graph) throws DatabaseException {
325         Resource represents = getPossibleRepresents(graph);
326         if (represents == null)
327             return StandardRVIResolver.INSTANCE.getPossibleRVI(graph, this);
328         RVIResolver resolver = graph.getPossibleAdapter(represents, RVIResolver.class);
329         if(resolver == null) return null;
330         return resolver.getPossibleRVI(graph, this);
331     }
332
333     @Override
334     public Resource getPossiblePredicateResource(ReadGraph graph) throws DatabaseException {
335         return null;
336     }
337
338     @Override
339     public Variable attachTo(ReadGraph graph, Variable parent) {
340         return new StandardGraphChildVariable(parent, node, resource);
341     }
342
343     @Override
344     public Variable attachToRenamed(ReadGraph graph, Variable parent, String name) {
345         return new StandardGraphChildVariable(parent, node, resource) {
346             @Override
347             public String getName(ReadGraph graph) throws DatabaseException {
348                 return name;
349             }
350         };
351     }
352
353 }