-package org.simantics.db.layer0.util;\r
-\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.common.request.BinaryRead;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.request.ParametrizedPrimitiveRead;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.internal.SimanticsInternal;\r
-import org.simantics.db.procedure.Listener;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;\r
-import org.simantics.scl.compiler.module.repository.ImportFailureException;\r
-import org.simantics.scl.compiler.module.repository.UpdateListener;\r
-import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
-import org.simantics.scl.osgi.SCLOsgi;\r
-import org.simantics.scl.runtime.SCLContext;\r
-\r
-/**\r
- * Finds the runtime environment of a model or other index root.\r
- * \r
- * @author Hannu Niemistö\r
- * @author Antti Villberg\r
- */\r
-public class RuntimeEnvironmentRequest2 extends BinaryRead<Resource, Resource, RuntimeEnvironment> {\r
-\r
- public RuntimeEnvironmentRequest2(Resource parameter, Resource parameter2) {\r
- super(parameter, parameter2);\r
- }\r
- \r
- protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {\r
- }\r
-\r
- static class UpdateListenerImpl implements UpdateListener {\r
- \r
- final EnvironmentSpecification environmentSpecification;\r
- final Listener<RuntimeEnvironment> callback;\r
- \r
- UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {\r
- this.environmentSpecification = environmentSpecification;\r
- this.callback = callback;\r
- }\r
-\r
- @Override\r
- public void notifyAboutUpdate() {\r
- if(callback.isDisposed()) {\r
- return;\r
- }\r
- getRuntimeEnvironment(environmentSpecification, callback, this);\r
- }\r
-\r
- final public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {\r
-\r
- try {\r
- \r
- SCLContext context = SCLContext.getCurrent();\r
- \r
- RuntimeEnvironment env;\r
- Object graph = context.get("graph");\r
- if(graph == null)\r
- try {\r
- env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {\r
- @Override\r
- public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {\r
- \r
- SCLContext sclContext = SCLContext.getCurrent();\r
- Object oldGraph = sclContext.get("graph");\r
- try {\r
- sclContext.put("graph", graph);\r
- return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(\r
- environmentSpecification,\r
- callback.getClass().getClassLoader(), listener);\r
- } catch (ImportFailureException e) {\r
- throw new DatabaseException(e);\r
- } catch (Throwable t) {\r
- throw new DatabaseException(t);\r
- } finally {\r
- sclContext.put("graph", oldGraph);\r
- }\r
- }\r
- });\r
- } catch (DatabaseException e) {\r
- callback.exception(e);\r
- return;\r
- }\r
- else \r
- env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(\r
- environmentSpecification,\r
- callback.getClass().getClassLoader(), listener);\r
- callback.execute(env);\r
- } catch (ImportFailureException e) {\r
- callback.exception(new DatabaseException(e));\r
- }\r
-\r
- }\r
- \r
- }; \r
-\r
- // This is needed to prevent garbage collection from collecting UpdateListenerImpls\r
- // -ModuleRepository only makes a weak reference to the listener\r
- final static Map<EnvironmentSpecification, UpdateListenerImpl> map = new HashMap<>(); \r
- \r
- @Override\r
- public RuntimeEnvironment perform(ReadGraph graph)\r
- throws DatabaseException {\r
- final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(\r
- "Builtin", "",\r
- "Prelude", "",\r
- "Simantics/All", "");\r
- fillEnvironmentSpecification(environmentSpecification);\r
- \r
- Layer0 L0 = Layer0.getInstance(graph);\r
- Collection<Resource> sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule));\r
- for (Resource sclModule : sclModules)\r
- environmentSpecification.importModule(graph.getURI(sclModule), "");\r
- \r
- Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter2, "SCLMain");\r
- if(mainModule != null)\r
- environmentSpecification.importModule(graph.getURI(mainModule), "");\r
- \r
- return graph.syncRequest(new ParametrizedPrimitiveRead<EnvironmentSpecification, RuntimeEnvironment>(environmentSpecification) {\r
- \r
- @Override\r
- public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {\r
-\r
- SCLContext context = SCLContext.getCurrent();\r
- Object oldGraph = context.put("graph", graph);\r
- try {\r
-\r
- if(procedure.isDisposed()) {\r
- UpdateListenerImpl.getRuntimeEnvironment(parameter, procedure, null);\r
- } else {\r
- UpdateListenerImpl impl = new UpdateListenerImpl(parameter, procedure);\r
- impl.notifyAboutUpdate();\r
- map.put(parameter, impl);\r
- }\r
-\r
- } finally {\r
- context.put("graph", oldGraph);\r
- }\r
-\r
- }\r
- \r
- @Override\r
- public void unregistered() {\r
- map.remove(parameter);\r
- }\r
- \r
- });\r
- }\r
- \r
- @Override\r
- public int hashCode() {\r
- return 31*getClass().hashCode() + super.hashCode();\r
- }\r
-\r
- public static void flush() {\r
- map.clear();\r
- }\r
-\r
-}
\ No newline at end of file
+package org.simantics.db.layer0.util;
+
+import java.util.Collection;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.ParametrizedPrimitiveRead;
+import org.simantics.db.common.utils.CommonDBUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.internal.SimanticsInternal;
+import org.simantics.db.procedure.Listener;
+import org.simantics.db.request.Read;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification;
+import org.simantics.scl.compiler.module.repository.ImportFailureException;
+import org.simantics.scl.compiler.module.repository.UpdateListener;
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.runtime.SCLContext;
+
+/**
+ * Finds the runtime environment of a model or other index root.
+ *
+ * @author Hannu Niemistö
+ * @author Antti Villberg
+ *
+ * Difference between this class and {@code RuntimeEnvironmentRequest} is an additional parameter
+ * that is typically some component type. All modules under this resource are added to the environment
+ * in addition to the SCLMain of the root resource.
+ */
+public class RuntimeEnvironmentRequest2 extends BinaryRead<Resource, Resource, RuntimeEnvironment> {
+
+ public RuntimeEnvironmentRequest2(Resource componentType, Resource indexRoot) {
+ super(componentType, indexRoot);
+ }
+
+ protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) {
+ }
+
+ static class UpdateListenerImpl extends UpdateListener {
+
+ final EnvironmentSpecification environmentSpecification;
+ final Listener<RuntimeEnvironment> callback;
+
+ UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback) {
+ this.environmentSpecification = environmentSpecification;
+ this.callback = callback;
+ }
+
+ @Override
+ public void notifyAboutUpdate() {
+ if(callback.isDisposed()) {
+ stopListening();
+ return;
+ }
+ getRuntimeEnvironment(environmentSpecification, callback, this);
+ }
+ };
+
+ public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener<RuntimeEnvironment> callback, UpdateListenerImpl listener) {
+
+ try {
+
+ SCLContext context = SCLContext.getCurrent();
+
+ RuntimeEnvironment env;
+ Object graph = context.get("graph");
+ if(graph == null)
+ try {
+ env = SimanticsInternal.getSession().syncRequest(new Read<RuntimeEnvironment>() {
+ @Override
+ public RuntimeEnvironment perform(ReadGraph graph) throws DatabaseException {
+
+ SCLContext sclContext = SCLContext.getCurrent();
+ Object oldGraph = sclContext.get("graph");
+ try {
+ sclContext.put("graph", graph);
+ return SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
+ environmentSpecification,
+ callback.getClass().getClassLoader(), listener);
+ } catch (ImportFailureException e) {
+ throw new DatabaseException(e);
+ } catch (Throwable t) {
+ throw new DatabaseException(t);
+ } finally {
+ sclContext.put("graph", oldGraph);
+ }
+ }
+ });
+ } catch (DatabaseException e) {
+ callback.exception(e);
+ return;
+ }
+ else
+ env = SCLOsgi.MODULE_REPOSITORY.createRuntimeEnvironment(
+ environmentSpecification,
+ callback.getClass().getClassLoader(), listener);
+ callback.execute(env);
+ } catch (ImportFailureException e) {
+ callback.exception(new DatabaseException(e));
+ }
+
+ }
+
+ @Override
+ public RuntimeEnvironment perform(ReadGraph graph)
+ throws DatabaseException {
+ final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of(
+ "Builtin", "",
+ "StandardLibrary", "",
+ "Simantics/All", "");
+ fillEnvironmentSpecification(environmentSpecification);
+
+ Layer0 L0 = Layer0.getInstance(graph);
+ if (parameter != null) {
+ Collection<Resource> sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule));
+ for (Resource sclModule : sclModules) {
+ environmentSpecification.importModule(graph.getURI(sclModule), "");
+ }
+ } else {
+ // `parameter` is optional and can be null for e.g. procedural user components
+ }
+
+ Resource mainModule = CommonDBUtils.getPossibleChild(graph, parameter2, "SCLMain");
+ if(mainModule != null) {
+ environmentSpecification.importModule(graph.getURI(mainModule), "");
+ for(Resource l : graph.getObjects(parameter2, L0.IsLinkedTo)) {
+ mainModule = CommonDBUtils.getPossibleChild(graph, l, "SCLMain");
+ if(mainModule != null)
+ environmentSpecification.importModule(graph.getURI(mainModule), "");
+ }
+ }
+
+ return graph.syncRequest(new ParametrizedPrimitiveRead<EnvironmentSpecification, RuntimeEnvironment>(environmentSpecification) {
+
+ UpdateListenerImpl sclListener;
+
+ @Override
+ public void register(ReadGraph graph, Listener<RuntimeEnvironment> procedure) {
+
+ SCLContext context = SCLContext.getCurrent();
+ Object oldGraph = context.put("graph", graph);
+ try {
+
+ if(procedure.isDisposed()) {
+ getRuntimeEnvironment(parameter, procedure, null);
+ } else {
+ sclListener = new UpdateListenerImpl(parameter, procedure);
+ sclListener.notifyAboutUpdate();
+ }
+
+ } finally {
+ context.put("graph", oldGraph);
+ }
+
+ }
+
+ @Override
+ public void unregistered() {
+ if(sclListener != null)
+ sclListener.stopListening();
+ }
+
+ });
+ }
+
+ @Override
+ public int hashCode() {
+ return 31*getClass().hashCode() + super.hashCode();
+ }
+
+}