1 package org.simantics.db.layer0.util;
\r
3 import java.util.Collection;
\r
4 import java.util.HashMap;
\r
5 import java.util.Map;
\r
7 import org.simantics.db.ReadGraph;
\r
8 import org.simantics.db.Resource;
\r
9 import org.simantics.db.common.request.BinaryRead;
\r
10 import org.simantics.db.common.request.ObjectsWithType;
\r
11 import org.simantics.db.common.request.ParametrizedPrimitiveRead;
\r
12 import org.simantics.db.exception.DatabaseException;
\r
13 import org.simantics.db.layer0.internal.SimanticsInternal;
\r
14 import org.simantics.db.procedure.Listener;
\r
15 import org.simantics.db.request.Read;
\r
16 import org.simantics.layer0.Layer0;
\r
17 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
\r
18 import org.simantics.scl.compiler.module.repository.ImportFailureException;
\r
19 import org.simantics.scl.compiler.module.repository.UpdateListener;
\r
20 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
\r
21 import org.simantics.scl.osgi.SCLOsgi;
\r
22 import org.simantics.scl.runtime.SCLContext;
\r
25 * Finds the runtime environment of a model or other index root.
\r
27 * @author Hannu Niemistö
\r
28 * @author Antti Villberg
\r
30 public class RuntimeEnvironmentRequest2 extends BinaryRead<Resource, Resource, RuntimeEnvironment> {
\r
32 public RuntimeEnvironmentRequest2(Resource parameter, Resource parameter2) {
\r
33 super(parameter, parameter2);
\r
36 protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
\r
39 static class UpdateListenerImpl implements UpdateListener {
\r
41 final EnvironmentSpecification environmentSpecification;
\r
42 final Listener<RuntimeEnvironment> callback;
\r
44 UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
\r
45 this.environmentSpecification = environmentSpecification;
\r
46 this.callback = callback;
\r
50 public void notifyAboutUpdate() {
\r
51 if(callback.isDisposed()) {
\r
54 getRuntimeEnvironment(environmentSpecification, callback, this);
\r
57 final public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
\r
61 SCLContext context = SCLContext.getCurrent();
\r
63 RuntimeEnvironment env;
\r
64 Object graph = context.get("graph");
\r
67 env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
\r
69 public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
\r
71 SCLContext sclContext = SCLContext.getCurrent();
\r
72 Object oldGraph = sclContext.get("graph");
\r
74 sclContext.put("graph", graph);
\r
75 return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
\r
76 environmentSpecification,
\r
77 callback.getClass().getClassLoader(), listener);
\r
78 } catch (ImportFailureException e) {
\r
79 throw new DatabaseException(e);
\r
80 } catch (Throwable t) {
\r
81 throw new DatabaseException(t);
\r
83 sclContext.put("graph", oldGraph);
\r
87 } catch (DatabaseException e) {
\r
88 callback.exception(e);
\r
92 env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
\r
93 environmentSpecification,
\r
94 callback.getClass().getClassLoader(), listener);
\r
95 callback.execute(env);
\r
96 } catch (ImportFailureException e) {
\r
97 callback.exception(new DatabaseException(e));
\r
104 // This is needed to prevent garbage collection from collecting UpdateListenerImpls
\r
105 // -ModuleRepository only makes a weak reference to the listener
\r
106 final static Map<EnvironmentSpecification, UpdateListenerImpl> map = new HashMap<>();
\r
109 public RuntimeEnvironment perform(ReadGraph graph)
\r
110 throws DatabaseException {
\r
111 final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
\r
114 "Simantics/All", "");
\r
115 fillEnvironmentSpecification(environmentSpecification);
\r
117 Layer0 L0 = Layer0.getInstance(graph);
\r
118 Collection<Resource> sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule));
\r
119 for (Resource sclModule : sclModules)
\r
120 environmentSpecification.importModule(graph.getURI(sclModule), "");
\r
122 Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter2, "SCLMain");
\r
123 if(mainModule != null)
\r
124 environmentSpecification.importModule(graph.getURI(mainModule), "");
\r
126 return graph.syncRequest(new ParametrizedPrimitiveRead<EnvironmentSpecification, RuntimeEnvironment>(environmentSpecification) {
\r
129 public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
\r
131 SCLContext context = SCLContext.getCurrent();
\r
132 Object oldGraph = context.put("graph", graph);
\r
135 if(procedure.isDisposed()) {
\r
136 UpdateListenerImpl.getRuntimeEnvironment(parameter, procedure, null);
\r
138 UpdateListenerImpl impl = new UpdateListenerImpl(parameter, procedure);
\r
139 impl.notifyAboutUpdate();
\r
140 map.put(parameter, impl);
\r
144 context.put("graph", oldGraph);
\r
150 public void unregistered() {
\r
151 map.remove(parameter);
\r
158 public int hashCode() {
\r
159 return 31*getClass().hashCode() + super.hashCode();
\r
162 public static void flush() {
\r