]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java
Documented difference of RuntimeEnvironmentRequest and Runti...quest2
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / RuntimeEnvironmentRequest2.java
1 package org.simantics.db.layer0.util;
2
3 import java.util.Collection;
4
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;
21
22 /**
23  * Finds the runtime environment of a model or other index root.
24  * 
25  * @author Hannu Niemistö
26  * @author Antti Villberg
27  * 
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. 
31  */
32 public class RuntimeEnvironmentRequest2 extends BinaryRead<Resource, Resource, RuntimeEnvironment> {
33
34     public RuntimeEnvironmentRequest2(Resource componentType, Resource indexRoot) {
35         super(componentType, indexRoot);
36     }
37
38     protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
39     }
40
41     static class UpdateListenerImpl extends UpdateListener {
42
43         final EnvironmentSpecification environmentSpecification;
44         final Listener<RuntimeEnvironment> callback;
45
46         UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
47             this.environmentSpecification = environmentSpecification;
48             this.callback = callback;
49         }
50
51         @Override
52         public void notifyAboutUpdate() {
53             if(callback.isDisposed()) {
54                 stopListening();
55                 return;
56             }
57             getRuntimeEnvironment(environmentSpecification, callback, this);
58         }
59     };
60
61     public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
62
63         try {
64
65             SCLContext context = SCLContext.getCurrent();
66
67             RuntimeEnvironment env;
68             Object graph = context.get("graph");
69             if(graph == null)
70                 try {
71                     env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
72                         @Override
73                         public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
74
75                             SCLContext sclContext = SCLContext.getCurrent();
76                             Object oldGraph = sclContext.get("graph");
77                             try {
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);
86                             } finally {
87                                 sclContext.put("graph", oldGraph);
88                             }
89                         }
90                     });
91                 } catch (DatabaseException e) {
92                     callback.exception(e);
93                     return;
94                 }
95             else 
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));
102         }
103
104     }
105
106     @Override
107     public RuntimeEnvironment perform(ReadGraph graph)
108             throws DatabaseException {
109         final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
110                 "Builtin", "",
111                 "StandardLibrary", "",
112                 "Simantics/All", "");
113         fillEnvironmentSpecification(environmentSpecification);
114
115         Layer0 L0 = Layer0.getInstance(graph);
116         Collection<Resource> sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule));
117         for (Resource sclModule : sclModules)
118             environmentSpecification.importModule(graph.getURI(sclModule), "");
119
120         Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter2, "SCLMain");
121         if(mainModule != null)
122             environmentSpecification.importModule(graph.getURI(mainModule), "");
123
124         return graph.syncRequest(new ParametrizedPrimitiveRead<EnvironmentSpecification, RuntimeEnvironment>(environmentSpecification) {
125
126             UpdateListenerImpl sclListener;
127
128             @Override
129             public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
130
131                 SCLContext context = SCLContext.getCurrent();
132                 Object oldGraph = context.put("graph", graph);
133                 try {
134
135                     if(procedure.isDisposed()) {
136                         getRuntimeEnvironment(parameter, procedure, null);
137                     } else {
138                         sclListener = new UpdateListenerImpl(parameter, procedure);
139                         sclListener.notifyAboutUpdate();
140                     }
141
142                 } finally {
143                     context.put("graph", oldGraph);
144                 }
145
146             }
147
148             @Override
149             public void unregistered() {
150                 if(sclListener != null)
151                     sclListener.stopListening();
152             }
153
154         });
155     }
156
157     @Override
158     public int hashCode() {
159         return 31*getClass().hashCode() + super.hashCode();
160     }
161
162 }