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