1 /**********************************************************************
2 * Copyright (c) 2013 Ericsson
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
10 * Matthew Khouzam - Initial API and implementation
11 * Patrick Tasse - Update open trace and add open experiment
12 **********************************************************************/
14 package org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
;
17 import java
.util
.List
;
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
.IEditorReference
;
46 import org
.eclipse
.ui
.IReusableEditor
;
47 import org
.eclipse
.ui
.IWorkbench
;
48 import org
.eclipse
.ui
.IWorkbenchPage
;
49 import org
.eclipse
.ui
.PartInitException
;
50 import org
.eclipse
.ui
.PlatformUI
;
51 import org
.eclipse
.ui
.ide
.IDE
;
52 import org
.eclipse
.ui
.part
.FileEditorInput
;
57 * Helper class for opening trace resources and loading them to a tracing
60 * @author Matthew Khouzam
63 public class TmfOpenTraceHelper
{
65 private static final String ENDL
= System
.getProperty("line.separator"); //$NON-NLS-1$
68 * Opens a trace from a path while importing it to the project
69 * "projectRoot". The trace is linked as a resource.
72 * The project to import to
76 * the shell to use for dialogs
77 * @return IStatus OK if successful
78 * @throws CoreException
79 * core exceptions if something is not well set up in the back
82 public IStatus
openTraceFromPath(String projectRoot
, String path
, Shell shell
) throws CoreException
{
83 return openTraceFromPath(projectRoot
, path
, shell
, null);
87 * Opens a trace from a path while importing it to the project
88 * "projectRoot". The trace is linked as a resource.
91 * The project to import to
95 * the shell to use for dialogs
96 * @param tracetypeHint
97 * The trace type id, can be null
98 * @return IStatus OK if successful
99 * @throws CoreException
100 * core exceptions if something is not well set up in the back
105 public IStatus
openTraceFromPath(String projectRoot
, String path
, Shell shell
, String tracetypeHint
) throws CoreException
{
106 TmfTraceType tt
= TmfTraceType
.getInstance();
107 TraceTypeHelper traceTypeToSet
= null;
109 traceTypeToSet
= tt
.selectTraceType(path
, shell
, tracetypeHint
);
110 } catch (TmfTraceImportException e
) {
111 MessageBox mb
= new MessageBox(shell
);
112 mb
.setMessage(e
.getMessage());
114 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, e
.getMessage());
116 if (traceTypeToSet
== null) {
117 return Status
.CANCEL_STATUS
;
119 IProject project
= ResourcesPlugin
.getWorkspace().getRoot().getProject(projectRoot
);
120 IFolder folder
= project
.getFolder(TmfTraceFolder
.TRACE_FOLDER_NAME
);
121 String traceName
= getTraceName(path
, folder
);
122 if (traceExists(path
, folder
)) {
123 return openTraceFromProject(projectRoot
, traceName
);
125 final IPath tracePath
= folder
.getFullPath().append(traceName
);
126 final IPath pathString
= Path
.fromOSString(path
);
127 IResource linkedTrace
= TmfImportHelper
.createLink(folder
, pathString
, traceName
);
128 if (linkedTrace
!= null && linkedTrace
.exists()) {
129 IStatus ret
= TmfTraceType
.setTraceType(tracePath
, traceTypeToSet
);
131 ret
= openTraceFromProject(projectRoot
, traceName
);
135 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
,
136 Messages
.TmfOpenTraceHelper_LinkFailed
);
139 private static boolean traceExists(String file
, IFolder folder
) {
140 String val
= getTraceName(file
, folder
);
141 return (folder
.findMember(val
) != null);
144 private static boolean isWrongMember(IFolder folder
, String ret
, final File traceFile
) {
145 final IResource candidate
= folder
.findMember(ret
);
146 if (candidate
!= null) {
147 final IPath rawLocation
= candidate
.getRawLocation();
148 final File file
= rawLocation
.toFile();
149 return !file
.equals(traceFile
);
155 * Gets the display name, either "filename" or "filename(n)" if there is
156 * already a filename existing where n is the next non-used integer starting
162 * the folder to import to
163 * @return the filename
165 private static String
getTraceName(String file
, IFolder folder
) {
167 final File traceFile
= new File(file
);
168 ret
= traceFile
.getName();
169 for (int i
= 2; isWrongMember(folder
, ret
, traceFile
); i
++) {
170 ret
= traceFile
.getName() + '(' + i
+ ')';
176 * Open a trace from a project
179 * the root of the project
182 * @return success or error
184 public static IStatus
openTraceFromProject(String projectRoot
, String traceName
) {
185 final IWorkspace workspace
= ResourcesPlugin
.getWorkspace();
186 final IWorkspaceRoot root
= workspace
.getRoot();
187 IProject project
= root
.getProject(projectRoot
);
188 TmfImportHelper
.forceFolderRefresh(project
.getFolder(TmfTraceFolder
.TRACE_FOLDER_NAME
));
190 final TmfProjectElement project2
= TmfProjectRegistry
.getProject(project
, true);
191 final TmfTraceFolder tracesFolder
= project2
.getTracesFolder();
192 final List
<TmfTraceElement
> traces
= tracesFolder
.getTraces();
193 TmfTraceElement found
= null;
194 for (TmfTraceElement candidate
: traces
) {
195 if (candidate
.getName().equals(traceName
)) {
200 return new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.TmfOpenTraceHelper_ErrorOpeningTrace
);
202 openTraceFromElement(found
);
203 return Status
.OK_STATUS
;
207 * Open a trace from a trace element. If the trace is already opened, its
208 * editor is activated and brought to top.
210 * @param traceElement
211 * the {@link TmfTraceElement} to open
213 public static void openTraceFromElement(final TmfTraceElement traceElement
) {
217 file
= traceElement
.createBookmarksFile();
218 } catch (final CoreException e
) {
219 Activator
.getDefault().logError(Messages
.TmfOpenTraceHelper_ErrorOpeningTrace
+ ' ' + traceElement
.getName());
220 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenTrace
, Messages
.TmfOpenTraceHelper_ErrorTrace
+ ENDL
+ ENDL
+ e
.getMessage());
224 final IWorkbench wb
= PlatformUI
.getWorkbench();
225 final IWorkbenchPage activePage
= wb
.getActiveWorkbenchWindow().getActivePage();
226 final IEditorPart editor
= findEditor(new FileEditorInput(file
), true);
227 if (editor
!= null) {
228 activePage
.activate(editor
);
232 Thread thread
= new Thread() {
236 final ITmfTrace trace
= traceElement
.instantiateTrace();
237 final ITmfEvent traceEvent
= traceElement
.instantiateEvent();
238 if ((trace
== null) || (traceEvent
== null)) {
239 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenTrace
, Messages
.TmfOpenTraceHelper_NoTraceType
);
247 trace
.initTrace(traceElement
.getResource(), traceElement
.getLocation().getPath(), traceEvent
.getClass());
248 } catch (final TmfTraceException e
) {
249 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenTrace
, Messages
.TmfOpenTraceHelper_InitError
+ ENDL
+ ENDL
+ e
);
254 // Get the editor id from the extension point
255 String traceEditorId
= traceElement
.getEditorId();
256 final String editorId
= (traceEditorId
!= null) ? traceEditorId
: TmfEventsEditor
.ID
;
257 final IEditorInput editorInput
= new TmfEditorInput(file
, trace
);
259 Display
.getDefault().asyncExec(new Runnable() {
263 activePage
.openEditor(editorInput
, editorId
);
264 IDE
.setDefaultEditor(file
, editorId
);
265 // editor should dispose the trace on close
266 } catch (final PartInitException e
) {
267 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenTrace
, Messages
.TmfOpenTraceHelper_ErrorOpeningTrace
+ ENDL
+ ENDL
+ e
.getMessage());
268 Activator
.getDefault().logError(Messages
.TmfOpenTraceHelper_ErrorOpeningTrace
+ ' ' + traceElement
.getName());
279 * Open an experiment from an experiment element. If the experiment is
280 * already opened, its editor is activated and brought to top.
282 * @param experimentElement
283 * the {@link TmfExperimentElement} to open
285 public static void openExperimentFromElement(final TmfExperimentElement experimentElement
) {
289 file
= experimentElement
.createBookmarksFile();
290 } catch (final CoreException e
) {
291 Activator
.getDefault().logError(Messages
.TmfOpenTraceHelper_ErrorOpeningExperiment
+ ' ' + experimentElement
.getName());
292 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenExperiment
, Messages
.TmfOpenTraceHelper_ErrorExperiment
+ ENDL
+ ENDL
+ e
.getMessage());
296 final IWorkbench wb
= PlatformUI
.getWorkbench();
297 final IWorkbenchPage activePage
= wb
.getActiveWorkbenchWindow().getActivePage();
298 final IEditorPart editor
= findEditor(new FileEditorInput(file
), true);
299 if (editor
!= null) {
300 activePage
.activate(editor
);
304 Thread thread
= new Thread() {
309 * Unlike traces, there is no instanceExperiment, so we call
310 * this function here alone. Maybe it would be better to do this
311 * on experiment's element constructor?
313 experimentElement
.refreshSupplementaryFolder();
315 // Instantiate the experiment's traces
316 final List
<TmfTraceElement
> traceEntries
= experimentElement
.getTraces();
317 final int nbTraces
= traceEntries
.size();
318 int cacheSize
= Integer
.MAX_VALUE
;
319 String commonEditorId
= null;
320 final ITmfTrace
[] traces
= new ITmfTrace
[nbTraces
];
321 for (int i
= 0; i
< nbTraces
; i
++) {
322 TmfTraceElement element
= traceEntries
.get(i
);
324 // Since trace is under an experiment, use the original
325 // trace from the traces folder
326 element
= element
.getElementUnderTraceFolder();
328 final ITmfTrace trace
= element
.instantiateTrace();
329 final ITmfEvent traceEvent
= element
.instantiateEvent();
330 if ((trace
== null) || (traceEvent
== null)) {
331 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenExperiment
,
332 Messages
.TmfOpenTraceHelper_ErrorOpeningTrace
+ ' ' + element
.getName() +
333 ENDL
+ Messages
.TmfOpenTraceHelper_NoTraceType
);
334 for (int j
= 0; j
< i
; j
++) {
343 trace
.initTrace(element
.getResource(), element
.getLocation().getPath(), traceEvent
.getClass());
344 } catch (final TmfTraceException e
) {
345 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenExperiment
,
346 element
.getName() + ':' + ' ' + Messages
.TmfOpenTraceHelper_InitError
+ ENDL
+ ENDL
+ e
);
347 for (int j
= 0; j
< i
; j
++) {
353 cacheSize
= Math
.min(cacheSize
, trace
.getCacheSize());
355 // If all traces use the same editorId, use it, otherwise
357 final String editorId
= element
.getEditorId();
358 if (commonEditorId
== null) {
359 commonEditorId
= (editorId
!= null) ? editorId
: TmfEventsEditor
.ID
;
360 } else if (!commonEditorId
.equals(editorId
)) {
361 commonEditorId
= TmfEventsEditor
.ID
;
366 // Create the experiment
367 final TmfExperiment experiment
= new TmfExperiment(ITmfEvent
.class, experimentElement
.getName(), traces
, cacheSize
, experimentElement
.getResource());
368 experiment
.setBookmarksFile(file
);
370 final String editorId
= commonEditorId
;
371 final IEditorInput editorInput
= new TmfEditorInput(file
, experiment
);
373 Display
.getDefault().asyncExec(new Runnable() {
377 activePage
.openEditor(editorInput
, editorId
);
378 IDE
.setDefaultEditor(file
, editorId
);
379 // editor should dispose the trace on close
380 } catch (final PartInitException e
) {
381 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenExperiment
, Messages
.TmfOpenTraceHelper_ErrorOpeningExperiment
+ ENDL
+ ENDL
+ e
.getMessage());
382 Activator
.getDefault().logError(Messages
.TmfOpenTraceHelper_ErrorOpeningExperiment
+ ' ' + experimentElement
.getName());
383 experiment
.dispose();
393 * Returns the editor with the specified input. Returns null if there is no
394 * opened editor with that input. If restore is requested, the method finds
395 * and returns the editor even if it is not restored yet after a restart.
400 * true if the editor should be restored
401 * @return an editor with input equals to <code>input</code>
403 private static IEditorPart
findEditor(IEditorInput input
, boolean restore
) {
404 final IWorkbench wb
= PlatformUI
.getWorkbench();
405 final IWorkbenchPage activePage
= wb
.getActiveWorkbenchWindow().getActivePage();
406 for (IEditorReference editorReference
: activePage
.getEditorReferences()) {
408 IEditorInput editorInput
= editorReference
.getEditorInput();
409 if (editorInput
.equals(input
)) {
410 return editorReference
.getEditor(restore
);
412 } catch (PartInitException e
) {
419 * Reopen a trace from a trace element in the provided editor
421 * @param traceElement
422 * the {@link TmfTraceElement} to open
424 * the reusable editor
426 public static void reopenTraceFromElement(final TmfTraceElement traceElement
, final IReusableEditor editor
) {
430 file
= traceElement
.createBookmarksFile();
431 } catch (final CoreException e
) {
432 Activator
.getDefault().logError(Messages
.TmfOpenTraceHelper_ErrorOpeningTrace
+ ' ' + traceElement
.getName());
433 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenTrace
, Messages
.TmfOpenTraceHelper_ErrorTrace
+ ENDL
+ ENDL
+ e
.getMessage());
437 Thread thread
= new Thread() {
441 final ITmfTrace trace
= traceElement
.instantiateTrace();
442 final ITmfEvent traceEvent
= traceElement
.instantiateEvent();
443 if ((trace
== null) || (traceEvent
== null)) {
444 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenTrace
, Messages
.TmfOpenTraceHelper_NoTraceType
);
452 trace
.initTrace(traceElement
.getResource(), traceElement
.getLocation().getPath(), traceEvent
.getClass());
453 } catch (final TmfTraceException e
) {
454 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenTrace
, Messages
.TmfOpenTraceHelper_InitError
+ ENDL
+ ENDL
+ e
);
459 final IEditorInput editorInput
= new TmfEditorInput(file
, trace
);
461 Display
.getDefault().asyncExec(new Runnable() {
464 final IWorkbench wb
= PlatformUI
.getWorkbench();
465 final IWorkbenchPage activePage
= wb
.getActiveWorkbenchWindow().getActivePage();
466 activePage
.reuseEditor(editor
, editorInput
);
467 activePage
.activate(editor
);
476 * Reopen an experiment from an experiment element in the provided editor
478 * @param experimentElement
479 * the {@link TmfExperimentElement} to open
481 * the reusable editor
483 public static void reopenExperimentFromElement(final TmfExperimentElement experimentElement
, final IReusableEditor editor
) {
487 file
= experimentElement
.createBookmarksFile();
488 } catch (final CoreException e
) {
489 Activator
.getDefault().logError(Messages
.TmfOpenTraceHelper_ErrorOpeningExperiment
+ ' ' + experimentElement
.getName());
490 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenExperiment
, Messages
.TmfOpenTraceHelper_ErrorExperiment
+ ENDL
+ ENDL
+ e
.getMessage());
494 Thread thread
= new Thread() {
499 * Unlike traces, there is no instanceExperiment, so we call
500 * this function here alone. Maybe it would be better to do this
501 * on experiment's element constructor?
503 experimentElement
.refreshSupplementaryFolder();
505 // Instantiate the experiment's traces
506 final List
<TmfTraceElement
> traceEntries
= experimentElement
.getTraces();
507 final int nbTraces
= traceEntries
.size();
508 int cacheSize
= Integer
.MAX_VALUE
;
509 final ITmfTrace
[] traces
= new ITmfTrace
[nbTraces
];
510 for (int i
= 0; i
< nbTraces
; i
++) {
511 TmfTraceElement element
= traceEntries
.get(i
);
513 // Since trace is under an experiment, use the original
514 // trace from the traces folder
515 element
= element
.getElementUnderTraceFolder();
517 final ITmfTrace trace
= element
.instantiateTrace();
518 final ITmfEvent traceEvent
= element
.instantiateEvent();
519 if ((trace
== null) || (traceEvent
== null)) {
520 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenExperiment
,
521 Messages
.TmfOpenTraceHelper_ErrorOpeningTrace
+ ' ' + element
.getName() +
522 ENDL
+ Messages
.TmfOpenTraceHelper_NoTraceType
);
523 for (int j
= 0; j
< i
; j
++) {
532 trace
.initTrace(element
.getResource(), element
.getLocation().getPath(), traceEvent
.getClass());
533 } catch (final TmfTraceException e
) {
534 TraceUtils
.displayErrorMsg(Messages
.TmfOpenTraceHelper_OpenExperiment
,
535 element
.getName() + ':' + ' ' + Messages
.TmfOpenTraceHelper_InitError
+ ENDL
+ ENDL
+ e
);
536 for (int j
= 0; j
< i
; j
++) {
542 cacheSize
= Math
.min(cacheSize
, trace
.getCacheSize());
547 // Create the experiment
548 final TmfExperiment experiment
= new TmfExperiment(ITmfEvent
.class, experimentElement
.getName(), traces
, cacheSize
, experimentElement
.getResource());
549 experiment
.setBookmarksFile(file
);
551 final IEditorInput editorInput
= new TmfEditorInput(file
, experiment
);
553 Display
.getDefault().asyncExec(new Runnable() {
556 final IWorkbench wb
= PlatformUI
.getWorkbench();
557 final IWorkbenchPage activePage
= wb
.getActiveWorkbenchWindow().getActivePage();
558 activePage
.reuseEditor(editor
, editorInput
);
559 activePage
.activate(editor
);