package org.simantics.db.layer0.variable; import gnu.trove.map.hash.THashMap; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import org.simantics.databoard.Bindings; import org.simantics.databoard.Databoard; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.StringBinding; import org.simantics.databoard.binding.error.BindingConstructionException; import org.simantics.databoard.binding.error.BindingException; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.databoard.type.Datatype; import org.simantics.databoard.util.URIStringUtils; import org.simantics.datatypes.literal.GUID; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.common.request.PropertyMapOfResource; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.AdaptionException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.exception.InvalidVariableException; import org.simantics.db.layer0.exception.MissingVariableException; import org.simantics.db.layer0.exception.MissingVariableValueException; import org.simantics.db.layer0.request.PossibleResource; import org.simantics.db.layer0.request.PropertyInfo; import org.simantics.db.layer0.request.VariableRVIRequest; import org.simantics.db.layer0.variable.RVI.GuidRVIPart; import org.simantics.db.layer0.variable.RVI.RVIPart; import org.simantics.db.layer0.variable.RVI.ResourceRVIPart; import org.simantics.db.layer0.variable.RVI.StringRVIPart; import org.simantics.db.layer0.variable.Variables.Role; import org.simantics.layer0.Layer0; /** * Abstract implementation of Variable -interface. * * @author Hannu Niemistö */ public abstract class AbstractVariable implements Variable { @SuppressWarnings("rawtypes") final public VariableNode node; public AbstractVariable(@SuppressWarnings("rawtypes") VariableNode node) { this.node = node; } /** * Returns a variable that is not one of the standard properties listed * in specification. */ protected abstract Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException; public abstract Variable getPossibleExtraProperty(ReadGraph graph, String name) throws DatabaseException; public abstract Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException; public abstract void collectExtraProperties(ReadGraph graph, Map properties) throws DatabaseException; public abstract Map collectDomainProperties(ReadGraph graph, Map map) throws DatabaseException; public abstract Collection getChildren(ReadGraph graph) throws DatabaseException; public abstract T getValue(ReadGraph graph) throws DatabaseException; public abstract T getValue(ReadGraph graph, Binding binding) throws DatabaseException; public abstract void setValue(WriteGraph graph, Object value, Binding binding) throws DatabaseException; public abstract String getName(ReadGraph graph) throws DatabaseException; //public abstract Object getSerialized(ReadGraph graph) throws DatabaseException; public abstract Variable getParent(ReadGraph graph) throws DatabaseException; public abstract Role getRole(ReadGraph graph) throws DatabaseException; public abstract Resource getRepresents(ReadGraph graph) throws DatabaseException; public abstract Set getClassifications(ReadGraph graph) throws DatabaseException; @Override public PropertyInfo getPropertyInfo(ReadGraph graph) throws DatabaseException { throw new DatabaseException("PropertyInfo is not available"); } @Override public Resource getIndexRoot(ReadGraph graph) throws DatabaseException { Resource represents = getPossibleRepresents(graph); if(represents != null) return graph.syncRequest(new PossibleIndexRoot(represents)); Variable parent = getParent(graph); if(parent == null) return null; return parent.getIndexRoot(graph); } public void validate(ReadGraph graph) throws DatabaseException { } public String getIdentifier() { return getClass().getSimpleName(); } @Override public Role getPossibleRole(ReadGraph graph) throws DatabaseException { try { return getRole(graph); } catch (DatabaseException e) { return null; } } protected Variable resolveChild(ReadGraph graph, Resource resource) throws DatabaseException { String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); for(Variable child : browseChildren(graph)) { String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING); if(rName.equals(name)) return child; } throw new DatabaseException("Could not resolve child " + resource); } protected Variable resolveChild(ReadGraph graph, GuidRVIPart part) throws DatabaseException { return StandardRVIResolver.resolveChildDefault(graph, this, part); } protected Variable resolveProperty(ReadGraph graph, Resource resource) throws DatabaseException { String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); for(Variable child : browseProperties(graph)) { String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING); if(rName.equals(name)) return child; } throw new DatabaseException("Could not resolve child " + resource); } protected Variable resolveProperty(ReadGraph graph, GuidRVIPart part) throws DatabaseException { return StandardRVIResolver.resolvePropertyDefault(graph, this, part); } protected Variable resolvePossibleChild(ReadGraph graph, Resource resource) throws DatabaseException { String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); for(Variable child : browseChildren(graph)) { String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING); if(rName.equals(name)) return child; } return null; } protected Variable resolvePossibleChild(ReadGraph graph, GuidRVIPart part) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for(Variable child : browseChildren(graph)) { GUID id = child.getPossiblePropertyValue(graph, L0.identifier, GUID.BINDING); if(id != null) { if(id.mostSignificant == part.mostSignificant && id.leastSignificant == part.leastSignificant) return child; } } return null; } protected Variable resolvePossibleProperty(ReadGraph graph, Resource resource) throws DatabaseException { String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); for(Variable child : browseProperties(graph)) { String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING); if(rName.equals(name)) return child; } return null; } protected Variable resolvePossibleProperty(ReadGraph graph, GuidRVIPart part) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for(Variable child : browseProperties(graph)) { GUID id = child.getPossiblePropertyValue(graph, L0.identifier, GUID.BINDING); if(id != null) { if(id.mostSignificant == part.mostSignificant && id.leastSignificant == part.leastSignificant) return child; } } return null; } public String getLabel(ReadGraph graph) throws DatabaseException { return getName(graph); } public String getPossibleLabel(ReadGraph graph) throws DatabaseException { Resource represents = getPossibleRepresents(graph); if(represents == null) return null; return graph.getPossibleRelatedValue2(represents, graph.getService(Layer0.class).HasLabel, getParent(graph), Bindings.STRING); } public Resource getType(ReadGraph graph) throws DatabaseException { Resource resource = getPossibleRepresents(graph); if(resource == null) { String uri = getPossiblePropertyValue(graph, "typeURI"); if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); throw new DatabaseException("No type for " + getURI(graph)); } return graph.getSingleType(resource); } public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException { throw new UnsupportedOperationException(); } @Override public RVI getRVI(ReadGraph graph) throws DatabaseException { Databoard databoard = graph.getService( Databoard.class ); Binding rviBinding = databoard.getBindingUnchecked( RVI.class ); if(Variables.isContext(graph, this)) { return RVI.empty( rviBinding ); } else { Variable parent = getParent(graph); if (parent == null) // TODO: consider using a more suitable exception here to better convey the situation. throw new MissingVariableException("no parent for variable " + this + " (URI=" + getPossibleURI(graph) + ")"); RVI base = graph.syncRequest(new VariableRVIRequest(parent)); RVIPart part = getRVIPart(graph); return new RVIBuilder(base).append(part).toRVI(); } } protected Variable getDomainProperty(ReadGraph graph, String name) throws DatabaseException { Variable property = getPossibleDomainProperty(graph, name); if(property == null) throw new MissingVariableException(getIdentifier() + ": Didn't find property " + name + "."); return property; } protected void addProperty(Map properties, String name, Object value, Binding binding) { if(value != null) { properties.put(name, new ConstantPropertyVariable(this, name, value, binding)); } } protected Variable getNameVariable(ReadGraph graph) throws DatabaseException { return new ConstantPropertyVariable(this, Variables.NAME, getName(graph), Bindings.STRING); } protected Variable getLabelVariable(ReadGraph graph) throws DatabaseException { return new ConstantPropertyVariable(this, Variables.LABEL, getPossibleLabel(graph), Bindings.STRING); } final public Collection browseProperties(ReadGraph graph) throws DatabaseException { return getProperties(graph); } private Map getPropertyMap(ReadGraph graph, String classification) throws DatabaseException { return collectDomainProperties(graph, classification, null); } final static class PropertyMap extends THashMap { final private Variable variable; PropertyMap(Variable variable) { this.variable = variable; } private Variable getTypeVariable() { return new AbstractConstantPropertyVariable(variable, Variables.TYPE, null) { @SuppressWarnings("unchecked") @Override public T getValue(ReadGraph graph) throws DatabaseException { Resource represents = parent.getRepresents(graph); if(represents == null) return null; return (T)graph.getPossibleType(represents, Layer0.getInstance(graph).Entity); } @Override public T getValue(ReadGraph graph, Binding binding) throws DatabaseException { return getValue(graph); } }; } private Variable getURIVariable() { return new AbstractConstantPropertyVariable(variable, Variables.URI, null) { @SuppressWarnings("unchecked") @Override public T getValue(ReadGraph graph) throws DatabaseException { return (T)variable.getURI(graph); } @Override public T getValue(ReadGraph graph, Binding binding) throws DatabaseException { return getValue(graph); } }; } public Variable get(Object key) { Variable result = super.get(key); if(result != null) return result; if(Variables.TYPE.equals(key)) return getTypeVariable(); else if(Variables.URI.equals(key)) return getURIVariable(); return variable; } } private Map getPropertyMap(ReadGraph graph) throws DatabaseException { PropertyMap properties = new PropertyMap(this); // Map properties = new HashMap(); // try { // properties.put(Variables.NAME, getNameVariable(graph)); // } catch (DatabaseException e) { // // A variable that has no name doesn't exist by definition. // // Therefore it can't have any properties. // return Collections.emptyMap(); // } // try { // Variable labelVariable = getLabelVariable(graph); // if(labelVariable != null) properties.put(Variables.LABEL, getLabelVariable(graph)); // } catch (DatabaseException e) { // // Label not absolutely mandatory. // } // addProperty(properties, Variables.TYPE, getPossibleType(graph), null); // addProperty(properties, Variables.URI, getPossibleURI(graph), Bindings.STRING); //addProperty(properties, Variables.SERIALISED, getSerialized(graph), Bindings.STRING); //addProperty(properties, Variables.PARENT, getParent(graph), null); // addProperty(properties, Variables.ROLE, getRole(graph), Bindings.STRING); // addProperty(properties, Variables.REPRESENTS, getPossibleRepresents(graph), null); collectExtraProperties(graph, properties); collectDomainProperties(graph, properties); return properties; } @Override public Collection getProperties(ReadGraph graph) throws DatabaseException { return getPropertyMap(graph).values(); } public Collection getProperties(ReadGraph graph, String classification) throws DatabaseException { Map propertyMap = getPropertyMap(graph, classification); if(propertyMap == null) return Collections.emptyList(); else return propertyMap.values(); } @Override public Collection getProperties(ReadGraph graph, Resource property) throws DatabaseException { return getProperties(graph, uri(graph, property)); } final public Collection browseChildren(ReadGraph graph) throws DatabaseException { return getChildren(graph); } @Override public Variable getPossibleProperty(ReadGraph graph, String name) throws DatabaseException { if(Variables.NAME.equals(name)) { return getNameVariable(graph); } if(Variables.LABEL.equals(name)) { return getLabelVariable(graph); } if(Variables.TYPE.equals(name)) { Object value = getPossibleType(graph); if(value != null) return new ConstantPropertyVariable(this, name, value, null); } if(Variables.URI.equals(name)) { // TODO: getPossibleURI or getURI? Object value = getURI(graph); if(value != null) return new ConstantPropertyVariable(this, name, value, Bindings.STRING); } // if(Variables.SERIALISED.equals(name)) { // Object value = getSerialized(graph); // if(value != null) // return new ConstantPropertyVariable(this, name, value, Bindings.STRING); // } /*if(Variables.PARENT.equals(name)) { Object value = getParent(graph); if(value != null) return new ConstantPropertyVariable(this, name, value, null); }*/ // if(Variables.ROLE.equals(name)) { // Object value = getRole(graph); // if(value != null) // return new ConstantPropertyVariable(this, name, value, null); // } // if(Variables.REPRESENTS.equals(name)) { // Object value = getRepresents(graph); // if(value != null) // return new ConstantPropertyVariable(this, name, value, null); // } Variable extra = getPossibleExtraProperty(graph, name); if(extra != null) return extra; return getPossibleDomainProperty(graph, name); } @Override public Variable getPossibleProperty(ReadGraph graph, Resource property) throws DatabaseException { return getPossibleProperty(graph, name(graph, property)); } @SuppressWarnings("unchecked") protected T checkNull(ReadGraph graph, Object value) throws DatabaseException { if(value == null) throw new MissingVariableValueException(getClass().getSimpleName() + ": Didn't find value for " + getPossibleURI(graph)); return (T)value; } private String name(ReadGraph graph, Resource property) throws DatabaseException { return graph.getRelatedValue(property, Layer0.getInstance(graph).HasName, Bindings.STRING); } private String uri(ReadGraph graph, Resource property) throws DatabaseException { return graph.getURI(property); } @Override public T getPropertyValue(ReadGraph graph, String name) throws DatabaseException { if(Variables.LABEL.equals(name)) return checkNull(graph, getLabel(graph)); Variable result = getDomainProperty(graph, name); if(result != null) return result.getValue(graph); if(Variables.NAME.equals(name)) return checkNull(graph, getName(graph)); if(Variables.TYPE.equals(name)) return checkNull(graph, getPossibleType(graph)); if(Variables.URI.equals(name)) return checkNull(graph, getURI(graph)); // if(Variables.SERIALISED.equals(name)) return checkNull(graph, getSerialized(graph)); // if(Variables.ROLE.equals(name)) return checkNull(graph, getRole(graph)); // if(Variables.REPRESENTS.equals(name)) return checkNull(graph, getRepresents(graph)); Variable extra = getPossibleExtraProperty(graph, name); if(extra != null) return extra.getValue(graph); return null; } @Override public T getPropertyValue(ReadGraph graph, Resource property) throws DatabaseException { return getPropertyValue(graph, name(graph, property)); } @SuppressWarnings("unchecked") @Override public T getPossiblePropertyValue(ReadGraph graph, String name) throws DatabaseException { Variable property = getPossibleDomainProperty(graph, name); if(property != null) return property.getPossibleValue(graph); if(Variables.NAME.equals(name)) return (T)getName(graph); if(Variables.LABEL.equals(name)) return (T)getLabel(graph); if(Variables.TYPE.equals(name)) return (T)getPossibleType(graph); if(Variables.URI.equals(name)) return (T)getURI(graph); // if(Variables.SERIALISED.equals(name)) return (T)getSerialized(graph); // if(Variables.ROLE.equals(name)) return (T)getRole(graph); // if(Variables.REPRESENTS.equals(name)) return (T)getRepresents(graph); Variable extra = getPossibleExtraProperty(graph, name); if(extra != null) return extra.getPossibleValue(graph); return null; } @Override public T getPossiblePropertyValue(ReadGraph graph, Resource property) throws DatabaseException { return getPossiblePropertyValue(graph, name(graph, property)); } @SuppressWarnings("unchecked") @Override public T getPropertyValue(ReadGraph graph, String name, Binding binding) throws DatabaseException { if(binding instanceof StringBinding) { StringBinding sb = (StringBinding)binding; try { if(Variables.NAME.equals(name)) return (T)sb.create((String)checkNull(graph, getName(graph))); if(Variables.LABEL.equals(name)) return (T)sb.create((String)checkNull(graph, getLabel(graph))); if(Variables.URI.equals(name)) return (T)sb.create((String)checkNull(graph, getURI(graph))); // if(Variables.SERIALISED.equals(name)) return (T)sb.create((String)checkNull(graph, getSerialized(graph))); } catch(BindingException e) { throw new DatabaseException(e); } } Variable property = getPossibleExtraProperty(graph, name); if(property != null) return property.getValue(graph, binding); property = getPossibleDomainProperty(graph, name); if(property == null) throw new MissingVariableException("Didn't find property " + name + " for " + this + "."); return property.getValue(graph, binding); } @Override public T getPropertyValue(ReadGraph graph, Resource property, Binding binding) throws DatabaseException { return getPropertyValue(graph, name(graph, property), binding); } @SuppressWarnings("unchecked") @Override public T getPossiblePropertyValue(ReadGraph graph, String name, Binding binding) throws DatabaseException { if(binding instanceof StringBinding) { StringBinding sb = (StringBinding)binding; try { if(Variables.NAME.equals(name)) return (T)sb.create((String)getName(graph)); if(Variables.LABEL.equals(name)) return (T)sb.create((String)getLabel(graph)); if(Variables.URI.equals(name)) return (T)sb.create((String)getURI(graph)); // if(Variables.SERIALISED.equals(name)) return (T)sb.create((String)getSerialized(graph)); } catch(BindingException e) { throw new DatabaseException(e); } } Variable property = getPossibleExtraProperty(graph, name); if(property != null) return property.getPossibleValue(graph, binding); property = getPossibleDomainProperty(graph, name); if(property == null) return null; return property.getPossibleValue(graph, binding); } @Override public T getPossiblePropertyValue(ReadGraph graph, Resource property, Binding binding) throws DatabaseException { return getPossiblePropertyValue(graph, name(graph, property), binding); } @Override public void setValue(WriteGraph graph, Object value) throws DatabaseException { try { setValue(graph, value, Bindings.getBinding(value.getClass())); } catch (BindingConstructionException e) { throw new DatabaseException(e); } } @Override public void setPropertyValue(WriteGraph graph, String name, Object value) throws DatabaseException { getProperty(graph, name).setValue(graph, value); } @Override public void setPropertyValue(WriteGraph graph, Resource property, Object value) throws DatabaseException { setPropertyValue(graph, name(graph, property), value); } @Override public void setPropertyValue(WriteGraph graph, String name, Object value, Binding binding) throws DatabaseException { getProperty(graph, name).setValue(graph, value, binding); } @Override public void setPropertyValue(WriteGraph graph, Resource property, Object value, Binding binding) throws DatabaseException { setPropertyValue(graph, name(graph, property), value, binding); } @Override public Variable getChild(ReadGraph graph, String name) throws DatabaseException { Variable child = getPossibleChild(graph, name); if(child == null) throw new MissingVariableException(getURI(graph) + ": didn't find child " + name + " for " + getIdentifier() + "."); return child; } @Override public Variable getProperty(ReadGraph graph, String name) throws DatabaseException { Variable result = getPossibleProperty(graph, name); if(result == null) throw new MissingVariableException(getClass().getSimpleName() + ": Didn't find property " + name + " for " + getPossibleURI(graph) + "."); return result; } @Override public Variable getProperty(ReadGraph graph, Resource property) throws DatabaseException { return getProperty(graph, name(graph, property)); } @Override public Variable browse(ReadGraph graph, String suffix) throws DatabaseException { if(suffix.isEmpty()) return this; switch(suffix.charAt(0)) { case '.': { Variable parent = getParent(graph); if(parent == null) throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ")."); return parent.browse(graph, suffix.substring(1)); } case '#': { int segmentEnd = getSegmentEnd(suffix); Variable property = getProperty(graph, decodeString(suffix.substring(1, segmentEnd))); if(property == null) throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ")."); return property.browse(graph, suffix.substring(segmentEnd)); } case '/': { int segmentEnd = getSegmentEnd(suffix); Variable child = getChild(graph, decodeString(suffix.substring(1, segmentEnd))); if(child == null) throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ")."); return child.browse(graph, suffix.substring(segmentEnd)); } default: throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ")."); } } private static int getSegmentEnd(String suffix) { int pos; for(pos=1;pos T getInterface(ReadGraph graph, Class clazz) throws DatabaseException { return null; } @Override public String getURI(ReadGraph graph) throws DatabaseException { validate(graph); Variable parent = getParent(graph); if (parent == null) throw new InvalidVariableException(this + " has no URI"); return parent.getURI(graph) + getRole(graph).getIdentifier() + encodeString(getName(graph)); } /** * For debug messages. * * @param graph * @return * @throws DatabaseException */ public String getPossibleURI(ReadGraph graph) throws DatabaseException { Variable parent = getParent(graph); if (parent == null) return null; if (parent instanceof AbstractVariable) { String parentUri = ((AbstractVariable) parent).getPossibleURI(graph); if (parentUri == null) return null; return parentUri + getRole(graph).getIdentifier() + encodeString(getName(graph)); } return null; } public T getPossibleValue(ReadGraph graph) throws DatabaseException { try { return getValue(graph); } catch(DatabaseException e) { return null; } } @Override public Variant getVariantValue(ReadGraph graph) throws DatabaseException { Binding binding = getPossibleDefaultBinding(graph); if(binding != null) { Object value = getValue(graph, binding); return new Variant(binding, value); } else { // System.err.println("no data type for " + getURI(graph)); // TODO: hackish, consider doing something else here? Object value = getValue(graph); try { binding = Bindings.OBJECT.getContentBinding(value); } catch (BindingException e) { throw new DatabaseException(e); } return new Variant(binding, value); } } public Variant getPossibleVariantValue(ReadGraph graph) throws DatabaseException { Binding binding = getPossibleDefaultBinding(graph); if(binding != null) { Object value = getPossibleValue(graph, binding); if(value == null) return null; return new Variant(binding, value); } else { Object value = getPossibleValue(graph); if(value == null) return null; try { // TODO: hackish, consider doing something else here? binding = value != null ? Bindings.getBinding(value.getClass()) : null; return new Variant(binding, value); } catch (BindingConstructionException e) { return null; } } } public T getPossibleValue(ReadGraph graph, Binding binding) throws DatabaseException { try { return getValue(graph, binding); } catch(MissingVariableValueException e) { return null; } } public T adapt(ReadGraph graph, Class clazz) throws DatabaseException { throw new AdaptionException(this + " does not support adaption to " + clazz); } @Override public T adaptPossible(ReadGraph graph, Class clazz) throws DatabaseException { try { return adapt(graph, clazz); } catch (AdaptionException e) { return null; } } public static String encodeString(String string) throws DatabaseException { if (string == null || "".equals(string)) return string; return URIStringUtils.escape(string); } public static String decodeString(String string) throws DatabaseException { return URIStringUtils.unescape(string); } protected Variable getPossiblePropertyFromContext(ReadGraph graph, Resource context, String name) throws DatabaseException { Map predicates = graph.syncRequest(new PropertyMapOfResource(context)); Resource property = predicates.get(name); if(property == null) return null; Resource object = graph.getSingleObject(context, property); Variable objectAdapter = graph.getPossibleContextualAdapter(object, new ModelledVariablePropertyDescriptorImpl(this, context, property), ModelledVariablePropertyDescriptor.class, Variable.class); if(objectAdapter != null) return objectAdapter; return graph.getPossibleContextualAdapter(property, new ModelledVariablePropertyDescriptorImpl(this, context, property), ModelledVariablePropertyDescriptor.class, Variable.class); } protected Map collectPropertiesFromContext(ReadGraph graph, Resource context, Map properties) throws DatabaseException { for(Map.Entry entry : graph.syncRequest(new PropertyMapOfResource(context)).entrySet()) { String name = entry.getKey(); Resource property = entry.getValue(); Resource object = graph.getSingleObject(context, property); Variable objectAdapter = graph.getPossibleContextualAdapter(object, new ModelledVariablePropertyDescriptorImpl(this, context, property), ModelledVariablePropertyDescriptor.class, Variable.class); if(objectAdapter != null) { if(objectAdapter != null) { if(properties == null) properties = new HashMap(); properties.put(name, objectAdapter); } } else { Variable predicateAdapter = graph.getPossibleContextualAdapter(property, new ModelledVariablePropertyDescriptorImpl(this, context, property), ModelledVariablePropertyDescriptor.class, Variable.class); if(predicateAdapter != null) { if(properties == null) properties = new HashMap(); properties.put(name, predicateAdapter); } } } return properties; } @Override public Variable resolve(ReadGraph graph, RVIPart part) throws DatabaseException { if(part instanceof StringRVIPart) { StringRVIPart srp = (StringRVIPart)part; if(Role.CHILD.equals(srp.getRole())) return getChild(graph, srp.string); else if(Role.PROPERTY.equals(srp.getRole())) return getProperty(graph, srp.string); } else if(part instanceof ResourceRVIPart) { ResourceRVIPart rrp = (ResourceRVIPart)part; if(Role.CHILD.equals(rrp.getRole())) return resolveChild(graph, rrp.resource); else if(Role.PROPERTY.equals(rrp.getRole())) return resolveProperty(graph, rrp.resource); } else if(part instanceof GuidRVIPart) { GuidRVIPart grp = (GuidRVIPart)part; if(Role.CHILD.equals(grp.getRole())) return resolveChild(graph, grp); else if(Role.PROPERTY.equals(grp.getRole())) return resolveProperty(graph, grp); } throw new DatabaseException("Unrecognized RVIPart: " + part); } @Override public Variable resolvePossible(ReadGraph graph, RVIPart part) throws DatabaseException { if(part instanceof StringRVIPart) { StringRVIPart srp = (StringRVIPart)part; if(Role.CHILD.equals(srp.getRole())) return getPossibleChild(graph, srp.string); else if(Role.PROPERTY.equals(srp.getRole())) return getPossibleProperty(graph, srp.string); } else if(part instanceof ResourceRVIPart) { ResourceRVIPart rrp = (ResourceRVIPart)part; if(Role.CHILD.equals(rrp.getRole())) return resolvePossibleChild(graph, rrp.resource); else if(Role.PROPERTY.equals(rrp.getRole())) return resolvePossibleProperty(graph, rrp.resource); } else if(part instanceof GuidRVIPart) { GuidRVIPart grp = (GuidRVIPart)part; if(Role.CHILD.equals(grp.getRole())) return resolvePossibleChild(graph, grp); else if(Role.PROPERTY.equals(grp.getRole())) return resolvePossibleProperty(graph, grp); } throw new DatabaseException("Unrecognized RVIPart: " + part); } @Override public Datatype getDatatype(ReadGraph graph) throws DatabaseException { throw new DatabaseException("No data type."); } public Binding getDefaultBinding(ReadGraph graph) throws DatabaseException { Datatype type = getDatatype(graph); return Bindings.getBinding(type); } public Binding getPossibleDefaultBinding(ReadGraph graph) throws DatabaseException { try { return getDefaultBinding(graph); } catch(DatabaseException e) { return null; } } @Override public Datatype getPossibleDatatype(ReadGraph graph) throws DatabaseException { try { return getDatatype(graph); } catch(DatabaseException e) { return null; } } // public Binding getPossibleDefaultBinding(ReadGraph graph) throws DatabaseException { // // Datatype type = getPossibleDatatype(graph); // if(type == null) return null; // return Bindings.getBinding(type); // // } // // @Override // public Datatype getPossibleDatatype(ReadGraph graph) throws DatabaseException { // // Variant vt = getVariantValue(graph); // if(vt == null) return null; // Binding binding = vt.getBinding(); // if(binding == null) return null; // return binding.type(); // // } @Override public Variable getPredicate(ReadGraph graph) throws DatabaseException { throw new DatabaseException(getClass().getSimpleName() + ": No predicate property for " + getPossibleURI(graph)); } @Override public Variable getPossiblePredicate(ReadGraph graph) throws DatabaseException { try { return getPredicate(graph); } catch(DatabaseException e) { return null; } } @Override public Resource getPredicateResource(ReadGraph graph) throws DatabaseException { Variable predicate = getPredicate(graph); if(predicate == null) throw new DatabaseException(getClass().getSimpleName() + ": No predicate property for " + getPossibleURI(graph)); return predicate.getRepresents(graph); } @Override public Resource getPossiblePredicateResource(ReadGraph graph) throws DatabaseException { Variable predicate = getPossiblePredicate(graph); if(predicate == null) return null; else return predicate.getPossibleRepresents(graph); } @Override public Resource getPossibleRepresents(ReadGraph graph) throws DatabaseException { try { return getRepresents(graph); } catch(DatabaseException e) { return null; } } @Override public Resource getPossibleType(ReadGraph graph) throws DatabaseException { Resource resource = getPossibleRepresents(graph); if(resource == null) { String uri = getPossiblePropertyValue(graph, "typeURI"); if(uri != null) return graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.instance()); return null; } return graph.getPossibleObject(resource, Layer0.getInstance(graph).InstanceOf); } public Resource getType(ReadGraph graph, Resource baseType) throws DatabaseException { Resource resource = getPossibleRepresents(graph); if(resource == null) { String uri = getPossiblePropertyValue(graph, "typeURI"); if(uri != null) return graph.syncRequest(new org.simantics.db.common.primitiverequest.Resource(uri), TransientCacheAsyncListener.instance()); throw new DatabaseException("No type for " + getURI(graph)); } return graph.getSingleType(resource, baseType); } @Override public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException { Resource resource = getPossibleRepresents(graph); if(resource == null) { String uri = getPossiblePropertyValue(graph, "typeURI"); if(uri != null) { Resource type = graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.instance()); if(type == null) return null; if(graph.isInheritedFrom(type, baseType)) return type; else return null; } return null; } return graph.getPossibleType(resource, baseType); } public Map collectDomainProperties(ReadGraph graph, String classification, Map map) throws DatabaseException { Map all = collectDomainProperties(graph, null); for(Map.Entry entry : all.entrySet()) { Set classifications = entry.getValue().getClassifications(graph); if(classifications.contains(classification)) { if(map == null) map = new HashMap(); map.put(entry.getKey(), entry.getValue()); } } return map; } @Override public RVI getPossibleRVI(ReadGraph graph) throws DatabaseException { try { return getRVI(graph); } catch(DatabaseException e) { return null; } } }