1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.handlers
;
12 import static org
.eclipse
.tracecompass
.common
.core
.NonNullUtils
.checkNotNull
;
14 import java
.io
.IOException
;
15 import java
.lang
.reflect
.InvocationTargetException
;
16 import java
.nio
.file
.Files
;
17 import java
.nio
.file
.Path
;
18 import java
.nio
.file
.Paths
;
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
.runtime
.CoreException
;
24 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
25 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
26 import org
.eclipse
.jdt
.annotation
.NonNullByDefault
;
27 import org
.eclipse
.jdt
.annotation
.Nullable
;
28 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
29 import org
.eclipse
.jface
.viewers
.ISelection
;
30 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
31 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
32 import org
.eclipse
.swt
.widgets
.Shell
;
33 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.operations
.TmfWorkspaceModifyOperation
;
34 import org
.eclipse
.tracecompass
.tmf
.core
.timestamp
.TmfTimeRange
;
35 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.ITmfTrace
;
36 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.TmfTraceManager
;
37 import org
.eclipse
.tracecompass
.tmf
.core
.trace
.trim
.ITmfTrimmableTrace
;
38 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.handlers
.HandlerUtils
;
39 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfOpenTraceHelper
;
40 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectElement
;
41 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceElement
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceFolder
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TraceUtils
;
44 import org
.eclipse
.ui
.PlatformUI
;
45 import org
.eclipse
.ui
.handlers
.HandlerUtil
;
48 * Handler for the Trace Trim operation.
50 * @author Alexandre Montplaisir
53 public class TrimTraceHandler
extends AbstractHandler
{
55 /** Suffix for new trimmed traces, added to the original trace name */
56 private static final String TRACE_NAME_SUFFIX
= "-trimmed"; //$NON-NLS-1$
59 public boolean isEnabled() {
60 final Object element
= HandlerUtils
.getSelectedModelElement();
61 if (element
== null) {
66 * plugin.xml should have done type/count verification already
68 TmfTraceElement traceElem
= (TmfTraceElement
) element
;
69 if (!(traceElem
.getTrace() instanceof ITmfTrimmableTrace
)) {
73 /* Only enable the action if a time range is currently selected */
74 TmfTraceManager tm
= TmfTraceManager
.getInstance();
75 TmfTimeRange selectionRange
= tm
.getCurrentTraceContext().getSelectionRange();
76 if (selectionRange
.getStartTime().equals(selectionRange
.getEndTime())) {
84 public @Nullable Object
execute(@Nullable ExecutionEvent event
) throws ExecutionException
{
85 ISelection selection
= HandlerUtil
.getCurrentSelectionChecked(event
);
86 Object element
= ((IStructuredSelection
) selection
).getFirstElement();
87 final TmfTraceElement traceElem
= (TmfTraceElement
) element
;
89 ITmfTrace trace
= traceElem
.getTrace();
91 /* That trace is not currently opened */
94 ITmfTrimmableTrace trimmableTrace
= (ITmfTrimmableTrace
) trace
;
97 /* Retrieve the current time range */
98 final Shell shell
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell();
99 TmfTraceManager tm
= TmfTraceManager
.getInstance();
100 TmfTimeRange timeRange
= tm
.getCurrentTraceContext().getSelectionRange();
101 if (timeRange
.getStartTime().equals(timeRange
.getEndTime())) {
102 MessageDialog
.openError(shell
, Messages
.TrimTraces_InvalidTimeRange_DialogTitle
, Messages
.TrimTraces_InvalidTimeRange_DialogText
);
106 /* Ensure the time range is in the right direction */
107 final TmfTimeRange tr
= ((timeRange
.getStartTime().compareTo(timeRange
.getEndTime()) > 0) ?
108 new TmfTimeRange(timeRange
.getEndTime(), timeRange
.getStartTime()) :
112 * Pop a dialog asking the user to select a parent directory for the new
115 DirectoryDialog dialog
= new DirectoryDialog(shell
);
116 dialog
.setText(Messages
.TrimTraces_DirectoryChooser_DialogTitle
);
117 String result
= dialog
.open();
118 if (result
== null) {
119 /* Dialog was cancelled, take no further action. */
123 /* Verify that the selected path is valid and writeable */
124 final Path parentPath
= checkNotNull(Paths
.get(result
));
125 if (!Files
.isDirectory(parentPath
)) {
126 MessageDialog
.openError(shell
, Messages
.TrimTraces_InvalidDirectory_DialogTitle
, Messages
.TrimTraces_InvalidDirectory_DialogText
);
129 if (!Files
.isWritable(parentPath
)) {
130 MessageDialog
.openError(shell
, Messages
.TrimTraces_InvalidDirectory_DialogTitle
, Messages
.TrimTraces_NoWriteAccess_DialogText
);
135 * Create a directory for the new trace. We will pick the next available
136 * name, adding -2, -3, etc. as needed.
138 String newTraceName
= trace
.getName() + TRACE_NAME_SUFFIX
;
139 Path potentialPath
= parentPath
.resolve(newTraceName
);
140 for (int i
= 2; Files
.exists(potentialPath
); i
++) {
141 newTraceName
= trace
.getName() + TRACE_NAME_SUFFIX
+ '-' + String
.valueOf(i
);
142 potentialPath
= parentPath
.resolve(newTraceName
);
145 final Path tracePath
= checkNotNull(potentialPath
);
147 Files
.createDirectory(tracePath
);
148 } catch (IOException e
) {
149 /* Should not happen since we have checked permissions, etc. */
150 throw new IllegalStateException(e
);
153 TmfWorkspaceModifyOperation trimOperation
= new TmfWorkspaceModifyOperation() {
155 public void execute(@Nullable IProgressMonitor monitor
) throws CoreException
{
156 IProgressMonitor mon
= (monitor
== null ?
new NullProgressMonitor() : monitor
);
158 /* Perform the trace-specific trim operation. */
159 trimmableTrace
.trim(tr
, tracePath
, mon
);
161 /* Import the new trace into the current project, at the top-level. */
162 TmfProjectElement currentProjectElement
= traceElem
.getProject();
163 TmfTraceFolder traceFolder
=currentProjectElement
.getTracesFolder();
164 TmfOpenTraceHelper
.openTraceFromPath(traceFolder
, tracePath
.toString(), shell
);
169 PlatformUI
.getWorkbench().getProgressService().run(true, true, trimOperation
);
170 } catch (InterruptedException e
) {
172 } catch (InvocationTargetException e
) {
173 TraceUtils
.displayErrorMsg(e
.toString(), e
.getTargetException().toString());