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