1 package org.simantics.db.layer0.variable;
3 import org.simantics.databoard.Bindings;
4 import org.simantics.databoard.Databoard;
5 import org.simantics.databoard.binding.Binding;
6 import org.simantics.datatypes.literal.GUID;
7 import org.simantics.db.ReadGraph;
8 import org.simantics.db.Resource;
9 import org.simantics.db.exception.DatabaseException;
10 import org.simantics.db.layer0.exception.MissingVariableException;
11 import org.simantics.db.layer0.request.VariablePossibleRVIRequest;
12 import org.simantics.db.layer0.request.VariableRVIRequest;
13 import org.simantics.db.layer0.variable.RVI.GuidRVIPart;
14 import org.simantics.db.layer0.variable.RVI.RVIPart;
15 import org.simantics.db.layer0.variable.RVI.ResourceRVIPart;
16 import org.simantics.db.layer0.variable.RVI.StringRVIPart;
17 import org.simantics.db.layer0.variable.Variables.Role;
18 import org.simantics.layer0.Layer0;
20 public class StandardRVIResolver implements RVIResolver {
22 public static final StandardRVIResolver INSTANCE = new StandardRVIResolver();
24 protected RVIPart getRVIPart(ReadGraph graph, Variable variable) throws DatabaseException {
25 if(variable instanceof AbstractVariable) {
26 AbstractVariable abst = (AbstractVariable)variable;
27 return abst.getRVIPart(graph);
29 Role role = variable.getRole(graph);
30 return new StringRVIPart(role, variable.getName(graph));
34 public RVI getRVI(ReadGraph graph, Variable variable) throws DatabaseException {
35 if(Variables.isContext(graph, variable)) {
36 Databoard databoard = graph.getService( Databoard.class );
37 Binding rviBinding = databoard.getBindingUnchecked( RVI.class );
38 return RVI.empty( rviBinding );
40 Variable parent = variable.getParent(graph);
42 // TODO: consider using a more suitable exception here to better convey the situation.
43 throw new MissingVariableException("no parent for variable " + variable + " (URI=" + variable.getURI(graph) + ")");
44 RVI base = graph.syncRequest(new VariableRVIRequest(parent));
45 RVIPart part = getRVIPart(graph, variable);
46 return new RVIBuilder(base).append(part).toRVI();
51 public RVI getPossibleRVI(ReadGraph graph, Variable variable) throws DatabaseException {
52 if(Variables.isContext(graph, variable)) {
53 Databoard databoard = graph.getService( Databoard.class );
54 Binding rviBinding = databoard.getBindingUnchecked( RVI.class );
55 return RVI.empty( rviBinding );
57 Variable parent = variable.getParent(graph);
58 if (parent == null) return null;
59 RVI base = graph.syncRequest(new VariablePossibleRVIRequest(parent));
60 if (base == null) return null;
61 RVIPart part = getRVIPart(graph, variable);
62 return new RVIBuilder(base).append(part).toRVI();
66 protected Variable resolveChild(ReadGraph graph, Variable variable, Resource resource) throws DatabaseException {
67 String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING);
68 return variable.getChild(graph, rName);
71 protected Variable resolveProperty(ReadGraph graph, Variable variable, Resource resource) throws DatabaseException {
72 String rName = graph.getRelatedValue(resource, Layer0.getInstance(graph).HasName, Bindings.STRING);
73 return variable.getProperty(graph, rName);
76 protected Variable resolveChild(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException {
77 return resolveChildDefault(graph, variable, part);
80 protected Variable resolveProperty(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException {
81 return resolvePropertyDefault(graph, variable, part);
84 public static Variable resolveChildDefault(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException {
85 Layer0 L0 = Layer0.getInstance(graph);
86 for(Variable child : variable.getChildren(graph)) {
87 GUID id = child.getPossiblePropertyValue(graph, L0.identifier, GUID.BINDING);
89 if(id.mostSignificant == part.mostSignificant && id.leastSignificant == part.leastSignificant)
93 throw new DatabaseException("Could not resolve child " + part);
96 public static Variable resolvePropertyDefault(ReadGraph graph, Variable variable, GuidRVIPart part) throws DatabaseException {
97 Layer0 L0 = Layer0.getInstance(graph);
98 for(Variable child : variable.getProperties(graph)) {
99 GUID id = child.getPossiblePropertyValue(graph, L0.identifier, GUID.BINDING);
101 if(id.mostSignificant == part.mostSignificant && id.leastSignificant == part.leastSignificant)
105 throw new DatabaseException("Could not resolve property " + part);
109 public Variable getVariable(ReadGraph graph, Variable context, RVIPart part) throws DatabaseException {
110 if(part instanceof StringRVIPart) {
111 StringRVIPart srp = (StringRVIPart)part;
112 if(Role.CHILD.equals(srp.getRole())) return context.getChild(graph, srp.string);
113 else if(Role.PROPERTY.equals(srp.getRole())) return context.getProperty(graph, srp.string);
114 } else if(part instanceof ResourceRVIPart) {
115 ResourceRVIPart rrp = (ResourceRVIPart)part;
116 if(Role.CHILD.equals(rrp.getRole())) return resolveChild(graph, context, rrp.resource);
117 else if(Role.PROPERTY.equals(rrp.getRole())) return resolveProperty(graph, context, rrp.resource);
118 } else if(part instanceof GuidRVIPart) {
119 GuidRVIPart grp = (GuidRVIPart)part;
120 if(Role.CHILD.equals(grp.getRole())) return resolveChild(graph, context, grp);
121 else if(Role.PROPERTY.equals(grp.getRole())) return resolveProperty(graph, context, grp);
123 throw new DatabaseException("Unrecognized RVIPart: " + part);