1 package org.simantics.db.layer0.util;
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;
20 * Finds the environment of a model or other index root.
22 public abstract class EnvironmentRequest extends UnaryRead<Resource, Pair<EnvironmentSpecification, Environment>> {
24 public EnvironmentRequest(Resource parameter) {
28 protected abstract void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification);
29 protected abstract String getRootModuleName();
31 static class UpdateListenerImpl extends UpdateListener {
33 final EnvironmentSpecification environmentSpecification;
34 final Listener<Environment> callback;
36 UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<Environment> callback) {
37 this.environmentSpecification = environmentSpecification;
38 this.callback = callback;
42 public void notifyAboutUpdate() {
43 if(callback.isDisposed()) {
47 getEnvironment(environmentSpecification, callback, this);
51 public static void getEnvironment(EnvironmentSpecification environmentSpecification, Listener<Environment> callback, UpdateListenerImpl listener) {
55 SCLContext context = SCLContext.getCurrent();
58 Object graph = context.get("graph");
61 env = SimanticsInternal.getSession().syncRequest(new Read<Environment>() {
63 public Environment perform(ReadGraph graph) throws DatabaseException {
65 SCLContext sclContext = SCLContext.getCurrent();
66 Object oldGraph = sclContext.get("graph");
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);
76 sclContext.put("graph", oldGraph);
80 } catch (DatabaseException e) {
81 callback.exception(e);
85 env = SCLOsgi.MODULE_REPOSITORY.createEnvironment(
86 environmentSpecification, listener);
87 callback.execute(env);
88 } catch (ImportFailureException e) {
89 callback.exception(new DatabaseException(e));
95 public Pair<EnvironmentSpecification, Environment> perform(ReadGraph graph)
96 throws DatabaseException {
97 final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
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, "");
108 mainModuleUri = graph.getURI(parameter) + "/#"; // Add something dummy to the model uri that cannot be in a real URI
110 return Pair.make(environmentSpecification, graph.syncRequest(new ParametrizedPrimitiveRead<String, Environment>(mainModuleUri) {
112 UpdateListenerImpl sclListener;
115 public void register(ReadGraph graph, Listener<Environment> procedure) {
117 SCLContext context = SCLContext.getCurrent();
118 Object oldGraph = context.put("graph", graph);
121 if(procedure.isDisposed()) {
122 getEnvironment(environmentSpecification, procedure, null);
124 sclListener = new UpdateListenerImpl(environmentSpecification, procedure);
125 sclListener.notifyAboutUpdate();
129 context.put("graph", oldGraph);
135 public void unregistered() {
136 if(sclListener != null)
137 sclListener.stopListening();
144 public int hashCode() {
145 return 31*getClass().hashCode() + super.hashCode();