99ea37c732b6c65d10f7613ee9f3d3bf21cfff80
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.control.ui / src / org / eclipse / linuxtools / internal / lttng2 / control / ui / views / handlers / ImportHandler.java
1 /**********************************************************************
2 * Copyright (c) 2012, 2014 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 * Bernd Hufmann - Initial API and implementation
11 * Bernd Hufmann - Updated for support of streamed traces
12 * Patrick Tasse - Add support for source location
13 **********************************************************************/
14 package org.eclipse.linuxtools.internal.lttng2.control.ui.views.handlers;
15
16 import java.net.URI;
17 import java.net.URISyntaxException;
18 import java.util.Iterator;
19 import java.util.List;
20
21 import org.eclipse.core.commands.ExecutionEvent;
22 import org.eclipse.core.commands.ExecutionException;
23 import org.eclipse.core.resources.IFolder;
24 import org.eclipse.core.resources.IProject;
25 import org.eclipse.core.resources.IResource;
26 import org.eclipse.core.resources.ResourcesPlugin;
27 import org.eclipse.core.runtime.CoreException;
28 import org.eclipse.core.runtime.IPath;
29 import org.eclipse.core.runtime.IProgressMonitor;
30 import org.eclipse.core.runtime.IStatus;
31 import org.eclipse.core.runtime.MultiStatus;
32 import org.eclipse.core.runtime.NullProgressMonitor;
33 import org.eclipse.core.runtime.Path;
34 import org.eclipse.core.runtime.Status;
35 import org.eclipse.core.runtime.SubMonitor;
36 import org.eclipse.core.runtime.URIUtil;
37 import org.eclipse.core.runtime.jobs.Job;
38 import org.eclipse.jface.dialogs.MessageDialogWithToggle;
39 import org.eclipse.jface.preference.IPreferenceStore;
40 import org.eclipse.jface.viewers.ISelection;
41 import org.eclipse.jface.viewers.StructuredSelection;
42 import org.eclipse.jface.window.Window;
43 import org.eclipse.jface.wizard.WizardDialog;
44 import org.eclipse.linuxtools.internal.lttng2.control.core.model.TraceSessionState;
45 import org.eclipse.linuxtools.internal.lttng2.control.ui.Activator;
46 import org.eclipse.linuxtools.internal.lttng2.control.ui.relayd.LttngRelaydConnectionInfo;
47 import org.eclipse.linuxtools.internal.lttng2.control.ui.relayd.LttngRelaydConnectionManager;
48 import org.eclipse.linuxtools.internal.lttng2.control.ui.relayd.LttngRelaydConsumer;
49 import org.eclipse.linuxtools.internal.lttng2.control.ui.views.ControlView;
50 import org.eclipse.linuxtools.internal.lttng2.control.ui.views.dialogs.IImportDialog;
51 import org.eclipse.linuxtools.internal.lttng2.control.ui.views.dialogs.ImportFileInfo;
52 import org.eclipse.linuxtools.internal.lttng2.control.ui.views.dialogs.TraceControlDialogFactory;
53 import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages;
54 import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceSessionComponent;
55 import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace.ImportTraceWizard;
56 import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
57 import org.eclipse.linuxtools.tmf.core.project.model.TmfTraceImportException;
58 import org.eclipse.linuxtools.tmf.core.project.model.TraceTypeHelper;
59 import org.eclipse.linuxtools.tmf.ctf.core.CtfConstants;
60 import org.eclipse.linuxtools.tmf.ui.project.model.TmfOpenTraceHelper;
61 import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectElement;
62 import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry;
63 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
64 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
65 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceTypeUIUtils;
66 import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder;
67 import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils;
68 import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
69 import org.eclipse.rse.services.files.IFileService;
70 import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
71 import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFileSubSystem;
72 import org.eclipse.swt.widgets.Display;
73 import org.eclipse.ui.IWorkbenchPage;
74 import org.eclipse.ui.IWorkbenchWindow;
75 import org.eclipse.ui.PlatformUI;
76
77 /**
78 * <p>
79 * Command handler implementation to import traces from a (remote) session to a
80 * tracing project.
81 * </p>
82 *
83 * @author Bernd Hufmann
84 */
85 public class ImportHandler extends BaseControlViewHandler {
86
87 // ------------------------------------------------------------------------
88 // Constants
89 // ------------------------------------------------------------------------
90 /** Name of default project to import traces to */
91 public static final String DEFAULT_REMOTE_PROJECT_NAME = "Remote"; //$NON-NLS-1$
92
93 /** The preference key to remeber whether or not the user wants the notification shown next time **/
94 private static final String NOTIFY_IMPORT_STREAMED_PREF_KEY = "NOTIFY_IMPORT_STREAMED"; //$NON-NLS-1$
95
96 // ------------------------------------------------------------------------
97 // Attributes
98 // ------------------------------------------------------------------------
99
100 /**
101 * The command parameter
102 */
103 protected CommandParameter fParam;
104
105 // ------------------------------------------------------------------------
106 // Operations
107 // ------------------------------------------------------------------------
108
109 @Override
110 public Object execute(ExecutionEvent event) throws ExecutionException {
111
112 IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
113
114 if (window == null) {
115 return false;
116 }
117
118 fLock.lock();
119 try {
120 final CommandParameter param = fParam.clone();
121
122 // create default project
123 IProject project = TmfProjectRegistry.createProject(DEFAULT_REMOTE_PROJECT_NAME, null, null);
124
125 if (param.getSession().isLiveTrace()) {
126 importLiveTrace(new LttngRelaydConnectionInfo(param.getSession().getLiveUrl(), param.getSession().getLivePort(), param.getSession().getName()), project);
127 return null;
128 } else if (param.getSession().isStreamedTrace()) {
129
130 IPreferenceStore store = Activator.getDefault().getPreferenceStore();
131 String notify = store.getString(NOTIFY_IMPORT_STREAMED_PREF_KEY);
132 if (!MessageDialogWithToggle.ALWAYS.equals(notify)) {
133 MessageDialogWithToggle.openInformation(window.getShell(), null, Messages.TraceControl_ImportDialogStreamedTraceNotification, Messages.TraceControl_ImportDialogStreamedTraceNotificationToggle, false, store, NOTIFY_IMPORT_STREAMED_PREF_KEY);
134 }
135
136 // Streamed trace
137 TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
138 TmfTraceFolder traceFolder = projectElement.getTracesFolder();
139
140 ImportTraceWizard wizard = new ImportTraceWizard();
141 wizard.init(PlatformUI.getWorkbench(), new StructuredSelection(traceFolder));
142 WizardDialog dialog = new WizardDialog(window.getShell(), wizard);
143 dialog.open();
144 return null;
145 }
146
147 // Remote trace
148 final IImportDialog dialog = TraceControlDialogFactory.getInstance().getImportDialog();
149 dialog.setSession(param.getSession());
150 dialog.setDefaultProject(DEFAULT_REMOTE_PROJECT_NAME);
151
152 if (dialog.open() != Window.OK) {
153 return null;
154 }
155
156 Job job = new Job(Messages.TraceControl_ImportJob) {
157 @Override
158 protected IStatus run(IProgressMonitor monitor) {
159
160 MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, IStatus.OK, Messages.TraceControl_ImportFailure, null);
161 List<ImportFileInfo> traces = dialog.getTracePathes();
162 IProject selectedProject = dialog.getProject();
163 for (Iterator<ImportFileInfo> iterator = traces.iterator(); iterator.hasNext();) {
164 try {
165
166 if (monitor.isCanceled()) {
167 status.add(Status.CANCEL_STATUS);
168 break;
169 }
170
171 ImportFileInfo remoteFile = iterator.next();
172
173 downloadTrace(remoteFile, selectedProject, monitor);
174
175 // Set trace type
176 IFolder traceFolder = remoteFile.getDestinationFolder();
177
178 IResource file = traceFolder.findMember(remoteFile.getLocalTraceName());
179
180 if (file != null) {
181 TraceTypeHelper helper = null;
182
183 try {
184 helper = TmfTraceTypeUIUtils.selectTraceType(file.getLocation().toOSString(), null, null);
185 } catch (TmfTraceImportException e) {
186 // the trace did not match any trace type
187 }
188
189 if (helper != null) {
190 status.add(TmfTraceTypeUIUtils.setTraceType(file, helper));
191 }
192
193 try {
194 final String scheme = "sftp"; //$NON-NLS-1$
195 String host = remoteFile.getImportFile().getHost().getName();
196 int port = remoteFile.getImportFile().getParentRemoteFileSubSystem().getConnectorService().getPort();
197 String path = remoteFile.getImportFile().getAbsolutePath();
198 if (file instanceof IFolder) {
199 path += IPath.SEPARATOR;
200 }
201 URI uri = new URI(scheme, null, host, port, path, null, null);
202 String sourceLocation = URIUtil.toUnencodedString(uri);
203 file.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation);
204 } catch (URISyntaxException e) {
205 }
206 }
207 } catch (ExecutionException e) {
208 status.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TraceControl_ImportFailure, e));
209 } catch (CoreException e) {
210 status.add(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.TraceControl_ImportFailure, e));
211 }
212 }
213 return status;
214 }
215 };
216 job.setUser(true);
217 job.schedule();
218 } finally {
219 fLock.unlock();
220 }
221 return null;
222 }
223
224 @Override
225 public boolean isEnabled() {
226 // Get workbench page for the Control View
227 IWorkbenchPage page = getWorkbenchPage();
228 if (page == null) {
229 return false;
230 }
231
232 // Check if one or more session are selected
233 ISelection selection = page.getSelection(ControlView.ID);
234 TraceSessionComponent session = null;
235 if (selection instanceof StructuredSelection) {
236 StructuredSelection structered = ((StructuredSelection) selection);
237 for (Iterator<?> iterator = structered.iterator(); iterator.hasNext();) {
238 Object element = iterator.next();
239 if (element instanceof TraceSessionComponent) {
240 // Add only TraceSessionComponents that are inactive and not
241 // destroyed
242 TraceSessionComponent tmpSession = (TraceSessionComponent) element;
243 if ((tmpSession.isSnapshotSession() || tmpSession.isLiveTrace() || (tmpSession.getSessionState() == TraceSessionState.INACTIVE)) && (!tmpSession.isDestroyed())) {
244 session = tmpSession;
245 }
246 }
247 }
248 }
249 boolean isEnabled = session != null;
250
251 fLock.lock();
252 try {
253 fParam = null;
254 if (isEnabled) {
255 fParam = new CommandParameter(session);
256 }
257 } finally {
258 fLock.unlock();
259 }
260 return isEnabled;
261 }
262
263 // ------------------------------------------------------------------------
264 // Helper methods
265 // ------------------------------------------------------------------------
266
267 /**
268 * Downloads a trace from the remote host to the given project.
269 *
270 * @param trace
271 * - trace information of trace to import
272 * @param project
273 * - project to import to
274 * @param monitor
275 * - a progress monitor
276 * @throws ExecutionException
277 */
278 private static void downloadTrace(ImportFileInfo trace, IProject project, IProgressMonitor monitor)
279 throws ExecutionException {
280 try {
281 IRemoteFileSubSystem fsss = trace.getImportFile().getParentRemoteFileSubSystem();
282
283 IFolder traceFolder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME);
284 if (!traceFolder.exists()) {
285 throw new ExecutionException(Messages.TraceControl_ImportDialogInvalidTracingProject + " (" + TmfTracesFolder.TRACES_FOLDER_NAME + ")"); //$NON-NLS-1$//$NON-NLS-2$
286 }
287
288 IFolder destinationFolder = trace.getDestinationFolder();
289 TraceUtils.createFolder(destinationFolder, monitor);
290
291 String traceName = trace.getLocalTraceName();
292 IFolder folder = destinationFolder.getFolder(traceName);
293 if (folder.exists()) {
294 if (!trace.isOverwrite()) {
295 throw new ExecutionException(Messages.TraceControl_ImportDialogTraceAlreadyExistError + ": " + traceName); //$NON-NLS-1$
296 }
297 } else {
298 folder.create(true, true, null);
299 }
300
301 IRemoteFile[] sources = fsss.list(trace.getImportFile(), IFileService.FILE_TYPE_FILES, new NullProgressMonitor());
302 SubMonitor subMonitor = SubMonitor.convert(monitor, sources.length);
303 subMonitor.beginTask(Messages.TraceControl_DownloadTask, sources.length);
304
305 for (int i = 0; i < sources.length; i++) {
306 if (subMonitor.isCanceled()) {
307 monitor.setCanceled(true);
308 return;
309 }
310 String destination = folder.getLocation().addTrailingSeparator().append(sources[i].getName()).toOSString();
311 subMonitor.setTaskName(Messages.TraceControl_DownloadTask + ' ' + traceName + '/' + sources[i].getName());
312 fsss.download(sources[i], destination, null, subMonitor.newChild(1));
313 }
314 } catch (SystemMessageException e) {
315 throw new ExecutionException(e.toString(), e);
316 } catch (CoreException e) {
317 throw new ExecutionException(e.toString(), e);
318 }
319 }
320
321 private static void importLiveTrace(final LttngRelaydConnectionInfo connectionInfo, final IProject project) {
322 Job job = new Job(Messages.TraceControl_ImportJob) {
323
324 @Override
325 protected IStatus run(final IProgressMonitor monitor) {
326 try {
327 // We initiate the connection first so that we can retrieve the trace path
328 LttngRelaydConsumer lttngRelaydConsumer = LttngRelaydConnectionManager.getInstance().getConsumer(connectionInfo);
329 try {
330 lttngRelaydConsumer.connect();
331 } catch (CoreException e) {
332 new Status(IStatus.ERROR, Activator.PLUGIN_ID, org.eclipse.linuxtools.internal.lttng2.control.ui.relayd.Messages.LttngRelaydConnectionManager_ConnectionError, e);
333 }
334 initializeTraceResource(connectionInfo, lttngRelaydConsumer.getTracePath(), project);
335 return Status.OK_STATUS;
336 } catch (CoreException | TmfTraceImportException e) {
337 return new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportHandler_LiveTraceInitError, e);
338 }
339 }
340
341 };
342 job.setSystem(true);
343 job.schedule();
344 }
345
346
347 private static void initializeTraceResource(final LttngRelaydConnectionInfo connectionInfo, final String tracePath, final IProject project) throws CoreException, TmfTraceImportException {
348 IFolder folder = project.getFolder(TmfTracesFolder.TRACES_FOLDER_NAME);
349 IFolder traceFolder = folder.getFolder(connectionInfo.getSessionName());
350 Path location = new Path(tracePath);
351 IStatus result = ResourcesPlugin.getWorkspace().validateLinkLocation(folder, location);
352 if (result.isOK()) {
353 traceFolder.createLink(location, IResource.REPLACE, new NullProgressMonitor());
354 } else {
355 throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, result.getMessage()));
356 }
357
358 TraceTypeHelper selectedTraceType = TmfTraceTypeUIUtils.selectTraceType(location.toOSString(), null, null);
359 // No trace type was determined.
360 TmfTraceTypeUIUtils.setTraceType(traceFolder, selectedTraceType);
361
362 final TmfProjectElement projectElement = TmfProjectRegistry.getProject(project, true);
363 final TmfTraceFolder tracesFolder = projectElement.getTracesFolder();
364 final List<TmfTraceElement> traces = tracesFolder.getTraces();
365 TmfTraceElement found = null;
366 for (TmfTraceElement candidate : traces) {
367 if (candidate.getName().equals(connectionInfo.getSessionName())) {
368 found = candidate;
369 }
370 }
371
372 if (found == null) {
373 throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.ImportHandler_LiveTraceElementError));
374 }
375
376 // Properties used to be able to reopen a trace in live mode
377 traceFolder.setPersistentProperty(CtfConstants.LIVE_HOST, connectionInfo.getHost());
378 traceFolder.setPersistentProperty(CtfConstants.LIVE_PORT, Integer.toString(connectionInfo.getPort()));
379 traceFolder.setPersistentProperty(CtfConstants.LIVE_SESSION_NAME, connectionInfo.getSessionName());
380
381 final TmfTraceElement finalTrace = found;
382 Display.getDefault().syncExec(new Runnable() {
383
384 @Override
385 public void run() {
386 TmfOpenTraceHelper.openTraceFromElement(finalTrace);
387 }
388 });
389 }
390 }
This page took 0.043387 seconds and 4 git commands to generate.