X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Fvariable%2FAbstractVariable.java;h=110ed2f777471aeef7e15128baa2381f3964d824;hb=1ecae6e1ad40507badb8807fb14bb67b4adf199c;hp=d9366b132aa2a41e471bf0cd2ea7d1c9b19cef96;hpb=6f11a60dee43d620d500c0cf5af34a1d91c80a8b;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java index d9366b132..110ed2f77 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/AbstractVariable.java @@ -39,6 +39,8 @@ 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; +import org.simantics.scl.runtime.SCLContext; +import org.simantics.scl.runtime.function.Function2; /** * Abstract implementation of Variable -interface. @@ -80,7 +82,7 @@ public abstract class AbstractVariable implements Variable { @Override public PropertyInfo getPropertyInfo(ReadGraph graph) throws DatabaseException { - throw new DatabaseException("PropertyInfo is not available"); + throw new InvalidVariableException("PropertyInfo is not available"); } @Override @@ -115,7 +117,7 @@ public abstract class AbstractVariable implements Variable { String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING); if(rName.equals(name)) return child; } - throw new DatabaseException("Could not resolve child " + resource); + throw new MissingVariableException("Could not resolve child " + rName, resource); } protected Variable resolveChild(ReadGraph graph, GuidRVIPart part) throws DatabaseException { @@ -128,7 +130,7 @@ public abstract class AbstractVariable implements Variable { String name = child.getPossiblePropertyValue(graph, Variables.NAME, Bindings.STRING); if(rName.equals(name)) return child; } - throw new DatabaseException("Could not resolve child " + resource); + throw new MissingVariableException("Could not resolve child " + rName, resource); } protected Variable resolveProperty(ReadGraph graph, GuidRVIPart part) throws DatabaseException { @@ -187,18 +189,6 @@ public abstract class AbstractVariable implements Variable { 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(); } @@ -213,7 +203,7 @@ public abstract class AbstractVariable implements Variable { 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) + ")"); + throw new MissingVariableException("no parent for variable " + this + " (URI=" + getPossibleURI(graph) + ")", getPossibleRepresents(graph)); RVI base = graph.syncRequest(new VariableRVIRequest(parent)); RVIPart part = getRVIPart(graph); return new RVIBuilder(base).append(part).toRVI(); @@ -223,7 +213,7 @@ public abstract class AbstractVariable implements Variable { 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 + "."); + throw new MissingVariableException(getIdentifier() + ": Didn't find property " + name + ".", getPossibleRepresents(graph)); return property; } @@ -470,17 +460,20 @@ public abstract class AbstractVariable implements Variable { @SuppressWarnings("unchecked") @Override - public T getPropertyValue(ReadGraph graph, String name, Binding binding) - throws DatabaseException { - if(binding instanceof StringBinding) { - StringBinding sb = (StringBinding)binding; + 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); + 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 org.simantics.db.exception.BindingException("Could not get value for property " + name + " with binding " + binding, e); } } Variable property = getPossibleExtraProperty(graph, name); @@ -488,7 +481,7 @@ public abstract class AbstractVariable implements Variable { return property.getValue(graph, binding); property = getPossibleDomainProperty(graph, name); if(property == null) - throw new MissingVariableException("Didn't find property " + name + " for " + this + "."); + throw new MissingVariableException("Didn't find property " + name + " for " + this + ".", getPossibleRepresents(graph)); return property.getValue(graph, binding); } @@ -509,7 +502,7 @@ public abstract class AbstractVariable implements Variable { 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); + throw new org.simantics.db.exception.BindingException("Could not get property value for " + name + " with binding " + binding, e); } } Variable property = getPossibleExtraProperty(graph, name); @@ -531,7 +524,7 @@ public abstract class AbstractVariable implements Variable { try { setValue(graph, value, Bindings.getBinding(value.getClass())); } catch (BindingConstructionException e) { - throw new DatabaseException(e); + throw new org.simantics.db.exception.BindingException("Could not set " + String.valueOf(value) + " value for " + getRepresents(graph), e); } } @@ -561,7 +554,7 @@ public abstract class AbstractVariable implements Variable { throws DatabaseException { Variable child = getPossibleChild(graph, name); if(child == null) - throw new MissingVariableException(getURI(graph) + ": didn't find child " + name + " for " + getIdentifier() + "."); + throw new MissingVariableException(getURI(graph) + ": didn't find child " + name + " for " + getIdentifier() + ".", getPossibleRepresents(graph)); return child; } @@ -569,7 +562,7 @@ public abstract class AbstractVariable implements Variable { 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) + "."); + throw new MissingVariableException(getClass().getSimpleName() + ": Didn't find property " + name + " for " + getPossibleURI(graph) + ".", getPossibleRepresents(graph)); return result; } @@ -588,7 +581,7 @@ public abstract class AbstractVariable implements Variable { case '.': { Variable parent = getParent(graph); if(parent == null) - throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ")."); + throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ").", getPossibleRepresents(graph)); return parent.browse(graph, suffix.substring(1)); } case '#': { @@ -596,7 +589,7 @@ public abstract class AbstractVariable implements Variable { Variable property = getProperty(graph, decodeString(suffix.substring(1, segmentEnd))); if(property == null) - throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ")."); + throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ").", getPossibleRepresents(graph)); return property.browse(graph, suffix.substring(segmentEnd)); } case '/': { @@ -604,11 +597,11 @@ public abstract class AbstractVariable implements Variable { Variable child = getChild(graph, decodeString(suffix.substring(1, segmentEnd))); if(child == null) - throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ")."); + throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ").", getPossibleRepresents(graph)); return child.browse(graph, suffix.substring(segmentEnd)); } default: - throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ")."); + throw new MissingVariableException("Didn't find " + suffix + " for " + this + " (" + getPossibleURI(graph) + ").", getPossibleRepresents(graph)); } } @@ -662,7 +655,7 @@ public abstract class AbstractVariable implements Variable { Variable variable = browsePossible(graph, config); if(variable == null) throw new MissingVariableException("Didn't find a variable related to " + - NameUtils.getSafeName(graph, config) + "."); + NameUtils.getSafeName(graph, config) + ".", config); return variable; } @@ -732,7 +725,7 @@ public abstract class AbstractVariable implements Variable { try { binding = Bindings.OBJECT.getContentBinding(value); } catch (BindingException e) { - throw new DatabaseException(e); + throw new org.simantics.db.exception.BindingException("Could not bind variant value " + String.valueOf(value) + " for " + getRepresents(graph), e); } return new Variant(binding, value); } @@ -846,7 +839,7 @@ public abstract class AbstractVariable implements Variable { 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); + throw new MissingVariableException("Unrecognized RVIPart: " + part, getPossibleRepresents(graph)); } @Override @@ -864,12 +857,12 @@ public abstract class AbstractVariable implements Variable { 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); + throw new MissingVariableException("Unrecognized RVIPart: " + part, getPossibleRepresents(graph)); } @Override public Datatype getDatatype(ReadGraph graph) throws DatabaseException { - throw new DatabaseException("No data type."); + throw new InvalidVariableException("No data type."); } public Binding getDefaultBinding(ReadGraph graph) throws DatabaseException { @@ -915,7 +908,7 @@ public abstract class AbstractVariable implements Variable { @Override public Variable getPredicate(ReadGraph graph) throws DatabaseException { - throw new DatabaseException(getClass().getSimpleName() + ": No predicate property for " + getPossibleURI(graph)); + throw new MissingVariableException(getClass().getSimpleName() + ": No predicate property for " + getPossibleURI(graph), getPossibleRepresents(graph)); } @Override @@ -926,14 +919,15 @@ public abstract class AbstractVariable implements Variable { 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 getPredicateResource(ReadGraph graph) throws DatabaseException { + Variable predicate = getPredicate(graph); + if (predicate == null) + throw new MissingVariableException(getClass().getSimpleName() + ": No predicate property for " + getPossibleURI(graph), getPossibleRepresents(graph)); + return predicate.getRepresents(graph); + } + @Override public Resource getPossiblePredicateResource(ReadGraph graph) throws DatabaseException { Variable predicate = getPossiblePredicate(graph); @@ -950,42 +944,108 @@ public abstract class AbstractVariable implements Variable { } } - @Override - public Resource getPossibleType(ReadGraph graph) throws DatabaseException { + public Resource getType(ReadGraph graph) throws DatabaseException { + Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, Layer0.getInstance(graph).Entity, getPossibleTypeFunction(graph)); + if (typeFromFunction != null) + return typeFromFunction; + Resource resource = getPossibleRepresents(graph); - if(resource == null) { - String uri = getPossiblePropertyValue(graph, "typeURI"); - if(uri != null) return graph.syncRequest(new PossibleResource(uri), TransientCacheAsyncListener.instance()); + 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); + } + + @Override + public Resource getPossibleType(ReadGraph graph) throws DatabaseException { + try { + Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, Layer0.getInstance(graph).Entity, getPossibleTypeFunction(graph)); + if (typeFromFunction != null) + return typeFromFunction; + } catch (DatabaseException t) { + return null; + } + + 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 typeFromFunction = getTypeFromPossibleTypeFunction(graph, baseType, getPossibleTypeFunction(graph)); + if (typeFromFunction != null) + return typeFromFunction; + 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()); + 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 { + @Override + public Resource getPossibleType(ReadGraph graph, Resource baseType) throws DatabaseException { + try { + Resource typeFromFunction = getTypeFromPossibleTypeFunction(graph, baseType, getPossibleTypeFunction(graph)); + if (typeFromFunction != null) + return typeFromFunction; + } catch (DatabaseException t) { + return null; + } + 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; - } + 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); - } + } + + private Resource getTypeFromPossibleTypeFunction(ReadGraph graph, Resource baseType, + Function2 fn) throws DatabaseException { + if (fn == null) + // Type function was not defined - return nothing + return null; + + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.put("graph", graph); + try { + return (Resource) fn.apply(this, baseType); + } catch (Throwable t) { + if (t instanceof DatabaseException) + throw (DatabaseException) t; + throw new DatabaseException(t); + } finally { + sclContext.put("graph", oldGraph); + } + } + + @SuppressWarnings("unchecked") + private Function2 getPossibleTypeFunction(ReadGraph graph) throws DatabaseException { + Variable custom = getPossibleProperty(graph, "typeResource"); + return custom != null + ? (Function2) custom.getPossibleValue(graph) + : null; + } public Map collectDomainProperties(ReadGraph graph, String classification, Map map) throws DatabaseException { Map all = collectDomainProperties(graph, null);