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;
18 import org.slf4j.Logger;
19 import org.slf4j.LoggerFactory;
22 * Finds the environment of a model or other index root.
24 public abstract class EnvironmentRequest extends UnaryRead<Resource, Pair<EnvironmentSpecification, Environment>> {
25 private static final Logger LOGGER = LoggerFactory.getLogger(EnvironmentRequest.class);
27 public EnvironmentRequest(Resource parameter) {
31 protected abstract void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification);
32 protected abstract String getRootModuleName();
34 static class UpdateListenerImpl extends UpdateListener {
36 final EnvironmentSpecification environmentSpecification;
37 final Listener<Environment> callback;
39 UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<Environment> callback) {
40 this.environmentSpecification = environmentSpecification;
41 this.callback = callback;
45 public void notifyAboutUpdate() {
46 if(callback.isDisposed()) {
50 getEnvironment(environmentSpecification, callback, this);
54 public static void getEnvironment(EnvironmentSpecification environmentSpecification, Listener<Environment> callback, UpdateListenerImpl listener) {
58 SCLContext context = SCLContext.getCurrent();
61 Object graph = context.get("graph");
64 env = SimanticsInternal.getSession().syncRequest(new Read<Environment>() {
66 public Environment perform(ReadGraph graph) throws DatabaseException {
68 SCLContext sclContext = SCLContext.getCurrent();
69 Object oldGraph = sclContext.get("graph");
71 sclContext.put("graph", graph);
72 return SCLOsgi.MODULE_REPOSITORY.createEnvironment(
73 environmentSpecification, listener);
74 } catch (ImportFailureException e) {
75 throw new DatabaseException(e);
76 } catch (Throwable t) {
77 throw new DatabaseException(t);
79 sclContext.put("graph", oldGraph);
83 } catch (DatabaseException e) {
84 LOGGER.error("Finding environment failed", e);
85 callback.exception(e);
89 env = SCLOsgi.MODULE_REPOSITORY.createEnvironment(
90 environmentSpecification, listener);
91 callback.execute(env);
92 } catch (ImportFailureException e) {
93 LOGGER.error("Finding environment failed", e);
94 callback.exception(new DatabaseException(e));
100 public Pair<EnvironmentSpecification, Environment> perform(ReadGraph graph)
101 throws DatabaseException {
102 final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
104 "StandardLibrary", "");
105 fillEnvironmentSpecification(environmentSpecification);
106 Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter, getRootModuleName());
107 String mainModuleUri;
108 if(mainModule != null) {
109 mainModuleUri = graph.getURI(mainModule);
110 environmentSpecification.importModule(mainModuleUri, "");
113 mainModuleUri = graph.getURI(parameter) + "/#"; // Add something dummy to the model uri that cannot be in a real URI
116 return Pair.make(environmentSpecification, graph.syncRequest(new ParametrizedPrimitiveRead<String, Environment>(mainModuleUri) {
118 UpdateListenerImpl sclListener;
121 public void register(ReadGraph graph, Listener<Environment> procedure) {
123 SCLContext context = SCLContext.getCurrent();
124 Object oldGraph = context.put("graph", graph);
127 if(procedure.isDisposed()) {
128 getEnvironment(environmentSpecification, procedure, null);
130 sclListener = new UpdateListenerImpl(environmentSpecification, procedure);
131 sclListener.notifyAboutUpdate();
135 context.put("graph", oldGraph);
141 public void unregistered() {
142 if(sclListener != null)
143 sclListener.stopListening();
147 } catch(DatabaseException e) {
148 LOGGER.error("Environment request failed", e);
154 public int hashCode() {
155 return 31*getClass().hashCode() + super.hashCode();