]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest.java
Use proper environment to resolve SCL types in ontology module
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / RuntimeEnvironmentRequest.java
1 package org.simantics.db.layer0.util;
2
3 import org.simantics.db.ReadGraph;
4 import org.simantics.db.Resource;
5 import org.simantics.db.common.request.ParametrizedPrimitiveRead;
6 import org.simantics.db.common.request.UnaryRead;
7 import org.simantics.db.exception.DatabaseException;
8 import org.simantics.db.layer0.internal.SimanticsInternal;
9 import org.simantics.db.procedure.Listener;
10 import org.simantics.db.request.Read;
11 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
12 import org.simantics.scl.compiler.module.repository.ImportFailureException;
13 import org.simantics.scl.compiler.module.repository.UpdateListener;
14 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
15 import org.simantics.scl.osgi.SCLOsgi;
16 import org.simantics.scl.runtime.SCLContext;
17
18 /**
19  * Finds the runtime environment of a model or other index root.
20  * 
21  * @author Hannu Niemistö
22  * @author Antti Villberg
23  */
24 public class RuntimeEnvironmentRequest extends UnaryRead<Resource, RuntimeEnvironment> {
25
26     public RuntimeEnvironmentRequest(Resource parameter) {
27         super(parameter);
28     }
29     
30     protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
31     }
32
33     static class UpdateListenerImpl extends UpdateListener {
34                 
35         final EnvironmentSpecification environmentSpecification;
36         final Listener<RuntimeEnvironment> callback;
37         
38         UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
39                 this.environmentSpecification = environmentSpecification;
40                 this.callback = callback;
41         }
42
43         @Override
44         public void notifyAboutUpdate() {
45                 if(callback.isDisposed()) {
46                     stopListening();
47                         return;
48                 }
49                 getRuntimeEnvironment(environmentSpecification, callback, this);
50         }
51     };     
52
53     public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
54
55         try {
56             
57             SCLContext context = SCLContext.getCurrent();
58             
59             RuntimeEnvironment env;
60             Object graph = context.get("graph");
61             if(graph == null)
62                 try {
63                     env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
64                         @Override
65                         public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
66                             
67                             SCLContext sclContext = SCLContext.getCurrent();
68                             Object oldGraph = sclContext.get("graph");
69                             try {
70                                 sclContext.put("graph", graph);
71                                 return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
72                                         environmentSpecification,
73                                         callback.getClass().getClassLoader(), listener);
74                             } catch (ImportFailureException e) {
75                                 throw new DatabaseException(e);
76                             } catch (Throwable t) {
77                                 throw new DatabaseException(t);
78                             } finally {
79                                 sclContext.put("graph", oldGraph);
80                             }
81                         }
82                     });
83                 } catch (DatabaseException e) {
84                     callback.exception(e);
85                     return;
86                 }
87             else 
88                 env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
89                         environmentSpecification,
90                         callback.getClass().getClassLoader(), listener);
91             callback.execute(env);
92         } catch (ImportFailureException e) {
93             callback.exception(new DatabaseException(e));
94         }
95
96     }
97     
98     @Override
99     public RuntimeEnvironment perform(ReadGraph graph)
100             throws DatabaseException {
101         final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
102                 "Builtin", "",
103                 "StandardLibrary", "",
104                 "Simantics/All", "");
105         fillEnvironmentSpecification(environmentSpecification);
106         Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter, "SCLMain");
107         String mainModuleUri;
108         if(mainModule != null) {
109             mainModuleUri = graph.getURI(mainModule);
110             environmentSpecification.importModule(mainModuleUri, "");
111         }
112         else
113             mainModuleUri = graph.getURI(parameter) + "/#"; // Add something dummy to the model uri that cannot be in a real URI
114         
115             return graph.syncRequest(new ParametrizedPrimitiveRead<String, RuntimeEnvironment>(mainModuleUri) {
116                 
117                 UpdateListenerImpl sclListener;
118                 
119                 @Override
120                 public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
121
122                         SCLContext context = SCLContext.getCurrent();
123                         Object oldGraph = context.put("graph", graph);
124                         try {
125
126                                 if(procedure.isDisposed()) {
127                                         getRuntimeEnvironment(environmentSpecification, procedure, null);
128                                 } else {
129                                     sclListener = new UpdateListenerImpl(environmentSpecification, procedure);
130                                     sclListener.notifyAboutUpdate();
131                                         }
132
133                         } finally {
134                                 context.put("graph", oldGraph);
135                         }
136
137                 }
138                 
139                 @Override
140                 public void unregistered() {
141                         if(sclListener != null)
142                             sclListener.stopListening();
143                 }
144                 
145             });
146     }
147     
148     @Override
149     public int hashCode() {
150         return 31*getClass().hashCode() + super.hashCode();
151     }
152
153 }