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