1 package org.simantics.db.layer0.variable;
3 import java.util.Collection;
4 import java.util.Collections;
8 import org.simantics.databoard.Bindings;
9 import org.simantics.datatypes.literal.GUID;
10 import org.simantics.db.ReadGraph;
11 import org.simantics.db.Resource;
12 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
13 import org.simantics.db.exception.AssumptionException;
14 import org.simantics.db.exception.DatabaseException;
15 import org.simantics.db.layer0.exception.InvalidVariableException;
16 import org.simantics.db.layer0.function.All;
17 import org.simantics.db.layer0.request.ClassificationsRequest;
18 import org.simantics.db.layer0.request.VariableURI;
19 import org.simantics.db.layer0.variable.RVI.RVIPart;
20 import org.simantics.db.layer0.variable.RVI.ResourceRVIPart;
21 import org.simantics.db.layer0.variable.RVI.StringRVIPart;
22 import org.simantics.db.layer0.variable.Variables.Role;
23 import org.simantics.layer0.Layer0;
24 import org.simantics.simulator.variable.exceptions.NodeManagerException;
26 public class StandardGraphChildVariable extends AbstractChildVariable implements ProxyVariableSupport {
32 public Variable getPossibleSpecialChild(ReadGraph graph, String name) throws DatabaseException {
36 public Map<String, Variable> collectSpecialChildren(ReadGraph graph, Map<String, Variable> children) throws DatabaseException {
41 * Standard implementation
45 final protected Variable parent;
46 final public Resource resource;
48 transient private int hash;
50 public StandardGraphChildVariable(Variable parent, VariableNode node, Resource resource) {
53 this.resource = resource;
57 public void validate(ReadGraph graph) throws DatabaseException {
58 if(!graph.hasStatement(resource)) throw new InvalidVariableException("The resource has been removed: " + resource);
62 protected Variable getPossibleDomainProperty(ReadGraph graph, String name) throws DatabaseException {
63 VariableMap map = getPossiblePropertyVariableMap(graph);
64 if(map == null) return null;
66 return map.getVariable(graph, this, name);
67 } catch (DatabaseException e) {
73 public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
74 VariableMap map = getPossibleChildVariableMap(graph);
75 if(map == null) return getPossibleSpecialChild(graph, name);
77 Variable result = map.getVariable(graph, this, name);
78 if(result != null) return result;
79 else return getPossibleSpecialChild(graph, name);
80 } catch (DatabaseException e) {
86 public Map<String, Variable> collectDomainProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {
87 VariableMap map = getPossiblePropertyVariableMap(graph);
88 if(map == null) return properties;
89 return map.getVariables(graph, this, properties);
93 public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
94 Map<String, Variable> result = null;
95 VariableMap map = getPossibleChildVariableMap(graph);
96 if(map != null) result = map.getVariables(graph, this, result);
97 result = collectSpecialChildren(graph, result);
98 if(result == null) return Collections.emptyList();
99 else return result.values();
102 @SuppressWarnings("unchecked")
104 public String getName(ReadGraph graph) throws DatabaseException {
106 return node.support.manager.getName(node.node);
108 String unescapedName = graph.getPossibleRelatedValue(resource, graph.getService(Layer0.class).HasName, Bindings.STRING);
109 if(unescapedName == null) return VariableUtils.unnamedResourceName(resource);
110 return unescapedName;
114 public Variable getNameVariable(ReadGraph graph) throws DatabaseException {
115 Resource resource = (Resource) getPossibleRepresents(graph);
116 if (resource != null) {
117 return new StandardGraphPropertyVariable(graph, this, null, resource, Layer0.getInstance(graph).HasName);
119 return super.getNameVariable(graph);
124 public String getLabel(ReadGraph graph) throws DatabaseException {
125 if(resource == null) return getName(graph);
126 String label = graph.getPossibleRelatedValue2(resource, graph.getService(Layer0.class).HasLabel);
127 return label != null ? label : getName(graph);
131 final protected Variable getLabelVariable(ReadGraph graph) throws DatabaseException {
132 Layer0 L0 = Layer0.getInstance(graph);
133 if(resource == null) return null;
134 return new StandardGraphPropertyVariable(graph, this, L0.HasLabel);
138 // final public Object getSerialized(ReadGraph graph) throws DatabaseException {
139 // Resource represents = getRepresents(graph);
140 // if(represents != null) return represents;
141 // else return getName(graph);
145 public Variable getParent(ReadGraph graph) throws DatabaseException {
150 final public Resource getRepresents(ReadGraph graph) throws DatabaseException {
152 throw new InvalidVariableException("Variable is not represented by any resource (URI=" + getPossibleURI(graph) + ").");
154 // Layer0X L0X = Layer0X.getInstance(graph);
155 // Resource represents = graph.getPossibleObject(resource, L0X.Represents);
156 // if(represents != null) return represents;
157 // else return resource;
161 public Resource getPossibleRepresents(ReadGraph graph)
162 throws DatabaseException {
167 final public String getURI(ReadGraph graph) throws DatabaseException {
170 if(parent == null) return "http:/";
171 String parentURI = graph.syncRequest(new VariableURI(parent), TransientCacheAsyncListener.<String>instance());
172 return parentURI + Role.CHILD.getIdentifier() + encodeString(getName(graph));
173 } catch (AssumptionException e) {
174 throw new InvalidVariableException(e);
179 * All variables must have proper URIs, this is only for debugging purposes.
181 * @see org.simantics.db.layer0.variable.AbstractVariable#getPossibleURI(org.simantics.db.ReadGraph)
184 public String getPossibleURI(ReadGraph graph) throws DatabaseException {
186 return getURI(graph);
187 } catch (DatabaseException e) {
193 public int hashCode() {
195 final int prime = 31;
197 result = prime * result + (parent != null ? parent.hashCode() : 0);
198 result = prime * result + (node != null ? node.hashCode() : 0);
199 result = prime * result + (resource != null ? resource.hashCode() : 0);
206 public boolean equals(Object obj) {
211 if (getClass() != obj.getClass())
214 StandardGraphChildVariable other = (StandardGraphChildVariable) obj;
217 if(!node.equals(other.node)) return false;
218 } else if (other.node != null) return false;
220 if(resource != null) {
221 if(!resource.equals(other.resource)) return false;
222 } else if (other.resource != null) return false;
225 if(!parent.equals(other.parent)) return false;
226 } else if (other.parent != null) return false;
233 public <T> T adapt(ReadGraph graph, Class<T> clazz) throws DatabaseException {
234 return graph.adapt(resource, clazz);
238 public <T> T adaptPossible(ReadGraph graph, Class<T> clazz) throws DatabaseException {
239 return graph.getPossibleAdapter(resource, clazz);
243 public RVIPart getRVIPart(ReadGraph graph) throws DatabaseException {
244 if(resource == null) return new StringRVIPart(Role.CHILD, getName(graph));
245 Layer0 L0 = Layer0.getInstance(graph);
246 GUID id = graph.getPossibleRelatedValue(resource, L0.identifier, GUID.BINDING);
248 return new RVI.GuidRVIPart(Role.CHILD, resource, id.mostSignificant, id.leastSignificant);
250 return new ResourceRVIPart(Role.CHILD, resource);
253 public String getIdentifier() {
254 return getClass().getSimpleName() + "[" + resource + "]";
257 protected VariableMap getPossiblePropertyVariableMap(ReadGraph graph) throws DatabaseException {
258 if(resource == null) return All.standardChildDomainProperties;
259 Resource domainProperties = Layer0.getInstance(graph).domainProperties;
260 return graph.getPossibleRelatedValue2(resource, domainProperties,
261 new StandardGraphPropertyVariable(graph, this, domainProperties));
264 protected VariableMap getPossibleChildVariableMap(ReadGraph graph) throws DatabaseException {
265 if(resource == null) return All.standardChildDomainChildren;
266 Resource domainChildren = Layer0.getInstance(graph).domainChildren;
267 return graph.getPossibleRelatedValue2(resource, domainChildren,
268 new StandardGraphPropertyVariable(graph, this, domainChildren));
272 public Map<String, Variable> collectDomainProperties(ReadGraph graph, String classification, Map<String, Variable> properties) throws DatabaseException {
273 VariableMap valueMap = getPossiblePropertyVariableMap(graph);
274 if(valueMap == null) return properties;
275 return valueMap.getVariables(graph, this, classification, properties);
279 public Variable resolve(ReadGraph graph, RVIPart part) throws DatabaseException {
280 Resource represents = getPossibleRepresents(graph);
281 if (represents == null)
282 return StandardRVIResolver.INSTANCE.getVariable(graph, this, part);
283 RVIResolver resolver = graph.adapt(represents, RVIResolver.class);
284 return resolver.getVariable(graph, this, part);
288 public Variable resolvePossible(ReadGraph graph, RVIPart part) throws DatabaseException {
290 return resolve(graph, part);
291 } catch (DatabaseException e) {
296 @SuppressWarnings("unchecked")
297 public Set<String> getClassifications(ReadGraph graph) throws DatabaseException {
298 Resource represents = getPossibleRepresents(graph);
299 Set<String> result = (represents != null) ? graph.syncRequest(new ClassificationsRequest(graph.getPrincipalTypes(represents))) : Collections.<String>emptySet();
300 if (result.isEmpty()) {
301 Resource type = getPossibleType(graph);
302 if(type != null) result = graph.syncRequest(new ClassificationsRequest(Collections.singleton(type)));
304 if (result.isEmpty() && node != null) {
306 result = node.support.manager.getClassifications(node.node);
307 } catch(NodeManagerException e) {
308 throw new DatabaseException(e);
315 public RVI getRVI(ReadGraph graph) throws DatabaseException {
316 Resource represents = getPossibleRepresents(graph);
317 if (represents == null)
318 return StandardRVIResolver.INSTANCE.getRVI(graph, this);
319 RVIResolver resolver = graph.adapt(represents, RVIResolver.class);
320 return resolver.getRVI(graph, this);
324 public RVI getPossibleRVI(ReadGraph graph) throws DatabaseException {
325 Resource represents = getPossibleRepresents(graph);
326 if (represents == null)
327 return StandardRVIResolver.INSTANCE.getPossibleRVI(graph, this);
328 RVIResolver resolver = graph.getPossibleAdapter(represents, RVIResolver.class);
329 if(resolver == null) return null;
330 return resolver.getPossibleRVI(graph, this);
334 public Resource getPossiblePredicateResource(ReadGraph graph) throws DatabaseException {
339 public Variable attachTo(ReadGraph graph, Variable parent) {
340 return new StandardGraphChildVariable(parent, node, resource);
344 public Variable attachToRenamed(ReadGraph graph, Variable parent, String name) {
345 return new StandardGraphChildVariable(parent, node, resource) {
347 public String getName(ReadGraph graph) throws DatabaseException {