]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java
Fix errors with procedural user components for computational values
[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 public class RuntimeEnvironmentRequest2 extends BinaryRead<Resource, Resource, RuntimeEnvironment> {
29
30     public RuntimeEnvironmentRequest2(Resource parameter, Resource parameter2) {
31         super(parameter, parameter2);
32     }
33     
34     protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
35     }
36
37     static class UpdateListenerImpl extends UpdateListener {
38
39         final EnvironmentSpecification environmentSpecification;
40         final Listener<RuntimeEnvironment> callback;
41
42         UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
43             this.environmentSpecification = environmentSpecification;
44             this.callback = callback;
45         }
46
47         @Override
48         public void notifyAboutUpdate() {
49             if(callback.isDisposed()) {
50                 stopListening();
51                 return;
52             }
53             getRuntimeEnvironment(environmentSpecification, callback, this);
54         }
55     };
56
57     final public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
58
59         try {
60
61             SCLContext context = SCLContext.getCurrent();
62
63             RuntimeEnvironment env;
64             Object graph = context.get("graph");
65             if(graph == null)
66                 try {
67                     env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
68                         @Override
69                         public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
70
71                             SCLContext sclContext = SCLContext.getCurrent();
72                             Object oldGraph = sclContext.get("graph");
73                             try {
74                                 sclContext.put("graph", graph);
75                                 return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
76                                         environmentSpecification,
77                                         callback.getClass().getClassLoader(), listener);
78                             } catch (ImportFailureException e) {
79                                 throw new DatabaseException(e);
80                             } catch (Throwable t) {
81                                 throw new DatabaseException(t);
82                             } finally {
83                                 sclContext.put("graph", oldGraph);
84                             }
85                         }
86                     });
87                 } catch (DatabaseException e) {
88                     callback.exception(e);
89                     return;
90                 }
91             else 
92                 env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
93                         environmentSpecification,
94                         callback.getClass().getClassLoader(), listener);
95             callback.execute(env);
96         } catch (ImportFailureException e) {
97             callback.exception(new DatabaseException(e));
98         }
99
100     }
101
102     @Override
103     public RuntimeEnvironment perform(ReadGraph graph)
104             throws DatabaseException {
105         final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
106                 "Builtin", "",
107                 "StandardLibrary", "",
108                 "Simantics/All", "");
109         fillEnvironmentSpecification(environmentSpecification);
110
111         Layer0 L0 = Layer0.getInstance(graph);
112         if (parameter != null) {
113             Collection<Resource> sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule));
114             for (Resource sclModule : sclModules) {
115                 environmentSpecification.importModule(graph.getURI(sclModule), "");
116             }
117         } else {
118             // `parameter` is optional and can be null for e.g. procedural user components
119         }
120
121         Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter2, "SCLMain");
122         if(mainModule != null)
123             environmentSpecification.importModule(graph.getURI(mainModule), "");
124
125         return graph.syncRequest(new ParametrizedPrimitiveRead<EnvironmentSpecification, RuntimeEnvironment>(environmentSpecification) {
126             UpdateListenerImpl sclListener;
127             @Override
128             public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
129
130                 SCLContext context = SCLContext.getCurrent();
131                 Object oldGraph = context.put("graph", graph);
132                 try {
133
134                     if(procedure.isDisposed()) {
135                         getRuntimeEnvironment(parameter, procedure, null);
136                     } else {
137                         sclListener = new UpdateListenerImpl(parameter, procedure);
138                         sclListener.notifyAboutUpdate();
139                     }
140
141                 } finally {
142                     context.put("graph", oldGraph);
143                 }
144
145             }
146
147             @Override
148             public void unregistered() {
149                 if(sclListener != null)
150                     sclListener.stopListening();
151             }
152
153         });
154     }
155
156     @Override
157     public int hashCode() {
158         return 31*getClass().hashCode() + super.hashCode();
159     }
160
161 }