1 package org.simantics.db.layer0.variable;
\r
3 import gnu.trove.map.hash.THashMap;
\r
5 import java.util.Collection;
\r
6 import java.util.Collections;
\r
7 import java.util.HashMap;
\r
8 import java.util.Map;
\r
9 import java.util.Set;
\r
11 import org.simantics.databoard.Bindings;
\r
12 import org.simantics.databoard.Databoard;
\r
13 import org.simantics.databoard.binding.Binding;
\r
14 import org.simantics.databoard.binding.StringBinding;
\r
15 import org.simantics.databoard.binding.error.BindingConstructionException;
\r
16 import org.simantics.databoard.binding.error.BindingException;
\r
17 import org.simantics.databoard.binding.mutable.Variant;
\r
18 import org.simantics.databoard.type.Datatype;
\r
19 import org.simantics.databoard.util.URIStringUtils;
\r
20 import org.simantics.datatypes.literal.GUID;
\r
21 import org.simantics.db.ReadGraph;
\r
22 import org.simantics.db.Resource;
\r
23 import org.simantics.db.WriteGraph;
\r
24 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
\r
25 import org.simantics.db.common.request.PossibleIndexRoot;
\r
26 import org.simantics.db.common.request.PropertyMapOfResource;
\r
27 import org.simantics.db.common.utils.NameUtils;
\r
28 import org.simantics.db.exception.AdaptionException;
\r
29 import org.simantics.db.exception.DatabaseException;
\r
30 import org.simantics.db.layer0.exception.InvalidVariableException;
\r
31 import org.simantics.db.layer0.exception.MissingVariableException;
\r
32 import org.simantics.db.layer0.exception.MissingVariableValueException;
\r
33 import org.simantics.db.layer0.request.PossibleResource;
\r
34 import org.simantics.db.layer0.request.PropertyInfo;
\r
35 import org.simantics.db.layer0.request.VariableRVIRequest;
\r
36 import org.simantics.db.layer0.variable.RVI.GuidRVIPart;
\r
37 import org.simantics.db.layer0.variable.RVI.RVIPart;
\r
38 import org.simantics.db.layer0.variable.RVI.ResourceRVIPart;
\r
39 import org.simantics.db.layer0.variable.RVI.StringRVIPart;
\r
40 import org.simantics.db.layer0.variable.Variables.Role;
\r
41 import org.simantics.layer0.Layer0;
\r
44 * Abstract implementation of Variable -interface.
\r
46 * @author Hannu Niemistö
\r
48 public abstract class AbstractVariable implements Variable {
\r
50 @SuppressWarnings("rawtypes")
\r
51 final public VariableNode node;
\r
53 public AbstractVariable(@SuppressWarnings("rawtypes") VariableNode node) {
\r
58 * Returns a variable that is not one of the standard properties listed
\r
59 * in <a href="https://www.simantics.org/wiki/index.php/Org.simantics.db.layer0.variable.Variable#Standard_required_properties">specification</a>.
\r
61 protected abstract Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException;
\r
62 public abstract Variable getPossibleExtraProperty(ReadGraph graph, String name) throws DatabaseException;
\r
63 public abstract Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException;
\r
65 public abstract void collectExtraProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException;
\r
66 public abstract Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> map) throws DatabaseException;
\r
67 public abstract Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException;
\r
69 public abstract <T> T getValue(ReadGraph graph) throws DatabaseException;
\r
70 public abstract <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException;
\r
72 public abstract void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException;
\r
73 public abstract String getName(ReadGraph graph) throws DatabaseException;
\r
74 //public abstract Object getSerialized(ReadGraph graph) throws DatabaseException;
\r
75 public abstract Variable getParent(ReadGraph graph) throws DatabaseException;
\r
76 public abstract Role getRole(ReadGraph graph) throws DatabaseException;
\r
77 public abstract Resource getRepresents(ReadGraph graph) throws DatabaseException;
\r
79 public abstract Set<String> getClassifications(ReadGraph graph) throws DatabaseException;
\r
82 public PropertyInfo getPropertyInfo(ReadGraph graph) throws DatabaseException {
\r
83 throw new DatabaseException("PropertyInfo is not available");
\r
87 public Resource getIndexRoot(ReadGraph graph) throws DatabaseException {
\r
88 Resource represents = getPossibleRepresents(graph);
\r
89 if(represents != null) return graph.syncRequest(new PossibleIndexRoot(represents));
\r
90 Variable parent = getParent(graph);
\r
91 if(parent == null) return null;
\r
92 return parent.getIndexRoot(graph);
\r
95 public void validate(ReadGraph graph) throws DatabaseException {
\r
98 public String getIdentifier() {
\r
99 return getClass().getSimpleName();
\r
104 public Role getPossibleRole(ReadGraph graph) throws DatabaseException {
\r
106 return getRole(graph);
\r
107 } catch (DatabaseException e) {
\r
112 protected Variable resolveChild(ReadGraph graph, Resource resource) throws DatabaseException {
\r
113 String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING);
\r
114 for(Variable child : browseChildren(graph)) {
\r
115 String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING);
\r
116 if(rName.equals(name)) return child;
\r
118 throw new DatabaseException("Could not resolve child " + resource);
\r
121 protected Variable resolveChild(ReadGraph graph, GuidRVIPart part) throws DatabaseException {
\r
122 return StandardRVIResolver.resolveChildDefault(graph, this, part);
\r
125 protected Variable resolveProperty(ReadGraph graph, Resource resource) throws DatabaseException {
\r
126 String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING);
\r
127 for(Variable child : browseProperties(graph)) {
\r
128 String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING);
\r
129 if(rName.equals(name)) return child;
\r
131 throw new DatabaseException("Could not resolve child " + resource);
\r
134 protected Variable resolveProperty(ReadGraph graph, GuidRVIPart part) throws DatabaseException {
\r
135 return StandardRVIResolver.resolvePropertyDefault(graph, this, part);
\r
138 protected Variable resolvePossibleChild(ReadGraph graph, Resource resource) throws DatabaseException {
\r
139 String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING);
\r
140 for(Variable child : browseChildren(graph)) {
\r
141 String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING);
\r
142 if(rName.equals(name)) return child;
\r
147 protected Variable resolvePossibleChild(ReadGraph graph, GuidRVIPart part) throws DatabaseException {
\r
148 Layer0 L0 = Layer0.getInstance(graph);
\r
149 for(Variable child : browseChildren(graph)) {
\r
150 GUID id = child.getPossiblePropertyValue(graph, L0.identifier, GUID.BINDING);
\r
152 if(id.mostSignificant == part.mostSignificant && id.leastSignificant == part.leastSignificant)
\r
159 protected Variable resolvePossibleProperty(ReadGraph graph, Resource resource) throws DatabaseException {
\r
160 String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING);
\r
161 for(Variable child : browseProperties(graph)) {
\r
162 String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING);
\r
163 if(rName.equals(name)) return child;
\r
168 protected Variable resolvePossibleProperty(ReadGraph graph, GuidRVIPart part) throws DatabaseException {
\r
169 Layer0 L0 = Layer0.getInstance(graph);
\r
170 for(Variable child : browseProperties(graph)) {
\r
171 GUID id = child.getPossiblePropertyValue(graph, L0.identifier, GUID.BINDING);
\r
173 if(id.mostSignificant == part.mostSignificant && id.leastSignificant == part.leastSignificant)
\r
180 public String getLabel(ReadGraph graph) throws DatabaseException {
\r
181 return getName(graph);
\r
184 public String getPossibleLabel(ReadGraph graph) throws DatabaseException {
\r
185 Resource represents = getPossibleRepresents(graph);
\r
186 if(represents == null) return null;
\r
187 return graph.getPossibleRelatedValue2(represents, graph.getService(Layer0.class).HasLabel, getParent(graph), Bindings.STRING);
\r
190 public Resource getType(ReadGraph graph) throws DatabaseException {
\r
192 Resource resource = getPossibleRepresents(graph);
\r
193 if(resource == null) {
\r
194 String uri = getPossiblePropertyValue(graph, "typeURI");
\r
195 if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.<Resource>instance());
\r
196 throw new DatabaseException("No type for " + getURI(graph));
\r
198 return graph.getSingleType(resource);
\r
202 public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException {
\r
203 throw new UnsupportedOperationException();
\r
207 public RVI getRVI(ReadGraph graph) throws DatabaseException {
\r
208 Databoard databoard = graph.getService( Databoard.class );
\r
209 Binding rviBinding = databoard.getBindingUnchecked( RVI.class );
\r
210 if(Variables.isContext(graph, this)) {
\r
211 return RVI.empty( rviBinding );
\r
213 Variable parent = getParent(graph);
\r
214 if (parent == null)
\r
215 // TODO: consider using a more suitable exception here to better convey the situation.
\r
216 throw new MissingVariableException("no parent for variable " + this + " (URI=" + getPossibleURI(graph) + ")");
\r
217 RVI base = graph.syncRequest(new VariableRVIRequest(parent));
\r
218 RVIPart part = getRVIPart(graph);
\r
219 return new RVIBuilder(base).append(part).toRVI();
\r
223 protected Variable getDomainProperty(ReadGraph graph, String name) throws DatabaseException {
\r
224 Variable property = getPossibleDomainProperty(graph, name);
\r
225 if(property == null)
\r
226 throw new MissingVariableException(getIdentifier() + ": Didn't find property " + name + ".");
\r
230 protected void addProperty(Map<String, Variable> properties, String name, Object value, Binding binding) {
\r
231 if(value != null) {
\r
232 properties.put(name, new ConstantPropertyVariable(this, name, value, binding));
\r
236 protected Variable getNameVariable(ReadGraph graph) throws DatabaseException {
\r
237 return new ConstantPropertyVariable(this, Variables.NAME, getName(graph), Bindings.STRING);
\r
240 protected Variable getLabelVariable(ReadGraph graph) throws DatabaseException {
\r
241 return new ConstantPropertyVariable(this, Variables.LABEL, getPossibleLabel(graph), Bindings.STRING);
\r
244 final public Collection<Variable> browseProperties(ReadGraph graph) throws DatabaseException {
\r
245 return getProperties(graph);
\r
248 private Map<String, Variable> getPropertyMap(ReadGraph graph, String classification) throws DatabaseException {
\r
249 return collectDomainProperties(graph, classification, null);
\r
252 final static class PropertyMap extends THashMap<String,Variable> {
\r
254 final private Variable variable;
\r
256 PropertyMap(Variable variable) {
\r
257 this.variable = variable;
\r
260 private Variable getTypeVariable() {
\r
262 return new AbstractConstantPropertyVariable(variable, Variables.TYPE, null) {
\r
264 @SuppressWarnings("unchecked")
\r
266 public <T> T getValue(ReadGraph graph) throws DatabaseException {
\r
267 Resource represents = parent.getRepresents(graph);
\r
268 if(represents == null) return null;
\r
269 return (T)graph.getPossibleType(represents, Layer0.getInstance(graph).Entity);
\r
273 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
\r
274 return getValue(graph);
\r
280 private Variable getURIVariable() {
\r
282 return new AbstractConstantPropertyVariable(variable, Variables.URI, null) {
\r
284 @SuppressWarnings("unchecked")
\r
286 public <T> T getValue(ReadGraph graph) throws DatabaseException {
\r
287 return (T)variable.getURI(graph);
\r
291 public <T> T getValue(ReadGraph graph, Binding binding) throws DatabaseException {
\r
292 return getValue(graph);
\r
298 public Variable get(Object key) {
\r
299 Variable result = super.get(key);
\r
300 if(result != null) return result;
\r
302 if(Variables.TYPE.equals(key)) return getTypeVariable();
\r
303 else if(Variables.URI.equals(key)) return getURIVariable();
\r
310 private Map<String, Variable> getPropertyMap(ReadGraph graph) throws DatabaseException {
\r
311 PropertyMap properties = new PropertyMap(this);
\r
312 // Map<String, Variable> properties = new HashMap<String, Variable>();
\r
314 // properties.put(Variables.NAME, getNameVariable(graph));
\r
315 // } catch (DatabaseException e) {
\r
316 // // A variable that has no name doesn't exist by definition.
\r
317 // // Therefore it can't have any properties.
\r
318 // return Collections.emptyMap();
\r
321 // Variable labelVariable = getLabelVariable(graph);
\r
322 // if(labelVariable != null) properties.put(Variables.LABEL, getLabelVariable(graph));
\r
323 // } catch (DatabaseException e) {
\r
324 // // Label not absolutely mandatory.
\r
326 // addProperty(properties, Variables.TYPE, getPossibleType(graph), null);
\r
327 // addProperty(properties, Variables.URI, getPossibleURI(graph), Bindings.STRING);
\r
328 //addProperty(properties, Variables.SERIALISED, getSerialized(graph), Bindings.STRING);
\r
329 //addProperty(properties, Variables.PARENT, getParent(graph), null);
\r
330 // addProperty(properties, Variables.ROLE, getRole(graph), Bindings.STRING);
\r
331 // addProperty(properties, Variables.REPRESENTS, getPossibleRepresents(graph), null);
\r
332 collectExtraProperties(graph, properties);
\r
333 collectDomainProperties(graph, properties);
\r
338 public Collection<Variable> getProperties(ReadGraph graph) throws DatabaseException {
\r
339 return getPropertyMap(graph).values();
\r
342 public Collection<Variable> getProperties(ReadGraph graph, String classification) throws DatabaseException {
\r
343 Map<String,Variable> propertyMap = getPropertyMap(graph, classification);
\r
344 if(propertyMap == null) return Collections.emptyList();
\r
345 else return propertyMap.values();
\r
349 public Collection<Variable> getProperties(ReadGraph graph, Resource property) throws DatabaseException {
\r
350 return getProperties(graph, uri(graph, property));
\r
353 final public Collection<Variable> browseChildren(ReadGraph graph) throws DatabaseException {
\r
354 return getChildren(graph);
\r
358 public Variable getPossibleProperty(ReadGraph graph, String name)
\r
359 throws DatabaseException {
\r
360 if(Variables.NAME.equals(name)) {
\r
361 return getNameVariable(graph);
\r
363 if(Variables.LABEL.equals(name)) {
\r
364 return getLabelVariable(graph);
\r
366 if(Variables.TYPE.equals(name)) {
\r
367 Object value = getPossibleType(graph);
\r
369 return new ConstantPropertyVariable(this, name, value, null);
\r
371 if(Variables.URI.equals(name)) {
\r
372 // TODO: getPossibleURI or getURI?
\r
373 Object value = getURI(graph);
\r
375 return new ConstantPropertyVariable(this, name, value, Bindings.STRING);
\r
377 // if(Variables.SERIALISED.equals(name)) {
\r
378 // Object value = getSerialized(graph);
\r
379 // if(value != null)
\r
380 // return new ConstantPropertyVariable(this, name, value, Bindings.STRING);
\r
382 /*if(Variables.PARENT.equals(name)) {
\r
383 Object value = getParent(graph);
\r
385 return new ConstantPropertyVariable(this, name, value, null);
\r
387 // if(Variables.ROLE.equals(name)) {
\r
388 // Object value = getRole(graph);
\r
389 // if(value != null)
\r
390 // return new ConstantPropertyVariable(this, name, value, null);
\r
392 // if(Variables.REPRESENTS.equals(name)) {
\r
393 // Object value = getRepresents(graph);
\r
394 // if(value != null)
\r
395 // return new ConstantPropertyVariable(this, name, value, null);
\r
397 Variable extra = getPossibleExtraProperty(graph, name);
\r
398 if(extra != null) return extra;
\r
399 return getPossibleDomainProperty(graph, name);
\r
403 public Variable getPossibleProperty(ReadGraph graph, Resource property) throws DatabaseException {
\r
404 return getPossibleProperty(graph, name(graph, property));
\r
407 @SuppressWarnings("unchecked")
\r
408 protected <T> T checkNull(ReadGraph graph, Object value) throws DatabaseException {
\r
410 throw new MissingVariableValueException(getClass().getSimpleName() + ": Didn't find value for " + getPossibleURI(graph));
\r
414 private String name(ReadGraph graph, Resource property) throws DatabaseException {
\r
415 return graph.getRelatedValue(property, Layer0.getInstance(graph).HasName, Bindings.STRING);
\r
418 private String uri(ReadGraph graph, Resource property) throws DatabaseException {
\r
419 return graph.getURI(property);
\r
423 public <T> T getPropertyValue(ReadGraph graph, String name) throws DatabaseException {
\r
424 if(Variables.LABEL.equals(name)) return checkNull(graph, getLabel(graph));
\r
425 Variable result = getDomainProperty(graph, name);
\r
426 if(result != null) return result.getValue(graph);
\r
427 if(Variables.NAME.equals(name)) return checkNull(graph, getName(graph));
\r
428 if(Variables.TYPE.equals(name)) return checkNull(graph, getPossibleType(graph));
\r
429 if(Variables.URI.equals(name)) return checkNull(graph, getURI(graph));
\r
430 // if(Variables.SERIALISED.equals(name)) return checkNull(graph, getSerialized(graph));
\r
431 // if(Variables.ROLE.equals(name)) return checkNull(graph, getRole(graph));
\r
432 // if(Variables.REPRESENTS.equals(name)) return checkNull(graph, getRepresents(graph));
\r
433 Variable extra = getPossibleExtraProperty(graph, name);
\r
434 if(extra != null) return extra.getValue(graph);
\r
439 public <T> T getPropertyValue(ReadGraph graph, Resource property) throws DatabaseException {
\r
440 return getPropertyValue(graph, name(graph, property));
\r
443 @SuppressWarnings("unchecked")
\r
445 public <T> T getPossiblePropertyValue(ReadGraph graph, String name)
\r
446 throws DatabaseException {
\r
448 Variable property = getPossibleDomainProperty(graph, name);
\r
449 if(property != null) return property.getPossibleValue(graph);
\r
451 if(Variables.NAME.equals(name)) return (T)getName(graph);
\r
452 if(Variables.LABEL.equals(name)) return (T)getLabel(graph);
\r
453 if(Variables.TYPE.equals(name)) return (T)getPossibleType(graph);
\r
454 if(Variables.URI.equals(name)) return (T)getURI(graph);
\r
455 // if(Variables.SERIALISED.equals(name)) return (T)getSerialized(graph);
\r
456 // if(Variables.ROLE.equals(name)) return (T)getRole(graph);
\r
457 // if(Variables.REPRESENTS.equals(name)) return (T)getRepresents(graph);
\r
459 Variable extra = getPossibleExtraProperty(graph, name);
\r
460 if(extra != null) return extra.getPossibleValue(graph);
\r
467 public <T> T getPossiblePropertyValue(ReadGraph graph, Resource property) throws DatabaseException {
\r
468 return getPossiblePropertyValue(graph, name(graph, property));
\r
471 @SuppressWarnings("unchecked")
\r
473 public <T> T getPropertyValue(ReadGraph graph, String name, Binding binding)
\r
474 throws DatabaseException {
\r
475 if(binding instanceof StringBinding) {
\r
476 StringBinding sb = (StringBinding)binding;
\r
478 if(Variables.NAME.equals(name)) return (T)sb.create((String)checkNull(graph, getName(graph)));
\r
479 if(Variables.LABEL.equals(name)) return (T)sb.create((String)checkNull(graph, getLabel(graph)));
\r
480 if(Variables.URI.equals(name)) return (T)sb.create((String)checkNull(graph, getURI(graph)));
\r
481 // if(Variables.SERIALISED.equals(name)) return (T)sb.create((String)checkNull(graph, getSerialized(graph)));
\r
482 } catch(BindingException e) {
\r
483 throw new DatabaseException(e);
\r
486 Variable property = getPossibleExtraProperty(graph, name);
\r
487 if(property != null)
\r
488 return property.getValue(graph, binding);
\r
489 property = getPossibleDomainProperty(graph, name);
\r
490 if(property == null)
\r
491 throw new MissingVariableException("Didn't find property " + name + " for " + this + ".");
\r
492 return property.getValue(graph, binding);
\r
496 public <T> T getPropertyValue(ReadGraph graph, Resource property, Binding binding) throws DatabaseException {
\r
497 return getPropertyValue(graph, name(graph, property), binding);
\r
500 @SuppressWarnings("unchecked")
\r
502 public <T> T getPossiblePropertyValue(ReadGraph graph, String name,
\r
503 Binding binding) throws DatabaseException {
\r
504 if(binding instanceof StringBinding) {
\r
505 StringBinding sb = (StringBinding)binding;
\r
507 if(Variables.NAME.equals(name)) return (T)sb.create((String)getName(graph));
\r
508 if(Variables.LABEL.equals(name)) return (T)sb.create((String)getLabel(graph));
\r
509 if(Variables.URI.equals(name)) return (T)sb.create((String)getURI(graph));
\r
510 // if(Variables.SERIALISED.equals(name)) return (T)sb.create((String)getSerialized(graph));
\r
511 } catch(BindingException e) {
\r
512 throw new DatabaseException(e);
\r
515 Variable property = getPossibleExtraProperty(graph, name);
\r
516 if(property != null)
\r
517 return property.getPossibleValue(graph, binding);
\r
518 property = getPossibleDomainProperty(graph, name);
\r
519 if(property == null)
\r
521 return property.getPossibleValue(graph, binding);
\r
525 public <T> T getPossiblePropertyValue(ReadGraph graph, Resource property, Binding binding) throws DatabaseException {
\r
526 return getPossiblePropertyValue(graph, name(graph, property), binding);
\r
530 public void setValue(WriteGraph graph, Object value) throws DatabaseException {
\r
532 setValue(graph, value, Bindings.getBinding(value.getClass()));
\r
533 } catch (BindingConstructionException e) {
\r
534 throw new DatabaseException(e);
\r
539 public void setPropertyValue(WriteGraph graph, String name, Object value) throws DatabaseException {
\r
540 getProperty(graph, name).setValue(graph, value);
\r
544 public void setPropertyValue(WriteGraph graph, Resource property, Object value) throws DatabaseException {
\r
545 setPropertyValue(graph, name(graph, property), value);
\r
549 public void setPropertyValue(WriteGraph graph, String name, Object value,
\r
550 Binding binding) throws DatabaseException {
\r
551 getProperty(graph, name).setValue(graph, value, binding);
\r
555 public void setPropertyValue(WriteGraph graph, Resource property, Object value, Binding binding) throws DatabaseException {
\r
556 setPropertyValue(graph, name(graph, property), value, binding);
\r
560 public Variable getChild(ReadGraph graph, String name)
\r
561 throws DatabaseException {
\r
562 Variable child = getPossibleChild(graph, name);
\r
564 throw new MissingVariableException(getURI(graph) + ": didn't find child " + name + " for " + getIdentifier() + ".");
\r
569 public Variable getProperty(ReadGraph graph, String name) throws DatabaseException {
\r
570 Variable result = getPossibleProperty(graph, name);
\r
572 throw new MissingVariableException(getClass().getSimpleName() + ": Didn't find property " + name + " for " + getPossibleURI(graph) + ".");
\r
577 public Variable getProperty(ReadGraph graph, Resource property) throws DatabaseException {
\r
578 return getProperty(graph, name(graph, property));
\r
582 public Variable browse(ReadGraph graph, String suffix)
\r
583 throws DatabaseException {
\r
585 if(suffix.isEmpty())
\r
587 switch(suffix.charAt(0)) {
\r
589 Variable parent = getParent(graph);
\r
591 throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ").");
\r
592 return parent.browse(graph, suffix.substring(1));
\r
595 int segmentEnd = getSegmentEnd(suffix);
\r
596 Variable property = getProperty(graph,
\r
597 decodeString(suffix.substring(1, segmentEnd)));
\r
598 if(property == null)
\r
599 throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ").");
\r
600 return property.browse(graph, suffix.substring(segmentEnd));
\r
603 int segmentEnd = getSegmentEnd(suffix);
\r
604 Variable child = getChild(graph,
\r
605 decodeString(suffix.substring(1, segmentEnd)));
\r
607 throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ").");
\r
608 return child.browse(graph, suffix.substring(segmentEnd));
\r
611 throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ").");
\r
616 private static int getSegmentEnd(String suffix) {
\r
618 for(pos=1;pos<suffix.length();++pos) {
\r
619 char c = suffix.charAt(pos);
\r
620 if(c == '/' || c == '#')
\r
627 public Variable browsePossible(ReadGraph graph, String suffix)
\r
628 throws DatabaseException {
\r
629 if(suffix.isEmpty())
\r
631 switch(suffix.charAt(0)) {
\r
633 Variable parent = getParent(graph);
\r
636 return parent.browsePossible(graph, suffix.substring(1));
\r
639 int segmentEnd = getSegmentEnd(suffix);
\r
640 Variable property = getPossibleProperty(graph,
\r
641 decodeString(suffix.substring(1, segmentEnd)));
\r
642 if(property == null)
\r
644 return property.browsePossible(graph, suffix.substring(segmentEnd));
\r
647 int segmentEnd = getSegmentEnd(suffix);
\r
648 Variable child = getPossibleChild(graph,
\r
649 decodeString(suffix.substring(1, segmentEnd)));
\r
652 return child.browsePossible(graph, suffix.substring(segmentEnd));
\r
660 public Variable browse(ReadGraph graph, Resource config)
\r
661 throws DatabaseException {
\r
662 Variable variable = browsePossible(graph, config);
\r
663 if(variable == null)
\r
664 throw new MissingVariableException("Didn't find a variable related to " +
\r
665 NameUtils.getSafeName(graph, config) + ".");
\r
670 public Variable browsePossible(ReadGraph graph, Resource config)
\r
671 throws DatabaseException {
\r
672 Layer0 l0 = Layer0.getInstance(graph);
\r
673 String name = (String)graph.getPossibleRelatedValue(config, l0.HasName, Bindings.STRING);
\r
676 return getPossibleChild(graph, name);
\r
680 public <T> T getInterface(ReadGraph graph, Class<T> clazz)
\r
681 throws DatabaseException {
\r
686 public String getURI(ReadGraph graph) throws DatabaseException {
\r
688 Variable parent = getParent(graph);
\r
689 if (parent == null)
\r
690 throw new InvalidVariableException(this + " has no URI");
\r
691 return parent.getURI(graph) + getRole(graph).getIdentifier() + encodeString(getName(graph));
\r
695 * For debug messages.
\r
699 * @throws DatabaseException
\r
701 public String getPossibleURI(ReadGraph graph) throws DatabaseException {
\r
702 Variable parent = getParent(graph);
\r
703 if (parent == null)
\r
705 if (parent instanceof AbstractVariable) {
\r
706 String parentUri = ((AbstractVariable) parent).getPossibleURI(graph);
\r
707 if (parentUri == null)
\r
709 return parentUri + getRole(graph).getIdentifier() + encodeString(getName(graph));
\r
714 public <T> T getPossibleValue(ReadGraph graph) throws DatabaseException {
\r
716 return getValue(graph);
\r
717 } catch(DatabaseException e) {
\r
723 public Variant getVariantValue(ReadGraph graph) throws DatabaseException {
\r
724 Binding binding = getPossibleDefaultBinding(graph);
\r
725 if(binding != null) {
\r
726 Object value = getValue(graph, binding);
\r
727 return new Variant(binding, value);
\r
729 // System.err.println("no data type for " + getURI(graph));
\r
730 // TODO: hackish, consider doing something else here?
\r
731 Object value = getValue(graph);
\r
733 binding = Bindings.OBJECT.getContentBinding(value);
\r
734 } catch (BindingException e) {
\r
735 throw new DatabaseException(e);
\r
737 return new Variant(binding, value);
\r
741 public Variant getPossibleVariantValue(ReadGraph graph) throws DatabaseException {
\r
742 Binding binding = getPossibleDefaultBinding(graph);
\r
743 if(binding != null) {
\r
744 Object value = getPossibleValue(graph, binding);
\r
745 if(value == null) return null;
\r
746 return new Variant(binding, value);
\r
748 Object value = getPossibleValue(graph);
\r
749 if(value == null) return null;
\r
751 // TODO: hackish, consider doing something else here?
\r
752 binding = value != null ? Bindings.getBinding(value.getClass()) : null;
\r
753 return new Variant(binding, value);
\r
754 } catch (BindingConstructionException e) {
\r
760 public <T> T getPossibleValue(ReadGraph graph, Binding binding) throws DatabaseException {
\r
762 return getValue(graph, binding);
\r
763 } catch(MissingVariableValueException e) {
\r
768 public <T> T adapt(ReadGraph graph, Class<T> clazz) throws DatabaseException {
\r
769 throw new AdaptionException(this + " does not support adaption to " + clazz);
\r
773 public <T> T adaptPossible(ReadGraph graph, Class<T> clazz) throws DatabaseException {
\r
775 return adapt(graph, clazz);
\r
776 } catch (AdaptionException e) {
\r
782 public static String encodeString(String string) throws DatabaseException {
\r
783 if (string == null || "".equals(string)) return string;
\r
784 return URIStringUtils.escape(string);
\r
787 public static String decodeString(String string) throws DatabaseException {
\r
788 return URIStringUtils.unescape(string);
\r
792 protected Variable getPossiblePropertyFromContext(ReadGraph graph, Resource context, String name) throws DatabaseException {
\r
794 Map<String, Resource> predicates = graph.syncRequest(new PropertyMapOfResource(context));
\r
795 Resource property = predicates.get(name);
\r
796 if(property == null) return null;
\r
797 Resource object = graph.getSingleObject(context, property);
\r
798 Variable objectAdapter = graph.getPossibleContextualAdapter(object, new ModelledVariablePropertyDescriptorImpl(this, context, property),
\r
799 ModelledVariablePropertyDescriptor.class, Variable.class);
\r
800 if(objectAdapter != null) return objectAdapter;
\r
801 return graph.getPossibleContextualAdapter(property, new ModelledVariablePropertyDescriptorImpl(this, context, property),
\r
802 ModelledVariablePropertyDescriptor.class, Variable.class);
\r
806 protected Map<String, Variable> collectPropertiesFromContext(ReadGraph graph, Resource context, Map<String, Variable> properties) throws DatabaseException {
\r
808 for(Map.Entry<String, Resource> entry : graph.syncRequest(new PropertyMapOfResource(context)).entrySet()) {
\r
809 String name = entry.getKey();
\r
810 Resource property = entry.getValue();
\r
811 Resource object = graph.getSingleObject(context, property);
\r
812 Variable objectAdapter = graph.getPossibleContextualAdapter(object, new ModelledVariablePropertyDescriptorImpl(this, context, property),
\r
813 ModelledVariablePropertyDescriptor.class, Variable.class);
\r
814 if(objectAdapter != null) {
\r
815 if(objectAdapter != null) {
\r
816 if(properties == null) properties = new HashMap<String,Variable>();
\r
817 properties.put(name, objectAdapter);
\r
820 Variable predicateAdapter = graph.getPossibleContextualAdapter(property, new ModelledVariablePropertyDescriptorImpl(this, context, property),
\r
821 ModelledVariablePropertyDescriptor.class, Variable.class);
\r
822 if(predicateAdapter != null) {
\r
823 if(properties == null) properties = new HashMap<String,Variable>();
\r
824 properties.put(name, predicateAdapter);
\r
835 public Variable resolve(ReadGraph graph, RVIPart part) throws DatabaseException {
\r
836 if(part instanceof StringRVIPart) {
\r
837 StringRVIPart srp = (StringRVIPart)part;
\r
838 if(Role.CHILD.equals(srp.getRole())) return getChild(graph, srp.string);
\r
839 else if(Role.PROPERTY.equals(srp.getRole())) return getProperty(graph, srp.string);
\r
840 } else if(part instanceof ResourceRVIPart) {
\r
841 ResourceRVIPart rrp = (ResourceRVIPart)part;
\r
842 if(Role.CHILD.equals(rrp.getRole())) return resolveChild(graph, rrp.resource);
\r
843 else if(Role.PROPERTY.equals(rrp.getRole())) return resolveProperty(graph, rrp.resource);
\r
844 } else if(part instanceof GuidRVIPart) {
\r
845 GuidRVIPart grp = (GuidRVIPart)part;
\r
846 if(Role.CHILD.equals(grp.getRole())) return resolveChild(graph, grp);
\r
847 else if(Role.PROPERTY.equals(grp.getRole())) return resolveProperty(graph, grp);
\r
849 throw new DatabaseException("Unrecognized RVIPart: " + part);
\r
853 public Variable resolvePossible(ReadGraph graph, RVIPart part) throws DatabaseException {
\r
854 if(part instanceof StringRVIPart) {
\r
855 StringRVIPart srp = (StringRVIPart)part;
\r
856 if(Role.CHILD.equals(srp.getRole())) return getPossibleChild(graph, srp.string);
\r
857 else if(Role.PROPERTY.equals(srp.getRole())) return getPossibleProperty(graph, srp.string);
\r
858 } else if(part instanceof ResourceRVIPart) {
\r
859 ResourceRVIPart rrp = (ResourceRVIPart)part;
\r
860 if(Role.CHILD.equals(rrp.getRole())) return resolvePossibleChild(graph, rrp.resource);
\r
861 else if(Role.PROPERTY.equals(rrp.getRole())) return resolvePossibleProperty(graph, rrp.resource);
\r
862 } else if(part instanceof GuidRVIPart) {
\r
863 GuidRVIPart grp = (GuidRVIPart)part;
\r
864 if(Role.CHILD.equals(grp.getRole())) return resolvePossibleChild(graph, grp);
\r
865 else if(Role.PROPERTY.equals(grp.getRole())) return resolvePossibleProperty(graph, grp);
\r
867 throw new DatabaseException("Unrecognized RVIPart: " + part);
\r
871 public Datatype getDatatype(ReadGraph graph) throws DatabaseException {
\r
872 throw new DatabaseException("No data type.");
\r
875 public Binding getDefaultBinding(ReadGraph graph) throws DatabaseException {
\r
876 Datatype type = getDatatype(graph);
\r
877 return Bindings.getBinding(type);
\r
880 public Binding getPossibleDefaultBinding(ReadGraph graph) throws DatabaseException {
\r
882 return getDefaultBinding(graph);
\r
883 } catch(DatabaseException e) {
\r
889 public Datatype getPossibleDatatype(ReadGraph graph) throws DatabaseException {
\r
891 return getDatatype(graph);
\r
892 } catch(DatabaseException e) {
\r
897 // public Binding getPossibleDefaultBinding(ReadGraph graph) throws DatabaseException {
\r
899 // Datatype type = getPossibleDatatype(graph);
\r
900 // if(type == null) return null;
\r
901 // return Bindings.getBinding(type);
\r
906 // public Datatype getPossibleDatatype(ReadGraph graph) throws DatabaseException {
\r
908 // Variant vt = getVariantValue(graph);
\r
909 // if(vt == null) return null;
\r
910 // Binding binding = vt.getBinding();
\r
911 // if(binding == null) return null;
\r
912 // return binding.type();
\r
917 public Variable getPredicate(ReadGraph graph) throws DatabaseException {
\r
918 throw new DatabaseException(getClass().getSimpleName() + ": No predicate property for " + getPossibleURI(graph));
\r
922 public Variable getPossiblePredicate(ReadGraph graph) throws DatabaseException {
\r
924 return getPredicate(graph);
\r
925 } catch(DatabaseException e) {
\r
931 public Resource getPredicateResource(ReadGraph graph) throws DatabaseException {
\r
932 Variable predicate = getPredicate(graph);
\r
933 if(predicate == null) throw new DatabaseException(getClass().getSimpleName() + ": No predicate property for " + getPossibleURI(graph));
\r
934 return predicate.getRepresents(graph);
\r
938 public Resource getPossiblePredicateResource(ReadGraph graph) throws DatabaseException {
\r
939 Variable predicate = getPossiblePredicate(graph);
\r
940 if(predicate == null) return null;
\r
941 else return predicate.getPossibleRepresents(graph);
\r
945 public Resource getPossibleRepresents(ReadGraph graph) throws DatabaseException {
\r
947 return getRepresents(graph);
\r
948 } catch(DatabaseException e) {
\r
954 public Resource getPossibleType(ReadGraph graph) throws DatabaseException {
\r
955 Resource resource = getPossibleRepresents(graph);
\r
956 if(resource == null) {
\r
957 String uri = getPossiblePropertyValue(graph, "typeURI");
\r
958 if(uri != null) return graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.<Resource>instance());
\r
961 return graph.getPossibleObject(resource, Layer0.getInstance(graph).InstanceOf);
\r
964 public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException {
\r
965 Resource resource = getPossibleRepresents(graph);
\r
966 if(resource == null) {
\r
967 String uri = getPossiblePropertyValue(graph, "typeURI");
\r
968 if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.<Resource>instance());
\r
969 throw new DatabaseException("No type for " + getURI(graph));
\r
971 return graph.getSingleType(resource, baseType);
\r
975 public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException {
\r
976 Resource resource = getPossibleRepresents(graph);
\r
977 if(resource == null) {
\r
978 String uri = getPossiblePropertyValue(graph, "typeURI");
\r
980 Resource type = graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.<Resource>instance());
\r
981 if(type == null) return null;
\r
982 if(graph.isInheritedFrom(type, baseType)) return type;
\r
987 return graph.getPossibleType(resource, baseType);
\r
990 public Map<String, Variable> collectDomainProperties(ReadGraph graph, String classification, Map<String, Variable> map) throws DatabaseException {
\r
991 Map<String,Variable> all = collectDomainProperties(graph, null);
\r
992 for(Map.Entry<String, Variable> entry : all.entrySet()) {
\r
993 Set<String> classifications = entry.getValue().getClassifications(graph);
\r
994 if(classifications.contains(classification)) {
\r
995 if(map == null) map = new HashMap<String,Variable>();
\r
996 map.put(entry.getKey(), entry.getValue());
\r
1003 public RVI getPossibleRVI(ReadGraph graph) throws DatabaseException {
\r
1005 return getRVI(graph);
\r
1006 } catch(DatabaseException e) {
\r