lttng: Rename lttng2 feature/plugins to lttng2.control
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.control.ui / src / org / eclipse / linuxtools / internal / lttng2 / control / ui / views / dialogs / ImportDialog.java
CommitLineData
291cbdbf 1/**********************************************************************
60ae41e1 2 * Copyright (c) 2012, 2014 Ericsson
cfdb727a 3 *
291cbdbf
BH
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
cfdb727a
AM
8 *
9 * Contributors:
291cbdbf 10 * Bernd Hufmann - Initial API and implementation
ba3a9bd2 11 * Bernd Hufmann - Added handling of streamed traces
d600c18f 12 * Marc-Andre Laperle - Use common method to get opened tmf projects
291cbdbf 13 **********************************************************************/
8e8c0226 14package org.eclipse.linuxtools.internal.lttng2.control.ui.views.dialogs;
291cbdbf
BH
15
16import java.util.ArrayList;
17import java.util.List;
18
19import org.eclipse.core.resources.IFolder;
20import org.eclipse.core.resources.IProject;
291cbdbf 21import org.eclipse.core.runtime.NullProgressMonitor;
786a5c52 22import org.eclipse.core.runtime.Path;
291cbdbf
BH
23import org.eclipse.jface.dialogs.Dialog;
24import org.eclipse.jface.dialogs.IDialogConstants;
25import org.eclipse.jface.dialogs.MessageDialog;
26import org.eclipse.jface.viewers.CheckStateChangedEvent;
27import org.eclipse.jface.viewers.CheckboxTreeViewer;
28import org.eclipse.jface.viewers.ICheckStateListener;
29import org.eclipse.jface.window.Window;
8e8c0226
AM
30import org.eclipse.linuxtools.internal.lttng2.control.ui.Activator;
31import org.eclipse.linuxtools.internal.lttng2.control.ui.views.messages.Messages;
32import org.eclipse.linuxtools.internal.lttng2.control.ui.views.model.impl.TraceSessionComponent;
33import org.eclipse.linuxtools.internal.lttng2.control.ui.views.remote.IRemoteSystemProxy;
291cbdbf 34import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
d600c18f 35import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils;
cd9821de 36import org.eclipse.rse.core.subsystems.RemoteChildrenContentsType;
291cbdbf
BH
37import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
38import org.eclipse.rse.subsystems.files.core.servicesubsystem.IFileServiceSubSystem;
39import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
40import org.eclipse.swt.SWT;
41import org.eclipse.swt.custom.CCombo;
f75337be
BH
42import org.eclipse.swt.events.SelectionAdapter;
43import org.eclipse.swt.events.SelectionEvent;
291cbdbf
BH
44import org.eclipse.swt.graphics.Point;
45import org.eclipse.swt.layout.GridData;
46import org.eclipse.swt.layout.GridLayout;
47import org.eclipse.swt.widgets.Button;
48import org.eclipse.swt.widgets.Composite;
49import org.eclipse.swt.widgets.Control;
50import org.eclipse.swt.widgets.Group;
51import org.eclipse.swt.widgets.Shell;
52import org.eclipse.swt.widgets.Text;
53import org.eclipse.swt.widgets.Tree;
54import org.eclipse.ui.model.WorkbenchContentProvider;
55import org.eclipse.ui.model.WorkbenchLabelProvider;
56
57/**
291cbdbf
BH
58 * <p>
59 * Dialog box for collecting trace import information.
60 * </p>
cfdb727a 61 *
dbd4432d 62 * @author Bernd Hufmann
291cbdbf
BH
63 */
64public class ImportDialog extends Dialog implements IImportDialog {
65
66 // ------------------------------------------------------------------------
67 // Constants
68 // ------------------------------------------------------------------------
cfdb727a 69 /** The icon file for this dialog box. */
291cbdbf 70 public static final String IMPORT_ICON_FILE = "icons/elcl16/import_trace.gif"; //$NON-NLS-1$
cfdb727a
AM
71
72 /** Parent directory for UST traces */
291cbdbf
BH
73 public static final String UST_PARENT_DIRECTORY = "ust"; //$NON-NLS-1$
74
cd9821de
BH
75 /** Name of metadata file of trace */
76 public static final String METADATA_FILE_NAME = "metadata"; //$NON-NLS-1$
77
78 /** Default name of kernel traces */
79 public static final String DEFAULT_KERNEL_TRACE_NAME = "kernel"; //$NON-NLS-1$
80
291cbdbf
BH
81 // ------------------------------------------------------------------------
82 // Attributes
83 // ------------------------------------------------------------------------
84 /**
85 * The dialog composite.
86 */
87 private Composite fDialogComposite = null;
88 /**
89 * The checkbox tree viewer for selecting available traces
90 */
91 private CheckboxTreeViewer fFolderViewer;
92 /**
93 * The combo box for selecting a project.
94 */
95 private CCombo fCombo;
96 /**
cfdb727a 97 * The overwrite button
291cbdbf
BH
98 */
99 private Button fOverwriteButton;
100 /**
101 * List of available LTTng 2.0 projects
102 */
103 private List<IProject> fProjects;
104 /**
105 * The parent where the new node should be added.
106 */
107 private TraceSessionComponent fSession = null;
cd9821de
BH
108
109 /**
110 * The name of the default project name
111 */
112 private String fDefaultProjectName = null;
291cbdbf 113 /**
cfdb727a 114 * List of traces to import
291cbdbf 115 */
e0838ca1 116 private final List<ImportFileInfo> fTraces = new ArrayList<>();
291cbdbf 117 /**
cfdb727a 118 * Selection index in project combo box.
291cbdbf
BH
119 */
120 private int fProjectIndex;
121 /**
122 * Flag to indicate that something went wrong when creating the dialog box.
123 */
124 private boolean fIsError = false;
f75337be
BH
125 /**
126 * Children of the remote folder (can be null)
127 */
128 private Object[] fFolderChildren = null;
cfdb727a 129
291cbdbf
BH
130 // ------------------------------------------------------------------------
131 // Constructors
132 // ------------------------------------------------------------------------
133 /**
134 * Constructor
135 * @param shell - a shell for the display of the dialog
136 */
137 public ImportDialog(Shell shell) {
138 super(shell);
8a396998 139 setShellStyle(SWT.RESIZE | getShellStyle());
291cbdbf
BH
140 }
141
142 // ------------------------------------------------------------------------
143 // Accessors
144 // ------------------------------------------------------------------------
11252342 145
291cbdbf
BH
146 @Override
147 public List<ImportFileInfo> getTracePathes() {
e0838ca1 148 List<ImportFileInfo> retList = new ArrayList<>();
291cbdbf
BH
149 retList.addAll(fTraces);
150 return retList;
151 }
152
291cbdbf
BH
153 @Override
154 public IProject getProject() {
155 return fProjects.get(fProjectIndex);
156 }
cfdb727a 157
291cbdbf
BH
158 @Override
159 public void setSession(TraceSessionComponent session) {
160 fSession = session;
161 }
162
cd9821de
BH
163 @Override
164 public void setDefaultProject(String defaultProject) {
165 fDefaultProjectName = defaultProject;
166 }
167
291cbdbf
BH
168 // ------------------------------------------------------------------------
169 // Operations
170 // ------------------------------------------------------------------------
11252342 171
291cbdbf
BH
172 @Override
173 protected void configureShell(Shell newShell) {
174 super.configureShell(newShell);
175 newShell.setText(Messages.TraceControl_ImportDialogTitle);
176 newShell.setImage(Activator.getDefault().loadIcon(IMPORT_ICON_FILE));
177 }
178
291cbdbf
BH
179 @Override
180 protected Control createDialogArea(Composite parent) {
cfdb727a 181
291cbdbf
BH
182 // Main dialog panel
183 fDialogComposite = new Composite(parent, SWT.NONE);
184 GridLayout layout = new GridLayout(1, true);
185 fDialogComposite.setLayout(layout);
186 fDialogComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
187
291cbdbf 188 try {
cd9821de 189 createRemoteComposite();
291cbdbf
BH
190 } catch (SystemMessageException e) {
191 createErrorComposite(parent, e.fillInStackTrace());
192 return fDialogComposite;
193 }
291cbdbf
BH
194 return fDialogComposite;
195 }
196
291cbdbf
BH
197 @Override
198 protected void createButtonsForButtonBar(Composite parent) {
f75337be
BH
199 Button selectAllButton = createButton(parent, IDialogConstants.SELECT_ALL_ID, Messages.TraceControl_ImportDialog_SelectAll, true);
200 selectAllButton.addSelectionListener(new SelectionAdapter() {
201 @Override
202 public void widgetSelected(SelectionEvent e) {
203 setFolderChildrenChecked(true);
204 }
205 });
206
207 Button deselectAllButton = createButton(parent, IDialogConstants.DESELECT_ALL_ID, Messages.TraceControl_ImportDialog_DeselectAll, true);
208 deselectAllButton.addSelectionListener(new SelectionAdapter() {
209 @Override
210 public void widgetSelected(SelectionEvent e) {
211 setFolderChildrenChecked(false);
212 }
213 });
214 createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, true);
215 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
216 updateOKButtonEnablement();
291cbdbf
BH
217 }
218
291cbdbf
BH
219 @Override
220 protected void okPressed() {
221 if (!fIsError) {
f3b33d40 222
291cbdbf
BH
223 // Validate input data
224 fTraces.clear();
225
226 fProjectIndex = fCombo.getSelectionIndex();
227
228 if (fProjectIndex < 0) {
229 MessageDialog.openError(getShell(),
230 Messages.TraceControl_ImportDialogTitle,
231 Messages.TraceControl_ImportDialogNoProjectSelectedError);
232 return;
233 }
234
235 IProject project = fProjects.get(fProjectIndex);
236 IFolder traceFolder = project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME);
237
238 if (!traceFolder.exists()) {
239 // Invalid LTTng 2.0 project
240 MessageDialog.openError(getShell(),
241 Messages.TraceControl_ImportDialogTitle,
242 Messages.TraceControl_ImportDialogInvalidTracingProject + " (" + TmfTraceFolder.TRACE_FOLDER_NAME + ")"); //$NON-NLS-1$//$NON-NLS-2$
243 return;
244 }
245
246 boolean overwriteAll = fOverwriteButton.getSelection();
247
248 Object[] checked = fFolderViewer.getCheckedElements();
249 for (int i = 0; i < checked.length; i++) {
250 IRemoteFile file = (IRemoteFile) checked[i];
cd9821de
BH
251 if (!file.isDirectory() && file.getName().equals(METADATA_FILE_NAME)) {
252 IRemoteFile trace = file.getParentRemoteFile();
253 IRemoteFile parent = trace.getParentRemoteFile();
254 boolean isKernel = false;
255 if (trace.getName().equals(DEFAULT_KERNEL_TRACE_NAME)) {
256 isKernel = true;
257 }
258 StringBuffer traceName = new StringBuffer();
259 traceName.append(trace.getName());
260 traceName.insert(0, '-');
261
589d0d33 262 String path = fSession.isSnapshotSession() ? fSession.getSnapshotInfo().getSnapshotPath() : fSession.getSessionPath();
786a5c52
BH
263 path = getUnifiedPath(path);
264 String parentPath = getUnifiedPath(parent.getAbsolutePath());
589d0d33 265
786a5c52 266 while (!parentPath.equals(path)) {
cd9821de
BH
267 traceName.insert(0, parent.getName());
268 traceName.insert(0, '-');
269 parent = parent.getParentRemoteFile();
786a5c52 270 parentPath = getUnifiedPath(parent.getAbsolutePath());
cd9821de
BH
271 }
272 traceName.insert(0, parent.getName());
cfdb727a 273
cd9821de
BH
274 ImportFileInfo info = new ImportFileInfo(trace, traceName.toString(), overwriteAll, isKernel);
275 IFolder folder = traceFolder.getFolder(traceName.toString());
291cbdbf 276
cfdb727a 277 // Verify if trace directory already exists (and not overwrite)
291cbdbf
BH
278 if (folder.exists() && !overwriteAll) {
279
280 // Ask user for overwrite or new name
281 IImportConfirmationDialog conf = TraceControlDialogFactory.getInstance().getImportConfirmationDialog();
cd9821de 282 conf.setTraceName(traceName.toString());
291cbdbf
BH
283
284 // Don't add trace to list if dialog was cancelled.
285 if (conf.open() == Window.OK) {
286 info.setOverwrite(conf.isOverwrite());
287 if (!conf.isOverwrite()) {
288 info.setLocalTraceName(conf.getNewTraceName());
289 }
290 fTraces.add(info);
291 }
cfdb727a 292 } else {
291cbdbf
BH
293 fTraces.add(info);
294 }
295 }
296 }
297
298 if (fTraces.isEmpty()) {
299 MessageDialog.openError(getShell(),
300 Messages.TraceControl_ImportDialogTitle,
301 Messages.TraceControl_ImportDialogNoTraceSelectedError);
302 return;
303 }
304 }
305
306 // validation successful -> call super.okPressed()
307 super.okPressed();
308 }
309
310 // ------------------------------------------------------------------------
311 // Helper methods and classes
312 // ------------------------------------------------------------------------
11252342 313
cfdb727a
AM
314 /**
315 * Helper class for the contents of a folder in a tracing project
316 *
317 * @author Bernd Hufmann
318 */
f455db37 319 public static class FolderContentProvider extends WorkbenchContentProvider {
291cbdbf
BH
320 @Override
321 public Object[] getChildren(Object o) {
322 if (o instanceof IRemoteFile) {
323 IRemoteFile element = (IRemoteFile) o;
324 // For our purpose, we need folders + files
325 if (!element.isDirectory()) {
326 return new Object[0];
327 }
328 }
329 return super.getChildren(o);
330 }
331 }
cfdb727a 332
291cbdbf
BH
333 /**
334 * Creates a dialog composite with an error message which can be used
335 * when an exception occurred during creation time of the dialog box.
336 * @param parent - a parent composite
cfdb727a 337 * @param e - a error causing exception
291cbdbf
BH
338 */
339 private void createErrorComposite(Composite parent, Throwable e) {
340 fIsError = true;
341 fDialogComposite.dispose();
cfdb727a 342
291cbdbf
BH
343 fDialogComposite = new Composite(parent, SWT.NONE);
344 GridLayout layout = new GridLayout(1, true);
345 fDialogComposite.setLayout(layout);
346 fDialogComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
cfdb727a 347
291cbdbf
BH
348 Text errorText = new Text(fDialogComposite, SWT.MULTI);
349 StringBuffer error = new StringBuffer();
350 error.append(Messages.TraceControl_ImportDialogCreationError);
351 error.append(System.getProperty("line.separator")); //$NON-NLS-1$
352 error.append(System.getProperty("line.separator")); //$NON-NLS-1$
353 error.append(e.toString());
354 errorText.setText(error.toString());
355 errorText.setLayoutData(new GridData(GridData.FILL_BOTH));
356 }
357
d600c18f 358 private void createRemoteComposite() throws SystemMessageException{
f3b33d40
BH
359 Group contextGroup = new Group(fDialogComposite, SWT.SHADOW_NONE);
360 contextGroup.setText(Messages.TraceControl_ImportDialogTracesGroupName);
361 GridLayout layout = new GridLayout(1, true);
362 contextGroup.setLayout(layout);
363 contextGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
364
365 IRemoteSystemProxy proxy = fSession.getTargetNode().getRemoteSystemProxy();
366
367 IFileServiceSubSystem fsss = proxy.getFileServiceSubSystem();
368
589d0d33
BH
369 final String path = fSession.isSnapshotSession() ? fSession.getSnapshotInfo().getSnapshotPath() : fSession.getSessionPath();
370 final IRemoteFile remoteFolder = fsss.getRemoteFileObject(path, new NullProgressMonitor());
371 // make sure that remote directory is read and not cached
372 remoteFolder.markStale(true, true);
f3b33d40 373
f75337be 374 fFolderViewer = new CheckboxTreeViewer(contextGroup, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
f3b33d40
BH
375 GridData data = new GridData(GridData.FILL_BOTH);
376 Tree tree = fFolderViewer.getTree();
377 tree.setLayoutData(data);
378 tree.setFont(fDialogComposite.getFont());
379 tree.setToolTipText(Messages.TraceControl_ImportDialogTracesTooltip);
380
381 fFolderViewer.setContentProvider(new FolderContentProvider());
382 fFolderViewer.setLabelProvider(new WorkbenchLabelProvider());
383
384 fFolderViewer.addCheckStateListener(new ICheckStateListener() {
385 @Override
386 public void checkStateChanged(CheckStateChangedEvent event) {
387 Object elem = event.getElement();
388 if (elem instanceof IRemoteFile) {
389 IRemoteFile element = (IRemoteFile) elem;
390 if (!element.isDirectory()) {
391 // A trick to keep selection of a file in sync with the directory
392 boolean p = fFolderViewer.getChecked((element.getParentRemoteFile()));
393 fFolderViewer.setChecked(element, p);
f75337be
BH
394 } else {
395 fFolderViewer.setSubtreeChecked(event.getElement(), event.getChecked());
396 if (!event.getChecked()) {
397 fFolderViewer.setChecked(element.getParentRemoteFile(), false);
398 }
f3b33d40 399 }
f75337be 400 updateOKButtonEnablement();
f3b33d40
BH
401 }
402 }
403 });
404 fFolderViewer.setInput(remoteFolder);
405
f75337be 406 fFolderChildren = remoteFolder.getContents(RemoteChildrenContentsType.getInstance());
589d0d33
BH
407 // children can be null if there the path doesn't exist. This happens when a trace
408 // session hadn't been started and no output was created.
f75337be 409 setFolderChildrenChecked(true);
cd9821de 410
f3b33d40
BH
411 Group projectGroup = new Group(fDialogComposite, SWT.SHADOW_NONE);
412 projectGroup.setText(Messages.TraceControl_ImportDialogProjectsGroupName);
413 layout = new GridLayout(1, true);
414 projectGroup.setLayout(layout);
415 projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
416
e0838ca1
AM
417 fProjects = new ArrayList<>();
418 List<String> projectNames = new ArrayList<>();
cd9821de 419
d600c18f
MAL
420 for (IProject project : TraceUtils.getOpenedTmfProjects()) {
421 fProjects.add(project);
422 projectNames.add(project.getName());
f3b33d40
BH
423 }
424
425 fCombo = new CCombo(projectGroup, SWT.READ_ONLY);
426 fCombo.setToolTipText(Messages.TraceControl_ImportDialogProjectsTooltip);
427 fCombo.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 1, 1));
428 fCombo.setItems(projectNames.toArray(new String[projectNames.size()]));
429
cd9821de
BH
430 if (fDefaultProjectName != null) {
431 int select = projectNames.indexOf(fDefaultProjectName);
432 fCombo.select(select);
433 }
434
f3b33d40
BH
435 Group overrideGroup = new Group(fDialogComposite, SWT.SHADOW_NONE);
436 layout = new GridLayout(1, true);
437 overrideGroup.setLayout(layout);
438 overrideGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
439
440 fOverwriteButton = new Button(overrideGroup, SWT.CHECK);
441 fOverwriteButton.setText(Messages.TraceControl_ImportDialogOverwriteButtonText);
442 getShell().setMinimumSize(new Point(500, 400));
443 }
444
f75337be
BH
445 private void setFolderChildrenChecked(boolean isChecked) {
446 if (fFolderChildren != null) {
447 for (Object child : fFolderChildren) {
448 fFolderViewer.setSubtreeChecked(child, isChecked);
449 }
450 }
451 updateOKButtonEnablement();
452 }
453
454 private void updateOKButtonEnablement() {
455 Object[] checked = fFolderViewer.getCheckedElements();
456 Button okButton = getButton(IDialogConstants.OK_ID);
457 if (okButton != null) {
458 okButton.setEnabled(checked.length > 0);
459 }
460 }
786a5c52
BH
461
462 private static String getUnifiedPath(String path) {
463 // Use Path class to remove unnecessary slashes
464 return new Path(path).removeTrailingSeparator().toString();
465 }
291cbdbf 466 }
This page took 0.062963 seconds and 5 git commands to generate.