1 package org.simantics.scenegraph.loader;
3 import gnu.trove.map.hash.THashMap;
5 import java.util.Collection;
6 import java.util.Collections;
9 import org.simantics.databoard.Bindings;
10 import org.simantics.databoard.binding.mutable.Variant;
11 import org.simantics.databoard.util.ObjectUtils;
12 import org.simantics.db.ReadGraph;
13 import org.simantics.db.Resource;
14 import org.simantics.db.exception.DatabaseException;
15 import org.simantics.db.layer0.variable.ConstantPropertyVariable;
16 import org.simantics.db.layer0.variable.StandardGraphChildVariable;
17 import org.simantics.db.layer0.variable.Variable;
18 import org.simantics.db.layer0.variable.Variables;
19 import org.simantics.scenegraph.INode;
21 public class ScenegraphVariable extends StandardGraphChildVariable {
23 final private SceneGraphContext context;
24 final private Map<String, Variant> originalProperties;
25 final private Map<String, Variable> properties;
27 public ScenegraphVariable(Variable parent, Resource resource, final Resource runtime, final INode root) {
28 this(parent, resource, runtime, root, Collections.<String, Variant>emptyMap());
31 public static class SceneGraphContextImpl implements SceneGraphContext {
33 final private ScenegraphVariable parent;
34 final private Resource runtime;
35 final private INode root;
37 public SceneGraphContextImpl(ScenegraphVariable parent, Resource runtime, INode root) {
40 this.runtime = runtime;
45 public INode getRoot() {
50 public Resource getRuntime() {
55 public Variable getRuntimeVariable() {
56 return new ScenegraphVariable(parent, runtime, runtime, root, parent.originalProperties);
60 public int hashCode() {
62 return runtime.hashCode() ^ ObjectUtils.hashCode(root);
67 public boolean equals(Object obj) {
69 if(this == obj) return true;
71 SceneGraphContextImpl other = (SceneGraphContextImpl)obj;
73 if(!runtime.equals(other.runtime)) return false;
74 if(!ObjectUtils.objectEquals(root, other.root)) return false;
83 public ScenegraphVariable(Variable parent, Resource resource, final Resource runtime, final INode root, final Map<String, Variant> properties) {
85 super(parent, null, resource);
88 this.context = new SceneGraphContextImpl(this, runtime, root);
92 this.originalProperties = properties;
93 if(properties.isEmpty()) this.properties = Collections.<String, Variable>emptyMap();
95 this.properties = new THashMap<String, Variable>();
96 for(Map.Entry<String, Variant> p : properties.entrySet()) {
97 this.properties.put(p.getKey(), new ConstantPropertyVariable(parent, p.getKey(), p.getValue().getValue(), p.getValue().getBinding()));
104 public String getName(ReadGraph graph) throws DatabaseException {
105 if(parent instanceof ScenegraphVariable) {
106 return super.getName(graph);
108 return "" + System.identityHashCode(this);
113 public Variable getNameVariable(ReadGraph graph) throws DatabaseException {
114 if(parent instanceof ScenegraphVariable) {
115 return super.getNameVariable(graph);
117 return new ConstantPropertyVariable(parent, Variables.NAME, "" + System.identityHashCode(this), Bindings.STRING);
121 protected <T> T tryAdapt(ReadGraph graph, Class<T> clazz) throws DatabaseException {
122 if(SceneGraphContext.class == clazz) return (T)context;
123 else if(INode.class == clazz) return (T)context.getRoot();
128 public <T> T adapt(ReadGraph graph, Class<T> clazz) throws DatabaseException {
129 T t = tryAdapt(graph, clazz);
130 return t != null ? t : super.adapt(graph, clazz);
134 public <T> T adaptPossible(ReadGraph graph, Class<T> clazz) throws DatabaseException {
135 T t = tryAdapt(graph, clazz);
136 return t != null ? t : super.adaptPossible(graph, clazz);
140 public boolean equals(Object obj) {
143 if(!super.equals(obj)) return false;
145 ScenegraphVariable other = (ScenegraphVariable)obj;
146 SceneGraphContext otherContext = other.context;
148 return ObjectUtils.objectEquals(context, otherContext);
153 public int hashCode() {
154 int s = super.hashCode();
155 if(context != null) s ^= context.getRuntime().hashCode();
160 public Collection<Variable> getChildren(ReadGraph graph) throws DatabaseException {
161 return ScenegraphLoaderUtils.computeChildren(graph, this);
165 public Variable getPossibleChild(ReadGraph graph, String name) throws DatabaseException {
166 for(Variable child : getChildren(graph)) {
167 if(child.getName(graph).equals(name)) return child;
173 public void collectExtraProperties(ReadGraph graph, Map<String, Variable> properties) throws DatabaseException {
174 properties.putAll(this.properties);
178 public Variable getPossibleExtraProperty(ReadGraph graph, String name) throws DatabaseException {
179 return properties.get(name);