--- /dev/null
+package org.simantics.scenegraph.loader;\r
+\r
+import java.util.Set;\r
+\r
+import org.simantics.Simantics;\r
+import org.simantics.db.Disposable;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.primitiverequest.PossibleResource;\r
+import org.simantics.db.common.procedure.adapter.ListenerSupport;\r
+import org.simantics.db.common.request.TernaryRead;\r
+import org.simantics.db.common.request.UnaryRead;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.request.ResourceVariable;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.VariableRepository;\r
+import org.simantics.scenegraph.INode;\r
+import org.simantics.scenegraph.ParentNode;\r
+import org.simantics.utils.datastructures.Pair;\r
+\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+public class ScenegraphLoaderProcess implements Disposable, ListenerSupport {\r
+\r
+ final private String name;\r
+ final Class<?> loaderClass;\r
+\r
+ protected INode root;\r
+\r
+ private boolean disposed = false;\r
+ \r
+ final protected Set<String> registeredURIs = new THashSet<String>();\r
+ \r
+ public ScenegraphLoaderProcess(String name) {\r
+ this(null, ScenegraphLoader.class, name);\r
+ }\r
+\r
+ public ScenegraphLoaderProcess(INode root, String name) {\r
+ this(root, ScenegraphLoader.class, name);\r
+ }\r
+ \r
+ public ScenegraphLoaderProcess(INode root, Class<?> loaderClass, String name) {\r
+ this.root = root;\r
+ this.loaderClass = loaderClass;\r
+ this.name = name;\r
+ //System.out.println("NEW ScenegraphLoaderProcess(" + name + "): " + this);\r
+ //new Exception("NEW ScenegraphLoaderProcess(" + name + "): " + this).printStackTrace();\r
+ }\r
+\r
+ public INode getRoot() {\r
+ return root;\r
+ }\r
+ \r
+ @Override\r
+ public String toString() {\r
+ return name;\r
+ }\r
+\r
+ protected void initialize(RequestProcessor processor, Variable configuration) throws DatabaseException {\r
+ \r
+ }\r
+ \r
+ final public <N extends ParentNode<?>> N load(final String curi, final Resource runtime) throws DatabaseException {\r
+ return load(Simantics.getSession(), curi, runtime);\r
+ }\r
+\r
+ final public <N extends ParentNode<?>> N load(RequestProcessor processor, final String curi, final Resource runtime) throws DatabaseException {\r
+ Resource resource = processor.sync(new PossibleResource(curi));\r
+ if(resource == null) throw new IllegalArgumentException("The given URI is invalid: " + curi);\r
+ return load(processor, resource, runtime);\r
+ }\r
+\r
+ final public <N extends ParentNode<?>> N load(Resource configuration, Resource runtime) throws DatabaseException {\r
+ return load(Simantics.getSession(), configuration, runtime);\r
+ }\r
+\r
+ final public <N extends ParentNode<?>> N load(RequestProcessor processor, Resource configuration, Resource runtime) throws DatabaseException {\r
+ N root = (N)getRoot();\r
+ return load(processor, getVariable(processor, this, configuration, runtime, root));\r
+ }\r
+ \r
+ final public Variable getVariable(RequestProcessor processor, String curi, Resource runtime) throws DatabaseException {\r
+ Resource resource = processor.sync(new PossibleResource(curi));\r
+ if(resource == null) throw new IllegalArgumentException("The given URI is invalid: " + curi);\r
+ return getVariable(processor, this, resource, runtime, root);\r
+ }\r
+ \r
+ final static public Variable getVariable(RequestProcessor processor, final ScenegraphLoaderProcess process, final Resource configuration, final Resource runtime, final INode root) throws DatabaseException {\r
+ \r
+ assert(root != null);\r
+\r
+ Pair<Variable,String> result = processor.sync(new TernaryRead<INode, Resource, Resource, Pair<Variable,String>>(root, runtime, configuration) {\r
+\r
+ @Override\r
+ public Pair<Variable,String> perform(ReadGraph graph) throws DatabaseException {\r
+ Variable conf = graph.sync(new ResourceVariable(parameter3));\r
+ Variable result = new ScenegraphVariable(conf, parameter3, parameter2, parameter);\r
+ return Pair.make(result, result.getURI(graph));\r
+ }\r
+ \r
+ });\r
+\r
+ VariableRepository.register(result.second, result.first);\r
+ if(process != null) process.registeredURIs.add(result.second);\r
+ return result.first;\r
+ \r
+ }\r
+ \r
+ final public <N extends ParentNode<?>> N load(RequestProcessor processor, final Variable configuration) throws DatabaseException {\r
+ \r
+ initialize(processor, configuration);\r
+ N root = (N)getRoot();\r
+ load(processor, configuration, root);\r
+ return root;\r
+ \r
+ }\r
+\r
+ <T extends ScenegraphLoader> Class<T> getLoaderClass() {\r
+ return (Class<T>)ScenegraphLoader.class;\r
+ }\r
+ \r
+ protected ScenegraphLoader getLoader(RequestProcessor processor, Variable configuration) throws DatabaseException {\r
+ \r
+ return processor.sync(new UnaryRead<Variable, ScenegraphLoader>(configuration) {\r
+\r
+ @Override\r
+ public ScenegraphLoader perform(ReadGraph graph) throws DatabaseException {\r
+ return parameter.adapt(graph, getLoaderClass());\r
+ }\r
+\r
+ });\r
+ }\r
+ \r
+ @SuppressWarnings("unchecked")\r
+ final private INode load(RequestProcessor processor, Variable configuration, ParentNode<?> current) throws DatabaseException {\r
+ \r
+ ScenegraphLoader loader = getLoader(processor, configuration);\r
+ \r
+ INode node = loader.create(processor, this, current, configuration);\r
+ if(node instanceof ParentNode) {\r
+ \r
+ for(Variable child : ScenegraphLoaderUtils.getChildren(processor, configuration)) {\r
+ load(processor, child, (ParentNode<INode>)node);\r
+ }\r
+ \r
+ }\r
+ \r
+ return node;\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void exception(Throwable t) {\r
+ Logger.defaultLogError(t);\r
+ }\r
+\r
+ @Override\r
+ public boolean isDisposed() {\r
+ return disposed;\r
+ }\r
+\r
+ @Override\r
+ public void dispose() {\r
+ //System.out.println("DISPOSE ScenegraphLoaderProcess(" + name + "): " + this);\r
+ //new Exception("DISPOSED ScenegraphLoaderProcess(" + name + "): " + this).printStackTrace();\r
+ disposed = true;\r
+ }\r
+ \r
+}\r