1 package org.simantics.db.common.request;
3 import org.simantics.db.ReadGraph;
4 import org.simantics.db.Resource;
5 import org.simantics.db.common.SimanticsInternal;
6 import org.simantics.db.common.utils.CommonDBUtils;
7 import org.simantics.db.exception.DatabaseException;
8 import org.simantics.db.procedure.Listener;
9 import org.simantics.db.request.Read;
10 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
11 import org.simantics.scl.compiler.module.repository.ImportFailureException;
12 import org.simantics.scl.compiler.module.repository.UpdateListener;
13 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
14 import org.simantics.scl.osgi.SCLOsgi;
15 import org.simantics.scl.runtime.SCLContext;
18 * Finds the runtime environment of a model or other index root.
20 * @author Hannu Niemistö
21 * @author Antti Villberg
23 public class RuntimeEnvironmentRequest extends UnaryRead<Resource, RuntimeEnvironment> {
25 public RuntimeEnvironmentRequest(Resource parameter) {
29 protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
32 static class UpdateListenerImpl extends UpdateListener {
34 final EnvironmentSpecification environmentSpecification;
35 final Listener<RuntimeEnvironment> callback;
37 UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
38 this.environmentSpecification = environmentSpecification;
39 this.callback = callback;
43 public void notifyAboutUpdate() {
44 if(callback.isDisposed()) {
48 getRuntimeEnvironment(environmentSpecification, callback, this);
52 public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
56 SCLContext context = SCLContext.getCurrent();
58 RuntimeEnvironment env;
59 Object graph = context.get("graph");
62 env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
64 public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
66 SCLContext sclContext = SCLContext.getCurrent();
67 Object oldGraph = sclContext.get("graph");
69 sclContext.put("graph", graph);
70 return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
71 environmentSpecification,
72 callback.getClass().getClassLoader(), listener);
73 } catch (ImportFailureException e) {
74 throw new DatabaseException(e);
75 } catch (Throwable t) {
76 throw new DatabaseException(t);
78 sclContext.put("graph", oldGraph);
82 } catch (DatabaseException e) {
83 callback.exception(e);
87 env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
88 environmentSpecification,
89 callback.getClass().getClassLoader(), listener);
90 callback.execute(env);
91 } catch (ImportFailureException e) {
92 callback.exception(new DatabaseException(e));
98 public RuntimeEnvironment perform(ReadGraph graph)
99 throws DatabaseException {
100 final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
102 "StandardLibrary", "",
103 "Simantics/All", "");
104 fillEnvironmentSpecification(environmentSpecification);
106 Resource mainModule = CommonDBUtils.getPossibleChild(graph, parameter, "SCLMain");
107 String mainModuleUri;
108 if(mainModule != null) {
109 mainModuleUri = graph.getURI(mainModule);
110 environmentSpecification.importModule(mainModuleUri, "");
113 mainModuleUri = graph.getURI(parameter) + "/#"; // Add something dummy to the model uri that cannot be in a real URI
115 return graph.syncRequest(new ParametrizedPrimitiveRead<String, RuntimeEnvironment>(mainModuleUri) {
117 UpdateListenerImpl sclListener;
120 public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
122 SCLContext context = SCLContext.getCurrent();
123 Object oldGraph = context.put("graph", graph);
126 if(procedure.isDisposed()) {
127 getRuntimeEnvironment(environmentSpecification, procedure, null);
129 sclListener = new UpdateListenerImpl(environmentSpecification, procedure);
130 sclListener.notifyAboutUpdate();
134 context.put("graph", oldGraph);
140 public void unregistered() {
141 if(sclListener != null)
142 sclListener.stopListening();
149 public int hashCode() {
150 return 31*getClass().hashCode() + super.hashCode();