tmf: Bug 416167: Buggy trace freezes UI when restored at start time
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.ui / src / org / eclipse / linuxtools / tmf / ui / project / model / TmfOpenTraceHelper.java
1 /**********************************************************************
2 * Copyright (c) 2013 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 * Patrick Tasse - Update open trace and add open experiment
12 **********************************************************************/
13
14 package org.eclipse.linuxtools.tmf.ui.project.model;
15
16 import java.io.File;
17 import java.util.List;
18
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.resources.IFolder;
21 import org.eclipse.core.resources.IProject;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.resources.IWorkspace;
24 import org.eclipse.core.resources.IWorkspaceRoot;
25 import org.eclipse.core.resources.ResourcesPlugin;
26 import org.eclipse.core.runtime.CoreException;
27 import org.eclipse.core.runtime.IPath;
28 import org.eclipse.core.runtime.IStatus;
29 import org.eclipse.core.runtime.Path;
30 import org.eclipse.core.runtime.Status;
31 import org.eclipse.linuxtools.internal.tmf.ui.Activator;
32 import org.eclipse.linuxtools.internal.tmf.ui.project.model.TmfImportHelper;
33 import org.eclipse.linuxtools.internal.tmf.ui.project.model.TmfTraceImportException;
34 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
35 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
36 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
37 import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
38 import org.eclipse.linuxtools.tmf.ui.editors.TmfEditorInput;
39 import org.eclipse.linuxtools.tmf.ui.editors.TmfEventsEditor;
40 import org.eclipse.swt.widgets.Display;
41 import org.eclipse.swt.widgets.MessageBox;
42 import org.eclipse.swt.widgets.Shell;
43 import org.eclipse.ui.IEditorInput;
44 import org.eclipse.ui.IEditorPart;
45 import org.eclipse.ui.IReusableEditor;
46 import org.eclipse.ui.IWorkbench;
47 import org.eclipse.ui.IWorkbenchPage;
48 import org.eclipse.ui.PartInitException;
49 import org.eclipse.ui.PlatformUI;
50 import org.eclipse.ui.ide.IDE;
51 import org.eclipse.ui.part.FileEditorInput;
52
53 /**
54 * Open trace helper
55 *
56 * Helper class for opening trace resources and loading them to a tracing
57 * project.
58 *
59 * @author Matthew Khouzam
60 * @since 2.1
61 */
62 public class TmfOpenTraceHelper {
63
64 private static final String ENDL = System.getProperty("line.separator"); //$NON-NLS-1$
65
66 /**
67 * Opens a trace from a path while importing it to the project
68 * "projectRoot". The trace is linked as a resource.
69 *
70 * @param projectRoot
71 * The project to import to
72 * @param path
73 * the file to import
74 * @param shell
75 * the shell to use for dialogs
76 * @return IStatus OK if successful
77 * @throws CoreException
78 * core exceptions if something is not well set up in the back
79 * end
80 */
81 public IStatus openTraceFromPath(String projectRoot, String path, Shell shell) throws CoreException {
82 TmfTraceType tt = TmfTraceType.getInstance();
83 TraceTypeHelper traceTypeToSet = null;
84 try {
85 traceTypeToSet = tt.selectTraceType(path, shell);
86 } catch (TmfTraceImportException e) {
87 MessageBox mb = new MessageBox(shell);
88 mb.setMessage(e.getMessage());
89 mb.open();
90 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage());
91 }
92 if (traceTypeToSet == null) {
93 return Status.CANCEL_STATUS;
94 }
95 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectRoot);
96 IFolder folder = project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME);
97 String traceName = getTraceName(path, folder);
98 if (traceExists(path, folder)) {
99 return openTraceFromProject(projectRoot, traceName);
100 }
101 final IPath tracePath = folder.getFullPath().append(traceName);
102 final IPath pathString = Path.fromOSString(path);
103 IResource linkedTrace = TmfImportHelper.createLink(folder, pathString, traceName);
104 if (linkedTrace != null && linkedTrace.exists()) {
105 IStatus ret = TmfTraceType.setTraceType(tracePath, traceTypeToSet);
106 if (ret.isOK()) {
107 ret = openTraceFromProject(projectRoot, traceName);
108 }
109 return ret;
110 }
111 return new Status(IStatus.ERROR, Activator.PLUGIN_ID,
112 Messages.TmfOpenTraceHelper_LinkFailed);
113 }
114
115 private static boolean traceExists(String file, IFolder folder) {
116 String val = getTraceName(file, folder);
117 return (folder.findMember(val) != null);
118 }
119
120 private static boolean isWrongMember(IFolder folder, String ret, final File traceFile) {
121 final IResource candidate = folder.findMember(ret);
122 if (candidate != null) {
123 final IPath rawLocation = candidate.getRawLocation();
124 final File file = rawLocation.toFile();
125 return !file.equals(traceFile);
126 }
127 return false;
128 }
129
130 /**
131 * Gets the display name, either "filename" or "filename(n)" if there is
132 * already a filename existing where n is the next non-used integer starting
133 * from 2
134 *
135 * @param file
136 * the file with path
137 * @param folder
138 * the folder to import to
139 * @return the filename
140 */
141 private static String getTraceName(String file, IFolder folder) {
142 String ret;
143 final File traceFile = new File(file);
144 ret = traceFile.getName();
145 for (int i = 2; isWrongMember(folder, ret, traceFile); i++) {
146 ret = traceFile.getName() + '(' + i + ')';
147 }
148 return ret;
149 }
150
151 /**
152 * Open a trace from a project
153 *
154 * @param projectRoot
155 * the root of the project
156 * @param traceName
157 * the trace name
158 * @return success or error
159 */
160 public static IStatus openTraceFromProject(String projectRoot, String traceName) {
161 final IWorkspace workspace = ResourcesPlugin.getWorkspace();
162 final IWorkspaceRoot root = workspace.getRoot();
163 IProject project = root.getProject(projectRoot);
164 TmfImportHelper.forceFolderRefresh(project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME));
165
166 final TmfProjectElement project2 = TmfProjectRegistry.getProject(project, true);
167 final TmfTraceFolder tracesFolder = project2.getTracesFolder();
168 final List<TmfTraceElement> traces = tracesFolder.getTraces();
169 TmfTraceElement found = null;
170 for (TmfTraceElement candidate : traces) {
171 if (candidate.getName().equals(traceName)) {
172 found = candidate;
173 }
174 }
175 if (found == null) {
176 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TmfOpenTraceHelper_ErrorOpeningTrace);
177 }
178 openTraceFromElement(found);
179 return Status.OK_STATUS;
180 }
181
182 /**
183 * Open a trace from a trace element. If the trace is already opened,
184 * its editor is activated and brought to top.
185 *
186 * @param traceElement
187 * the {@link TmfTraceElement} to open
188 */
189 public static void openTraceFromElement(final TmfTraceElement traceElement) {
190
191 final IFile file;
192 try {
193 file = traceElement.createBookmarksFile();
194 } catch (final CoreException e) {
195 Activator.getDefault().logError(Messages.TmfOpenTraceHelper_ErrorOpeningTrace + ' ' + traceElement.getName());
196 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenTrace, Messages.TmfOpenTraceHelper_ErrorTrace + ENDL + ENDL + e.getMessage());
197 return;
198 }
199
200 final IWorkbench wb = PlatformUI.getWorkbench();
201 final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
202 final IEditorPart editor = activePage.findEditor(new FileEditorInput(file));
203 if (editor != null) {
204 activePage.activate(editor);
205 return;
206 }
207
208 Thread thread = new Thread() {
209 @Override
210 public void run() {
211
212 final ITmfTrace trace = traceElement.instantiateTrace();
213 final ITmfEvent traceEvent = traceElement.instantiateEvent();
214 if ((trace == null) || (traceEvent == null)) {
215 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenTrace, Messages.TmfOpenTraceHelper_NoTraceType);
216 if (trace != null) {
217 trace.dispose();
218 }
219 return;
220 }
221
222 try {
223 trace.initTrace(traceElement.getResource(), traceElement.getLocation().getPath(), traceEvent.getClass());
224 } catch (final TmfTraceException e) {
225 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenTrace, Messages.TmfOpenTraceHelper_InitError + ENDL + ENDL + e);
226 trace.dispose();
227 return;
228 }
229
230 // Get the editor id from the extension point
231 String traceEditorId = traceElement.getEditorId();
232 final String editorId = (traceEditorId != null) ? traceEditorId : TmfEventsEditor.ID;
233 final IEditorInput editorInput = new TmfEditorInput(file, trace);
234
235 Display.getDefault().asyncExec(new Runnable() {
236 @Override
237 public void run() {
238 try {
239 activePage.openEditor(editorInput, editorId);
240 IDE.setDefaultEditor(file, editorId);
241 // editor should dispose the trace on close
242 } catch (final PartInitException e) {
243 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenTrace, Messages.TmfOpenTraceHelper_ErrorOpeningTrace + ENDL + ENDL + e.getMessage());
244 Activator.getDefault().logError(Messages.TmfOpenTraceHelper_ErrorOpeningTrace + ' ' + traceElement.getName());
245 trace.dispose();
246 }
247 }
248 });
249 }
250 };
251 thread.start();
252 }
253
254 /**
255 * Open an experiment from an experiment element. If the experiment is already opened,
256 * its editor is activated and brought to top.
257 *
258 * @param experimentElement
259 * the {@link TmfExperimentElement} to open
260 */
261 public static void openExperimentFromElement(final TmfExperimentElement experimentElement) {
262
263 final IFile file;
264 try {
265 file = experimentElement.createBookmarksFile();
266 } catch (final CoreException e) {
267 Activator.getDefault().logError(Messages.TmfOpenTraceHelper_ErrorOpeningExperiment + ' ' + experimentElement.getName());
268 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenExperiment, Messages.TmfOpenTraceHelper_ErrorExperiment + ENDL + ENDL + e.getMessage());
269 return;
270 }
271
272 final IWorkbench wb = PlatformUI.getWorkbench();
273 final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
274 final IEditorPart editor = activePage.findEditor(new FileEditorInput(file));
275 if (editor != null) {
276 activePage.activate(editor);
277 return;
278 }
279
280 Thread thread = new Thread() {
281 @Override
282 public void run() {
283
284 /* Unlike traces, there is no instanceExperiment, so we call this function
285 * here alone. Maybe it would be better to do this on experiment's element
286 * constructor?
287 */
288 experimentElement.refreshSupplementaryFolder();
289
290 // Instantiate the experiment's traces
291 final List<TmfTraceElement> traceEntries = experimentElement.getTraces();
292 final int nbTraces = traceEntries.size();
293 int cacheSize = Integer.MAX_VALUE;
294 String commonEditorId = null;
295 final ITmfTrace[] traces = new ITmfTrace[nbTraces];
296 for (int i = 0; i < nbTraces; i++) {
297 TmfTraceElement element = traceEntries.get(i);
298
299 // Since trace is under an experiment, use the original trace from the traces folder
300 element = element.getElementUnderTraceFolder();
301
302 final ITmfTrace trace = element.instantiateTrace();
303 final ITmfEvent traceEvent = element.instantiateEvent();
304 if ((trace == null) || (traceEvent == null)) {
305 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenExperiment,
306 Messages.TmfOpenTraceHelper_ErrorOpeningTrace + ' ' + element.getName() +
307 ENDL + Messages.TmfOpenTraceHelper_NoTraceType);
308 for (int j = 0; j < i; j++) {
309 traces[j].dispose();
310 }
311 if (trace != null) {
312 trace.dispose();
313 }
314 return;
315 }
316 try {
317 trace.initTrace(element.getResource(), element.getLocation().getPath(), traceEvent.getClass());
318 } catch (final TmfTraceException e) {
319 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenExperiment,
320 element.getName() + ':' + ' ' + Messages.TmfOpenTraceHelper_InitError + ENDL + ENDL + e);
321 for (int j = 0; j < i; j++) {
322 traces[j].dispose();
323 }
324 trace.dispose();
325 return;
326 }
327 cacheSize = Math.min(cacheSize, trace.getCacheSize());
328
329 // If all traces use the same editorId, use it, otherwise use the default
330 final String editorId = element.getEditorId();
331 if (commonEditorId == null) {
332 commonEditorId = (editorId != null) ? editorId : TmfEventsEditor.ID;
333 } else if (!commonEditorId.equals(editorId)) {
334 commonEditorId = TmfEventsEditor.ID;
335 }
336 traces[i] = trace;
337 }
338
339 // Create the experiment
340 final TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, experimentElement.getName(), traces, cacheSize, experimentElement.getResource());
341 experiment.setBookmarksFile(file);
342
343 final String editorId = commonEditorId;
344 final IEditorInput editorInput = new TmfEditorInput(file, experiment);
345
346 Display.getDefault().asyncExec(new Runnable() {
347 @Override
348 public void run() {
349 try {
350 activePage.openEditor(editorInput, editorId);
351 IDE.setDefaultEditor(file, editorId);
352 // editor should dispose the trace on close
353 } catch (final PartInitException e) {
354 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenExperiment, Messages.TmfOpenTraceHelper_ErrorOpeningExperiment + ENDL + ENDL + e.getMessage());
355 Activator.getDefault().logError(Messages.TmfOpenTraceHelper_ErrorOpeningExperiment + ' ' + experimentElement.getName());
356 experiment.dispose();
357 }
358 }
359 });
360 }
361 };
362 thread.start();
363 }
364
365 /**
366 * Reopen a trace from a trace element in the provided editor
367 *
368 * @param traceElement
369 * the {@link TmfTraceElement} to open
370 * @param editor
371 * the reusable editor
372 */
373 public static void reopenTraceFromElement(final TmfTraceElement traceElement, final IReusableEditor editor) {
374
375 final IFile file;
376 try {
377 file = traceElement.createBookmarksFile();
378 } catch (final CoreException e) {
379 Activator.getDefault().logError(Messages.TmfOpenTraceHelper_ErrorOpeningTrace + ' ' + traceElement.getName());
380 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenTrace, Messages.TmfOpenTraceHelper_ErrorTrace + ENDL + ENDL + e.getMessage());
381 return;
382 }
383
384 Thread thread = new Thread() {
385 @Override
386 public void run() {
387
388 final ITmfTrace trace = traceElement.instantiateTrace();
389 final ITmfEvent traceEvent = traceElement.instantiateEvent();
390 if ((trace == null) || (traceEvent == null)) {
391 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenTrace, Messages.TmfOpenTraceHelper_NoTraceType);
392 if (trace != null) {
393 trace.dispose();
394 }
395 return;
396 }
397
398 try {
399 trace.initTrace(traceElement.getResource(), traceElement.getLocation().getPath(), traceEvent.getClass());
400 } catch (final TmfTraceException e) {
401 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenTrace, Messages.TmfOpenTraceHelper_InitError + ENDL + ENDL + e);
402 trace.dispose();
403 return;
404 }
405
406 final IEditorInput editorInput = new TmfEditorInput(file, trace);
407
408 Display.getDefault().asyncExec(new Runnable() {
409 @Override
410 public void run() {
411 final IWorkbench wb = PlatformUI.getWorkbench();
412 final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
413 activePage.reuseEditor(editor, editorInput);
414 activePage.activate(editor);
415 }
416 });
417 }
418 };
419 thread.start();
420 }
421
422 /**
423 * Reopen an experiment from an experiment element in the provided editor
424 *
425 * @param experimentElement
426 * the {@link TmfExperimentElement} to open
427 * @param editor
428 * the reusable editor
429 */
430 public static void reopenExperimentFromElement(final TmfExperimentElement experimentElement, final IReusableEditor editor) {
431
432 final IFile file;
433 try {
434 file = experimentElement.createBookmarksFile();
435 } catch (final CoreException e) {
436 Activator.getDefault().logError(Messages.TmfOpenTraceHelper_ErrorOpeningExperiment + ' ' + experimentElement.getName());
437 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenExperiment, Messages.TmfOpenTraceHelper_ErrorExperiment + ENDL + ENDL + e.getMessage());
438 return;
439 }
440
441 Thread thread = new Thread() {
442 @Override
443 public void run() {
444
445 /* Unlike traces, there is no instanceExperiment, so we call this function
446 * here alone. Maybe it would be better to do this on experiment's element
447 * constructor?
448 */
449 experimentElement.refreshSupplementaryFolder();
450
451 // Instantiate the experiment's traces
452 final List<TmfTraceElement> traceEntries = experimentElement.getTraces();
453 final int nbTraces = traceEntries.size();
454 int cacheSize = Integer.MAX_VALUE;
455 final ITmfTrace[] traces = new ITmfTrace[nbTraces];
456 for (int i = 0; i < nbTraces; i++) {
457 TmfTraceElement element = traceEntries.get(i);
458
459 // Since trace is under an experiment, use the original trace from the traces folder
460 element = element.getElementUnderTraceFolder();
461
462 final ITmfTrace trace = element.instantiateTrace();
463 final ITmfEvent traceEvent = element.instantiateEvent();
464 if ((trace == null) || (traceEvent == null)) {
465 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenExperiment,
466 Messages.TmfOpenTraceHelper_ErrorOpeningTrace + ' ' + element.getName() +
467 ENDL + Messages.TmfOpenTraceHelper_NoTraceType);
468 for (int j = 0; j < i; j++) {
469 traces[j].dispose();
470 }
471 if (trace != null) {
472 trace.dispose();
473 }
474 return;
475 }
476 try {
477 trace.initTrace(element.getResource(), element.getLocation().getPath(), traceEvent.getClass());
478 } catch (final TmfTraceException e) {
479 TraceUtils.displayErrorMsg(Messages.TmfOpenTraceHelper_OpenExperiment,
480 element.getName() + ':' + ' ' + Messages.TmfOpenTraceHelper_InitError + ENDL + ENDL + e);
481 for (int j = 0; j < i; j++) {
482 traces[j].dispose();
483 }
484 trace.dispose();
485 return;
486 }
487 cacheSize = Math.min(cacheSize, trace.getCacheSize());
488
489 traces[i] = trace;
490 }
491
492 // Create the experiment
493 final TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, experimentElement.getName(), traces, cacheSize, experimentElement.getResource());
494 experiment.setBookmarksFile(file);
495
496 final IEditorInput editorInput = new TmfEditorInput(file, experiment);
497
498 Display.getDefault().asyncExec(new Runnable() {
499 @Override
500 public void run() {
501 final IWorkbench wb = PlatformUI.getWorkbench();
502 final IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage();
503 activePage.reuseEditor(editor, editorInput);
504 activePage.activate(editor);
505 }
506 });
507 }
508 };
509 thread.start();
510 }
511
512 }
This page took 0.043349 seconds and 5 git commands to generate.