]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.simulation.ui.handlers;\r
13 \r
14 import java.util.concurrent.Semaphore;\r
15 import java.util.concurrent.atomic.AtomicInteger;\r
16 import java.util.function.Consumer;\r
17 \r
18 import org.eclipse.core.runtime.IProgressMonitor;\r
19 import org.eclipse.core.runtime.IStatus;\r
20 import org.eclipse.core.runtime.Status;\r
21 import org.eclipse.core.runtime.SubMonitor;\r
22 import org.eclipse.core.runtime.jobs.Job;\r
23 import org.eclipse.jface.dialogs.MessageDialog;\r
24 import org.eclipse.swt.widgets.Shell;\r
25 import org.eclipse.ui.PlatformUI;\r
26 import org.eclipse.ui.progress.IProgressConstants2;\r
27 import org.simantics.DatabaseJob;\r
28 import org.simantics.db.ReadGraph;\r
29 import org.simantics.db.RequestProcessor;\r
30 import org.simantics.db.Resource;\r
31 import org.simantics.db.common.request.UniqueRead;\r
32 import org.simantics.db.common.utils.NameUtils;\r
33 import org.simantics.db.exception.AdaptionException;\r
34 import org.simantics.db.exception.DatabaseException;\r
35 import org.simantics.message.ILogger;\r
36 import org.simantics.message.MessageService;\r
37 import org.simantics.project.IProject;\r
38 import org.simantics.simulation.Activator;\r
39 import org.simantics.simulation.experiment.IExperiment;\r
40 import org.simantics.simulation.model.ExperimentLoadingCancelled;\r
41 import org.simantics.simulation.model.ExperimentLoadingFailed;\r
42 import org.simantics.simulation.project.IExperimentActivationListener;\r
43 import org.simantics.simulation.project.IExperimentManager;\r
44 import org.simantics.simulation.ui.ExperimentManagerListener;\r
45 import org.simantics.utils.DataContainer;\r
46 import org.simantics.utils.ui.ErrorLogger;\r
47 import org.simantics.utils.ui.workbench.WorkbenchUtils;\r
48 \r
49 /**\r
50  * A utility for performing experiment activation as a {@link Job} in the\r
51  * background.\r
52  * \r
53  * @author Tuukka Lehtonen\r
54  * \r
55  * @see ActivateExperimentAction\r
56  * @see ActivateExperimentHandler\r
57  */\r
58 public class ExperimentActivator {\r
59 \r
60     /**\r
61      * @param project\r
62      * @param experimentManager\r
63      * @param experiment\r
64      */\r
65     public static void scheduleActivation(RequestProcessor processor, IProject project, IExperimentManager experimentManager, Resource experiment) {\r
66         scheduleActivation(processor, project, experimentManager, experiment, null);\r
67     }\r
68 \r
69     /**\r
70      * @param project\r
71      * @param experimentManager\r
72      * @param experiment\r
73      */\r
74     public static void scheduleActivation(RequestProcessor processor, IProject project, IExperimentManager experimentManager, Resource experiment, Consumer<IExperiment> callback) {\r
75         String jobName = "Activate Experiment";\r
76         String experimentName = getName(processor, experiment);\r
77         if (experimentName != null)\r
78             jobName += " '" + experimentName + "'";\r
79 \r
80         scheduleActivation(jobName, project, experimentManager, experiment, callback);\r
81     }\r
82 \r
83     static class ExperimentActivationJob extends DatabaseJob {\r
84         private IProject project;\r
85         private IExperimentManager experimentManager;\r
86         private Resource experiment;\r
87         private Consumer<IExperiment> callback;\r
88 \r
89         public ExperimentActivationJob(String name, IProject project, IExperimentManager experimentManager, Resource experiment, Consumer<IExperiment> callback) {\r
90             super(name);\r
91             this.project = project;\r
92             this.experimentManager = experimentManager;\r
93             this.experiment = experiment;\r
94             this.callback = callback;\r
95         }\r
96 \r
97         @Override\r
98         protected IStatus run(IProgressMonitor monitor) {\r
99             try {\r
100                 return ExperimentActivator.activate(monitor, project, experimentManager, experiment, callback);\r
101             } finally {\r
102                 monitor.done();\r
103                 // Aid GC\r
104                 project = null;\r
105                 experimentManager = null;\r
106                 experiment = null;\r
107             }\r
108         }\r
109     }\r
110 \r
111     /**\r
112      * @param project\r
113      * @param experimentManager\r
114      * @param experiment\r
115      */\r
116     public static void scheduleActivation(String jobName, IProject project, IExperimentManager experimentManager, Resource experiment) {\r
117         scheduleActivation(jobName, project, experimentManager, experiment, null);\r
118     }\r
119 \r
120     /**\r
121      * @param project\r
122      * @param experimentManager\r
123      * @param experiment\r
124      */\r
125     public static void scheduleActivation(String jobName, IProject project, IExperimentManager experimentManager, Resource experiment, Consumer<IExperiment> callback) {\r
126         Job job = new ExperimentActivationJob(jobName, project, experimentManager, experiment, callback);\r
127         job.setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE);\r
128         job.setUser(true);\r
129         job.schedule();\r
130     }\r
131 \r
132     public static IStatus activate(IProgressMonitor monitor, IProject project, IExperimentManager experimentManager, Resource experiment) {\r
133         return activate(monitor, project, experimentManager, experiment, null);\r
134     }\r
135 \r
136     public static IStatus activate(IProgressMonitor monitor, IProject project, IExperimentManager experimentManager, Resource experiment, Consumer<IExperiment> callback) {\r
137         return new ExperimentActivator().activateExperiment(monitor, project, experimentManager, experiment, callback);\r
138     }\r
139 \r
140     private static String getName(RequestProcessor processor, final Resource resource) {\r
141         try {\r
142             return processor.syncRequest(new UniqueRead<String>() {\r
143                 @Override\r
144                 public String perform(ReadGraph graph) throws DatabaseException {\r
145                     try {\r
146                         return graph.adapt(resource, String.class);\r
147                     } catch (AdaptionException e) {\r
148                         return NameUtils.getSafeName(graph, resource);\r
149                     }\r
150                 }\r
151             });\r
152         } catch (DatabaseException e) {\r
153             ErrorLogger.defaultLogWarning(e);\r
154             return null;\r
155         }\r
156     }\r
157 \r
158     private IStatus activateExperiment(IProgressMonitor monitor, IProject project, IExperimentManager manager, final Resource experimentResource, Consumer<IExperiment> callback) {\r
159         final SubMonitor mon = SubMonitor.convert(monitor, "Activating experiment", 100000);\r
160 \r
161         ExperimentManagerListener.listenManager(manager);\r
162         final Semaphore activated = new Semaphore(0);\r
163         final DataContainer<IExperiment> activatedExperiment = new DataContainer<>();\r
164         final DataContainer<Throwable> problem = new DataContainer<>();\r
165         final AtomicInteger worstMessageSeverity = new AtomicInteger(IStatus.OK);\r
166         final ILogger messageService = MessageService.getDefault();\r
167         manager.startExperiment(experimentResource, new IExperimentActivationListener() {\r
168 \r
169             @Override\r
170             public void onExperimentActivated(final IExperiment experiment) {\r
171                 MessageService.defaultLog(new org.eclipse.core.runtime.Status(IStatus.INFO, "org.simantics.simulation.ui", 0, "Activated experiment " + experiment.getIdentifier() , null));\r
172                 activatedExperiment.set(experiment);\r
173                 activated.release();\r
174             }\r
175             @Override\r
176             public void onFailure(Throwable e) {\r
177                 problem.set(e);\r
178                 activated.release();\r
179             }\r
180             @Override\r
181             public void onMessage(IStatus message) {\r
182                 messageService.log(message);\r
183                 int s = message.getSeverity();\r
184                 if (s > worstMessageSeverity.get())\r
185                     worstMessageSeverity.set(s);\r
186             }\r
187             @Override\r
188             public IProgressMonitor getProgressMonitor() {\r
189                 return mon;\r
190             }\r
191         }, true);\r
192         try {\r
193             activated.acquire();\r
194             Throwable t = problem.get();\r
195             IStatus status = null;\r
196             if (t != null) {\r
197                 if (t instanceof ExperimentLoadingFailed) {\r
198                     ExperimentLoadingFailed ex = (ExperimentLoadingFailed) t;\r
199                     if (t instanceof ExperimentLoadingCancelled) {\r
200                         status = Status.CANCEL_STATUS;\r
201                     } else {\r
202                         // Make sure that the error window gets correct parent\r
203                         // shell, i.e. the workbench window shell, not the job\r
204                         // progress window shell.\r
205                         Activator.logError("Experiment activation failed, see exception for details.", t);\r
206                         if (PlatformUI.isWorkbenchRunning())\r
207                             PlatformUI.getWorkbench().getDisplay().asyncExec(showError("Experiment Activation Failed", t.getMessage() + "\n\nSee Error Log for details."));\r
208                     }\r
209                     if (ex.getHelperAction() != null && PlatformUI.isWorkbenchRunning())\r
210                         PlatformUI.getWorkbench().getDisplay().asyncExec(ex.getHelperAction());\r
211                 } else {\r
212                     Activator.logError("Experiment activation failed, see exception for details.", t);\r
213                     if (PlatformUI.isWorkbenchRunning())\r
214                         PlatformUI.getWorkbench().getDisplay().asyncExec(showError("Experiment Activation Failed", t.getMessage() + "\n\nSee Error Log for details."));\r
215                 }\r
216             }\r
217 \r
218 //            if (worstMessageSeverity.get() > IStatus.OK) {\r
219 //                SWTUtils.asyncExec(PlatformUI.getWorkbench().getDisplay(), new Runnable() {\r
220 //                    @Override\r
221 //                    public void run() {\r
222 //                        try {\r
223 //                            WorkbenchUtils.activateView("org.simantics.message.view");\r
224 //                        } catch (PartInitException ex) {\r
225 //                            ExceptionUtils.logError(ex);\r
226 //                        }\r
227 //                    }\r
228 //                });\r
229 //            }\r
230 \r
231             if (callback != null)\r
232                 callback.accept(activatedExperiment.get());\r
233 \r
234             return status != null ? status : Status.OK_STATUS;\r
235         } catch (InterruptedException e) {\r
236             return Status.CANCEL_STATUS;\r
237         }\r
238     }\r
239 \r
240     private Runnable showError(String title, String message) {\r
241         return new Runnable() {\r
242             @Override\r
243             public void run() {\r
244                 Shell parent = WorkbenchUtils.getActiveWorkbenchWindowShell();\r
245                 MessageDialog.openError(parent, title, message);\r
246             }\r
247         };\r
248     }\r
249 \r
250 }\r