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