1 package org.simantics.db.layer0.util;
\r
3 import java.util.HashMap;
\r
4 import java.util.Map;
\r
6 import org.simantics.db.ReadGraph;
\r
7 import org.simantics.db.Resource;
\r
8 import org.simantics.db.common.request.ParametrizedPrimitiveRead;
\r
9 import org.simantics.db.common.request.UnaryRead;
\r
10 import org.simantics.db.exception.DatabaseException;
\r
11 import org.simantics.db.layer0.internal.SimanticsInternal;
\r
12 import org.simantics.db.procedure.Listener;
\r
13 import org.simantics.db.request.Read;
\r
14 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
\r
15 import org.simantics.scl.compiler.module.repository.ImportFailureException;
\r
16 import org.simantics.scl.compiler.module.repository.UpdateListener;
\r
17 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
\r
18 import org.simantics.scl.osgi.SCLOsgi;
\r
19 import org.simantics.scl.runtime.SCLContext;
\r
22 * Finds the runtime environment of a model or other index root.
\r
24 * @author Hannu Niemistö
\r
25 * @author Antti Villberg
\r
27 public class RuntimeEnvironmentRequest extends UnaryRead<Resource, RuntimeEnvironment> {
\r
29 public RuntimeEnvironmentRequest(Resource parameter) {
\r
33 protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
\r
36 static class UpdateListenerImpl implements UpdateListener {
\r
38 final EnvironmentSpecification environmentSpecification;
\r
39 final Listener<RuntimeEnvironment> callback;
\r
41 UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
\r
42 this.environmentSpecification = environmentSpecification;
\r
43 this.callback = callback;
\r
47 public void notifyAboutUpdate() {
\r
48 if(callback.isDisposed()) {
\r
51 getRuntimeEnvironment(environmentSpecification, callback, this);
\r
54 final public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
\r
58 SCLContext context = SCLContext.getCurrent();
\r
60 RuntimeEnvironment env;
\r
61 Object graph = context.get("graph");
\r
64 env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
\r
66 public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
\r
68 SCLContext sclContext = SCLContext.getCurrent();
\r
69 Object oldGraph = sclContext.get("graph");
\r
71 sclContext.put("graph", graph);
\r
72 return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
\r
73 environmentSpecification,
\r
74 callback.getClass().getClassLoader(), listener);
\r
75 } catch (ImportFailureException e) {
\r
76 throw new DatabaseException(e);
\r
77 } catch (Throwable t) {
\r
78 throw new DatabaseException(t);
\r
80 sclContext.put("graph", oldGraph);
\r
84 } catch (DatabaseException e) {
\r
85 callback.exception(e);
\r
89 env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
\r
90 environmentSpecification,
\r
91 callback.getClass().getClassLoader(), listener);
\r
92 callback.execute(env);
\r
93 } catch (ImportFailureException e) {
\r
94 callback.exception(new DatabaseException(e));
\r
101 // This is needed to prevent garbage collection from collecting UpdateListenerImpls
\r
102 // -ModuleRepository only makes a weak reference to the listener
\r
103 final static Map<String, UpdateListenerImpl> map = new HashMap<String, UpdateListenerImpl>();
\r
106 public RuntimeEnvironment perform(ReadGraph graph)
\r
107 throws DatabaseException {
\r
108 final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
\r
111 "Simantics/All", "");
\r
112 fillEnvironmentSpecification(environmentSpecification);
\r
113 Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter, "SCLMain");
\r
114 String mainModuleUri;
\r
115 if(mainModule != null) {
\r
116 mainModuleUri = graph.getURI(mainModule);
\r
117 environmentSpecification.importModule(mainModuleUri, "");
\r
120 mainModuleUri = graph.getURI(parameter) + "/#"; // Add something dummy to the model uri that cannot be in a real URI
\r
122 return graph.syncRequest(new ParametrizedPrimitiveRead<String, RuntimeEnvironment>(mainModuleUri) {
\r
125 public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
\r
127 SCLContext context = SCLContext.getCurrent();
\r
128 Object oldGraph = context.put("graph", graph);
\r
131 if(procedure.isDisposed()) {
\r
132 UpdateListenerImpl.getRuntimeEnvironment(environmentSpecification, procedure, null);
\r
134 UpdateListenerImpl impl = new UpdateListenerImpl(environmentSpecification, procedure);
\r
135 impl.notifyAboutUpdate();
\r
136 map.put(parameter, impl);
\r
140 context.put("graph", oldGraph);
\r
146 public void unregistered() {
\r
147 map.remove(parameter);
\r
154 public int hashCode() {
\r
155 return 31*getClass().hashCode() + super.hashCode();
\r
158 public static void flush() {
\r