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