]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.simulation.ui/src/org/simantics/simulation/ui/handlers/ExperimentActivator.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.simulation.ui / src / org / simantics / simulation / ui / handlers / ExperimentActivator.java
diff --git a/bundles/org.simantics.simulation.ui/src/org/simantics/simulation/ui/handlers/ExperimentActivator.java b/bundles/org.simantics.simulation.ui/src/org/simantics/simulation/ui/handlers/ExperimentActivator.java
new file mode 100644 (file)
index 0000000..098ef22
--- /dev/null
@@ -0,0 +1,250 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.simulation.ui.handlers;\r
+\r
+import java.util.concurrent.Semaphore;\r
+import java.util.concurrent.atomic.AtomicInteger;\r
+import java.util.function.Consumer;\r
+\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.SubMonitor;\r
+import org.eclipse.core.runtime.jobs.Job;\r
+import org.eclipse.jface.dialogs.MessageDialog;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.ui.PlatformUI;\r
+import org.eclipse.ui.progress.IProgressConstants2;\r
+import org.simantics.DatabaseJob;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.request.UniqueRead;\r
+import org.simantics.db.common.utils.NameUtils;\r
+import org.simantics.db.exception.AdaptionException;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.message.ILogger;\r
+import org.simantics.message.MessageService;\r
+import org.simantics.project.IProject;\r
+import org.simantics.simulation.Activator;\r
+import org.simantics.simulation.experiment.IExperiment;\r
+import org.simantics.simulation.model.ExperimentLoadingCancelled;\r
+import org.simantics.simulation.model.ExperimentLoadingFailed;\r
+import org.simantics.simulation.project.IExperimentActivationListener;\r
+import org.simantics.simulation.project.IExperimentManager;\r
+import org.simantics.simulation.ui.ExperimentManagerListener;\r
+import org.simantics.utils.DataContainer;\r
+import org.simantics.utils.ui.ErrorLogger;\r
+import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
+\r
+/**\r
+ * A utility for performing experiment activation as a {@link Job} in the\r
+ * background.\r
+ * \r
+ * @author Tuukka Lehtonen\r
+ * \r
+ * @see ActivateExperimentAction\r
+ * @see ActivateExperimentHandler\r
+ */\r
+public class ExperimentActivator {\r
+\r
+    /**\r
+     * @param project\r
+     * @param experimentManager\r
+     * @param experiment\r
+     */\r
+    public static void scheduleActivation(RequestProcessor processor, IProject project, IExperimentManager experimentManager, Resource experiment) {\r
+        scheduleActivation(processor, project, experimentManager, experiment, null);\r
+    }\r
+\r
+    /**\r
+     * @param project\r
+     * @param experimentManager\r
+     * @param experiment\r
+     */\r
+    public static void scheduleActivation(RequestProcessor processor, IProject project, IExperimentManager experimentManager, Resource experiment, Consumer<IExperiment> callback) {\r
+        String jobName = "Activate Experiment";\r
+        String experimentName = getName(processor, experiment);\r
+        if (experimentName != null)\r
+            jobName += " '" + experimentName + "'";\r
+\r
+        scheduleActivation(jobName, project, experimentManager, experiment, callback);\r
+    }\r
+\r
+    static class ExperimentActivationJob extends DatabaseJob {\r
+        private IProject project;\r
+        private IExperimentManager experimentManager;\r
+        private Resource experiment;\r
+        private Consumer<IExperiment> callback;\r
+\r
+        public ExperimentActivationJob(String name, IProject project, IExperimentManager experimentManager, Resource experiment, Consumer<IExperiment> callback) {\r
+            super(name);\r
+            this.project = project;\r
+            this.experimentManager = experimentManager;\r
+            this.experiment = experiment;\r
+            this.callback = callback;\r
+        }\r
+\r
+        @Override\r
+        protected IStatus run(IProgressMonitor monitor) {\r
+            try {\r
+                return ExperimentActivator.activate(monitor, project, experimentManager, experiment, callback);\r
+            } finally {\r
+                monitor.done();\r
+                // Aid GC\r
+                project = null;\r
+                experimentManager = null;\r
+                experiment = null;\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param project\r
+     * @param experimentManager\r
+     * @param experiment\r
+     */\r
+    public static void scheduleActivation(String jobName, IProject project, IExperimentManager experimentManager, Resource experiment) {\r
+        scheduleActivation(jobName, project, experimentManager, experiment, null);\r
+    }\r
+\r
+    /**\r
+     * @param project\r
+     * @param experimentManager\r
+     * @param experiment\r
+     */\r
+    public static void scheduleActivation(String jobName, IProject project, IExperimentManager experimentManager, Resource experiment, Consumer<IExperiment> callback) {\r
+        Job job = new ExperimentActivationJob(jobName, project, experimentManager, experiment, callback);\r
+        job.setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE);\r
+        job.setUser(true);\r
+        job.schedule();\r
+    }\r
+\r
+    public static IStatus activate(IProgressMonitor monitor, IProject project, IExperimentManager experimentManager, Resource experiment) {\r
+        return activate(monitor, project, experimentManager, experiment, null);\r
+    }\r
+\r
+    public static IStatus activate(IProgressMonitor monitor, IProject project, IExperimentManager experimentManager, Resource experiment, Consumer<IExperiment> callback) {\r
+        return new ExperimentActivator().activateExperiment(monitor, project, experimentManager, experiment, callback);\r
+    }\r
+\r
+    private static String getName(RequestProcessor processor, final Resource resource) {\r
+        try {\r
+            return processor.syncRequest(new UniqueRead<String>() {\r
+                @Override\r
+                public String perform(ReadGraph graph) throws DatabaseException {\r
+                    try {\r
+                        return graph.adapt(resource, String.class);\r
+                    } catch (AdaptionException e) {\r
+                        return NameUtils.getSafeName(graph, resource);\r
+                    }\r
+                }\r
+            });\r
+        } catch (DatabaseException e) {\r
+            ErrorLogger.defaultLogWarning(e);\r
+            return null;\r
+        }\r
+    }\r
+\r
+    private IStatus activateExperiment(IProgressMonitor monitor, IProject project, IExperimentManager manager, final Resource experimentResource, Consumer<IExperiment> callback) {\r
+        final SubMonitor mon = SubMonitor.convert(monitor, "Activating experiment", 100000);\r
+\r
+        ExperimentManagerListener.listenManager(manager);\r
+        final Semaphore activated = new Semaphore(0);\r
+        final DataContainer<IExperiment> activatedExperiment = new DataContainer<>();\r
+        final DataContainer<Throwable> problem = new DataContainer<>();\r
+        final AtomicInteger worstMessageSeverity = new AtomicInteger(IStatus.OK);\r
+        final ILogger messageService = MessageService.getDefault();\r
+        manager.startExperiment(experimentResource, new IExperimentActivationListener() {\r
+\r
+            @Override\r
+            public void onExperimentActivated(final IExperiment experiment) {\r
+                MessageService.defaultLog(new org.eclipse.core.runtime.Status(IStatus.INFO, "org.simantics.simulation.ui", 0, "Activated experiment " + experiment.getIdentifier() , null));\r
+                activatedExperiment.set(experiment);\r
+                activated.release();\r
+            }\r
+            @Override\r
+            public void onFailure(Throwable e) {\r
+                problem.set(e);\r
+                activated.release();\r
+            }\r
+            @Override\r
+            public void onMessage(IStatus message) {\r
+                messageService.log(message);\r
+                int s = message.getSeverity();\r
+                if (s > worstMessageSeverity.get())\r
+                    worstMessageSeverity.set(s);\r
+            }\r
+            @Override\r
+            public IProgressMonitor getProgressMonitor() {\r
+                return mon;\r
+            }\r
+        }, true);\r
+        try {\r
+            activated.acquire();\r
+            Throwable t = problem.get();\r
+            IStatus status = null;\r
+            if (t != null) {\r
+                if (t instanceof ExperimentLoadingFailed) {\r
+                    ExperimentLoadingFailed ex = (ExperimentLoadingFailed) t;\r
+                    if (t instanceof ExperimentLoadingCancelled) {\r
+                        status = Status.CANCEL_STATUS;\r
+                    } else {\r
+                        // Make sure that the error window gets correct parent\r
+                        // shell, i.e. the workbench window shell, not the job\r
+                        // progress window shell.\r
+                        Activator.logError("Experiment activation failed, see exception for details.", t);\r
+                        if (PlatformUI.isWorkbenchRunning())\r
+                            PlatformUI.getWorkbench().getDisplay().asyncExec(showError("Experiment Activation Failed", t.getMessage() + "\n\nSee Error Log for details."));\r
+                    }\r
+                    if (ex.getHelperAction() != null && PlatformUI.isWorkbenchRunning())\r
+                        PlatformUI.getWorkbench().getDisplay().asyncExec(ex.getHelperAction());\r
+                } else {\r
+                    Activator.logError("Experiment activation failed, see exception for details.", t);\r
+                    if (PlatformUI.isWorkbenchRunning())\r
+                        PlatformUI.getWorkbench().getDisplay().asyncExec(showError("Experiment Activation Failed", t.getMessage() + "\n\nSee Error Log for details."));\r
+                }\r
+            }\r
+\r
+//            if (worstMessageSeverity.get() > IStatus.OK) {\r
+//                SWTUtils.asyncExec(PlatformUI.getWorkbench().getDisplay(), new Runnable() {\r
+//                    @Override\r
+//                    public void run() {\r
+//                        try {\r
+//                            WorkbenchUtils.activateView("org.simantics.message.view");\r
+//                        } catch (PartInitException ex) {\r
+//                            ExceptionUtils.logError(ex);\r
+//                        }\r
+//                    }\r
+//                });\r
+//            }\r
+\r
+            if (callback != null)\r
+                callback.accept(activatedExperiment.get());\r
+\r
+            return status != null ? status : Status.OK_STATUS;\r
+        } catch (InterruptedException e) {\r
+            return Status.CANCEL_STATUS;\r
+        }\r
+    }\r
+\r
+    private Runnable showError(String title, String message) {\r
+        return new Runnable() {\r
+            @Override\r
+            public void run() {\r
+                Shell parent = WorkbenchUtils.getActiveWorkbenchWindowShell();\r
+                MessageDialog.openError(parent, title, message);\r
+            }\r
+        };\r
+    }\r
+\r
+}\r