From 535501106fe714c6875b98bf8e7c744a07159d6e Mon Sep 17 00:00:00 2001 From: Miro Richard Eklund Date: Mon, 28 Nov 2016 11:15:15 +0200 Subject: [PATCH] UCs can have their own SCLModule definitions User Components now see their own SCLModule definitions without including them to the index roots SCLMain. Makes UCs more individual and eases the usage of them. refs #6514 Change-Id: I55e5bc78a1dc93382d9ca8d3ea78837baa59fe28 --- .../util/RuntimeEnvironmentRequest2.java | 166 ++++++++++++++++++ .../request/ServerSCLHandlerValueRequest.java | 8 +- .../server/request/ServerSCLValueRequest.java | 7 +- ...AbstractCompileStructuralValueRequest.java | 3 +- 4 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java new file mode 100644 index 000000000..a01946121 --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/RuntimeEnvironmentRequest2.java @@ -0,0 +1,166 @@ +package org.simantics.db.layer0.util; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +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.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 + */ +public class RuntimeEnvironmentRequest2 extends BinaryRead { + + public RuntimeEnvironmentRequest2(Resource parameter, Resource parameter2) { + super(parameter, parameter2); + } + + protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) { + } + + static class UpdateListenerImpl implements UpdateListener { + + final EnvironmentSpecification environmentSpecification; + final Listener callback; + + UpdateListenerImpl(EnvironmentSpecification environmentSpecification, Listener callback) { + this.environmentSpecification = environmentSpecification; + this.callback = callback; + } + + @Override + public void notifyAboutUpdate() { + if(callback.isDisposed()) { + return; + } + getRuntimeEnvironment(environmentSpecification, callback, this); + } + + final public static void getRuntimeEnvironment(EnvironmentSpecification environmentSpecification, Listener 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() { + @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)); + } + + } + + }; + + // This is needed to prevent garbage collection from collecting UpdateListenerImpls + // -ModuleRepository only makes a weak reference to the listener + final static Map map = new HashMap<>(); + + @Override + public RuntimeEnvironment perform(ReadGraph graph) + throws DatabaseException { + final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of( + "Builtin", "", + "Prelude", "", + "Simantics/All", ""); + fillEnvironmentSpecification(environmentSpecification); + + Layer0 L0 = Layer0.getInstance(graph); + Collection sclModules = graph.syncRequest(new ObjectsWithType(parameter, L0.ConsistsOf, L0.SCLModule)); + for (Resource sclModule : sclModules) + environmentSpecification.importModule(graph.getURI(sclModule), ""); + + Resource mainModule = Layer0Utils.getPossibleChild(graph, parameter2, "SCLMain"); + if(mainModule != null) + environmentSpecification.importModule(graph.getURI(mainModule), ""); + + return graph.syncRequest(new ParametrizedPrimitiveRead(environmentSpecification) { + + @Override + public void register(ReadGraph graph, Listener procedure) { + + SCLContext context = SCLContext.getCurrent(); + Object oldGraph = context.put("graph", graph); + try { + + if(procedure.isDisposed()) { + UpdateListenerImpl.getRuntimeEnvironment(parameter, procedure, null); + } else { + UpdateListenerImpl impl = new UpdateListenerImpl(parameter, procedure); + impl.notifyAboutUpdate(); + map.put(parameter, impl); + } + + } finally { + context.put("graph", oldGraph); + } + + } + + @Override + public void unregistered() { + map.remove(parameter); + } + + }); + } + + @Override + public int hashCode() { + return 31*getClass().hashCode() + super.hashCode(); + } + + public static void flush() { + map.clear(); + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java index ca82be6c9..12a4e017a 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLHandlerValueRequest.java @@ -13,7 +13,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.VariableRead; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; -import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; +import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.db.layer0.variable.Variable; import org.simantics.document.server.Functions; import org.simantics.document.server.bean.DataDefinition; @@ -120,8 +120,8 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR return "\\context -> " + exp; } - protected RuntimeEnvironmentRequest getRuntimeEnvironmentRequest(Resource indexRoot) { - return new RuntimeEnvironmentRequest(indexRoot) { + protected RuntimeEnvironmentRequest2 getRuntimeEnvironmentRequest(Resource componentType, Resource indexRoot) { + return new RuntimeEnvironmentRequest2(componentType, indexRoot) { @Override protected void fillEnvironmentSpecification( EnvironmentSpecification environmentSpecification) { @@ -138,7 +138,7 @@ public class ServerSCLHandlerValueRequest extends AbstractExpressionCompilationR public CompilationContext perform(ReadGraph graph) throws DatabaseException { Pair parameter = getComponentTypeAndRoot(graph, variable); - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.second)); + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second)); Map propertyMap = graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java index 246acfdec..d9c5a0103 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/ServerSCLValueRequest.java @@ -12,6 +12,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; +import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.db.layer0.variable.Variable; import org.simantics.document.server.request.ServerSCLValueRequest.CompilationContext; import org.simantics.layer0.Layer0; @@ -100,8 +101,8 @@ public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest< return graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING); } - protected RuntimeEnvironmentRequest getRuntimeEnvironmentRequest(Resource indexRoot) { - return new RuntimeEnvironmentRequest(indexRoot) { + protected RuntimeEnvironmentRequest2 getRuntimeEnvironmentRequest(Resource componentType, Resource indexRoot) { + return new RuntimeEnvironmentRequest2(componentType, indexRoot) { @Override protected void fillEnvironmentSpecification( EnvironmentSpecification environmentSpecification) { @@ -116,7 +117,7 @@ public class ServerSCLValueRequest extends AbstractExpressionCompilationRequest< @Override public CompilationContext perform(ReadGraph graph) throws DatabaseException { - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.second)); + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second)); Map propertyMap = graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()), TransientCacheListener.>instance()); diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java index e369050e9..7a6b45e3c 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java @@ -12,6 +12,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; +import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.elaboration.expressions.EApply; @@ -85,7 +86,7 @@ abstract public class AbstractCompileStructuralValueRequest extends AbstractExpr @Override public CompilationContext perform(ReadGraph graph) throws DatabaseException { - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(resource2)); + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest2(resource, resource2)); Map propertyMap = graph.syncRequest(new ReadComponentTypeInterfaceRequest(resource, runtimeEnvironment.getEnvironment()), TransientCacheListener.>instance()); -- 2.43.2