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.common.utils.CommonDBUtils;
11 import org.simantics.db.exception.DatabaseException;
12 import org.simantics.db.layer0.internal.SimanticsInternal;
13 import org.simantics.db.procedure.Listener;
14 import org.simantics.db.request.Read;
15 import org.simantics.layer0.Layer0;
16 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
17 import org.simantics.scl.compiler.module.repository.ImportFailureException;
18 import org.simantics.scl.compiler.module.repository.UpdateListener;
19 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
20 import org.simantics.scl.osgi.SCLOsgi;
21 import org.simantics.scl.runtime.SCLContext;
24 * Finds the runtime environment of a model or other index root.
26 * @author Hannu Niemistö
27 * @author Antti Villberg
29 * Difference between this class and {@code RuntimeEnvironmentRequest} is an additional parameter
30 * that is typically some component type. All modules under this resource are added to the environment
31 * in addition to the SCLMain of the root resource.
33 public class RuntimeEnvironmentRequest2 extends BinaryRead<Resource, Resource, RuntimeEnvironment> {
35 public RuntimeEnvironmentRequest2(Resource componentType, Resource indexRoot) {
36 super(componentType, indexRoot);
39 protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
42 static class UpdateListenerImpl extends UpdateListener {
44 final EnvironmentSpecification environmentSpecification;
45 final Listener<RuntimeEnvironment> callback;
47 UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
48 this.environmentSpecification = environmentSpecification;
49 this.callback = callback;
53 public void notifyAboutUpdate() {
54 if(callback.isDisposed()) {
58 getRuntimeEnvironment(environmentSpecification, callback, this);
62 public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
66 SCLContext context = SCLContext.getCurrent();
68 RuntimeEnvironment env;
69 Object graph = context.get("graph");
72 env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
74 public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
76 SCLContext sclContext = SCLContext.getCurrent();
77 Object oldGraph = sclContext.get("graph");
79 sclContext.put("graph", graph);
80 return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
81 environmentSpecification,
82 callback.getClass().getClassLoader(), listener);
83 } catch (ImportFailureException e) {
84 throw new DatabaseException(e);
85 } catch (Throwable t) {
86 throw new DatabaseException(t);
88 sclContext.put("graph", oldGraph);
92 } catch (DatabaseException e) {
93 callback.exception(e);
97 env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
98 environmentSpecification,
99 callback.getClass().getClassLoader(), listener);
100 callback.execute(env);
101 } catch (ImportFailureException e) {
102 callback.exception(new DatabaseException(e));
108 public RuntimeEnvironment perform(ReadGraph graph)
109 throws DatabaseException {
110 final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
112 "StandardLibrary", "",
113 "Simantics/All", "");
114 fillEnvironmentSpecification(environmentSpecification);
116 Layer0 L0 = Layer0.getInstance(graph);
117 if (parameter != null) {
118 Collection<Resource> sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule));
119 for (Resource sclModule : sclModules) {
120 environmentSpecification.importModule(graph.getURI(sclModule), "");
123 // `parameter` is optional and can be null for e.g. procedural user components
126 Resource mainModule = CommonDBUtils.getPossibleChild(graph, parameter2, "SCLMain");
127 if(mainModule != null) {
128 environmentSpecification.importModule(graph.getURI(mainModule), "");
129 for(Resource l : graph.getObjects(parameter2, L0.IsLinkedTo)) {
130 mainModule = CommonDBUtils.getPossibleChild(graph, l, "SCLMain");
131 if(mainModule != null)
132 environmentSpecification.importModule(graph.getURI(mainModule), "");
136 return graph.syncRequest(new ParametrizedPrimitiveRead<EnvironmentSpecification, RuntimeEnvironment>(environmentSpecification) {
138 UpdateListenerImpl sclListener;
141 public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
143 SCLContext context = SCLContext.getCurrent();
144 Object oldGraph = context.put("graph", graph);
147 if(procedure.isDisposed()) {
148 getRuntimeEnvironment(parameter, procedure, null);
150 sclListener = new UpdateListenerImpl(parameter, procedure);
151 sclListener.notifyAboutUpdate();
155 context.put("graph", oldGraph);
161 public void unregistered() {
162 if(sclListener != null)
163 sclListener.stopListening();
170 public int hashCode() {
171 return 31*getClass().hashCode() + super.hashCode();