1 /**********************************************************************
2 * Copyright (c) 2012, 2013 Ericsson
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 * Bernd Hufmann - Initial API and implementation
11 * Bernd Hufmann - Added handling of streamed traces
12 **********************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.views
.control
.dialogs
;
15 import java
.util
.ArrayList
;
16 import java
.util
.List
;
18 import org
.eclipse
.core
.resources
.IFolder
;
19 import org
.eclipse
.core
.resources
.IProject
;
20 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
21 import org
.eclipse
.core
.runtime
.CoreException
;
22 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
23 import org
.eclipse
.jface
.dialogs
.Dialog
;
24 import org
.eclipse
.jface
.dialogs
.IDialogConstants
;
25 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
26 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
27 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
28 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
29 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
30 import org
.eclipse
.jface
.window
.Window
;
31 import org
.eclipse
.jface
.wizard
.WizardDialog
;
32 import org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.Activator
;
33 import org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.views
.control
.messages
.Messages
;
34 import org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.views
.control
.model
.impl
.TraceSessionComponent
;
35 import org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.views
.control
.remote
.IRemoteSystemProxy
;
36 import org
.eclipse
.linuxtools
.tmf
.core
.TmfProjectNature
;
37 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
38 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
.ImportTraceWizard
;
39 import org
.eclipse
.rse
.services
.clientserver
.messages
.SystemMessageException
;
40 import org
.eclipse
.rse
.subsystems
.files
.core
.servicesubsystem
.IFileServiceSubSystem
;
41 import org
.eclipse
.rse
.subsystems
.files
.core
.subsystems
.IRemoteFile
;
42 import org
.eclipse
.swt
.SWT
;
43 import org
.eclipse
.swt
.custom
.CCombo
;
44 import org
.eclipse
.swt
.graphics
.Point
;
45 import org
.eclipse
.swt
.layout
.GridData
;
46 import org
.eclipse
.swt
.layout
.GridLayout
;
47 import org
.eclipse
.swt
.widgets
.Button
;
48 import org
.eclipse
.swt
.widgets
.Composite
;
49 import org
.eclipse
.swt
.widgets
.Control
;
50 import org
.eclipse
.swt
.widgets
.Group
;
51 import org
.eclipse
.swt
.widgets
.Shell
;
52 import org
.eclipse
.swt
.widgets
.Text
;
53 import org
.eclipse
.swt
.widgets
.Tree
;
54 import org
.eclipse
.ui
.PlatformUI
;
55 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
56 import org
.eclipse
.ui
.model
.WorkbenchLabelProvider
;
60 * Dialog box for collecting trace import information.
63 * @author Bernd Hufmann
65 public class ImportDialog
extends Dialog
implements IImportDialog
{
67 // ------------------------------------------------------------------------
69 // ------------------------------------------------------------------------
70 /** The icon file for this dialog box. */
71 public static final String IMPORT_ICON_FILE
= "icons/elcl16/import_trace.gif"; //$NON-NLS-1$
73 /** Parent directory for UST traces */
74 public static final String UST_PARENT_DIRECTORY
= "ust"; //$NON-NLS-1$
76 // ------------------------------------------------------------------------
78 // ------------------------------------------------------------------------
80 * The dialog composite.
82 private Composite fDialogComposite
= null;
84 * The checkbox tree viewer for selecting available traces
86 private CheckboxTreeViewer fFolderViewer
;
88 * The combo box for selecting a project.
90 private CCombo fCombo
;
92 * The overwrite button
94 private Button fOverwriteButton
;
96 * The button to open import wizard for import locally.
98 private Button fImportLocallyButton
;
100 * List of available LTTng 2.0 projects
102 private List
<IProject
> fProjects
;
104 * The parent where the new node should be added.
106 private TraceSessionComponent fSession
= null;
108 * List of traces to import
110 private final List
<ImportFileInfo
> fTraces
= new ArrayList
<ImportFileInfo
>();
112 * Selection index in project combo box.
114 private int fProjectIndex
;
116 * Flag to indicate that something went wrong when creating the dialog box.
118 private boolean fIsError
= false;
120 // ------------------------------------------------------------------------
122 // ------------------------------------------------------------------------
125 * @param shell - a shell for the display of the dialog
127 public ImportDialog(Shell shell
) {
129 setShellStyle(SWT
.RESIZE
);
132 // ------------------------------------------------------------------------
134 // ------------------------------------------------------------------------
137 * @see org.eclipse.linuxtools.internal.lttng2.ui.views.control.dialogs.IImportDialog#getTracePathes()
140 public List
<ImportFileInfo
> getTracePathes() {
141 List
<ImportFileInfo
> retList
= new ArrayList
<ImportFileInfo
>();
142 retList
.addAll(fTraces
);
148 * @see org.eclipse.linuxtools.internal.lttng2.ui.views.control.dialogs.IImportDialog#getProject()
151 public IProject
getProject() {
152 return fProjects
.get(fProjectIndex
);
157 * @see org.eclipse.linuxtools.internal.lttng2.ui.views.control.dialogs.IImportDialog#setSession(org.eclipse.linuxtools.internal.lttng2.ui.views.control.model.impl.TraceSessionComponent)
160 public void setSession(TraceSessionComponent session
) {
164 // ------------------------------------------------------------------------
166 // ------------------------------------------------------------------------
169 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
172 protected void configureShell(Shell newShell
) {
173 super.configureShell(newShell
);
174 newShell
.setText(Messages
.TraceControl_ImportDialogTitle
);
175 newShell
.setImage(Activator
.getDefault().loadIcon(IMPORT_ICON_FILE
));
180 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
183 protected Control
createDialogArea(Composite parent
) {
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
));
192 if (fSession
.isStreamedTrace()) {
193 createLocalComposite();
195 createRemoteComposite();
197 } catch (CoreException e
) {
198 createErrorComposite(parent
, e
.fillInStackTrace());
199 return fDialogComposite
;
200 } catch (SystemMessageException e
) {
201 createErrorComposite(parent
, e
.fillInStackTrace());
202 return fDialogComposite
;
204 return fDialogComposite
;
209 * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
212 protected void createButtonsForButtonBar(Composite parent
) {
213 createButton(parent
, IDialogConstants
.CANCEL_ID
, "&Cancel", true); //$NON-NLS-1$
214 fImportLocallyButton
= createButton(parent
, IDialogConstants
.OK_ID
, "&Ok", true); //$NON-NLS-1$
215 if (fSession
.isStreamedTrace()) {
216 fImportLocallyButton
.setText("&Next..."); //$NON-NLS-1$
222 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
225 protected void okPressed() {
228 // Validate input data
231 fProjectIndex
= fCombo
.getSelectionIndex();
233 if (fProjectIndex
< 0) {
234 MessageDialog
.openError(getShell(),
235 Messages
.TraceControl_ImportDialogTitle
,
236 Messages
.TraceControl_ImportDialogNoProjectSelectedError
);
240 if (fSession
.isStreamedTrace()) {
241 // For streaming use standard import wizard from TMF because exact location
242 // is not available (lttng backend limitation)
243 IProject project
= fProjects
.get(fCombo
.getSelectionIndex());
244 ImportTraceWizard wizard
= new ImportTraceWizard();
245 wizard
.init(PlatformUI
.getWorkbench(), new StructuredSelection(project
));
246 WizardDialog dialog
= new WizardDialog(getShell(), wizard
);
247 if (dialog
.open() == Window
.OK
) {
250 super.cancelPressed();
254 IProject project
= fProjects
.get(fProjectIndex
);
255 IFolder traceFolder
= project
.getFolder(TmfTraceFolder
.TRACE_FOLDER_NAME
);
257 if (!traceFolder
.exists()) {
258 // Invalid LTTng 2.0 project
259 MessageDialog
.openError(getShell(),
260 Messages
.TraceControl_ImportDialogTitle
,
261 Messages
.TraceControl_ImportDialogInvalidTracingProject
+ " (" + TmfTraceFolder
.TRACE_FOLDER_NAME
+ ")"); //$NON-NLS-1$//$NON-NLS-2$
265 boolean overwriteAll
= fOverwriteButton
.getSelection();
267 Object
[] checked
= fFolderViewer
.getCheckedElements();
268 for (int i
= 0; i
< checked
.length
; i
++) {
269 IRemoteFile file
= (IRemoteFile
) checked
[i
];
271 // Only add actual trace directories
272 if (file
.isDirectory() && !UST_PARENT_DIRECTORY
.equals(file
.getName())) {
274 ImportFileInfo info
= new ImportFileInfo(file
, file
.getName(), overwriteAll
);
275 String traceName
= info
.getLocalTraceName();
276 IFolder folder
= traceFolder
.getFolder(traceName
);
278 // Verify if trace directory already exists (and not overwrite)
279 if (folder
.exists() && !overwriteAll
) {
281 // Ask user for overwrite or new name
282 IImportConfirmationDialog conf
= TraceControlDialogFactory
.getInstance().getImportConfirmationDialog();
283 conf
.setTraceName(traceName
);
285 // Don't add trace to list if dialog was cancelled.
286 if (conf
.open() == Window
.OK
) {
287 info
.setOverwrite(conf
.isOverwrite());
288 if (!conf
.isOverwrite()) {
289 info
.setLocalTraceName(conf
.getNewTraceName());
299 if (fTraces
.isEmpty()) {
300 MessageDialog
.openError(getShell(),
301 Messages
.TraceControl_ImportDialogTitle
,
302 Messages
.TraceControl_ImportDialogNoTraceSelectedError
);
307 // validation successful -> call super.okPressed()
311 // ------------------------------------------------------------------------
312 // Helper methods and classes
313 // ------------------------------------------------------------------------
315 * Helper class for the contents of a folder in a tracing project
317 * @author Bernd Hufmann
319 public static class FolderContentProvider
extends WorkbenchContentProvider
{
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];
329 return super.getChildren(o
);
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
337 * @param e - a error causing exception
339 private void createErrorComposite(Composite parent
, Throwable e
) {
341 fDialogComposite
.dispose();
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
));
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
));
358 private void createRemoteComposite() throws CoreException
, SystemMessageException
{
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
));
365 IRemoteSystemProxy proxy
= fSession
.getTargetNode().getRemoteSystemProxy();
367 IFileServiceSubSystem fsss
= proxy
.getFileServiceSubSystem();
369 IRemoteFile remoteFolder
= fsss
.getRemoteFileObject(fSession
.getSessionPath(), new NullProgressMonitor());
371 fFolderViewer
= new CheckboxTreeViewer(contextGroup
, SWT
.BORDER
);
372 GridData data
= new GridData(GridData
.FILL_BOTH
);
373 Tree tree
= fFolderViewer
.getTree();
374 tree
.setLayoutData(data
);
375 tree
.setFont(fDialogComposite
.getFont());
376 tree
.setToolTipText(Messages
.TraceControl_ImportDialogTracesTooltip
);
378 fFolderViewer
.setContentProvider(new FolderContentProvider());
379 fFolderViewer
.setLabelProvider(new WorkbenchLabelProvider());
381 fFolderViewer
.addCheckStateListener(new ICheckStateListener() {
383 public void checkStateChanged(CheckStateChangedEvent event
) {
384 Object elem
= event
.getElement();
385 if (elem
instanceof IRemoteFile
) {
386 IRemoteFile element
= (IRemoteFile
) elem
;
387 if (!element
.isDirectory()) {
388 // A trick to keep selection of a file in sync with the directory
389 boolean p
= fFolderViewer
.getChecked((element
.getParentRemoteFile()));
390 fFolderViewer
.setChecked(element
, p
);
393 fFolderViewer
.setSubtreeChecked(event
.getElement(), event
.getChecked());
394 if (!event
.getChecked()) {
395 fFolderViewer
.setChecked(element
.getParentRemoteFile(), false);
400 fFolderViewer
.setInput(remoteFolder
);
402 Group projectGroup
= new Group(fDialogComposite
, SWT
.SHADOW_NONE
);
403 projectGroup
.setText(Messages
.TraceControl_ImportDialogProjectsGroupName
);
404 layout
= new GridLayout(1, true);
405 projectGroup
.setLayout(layout
);
406 projectGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
408 fProjects
= new ArrayList
<IProject
>();
409 List
<String
> projectNames
= new ArrayList
<String
>();
410 for (IProject project
: ResourcesPlugin
.getWorkspace().getRoot().getProjects()) {
411 if (project
.isOpen() && project
.hasNature(TmfProjectNature
.ID
)) {
412 fProjects
.add(project
);
413 projectNames
.add(project
.getName());
417 fCombo
= new CCombo(projectGroup
, SWT
.READ_ONLY
);
418 fCombo
.setToolTipText(Messages
.TraceControl_ImportDialogProjectsTooltip
);
419 fCombo
.setLayoutData(new GridData(GridData
.FILL
, GridData
.CENTER
, true, false, 1, 1));
420 fCombo
.setItems(projectNames
.toArray(new String
[projectNames
.size()]));
422 Group overrideGroup
= new Group(fDialogComposite
, SWT
.SHADOW_NONE
);
423 layout
= new GridLayout(1, true);
424 overrideGroup
.setLayout(layout
);
425 overrideGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
427 fOverwriteButton
= new Button(overrideGroup
, SWT
.CHECK
);
428 fOverwriteButton
.setText(Messages
.TraceControl_ImportDialogOverwriteButtonText
);
429 getShell().setMinimumSize(new Point(500, 400));
432 private void createLocalComposite() throws CoreException
{
434 Group projectGroup
= new Group(fDialogComposite
, SWT
.SHADOW_NONE
);
435 projectGroup
.setText(Messages
.TraceControl_ImportDialogProjectsGroupName
);
436 GridLayout layout
= new GridLayout(1, true);
437 projectGroup
.setLayout(layout
);
438 projectGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
440 fProjects
= new ArrayList
<IProject
>();
441 List
<String
> projectNames
= new ArrayList
<String
>();
442 for (IProject project
: ResourcesPlugin
.getWorkspace().getRoot().getProjects()) {
443 if (project
.isOpen() && project
.hasNature(TmfProjectNature
.ID
)) {
444 fProjects
.add(project
);
445 projectNames
.add(project
.getName());
449 fCombo
= new CCombo(projectGroup
, SWT
.READ_ONLY
);
450 fCombo
.setToolTipText(Messages
.TraceControl_ImportDialogProjectsTooltip
);
451 fCombo
.setLayoutData(new GridData(GridData
.FILL
, GridData
.CENTER
, true, false, 1, 1));
452 fCombo
.setItems(projectNames
.toArray(new String
[projectNames
.size()]));
454 // Group overrideGroup = new Group(fDialogComposite, SWT.SHADOW_NONE);
455 // layout = new GridLayout(1, true);
456 // overrideGroup.setLayout(layout);
457 // overrideGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
459 // fOverwriteButton = new Button(overrideGroup, SWT.CHECK);
460 // fOverwriteButton.setText(Messages.TraceControl_ImportDialogOverwriteButtonText);
462 getShell().setMinimumSize(new Point(500, 50));