1 /*******************************************************************************
2 * Copyright (c) 2013, 2015 École Polytechnique de Montréal
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 * Geneviève Bastien - Initial implementation and API
11 * Cédric Biancheri - Added a wizard to select the root node
12 *******************************************************************************/
14 package org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.handlers
;
16 import java
.util
.ArrayList
;
17 import java
.util
.Iterator
;
18 import java
.util
.List
;
20 import org
.eclipse
.core
.commands
.AbstractHandler
;
21 import org
.eclipse
.core
.commands
.ExecutionEvent
;
22 import org
.eclipse
.core
.commands
.ExecutionException
;
23 import org
.eclipse
.core
.resources
.IContainer
;
24 import org
.eclipse
.core
.resources
.IFolder
;
25 import org
.eclipse
.core
.resources
.IResource
;
26 import org
.eclipse
.core
.runtime
.CoreException
;
27 import org
.eclipse
.jface
.viewers
.ISelection
;
28 import org
.eclipse
.jface
.viewers
.TreeSelection
;
29 import org
.eclipse
.jface
.window
.Window
;
30 import org
.eclipse
.jface
.wizard
.WizardDialog
;
31 import org
.eclipse
.swt
.widgets
.Display
;
32 import org
.eclipse
.swt
.widgets
.Shell
;
33 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.event
.ITmfEvent
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.exceptions
.TmfTraceException
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.synchronization
.SynchronizationAlgorithm
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
38 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
39 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.experiment
.TmfExperiment
;
40 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfExperimentElement
;
41 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceElement
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TraceUtils
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.wizards
.SelectRootNodeWizard
;
44 import org
.eclipse
.ui
.IWorkbenchWindow
;
45 import org
.eclipse
.ui
.PlatformUI
;
46 import org
.eclipse
.ui
.handlers
.HandlerUtil
;
49 * Handles the synchronization of an experiment, when the user selects this
52 public class SynchronizeTracesHandler
extends AbstractHandler
{
54 // ------------------------------------------------------------------------
56 // ------------------------------------------------------------------------
58 private TreeSelection fSelection
= null;
59 private static final String CR
= System
.getProperty("line.separator"); //$NON-NLS-1$
60 private TmfExperimentElement fExperiment
= null;
61 private TmfTraceElement fRootNode
= null;
62 private String fRootNodeId
= null;
64 // ------------------------------------------------------------------------
66 // ------------------------------------------------------------------------
69 public Object
execute(ExecutionEvent event
) throws ExecutionException
{
71 // Check if we are closing down
72 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
78 ISelection selection
= HandlerUtil
.getCurrentSelectionChecked(event
);
80 // Make sure selection contains only traces
82 final ArrayList
<TmfTraceElement
> tl
= new ArrayList
<>();
83 final ArrayList
<TmfExperimentElement
> uiexperiment
= new ArrayList
<>();
84 if (selection
instanceof TreeSelection
) {
85 fSelection
= (TreeSelection
) selection
;
86 Iterator
<Object
> iterator
= fSelection
.iterator();
87 while (iterator
.hasNext()) {
88 Object element
= iterator
.next();
89 if (element
instanceof TmfExperimentElement
) {
90 TmfExperimentElement exp
= (TmfExperimentElement
) element
;
91 uiexperiment
.add(exp
);
92 for (TmfTraceElement trace
: exp
.getTraces()) {
99 if ((uiexperiment
.size() != 1) || (tl
.size() < 2)) {
100 TraceUtils
.displayErrorMsg(Messages
.SynchronizeTracesHandler_Title
, Messages
.SynchronizeTracesHandler_WrongTraceNumber
);
103 fExperiment
= uiexperiment
.get(0);
107 // Fire the Select Root Node Wizard
108 IWorkbenchWindow workbenchWindow
= HandlerUtil
.getActiveWorkbenchWindowChecked(event
);
109 Shell shell
= workbenchWindow
.getShell();
110 SelectRootNodeWizard wizard
= new SelectRootNodeWizard(fExperiment
);
111 WizardDialog dialog
= new WizardDialog(shell
, wizard
);
112 int returnValue
= dialog
.open();
113 if (returnValue
== Window
.CANCEL
) {
116 fRootNode
= wizard
.getRootNode();
118 Thread thread
= new Thread() {
122 final ITmfTrace
[] traces
= new ITmfTrace
[tl
.size()];
123 final TmfExperimentElement exp
= uiexperiment
.get(0);
125 for (int i
= 0; i
< tl
.size(); i
++) {
126 ITmfTrace trace
= tl
.get(i
).instantiateTrace();
127 ITmfEvent traceEvent
= tl
.get(i
).instantiateEvent();
129 TraceUtils
.displayErrorMsg(Messages
.SynchronizeTracesHandler_Title
, Messages
.SynchronizeTracesHandler_WrongType
+ tl
.get(i
).getName());
130 for (int j
= 0; j
< i
; j
++) {
136 trace
.initTrace(tl
.get(i
).getResource(), tl
.get(i
).getResource().getLocation().toOSString(), traceEvent
.getClass());
137 TmfTraceManager
.refreshSupplementaryFiles(trace
);
138 } catch (TmfTraceException e
) {
139 TraceUtils
.displayErrorMsg(Messages
.SynchronizeTracesHandler_Title
, Messages
.SynchronizeTracesHandler_InitError
+ CR
+ CR
+ e
);
141 for (int j
= 0; j
< i
; j
++) {
146 if (tl
.get(i
).getElementPath().equals(fRootNode
.getElementPath())) {
147 fRootNodeId
= trace
.getHostId();
153 * FIXME Unlike traces, there is no instanceExperiment, so we
154 * call this function here alone. Maybe it would be better to do
155 * this on experiment's element constructor?
157 exp
.refreshSupplementaryFolder();
158 final TmfExperiment experiment
= new TmfExperiment(ITmfEvent
.class,
159 exp
.getName(), traces
, TmfExperiment
.DEFAULT_INDEX_PAGE_SIZE
, exp
.getResource());
161 final SynchronizationAlgorithm syncAlgo
= experiment
.synchronizeTraces(true);
162 syncAlgo
.setRootNode(fRootNodeId
);
164 TmfTraceManager
.refreshSupplementaryFiles(experiment
);
166 Display
.getDefault().asyncExec(new Runnable() {
169 List
<TmfTraceElement
> tracesToAdd
= new ArrayList
<>();
170 List
<TmfTraceElement
> tracesToRemove
= new ArrayList
<>();
172 * For each trace in the experiment, if there is a
173 * transform equation, copy the original trace, so that
174 * a new state system will be generated with sync time.
176 for (TmfTraceElement traceel
: tl
) {
178 * Find the trace corresponding to this element in
181 ITmfTrace expTrace
= null;
182 for (ITmfTrace t
: experiment
.getTraces()) {
183 if (t
.getResource().equals(traceel
.getResource())) {
188 if ((expTrace
!= null) && syncAlgo
.isTraceSynced(expTrace
.getHostId())) {
189 /* Find the original trace */
190 TmfTraceElement origtrace
= traceel
.getElementUnderTraceFolder();
193 * Make sure a trace with the new name does not
196 StringBuilder newname
= new StringBuilder(traceel
.getName());
197 IContainer parentFolder
= origtrace
.getResource().getParent();
202 if (parentFolder
.findMember(newname
.toString()) != null) {
205 } while (traceexists
);
207 /* Copy the original trace */
208 TmfTraceElement newtrace
= origtrace
.copy(newname
.toString());
209 if (newtrace
== null) {
210 TraceUtils
.displayErrorMsg(Messages
.SynchronizeTracesHandler_Title
,
211 Messages
.SynchronizeTracesHandler_Error
+ CR
+ CR
+ String
.format(Messages
.SynchronizeTracesHandler_CopyProblem
, origtrace
.getName()));
216 * Instantiate the new trace and set its sync
219 ITmfTrace trace
= newtrace
.instantiateTrace();
220 ITmfEvent traceEvent
= newtrace
.instantiateEvent();
223 trace
.initTrace(newtrace
.getResource(), newtrace
.getResource().getLocation().toOSString(), traceEvent
.getClass());
224 } catch (TmfTraceException e
) {
225 Activator
.getDefault().logError(String
.format(Messages
.SynchronizeTracesHandler_ErrorSynchingForTrace
, exp
.getName(), traceel
.getName()), e
);
226 TraceUtils
.displayErrorMsg(Messages
.SynchronizeTracesHandler_Title
, Messages
.SynchronizeTracesHandler_Error
+ CR
+ CR
+ e
.getMessage());
228 trace
.setTimestampTransform(syncAlgo
.getTimestampTransform(trace
));
229 TmfTraceManager
.refreshSupplementaryFiles(trace
);
232 tracesToAdd
.add(newtrace
);
233 tracesToRemove
.add(traceel
);
236 experiment
.dispose();
238 // Move synchronization file temporarily so that
239 // it doesn't get deleted by the experiment change
240 IFolder tmpFolder
= exp
.getTraceSupplementaryFolder(exp
.getName() + '.' + experiment
.getSynchronizationFolder(false));
241 IResource syncFile
= null;
242 for (IResource resource
: exp
.getSupplementaryResources()) {
243 if (resource
.getName().equals(experiment
.getSynchronizationFolder(false))) {
245 resource
.move(tmpFolder
.getFullPath(), false, null);
248 } catch (CoreException e
) {
249 Activator
.getDefault().logError(String
.format(Messages
.SynchronizeTracesHandler_ErrorSynchingExperiment
, exp
.getName()), e
);
254 for (TmfTraceElement trace
: tracesToRemove
) {
256 exp
.removeTrace(trace
);
257 } catch (CoreException e
) {
258 Activator
.getDefault().logError(String
.format(Messages
.SynchronizeTracesHandler_ErrorSynchingForTrace
, exp
.getName(), trace
.getName()), e
);
259 TraceUtils
.displayErrorMsg(Messages
.SynchronizeTracesHandler_Title
, Messages
.SynchronizeTracesHandler_Error
+ CR
+ CR
+ e
.getMessage());
262 for (TmfTraceElement trace
: tracesToAdd
) {
266 // Move synchronization file back
267 if (tmpFolder
.exists() && syncFile
!= null) {
269 tmpFolder
.move(syncFile
.getFullPath(), false, null);
270 } catch (CoreException e
) {
271 Activator
.getDefault().logError(String
.format(Messages
.SynchronizeTracesHandler_ErrorSynchingExperiment
, exp
.getName()), e
);