-package org.simantics.simulation.project;\r
-\r
-import java.util.concurrent.atomic.AtomicReference;\r
-import java.util.function.Consumer;\r
-\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.VirtualGraph;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.CommentMetadata;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.service.VirtualGraphSupport;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.scl.runtime.function.Function2;\r
-import org.simantics.simulation.experiment.ExperimentState;\r
-import org.simantics.simulation.experiment.IExperiment;\r
-import org.simantics.simulation.experiment.IExperimentListener;\r
-import org.simantics.simulation.ontology.SimulationResource;\r
-import org.simantics.utils.datastructures.Callback;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-\r
-/**\r
- * Facade for handling experiment run modeling and experiment activation\r
- * related tasks.\r
- * \r
- * @author Tuukka Lehtonen\r
- */\r
-public class ExperimentRuns {\r
-\r
- /**\r
- * @param session\r
- * @param experimentResource\r
- * @param experiment\r
- * @param listener\r
- */\r
- public static void createRun(Session session, Resource experimentResource, IExperiment experiment,\r
- IExperimentActivationListener listener, Consumer<Resource> successCallback) {\r
- VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);\r
- createRun(session, support.getWorkspacePersistent("experiments"), experimentResource, experiment, listener, successCallback);\r
- }\r
-\r
- /**\r
- * Create new experiment run in a selected virtual graph.\r
- * \r
- * @param session\r
- * @param graph\r
- * @param experimentResource\r
- * @param experiment\r
- * @param listener\r
- */\r
- public static void createRun(final Session session, VirtualGraph graph, final Resource experimentResource,\r
- final IExperiment experiment, final IExperimentActivationListener listener,\r
- final Consumer<Resource> successCallback)\r
- {\r
- createRun(session, graph, experimentResource, experiment, SimulationResource.URIs.Run, listener, successCallback);\r
- }\r
-\r
- public static void createRun(final Session session, VirtualGraph vg, final Resource experimentResource,\r
- final IExperiment experiment, final String experimentRunTypeURI,\r
- final IExperimentActivationListener listener, final Consumer<Resource> successCallback)\r
- {\r
- createRun(session, vg, experimentResource, experiment, experimentRunTypeURI, listener, null, successCallback);\r
- }\r
-\r
- /**\r
- * Create new experiment run in a selected virtual graph.\r
- * \r
- * @param session\r
- * @param vg\r
- * @param experimentResource\r
- * @param experiment\r
- * @param experimentRunTypeURI\r
- * @param listener\r
- * @param successCallback if non-null invoked with the created run resource\r
- * as an argument, just before invoking\r
- * listener.onExperimentActivated(experiment)\r
- */\r
- public static void createRun(final Session session, VirtualGraph vg, final Resource experimentResource,\r
- final IExperiment experiment, final String experimentRunTypeURI,\r
- final IExperimentActivationListener listener, final Function2<WriteGraph, Resource, Object> external, final Consumer<Resource> successCallback)\r
- {\r
- final AtomicReference<Resource> _run = new AtomicReference<Resource>();\r
- session.asyncRequest(new WriteRequest(vg) {\r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
-// System.out.println("ExperimentActivator " + experimentResource + " " + experiment.getIdentifier());\r
-\r
- final Layer0 L0 = Layer0.getInstance(graph);\r
- final SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-\r
- final Resource run = graph.newResource();\r
- String label = NameUtils.findFreshLabel(graph, "Experiment", experimentResource);\r
- graph.claim(run, L0.InstanceOf, null, graph.getResource(experimentRunTypeURI));\r
- graph.addLiteral(run, L0.HasName, L0.NameOf, L0.String, experiment.getIdentifier(), Bindings.STRING);\r
- graph.addLiteral(run, L0.HasLabel, L0.HasLabel_Inverse, L0.String, label, Bindings.STRING);\r
- graph.addLiteral(run, SIMU.HasActivationTime, SIMU.HasActivationTime_Inverse, L0.Long, System.currentTimeMillis(), Bindings.LONG);\r
- graph.claim(experimentResource, L0.ConsistsOf, L0.PartOf, run);\r
- \r
- // Mark the run active in the transient virtual graph.\r
- VirtualGraph runtime = graph.getService(VirtualGraph.class);\r
- graph.syncRequest(new WriteRequest(runtime) {\r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
- graph.claim(run, SIMU.IsActive, run);\r
- if(external != null)\r
- external.apply(graph, run);\r
- }\r
- });\r
-\r
- _run.set(run);\r
- }\r
- }, new Callback<DatabaseException>() {\r
- @Override\r
- public void run(DatabaseException e) {\r
- if (e != null) {\r
- if (listener != null)\r
- listener.onFailure(e);\r
- else\r
- ErrorLogger.defaultLogError(e);\r
- } else {\r
- attachStateListener(session, experiment, _run.get());\r
- if (successCallback != null)\r
- successCallback.accept(_run.get());\r
- if (listener != null)\r
- listener.onExperimentActivated(experiment);\r
- }\r
- }\r
- });\r
- }\r
-\r
- /**\r
- * Add listener for tracking run IsActive state in the graph.\r
- * \r
- * @param session\r
- * @param experiment\r
- * @param run\r
- */\r
- private static void attachStateListener(final Session session, IExperiment experiment, final Resource run) {\r
- experiment.addListener(new IExperimentListener() {\r
- @Override\r
- public void stateChanged(ExperimentState state) {\r
- if (state == ExperimentState.DISPOSED) {\r
- VirtualGraph runtime = session.getService(VirtualGraph.class);\r
- session.asyncRequest(new WriteRequest(runtime) {\r
- @Override\r
- public void perform(WriteGraph graph) throws DatabaseException {\r
- SimulationResource SIMU = SimulationResource.getInstance(graph);\r
- graph.denyStatement(run, SIMU.IsActive, run);\r
- \r
- CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
- graph.addMetadata(cm.add("Attaching state listener to track isActive for run"));\r
- }\r
- }, new Callback<DatabaseException>() {\r
- @Override\r
- public void run(DatabaseException e) {\r
- if (e != null)\r
- ErrorLogger.defaultLogError(e);\r
- }\r
- });\r
- }\r
- }\r
- });\r
- }\r
-\r
-}\r
+package org.simantics.simulation.project;
+
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.VirtualGraph;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.request.WriteResultRequest;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.service.VirtualGraphSupport;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.runtime.function.Function2;
+import org.simantics.simulation.experiment.ExperimentState;
+import org.simantics.simulation.experiment.IExperiment;
+import org.simantics.simulation.experiment.IExperimentListener;
+import org.simantics.simulation.ontology.SimulationResource;
+import org.simantics.utils.ui.ErrorLogger;
+
+/**
+ * Facade for handling experiment run modeling and experiment activation
+ * related tasks.
+ *
+ * @author Tuukka Lehtonen
+ */
+public class ExperimentRuns {
+
+ /**
+ * @param session
+ * @param experimentResource
+ * @param experiment
+ * @param listener
+ */
+ public static void createRun(Session session, Resource experimentResource, IExperiment experiment,
+ IExperimentActivationListener listener, Consumer<Resource> successCallback) {
+ VirtualGraphSupport support = session.getService(VirtualGraphSupport.class);
+ createRun(session, support.getWorkspacePersistent("experiments"), experimentResource, experiment, listener, successCallback);
+ }
+
+ /**
+ * Create new experiment run in a selected virtual graph.
+ *
+ * @param session
+ * @param graph
+ * @param experimentResource
+ * @param experiment
+ * @param listener
+ */
+ public static void createRun(final Session session, VirtualGraph graph, final Resource experimentResource,
+ final IExperiment experiment, final IExperimentActivationListener listener,
+ final Consumer<Resource> successCallback)
+ {
+ createRun(session, graph, experimentResource, experiment, SimulationResource.URIs.Run, listener, successCallback);
+ }
+
+ public static void createRun(final Session session, VirtualGraph vg, final Resource experimentResource,
+ final IExperiment experiment, final String experimentRunTypeURI,
+ final IExperimentActivationListener listener, final Consumer<Resource> successCallback)
+ {
+ createRun(session, vg, experimentResource, experiment, experimentRunTypeURI, listener, null, successCallback);
+ }
+
+ /**
+ * Create new experiment run in a selected virtual graph.
+ *
+ * @param session
+ * @param vg
+ * @param experimentResource
+ * @param experiment
+ * @param experimentRunTypeURI
+ * @param listener
+ * @param successCallback if non-null invoked with the created run resource
+ * as an argument, just before invoking
+ * listener.onExperimentActivated(experiment)
+ */
+ public static void createRun(final Session session, VirtualGraph vg, final Resource experimentResource,
+ final IExperiment experiment, final String experimentRunTypeURI,
+ final IExperimentActivationListener listener,
+ final Function2<WriteGraph, Resource, Object> externalWrite,
+ final Consumer<Resource> successCallback)
+ {
+ createRun(session, vg,
+ experimentResource, experiment, experimentRunTypeURI,
+ listener, externalWrite, successCallback, true);
+ }
+
+ /**
+ * Create new experiment run in a selected virtual graph.
+ *
+ * @param session
+ * @param vg
+ * @param experimentResource
+ * @param experiment
+ * @param experimentRunTypeURI
+ * @param listener
+ * @param successCallback if non-null invoked with the created run resource
+ * as an argument, just before invoking
+ * listener.onExperimentActivated(experiment)
+ * @param attachDeactivationListener <code>true</code> to run for the created run-resource
+ * {@link #attachStateListener(Session, IExperiment, Resource)}
+ */
+ public static void createRun(
+ Session session,
+ VirtualGraph vg,
+ Resource experimentResource,
+ IExperiment experiment,
+ String experimentRunTypeURI,
+ IExperimentActivationListener listener,
+ Function2<WriteGraph, Resource, Object> externalWrite,
+ Consumer<Resource> successCallback,
+ boolean attachDeactivationListener)
+ {
+ final AtomicReference<Resource> run = new AtomicReference<>();
+ session.asyncRequest(new WriteRequest(vg) {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+// System.out.println("ExperimentActivator " + experimentResource + " " + experiment.getIdentifier());
+ run.set( createRun(graph, experimentResource, experiment, experimentRunTypeURI, externalWrite) );
+ }
+ }, e -> {
+ if (e != null) {
+ if (listener != null)
+ listener.onFailure(e);
+ else
+ ErrorLogger.defaultLogError(e);
+ } else {
+ if (attachDeactivationListener)
+ attachStateListener(session, experiment, run.get());
+ if (successCallback != null)
+ successCallback.accept(run.get());
+ if (listener != null)
+ listener.onExperimentActivated(experiment);
+ }
+ });
+ }
+
+ /**
+ * Create new experiment run in a selected virtual graph.
+ *
+ * @param session
+ * @param vg
+ * @param experimentResource
+ * @param experiment
+ * @param experimentRunTypeURI
+ * @param listener
+ * @param successCallback if non-null invoked with the created run resource
+ * as an argument, just before invoking
+ * listener.onExperimentActivated(experiment)
+ */
+ public static Resource createRun(WriteGraph graph,
+ VirtualGraph vg,
+ Resource experimentResource,
+ IExperiment experiment,
+ String experimentRunTypeURI,
+ Function2<WriteGraph, Resource, Object> externalWrite)
+ throws DatabaseException
+ {
+ return graph.syncRequest(new WriteResultRequest<Resource>(vg) {
+ @Override
+ public Resource perform(WriteGraph graph) throws DatabaseException {
+ return createRun(graph, experimentResource, experiment, experimentRunTypeURI, externalWrite);
+ }
+ });
+ }
+
+ public static Resource createRun(WriteGraph graph,
+ Resource experimentResource,
+ IExperiment experiment,
+ String experimentRunTypeURI,
+ Function2<WriteGraph, Resource, Object> externalWrite)
+ throws DatabaseException
+ {
+ Layer0 L0 = Layer0.getInstance(graph);
+ SimulationResource SIMU = SimulationResource.getInstance(graph);
+
+ Resource run = graph.newResource();
+ String label = NameUtils.findFreshLabel(graph, "Experiment", experimentResource);
+ graph.claim(run, L0.InstanceOf, null, graph.getResource(experimentRunTypeURI));
+ graph.addLiteral(run, L0.HasName, L0.NameOf, L0.String, experiment.getIdentifier(), Bindings.STRING);
+ graph.addLiteral(run, L0.HasLabel, L0.HasLabel_Inverse, L0.String, label, Bindings.STRING);
+ graph.addLiteral(run, SIMU.HasActivationTime, SIMU.HasActivationTime_Inverse, L0.Long, System.currentTimeMillis(), Bindings.LONG);
+ graph.claim(experimentResource, L0.ConsistsOf, L0.PartOf, run);
+
+ markRunActive(graph, run, externalWrite);
+
+ return run;
+ }
+
+ /**
+ * Mark the run active in the transient virtual graph.
+ *
+ * @param graph
+ * @param run
+ * @param externalWrite
+ * @throws DatabaseException
+ */
+ private static void markRunActive(
+ WriteGraph graph,
+ Resource run,
+ Function2<WriteGraph, Resource, Object> externalWrite)
+ throws DatabaseException
+ {
+ SimulationResource SIMU = SimulationResource.getInstance(graph);
+ VirtualGraph runtime = graph.getService(VirtualGraph.class);
+ graph.syncRequest(new WriteRequest(runtime) {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ graph.claim(run, SIMU.IsActive, run);
+ if(externalWrite != null)
+ externalWrite.apply(graph, run);
+ }
+ });
+ }
+
+ /**
+ * Add listener for tracking run IsActive state in the graph.
+ *
+ * @param session
+ * @param experiment
+ * @param run
+ */
+ private static void attachStateListener(final Session session, IExperiment experiment, final Resource run) {
+ experiment.addListener(new IExperimentListener() {
+ @Override
+ public void stateChanged(ExperimentState state) {
+ if (state == ExperimentState.DISPOSED) {
+ VirtualGraph runtime = session.getService(VirtualGraph.class);
+ session.asyncRequest(new WriteRequest(runtime) {
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ SimulationResource SIMU = SimulationResource.getInstance(graph);
+ graph.denyStatement(run, SIMU.IsActive, run);
+ }
+ }, e -> {
+ if (e != null)
+ ErrorLogger.defaultLogError(e);
+ });
+ }
+ }
+ });
+ }
+
+}