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