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.common.utils.CommonDBUtils;
8 import org.simantics.db.exception.DatabaseException;
9 import org.simantics.db.layer0.internal.SimanticsInternal;
10 import org.simantics.db.procedure.Listener;
11 import org.simantics.db.request.Read;
12 import org.simantics.layer0.Layer0;
13 import org.simantics.scl.compiler.environment.Environment;
14 import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
15 import org.simantics.scl.compiler.module.repository.ImportFailureException;
16 import org.simantics.scl.compiler.module.repository.UpdateListener;
17 import org.simantics.scl.osgi.SCLOsgi;
18 import org.simantics.scl.runtime.SCLContext;
19 import org.simantics.utils.datastructures.Pair;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
24 * Finds the environment of a model or other index root.
26 public abstract class EnvironmentRequest extends UnaryRead<Resource, Pair<EnvironmentSpecification, Environment>> {
27 private static final Logger LOGGER = LoggerFactory.getLogger(EnvironmentRequest.class);
29 public EnvironmentRequest(Resource parameter) {
33 protected abstract void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification);
34 protected abstract String getRootModuleName();
36 static class UpdateListenerImpl extends UpdateListener {
38 final EnvironmentSpecification environmentSpecification;
39 final Listener<Environment> callback;
41 UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<Environment> callback) {
42 this.environmentSpecification = environmentSpecification;
43 this.callback = callback;
47 public void notifyAboutUpdate() {
48 if(callback.isDisposed()) {
52 getEnvironment(environmentSpecification, callback, this);
56 public static void getEnvironment(EnvironmentSpecification environmentSpecification, Listener<Environment> callback, UpdateListenerImpl listener) {
60 SCLContext context = SCLContext.getCurrent();
63 Object graph = context.get("graph");
66 env = SimanticsInternal.getSession().syncRequest(new Read<Environment>() {
68 public Environment perform(ReadGraph graph) throws DatabaseException {
70 SCLContext sclContext = SCLContext.getCurrent();
71 Object oldGraph = sclContext.get("graph");
73 sclContext.put("graph", graph);
74 return SCLOsgi.MODULE_REPOSITORY.createEnvironment(
75 environmentSpecification, listener);
76 } catch (ImportFailureException e) {
77 throw new DatabaseException(e);
78 } catch (Throwable t) {
79 throw new DatabaseException(t);
81 sclContext.put("graph", oldGraph);
85 } catch (DatabaseException e) {
86 LOGGER.error("Finding environment failed", e);
87 callback.exception(e);
91 env = SCLOsgi.MODULE_REPOSITORY.createEnvironment(
92 environmentSpecification, listener);
93 callback.execute(env);
94 } catch (ImportFailureException e) {
95 LOGGER.error("Finding environment failed", e);
96 callback.exception(new DatabaseException(e));
102 public Pair<EnvironmentSpecification, Environment> perform(ReadGraph graph)
103 throws DatabaseException {
104 final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
106 "StandardLibrary", "");
107 fillEnvironmentSpecification(environmentSpecification);
108 Resource mainModule = CommonDBUtils.getPossibleChild(graph, parameter, getRootModuleName());
109 String mainModuleUri;
110 if(mainModule != null) {
111 mainModuleUri = graph.getURI(mainModule);
112 environmentSpecification.importModule(mainModuleUri, "");
113 Layer0 L0 = Layer0.getInstance(graph);
114 for(Resource l : graph.getObjects(parameter, L0.IsLinkedTo)) {
115 mainModule = CommonDBUtils.getPossibleChild(graph, l, "SCLMain");
116 if(mainModule != null)
117 environmentSpecification.importModule(graph.getURI(mainModule), "");
121 mainModuleUri = graph.getURI(parameter) + "/#"; // Add something dummy to the model uri that cannot be in a real URI
124 return Pair.make(environmentSpecification, graph.syncRequest(new ParametrizedPrimitiveRead<String, Environment>(mainModuleUri) {
126 UpdateListenerImpl sclListener;
129 public void register(ReadGraph graph, Listener<Environment> procedure) {
131 SCLContext context = SCLContext.getCurrent();
132 Object oldGraph = context.put("graph", graph);
135 if(procedure.isDisposed()) {
136 getEnvironment(environmentSpecification, procedure, null);
138 sclListener = new UpdateListenerImpl(environmentSpecification, procedure);
139 sclListener.notifyAboutUpdate();
143 context.put("graph", oldGraph);
149 public void unregistered() {
150 if(sclListener != null)
151 sclListener.stopListening();
155 } catch(DatabaseException e) {
156 LOGGER.error("Environment request failed", e);
162 public int hashCode() {
163 return 31*getClass().hashCode() + super.hashCode();