package org.simantics.db.layer0.variable; import org.simantics.databoard.Bindings; import org.simantics.databoard.Databoard; import org.simantics.databoard.binding.Binding; import org.simantics.datatypes.literal.GUID; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.exception.MissingVariableException; import org.simantics.db.layer0.request.VariablePossibleRVIRequest; 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; public class StandardRVIResolver implements RVIResolver { public static final StandardRVIResolver INSTANCE = new StandardRVIResolver(); protected RVIPart getRVIPart(ReadGraph graph, Variable variable) throws DatabaseException { if(variable instanceof AbstractVariable) { AbstractVariable abst = (AbstractVariable)variable; return abst.getRVIPart(graph); } Role role = variable.getRole(graph); return new StringRVIPart(role, variable.getName(graph)); } @Override public RVI getRVI(ReadGraph graph, Variable variable) throws DatabaseException { if(Variables.isContext(graph, variable)) { Databoard databoard = graph.getService( Databoard.class ); Binding rviBinding = databoard.getBindingUnchecked( RVI.class ); return RVI.empty( rviBinding ); } else { Variable parent = variable.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 " + variable + " (URI=" + variable.getURI(graph) + ")", variable.getPossibleRepresents(graph)); RVI base = graph.syncRequest(new VariableRVIRequest(parent)); RVIPart part = getRVIPart(graph, variable); return new RVIBuilder(base).append(part).toRVI(); } } @Override public RVI getPossibleRVI(ReadGraph graph, Variable variable) throws DatabaseException { if(Variables.isContext(graph, variable)) { Databoard databoard = graph.getService( Databoard.class ); Binding rviBinding = databoard.getBindingUnchecked( RVI.class ); return RVI.empty( rviBinding ); } else { Variable parent = variable.getParent(graph); if (parent == null) return null; RVI base = graph.syncRequest(new VariablePossibleRVIRequest(parent)); if (base == null) return null; RVIPart part = getRVIPart(graph, variable); return new RVIBuilder(base).append(part).toRVI(); } } protected Variable resolveChild(ReadGraph graph, Variable variable, Resource resource) throws DatabaseException { String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); return variable.getChild(graph, rName); } protected Variable resolveProperty(ReadGraph graph, Variable variable, Resource resource) throws DatabaseException { String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING); return variable.getProperty(graph, rName); } protected Variable resolveChild(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException { return resolveChildDefault(graph, variable, part); } protected Variable resolveProperty(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException { return resolvePropertyDefault(graph, variable, part); } public static Variable resolveChildDefault(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for(Variable child : variable.getChildren(graph)) { GUID id = child.getPossiblePropertyValue(graph, L0.identifier, GUID.BINDING); if(id != null) { if(id.mostSignificant == part.mostSignificant && id.leastSignificant == part.leastSignificant) return child; } } throw new MissingVariableException("Could not resolve child " + part, variable.getPossibleRepresents(graph)); } public static Variable resolvePropertyDefault(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); for(Variable child : variable.getProperties(graph)) { GUID id = child.getPossiblePropertyValue(graph, L0.identifier, GUID.BINDING); if(id != null) { if(id.mostSignificant == part.mostSignificant && id.leastSignificant == part.leastSignificant) return child; } } throw new MissingVariableException("Could not resolve property " + part, variable.getPossibleRepresents(graph)); } @Override public Variable getVariable(ReadGraph graph, Variable context, RVIPart part) throws DatabaseException { if(part instanceof StringRVIPart) { StringRVIPart srp = (StringRVIPart)part; if(Role.CHILD.equals(srp.getRole())) return context.getChild(graph, srp.string); else if(Role.PROPERTY.equals(srp.getRole())) return context.getProperty(graph, srp.string); } else if(part instanceof ResourceRVIPart) { ResourceRVIPart rrp = (ResourceRVIPart)part; if(Role.CHILD.equals(rrp.getRole())) return resolveChild(graph, context, rrp.resource); else if(Role.PROPERTY.equals(rrp.getRole())) return resolveProperty(graph, context, rrp.resource); } else if(part instanceof GuidRVIPart) { GuidRVIPart grp = (GuidRVIPart)part; if(Role.CHILD.equals(grp.getRole())) return resolveChild(graph, context, grp); else if(Role.PROPERTY.equals(grp.getRole())) return resolveProperty(graph, context, grp); } throw new MissingVariableException("Unrecognized RVIPart: " + part, context.getPossibleRepresents(graph)); } }