1 package org.simantics.db.layer0.util;
3 import java.util.Collection;
5 import org.simantics.db.ReadGraph;
6 import org.simantics.db.Resource;
7 import org.simantics.db.common.request.BinaryRead;
8 import org.simantics.db.common.request.ObjectsWithType;
9 import org.simantics.db.common.request.ParametrizedPrimitiveRead;
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.layer0.Layer0;
15 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
16 import org.simantics.scl.compiler.module.repository.ImportFailureException;
17 import org.simantics.scl.compiler.module.repository.UpdateListener;
18 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
19 import org.simantics.scl.osgi.SCLOsgi;
20 import org.simantics.scl.runtime.SCLContext;
23 * Finds the runtime environment of a model or other index root.
25 * @author Hannu Niemistö
26 * @author Antti Villberg
28 * Difference between this class and {@code RuntimeEnvironmentRequest} is an additional parameter
29 * that is typically some component type. All modules under this resource are added to the environment
30 * in addition to the SCLMain of the root resource.
32 public class RuntimeEnvironmentRequest2 extends BinaryRead<Resource, Resource, RuntimeEnvironment> {
34 public RuntimeEnvironmentRequest2(Resource componentType, Resource indexRoot) {
35 super(componentType, indexRoot);
38 protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
41 static class UpdateListenerImpl extends UpdateListener {
43 final EnvironmentSpecification environmentSpecification;
44 final Listener<RuntimeEnvironment> callback;
46 UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
47 this.environmentSpecification = environmentSpecification;
48 this.callback = callback;
52 public void notifyAboutUpdate() {
53 if(callback.isDisposed()) {
57 getRuntimeEnvironment(environmentSpecification, callback, this);
61 public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
65 SCLContext context = SCLContext.getCurrent();
67 RuntimeEnvironment env;
68 Object graph = context.get("graph");
71 env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
73 public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
75 SCLContext sclContext = SCLContext.getCurrent();
76 Object oldGraph = sclContext.get("graph");
78 sclContext.put("graph", graph);
79 return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
80 environmentSpecification,
81 callback.getClass().getClassLoader(), listener);
82 } catch (ImportFailureException e) {
83 throw new DatabaseException(e);
84 } catch (Throwable t) {
85 throw new DatabaseException(t);
87 sclContext.put("graph", oldGraph);
91 } catch (DatabaseException e) {
92 callback.exception(e);
96 env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
97 environmentSpecification,
98 callback.getClass().getClassLoader(), listener);
99 callback.execute(env);
100 } catch (ImportFailureException e) {
101 callback.exception(new DatabaseException(e));
107 public RuntimeEnvironment perform(ReadGraph graph)
108 throws DatabaseException {
109 final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
111 "StandardLibrary", "",
112 "Simantics/All", "");
113 fillEnvironmentSpecification(environmentSpecification);
115 Layer0 L0 = Layer0.getInstance(graph);
116 if (parameter != null) {
117 Collection<Resource> sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule));
118 for (Resource sclModule : sclModules) {
119 environmentSpecification.importModule(graph.getURI(sclModule), "");
122 // `parameter` is optional and can be null for e.g. procedural user components
125 Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter2, "SCLMain");
126 if(mainModule != null)
127 environmentSpecification.importModule(graph.getURI(mainModule), "");
129 return graph.syncRequest(new ParametrizedPrimitiveRead<EnvironmentSpecification, RuntimeEnvironment>(environmentSpecification) {
131 UpdateListenerImpl sclListener;
134 public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
136 SCLContext context = SCLContext.getCurrent();
137 Object oldGraph = context.put("graph", graph);
140 if(procedure.isDisposed()) {
141 getRuntimeEnvironment(parameter, procedure, null);
143 sclListener = new UpdateListenerImpl(parameter, procedure);
144 sclListener.notifyAboutUpdate();
148 context.put("graph", oldGraph);
154 public void unregistered() {
155 if(sclListener != null)
156 sclListener.stopListening();
163 public int hashCode() {
164 return 31*getClass().hashCode() + super.hashCode();