X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.db.common%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fcommon%2Frequest%2FRuntimeEnvironmentRequest.java;fp=bundles%2Forg.simantics.db.common%2Fsrc%2Forg%2Fsimantics%2Fdb%2Fcommon%2Frequest%2FRuntimeEnvironmentRequest.java;h=24a5c10c909be94716ae7d907b3c698144af7975;hb=0ffcb1180dcccf28e66a391338885be224ba1c47;hp=0000000000000000000000000000000000000000;hpb=342a2b006b88330280060c16c2ab50374468a4c6;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/RuntimeEnvironmentRequest.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/RuntimeEnvironmentRequest.java new file mode 100644 index 000000000..24a5c10c9 --- /dev/null +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/RuntimeEnvironmentRequest.java @@ -0,0 +1,153 @@ +package org.simantics.db.common.request; + +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.SimanticsInternal; +import org.simantics.db.common.utils.CommonDBUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.procedure.Listener; +import org.simantics.db.request.Read; +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 RuntimeEnvironmentRequest extends UnaryRead { + + public RuntimeEnvironmentRequest(Resource parameter) { + super(parameter); + } + + protected void fillEnvironmentSpecification(EnvironmentSpecification environmentSpecification) { + } + + static class UpdateListenerImpl extends 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()) { + stopListening(); + return; + } + getRuntimeEnvironment(environmentSpecification, callback, this); + } + }; + + 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)); + } + + } + + @Override + public RuntimeEnvironment perform(ReadGraph graph) + throws DatabaseException { + final EnvironmentSpecification environmentSpecification = EnvironmentSpecification.of( + "Builtin", "", + "StandardLibrary", "", + "Simantics/All", ""); + fillEnvironmentSpecification(environmentSpecification); + + Resource mainModule = CommonDBUtils.getPossibleChild(graph, parameter, "SCLMain"); + String mainModuleUri; + if(mainModule != null) { + mainModuleUri = graph.getURI(mainModule); + environmentSpecification.importModule(mainModuleUri, ""); + } + else + mainModuleUri = graph.getURI(parameter) + "/#"; // Add something dummy to the model uri that cannot be in a real URI + + return graph.syncRequest(new ParametrizedPrimitiveRead(mainModuleUri) { + + UpdateListenerImpl sclListener; + + @Override + public void register(ReadGraph graph, Listener procedure) { + + SCLContext context = SCLContext.getCurrent(); + Object oldGraph = context.put("graph", graph); + try { + + if(procedure.isDisposed()) { + getRuntimeEnvironment(environmentSpecification, procedure, null); + } else { + sclListener = new UpdateListenerImpl(environmentSpecification, 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(); + } + +}