1 /**********************************************************************
2 * Copyright (c) 2012 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 **********************************************************************/
12 package org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.views
.control
.dialogs
;
14 import java
.util
.ArrayList
;
15 import java
.util
.List
;
17 import org
.eclipse
.core
.resources
.IFolder
;
18 import org
.eclipse
.core
.resources
.IProject
;
19 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
20 import org
.eclipse
.core
.runtime
.CoreException
;
21 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
22 import org
.eclipse
.jface
.dialogs
.Dialog
;
23 import org
.eclipse
.jface
.dialogs
.IDialogConstants
;
24 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
25 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
26 import org
.eclipse
.jface
.viewers
.CheckboxTreeViewer
;
27 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
28 import org
.eclipse
.jface
.viewers
.StructuredSelection
;
29 import org
.eclipse
.jface
.window
.Window
;
30 import org
.eclipse
.jface
.wizard
.WizardDialog
;
31 import org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.Activator
;
32 import org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.views
.control
.messages
.Messages
;
33 import org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.views
.control
.model
.impl
.TraceSessionComponent
;
34 import org
.eclipse
.linuxtools
.internal
.lttng2
.ui
.views
.control
.remote
.IRemoteSystemProxy
;
35 import org
.eclipse
.linuxtools
.tmf
.core
.TmfProjectNature
;
36 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.model
.TmfTraceFolder
;
37 import org
.eclipse
.linuxtools
.tmf
.ui
.project
.wizards
.ImportTraceWizard
;
38 import org
.eclipse
.rse
.services
.clientserver
.messages
.SystemMessageException
;
39 import org
.eclipse
.rse
.subsystems
.files
.core
.servicesubsystem
.IFileServiceSubSystem
;
40 import org
.eclipse
.rse
.subsystems
.files
.core
.subsystems
.IRemoteFile
;
41 import org
.eclipse
.swt
.SWT
;
42 import org
.eclipse
.swt
.custom
.CCombo
;
43 import org
.eclipse
.swt
.graphics
.Point
;
44 import org
.eclipse
.swt
.layout
.GridData
;
45 import org
.eclipse
.swt
.layout
.GridLayout
;
46 import org
.eclipse
.swt
.widgets
.Button
;
47 import org
.eclipse
.swt
.widgets
.Composite
;
48 import org
.eclipse
.swt
.widgets
.Control
;
49 import org
.eclipse
.swt
.widgets
.Group
;
50 import org
.eclipse
.swt
.widgets
.Shell
;
51 import org
.eclipse
.swt
.widgets
.Text
;
52 import org
.eclipse
.swt
.widgets
.Tree
;
53 import org
.eclipse
.ui
.PlatformUI
;
54 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
55 import org
.eclipse
.ui
.model
.WorkbenchLabelProvider
;
59 * Dialog box for collecting trace import information.
62 * @author Bernd Hufmann
64 public class ImportDialog
extends Dialog
implements IImportDialog
{
66 // ------------------------------------------------------------------------
68 // ------------------------------------------------------------------------
69 /** The icon file for this dialog box. */
70 public static final String IMPORT_ICON_FILE
= "icons/elcl16/import_trace.gif"; //$NON-NLS-1$
72 /** Parent directory for UST traces */
73 public static final String UST_PARENT_DIRECTORY
= "ust"; //$NON-NLS-1$
75 // ------------------------------------------------------------------------
77 // ------------------------------------------------------------------------
79 * The dialog composite.
81 private Composite fDialogComposite
= null;
83 * The checkbox tree viewer for selecting available traces
85 private CheckboxTreeViewer fFolderViewer
;
87 * The combo box for selecting a project.
89 private CCombo fCombo
;
91 * The overwrite button
93 private Button fOverwriteButton
;
95 * The button to open import wizard for import locally.
97 private Button fImportLocallyButton
;
99 * List of available LTTng 2.0 projects
101 private List
<IProject
> fProjects
;
103 * The parent where the new node should be added.
105 private TraceSessionComponent fSession
= null;
107 * List of traces to import
109 private final List
<ImportFileInfo
> fTraces
= new ArrayList
<ImportFileInfo
>();
111 * Selection index in project combo box.
113 private int fProjectIndex
;
115 * Flag to indicate that something went wrong when creating the dialog box.
117 private boolean fIsError
= false;
119 // ------------------------------------------------------------------------
121 // ------------------------------------------------------------------------
124 * @param shell - a shell for the display of the dialog
126 public ImportDialog(Shell shell
) {
128 setShellStyle(SWT
.RESIZE
);
131 // ------------------------------------------------------------------------
133 // ------------------------------------------------------------------------
136 * @see org.eclipse.linuxtools.internal.lttng2.ui.views.control.dialogs.IImportDialog#getTracePathes()
139 public List
<ImportFileInfo
> getTracePathes() {
140 List
<ImportFileInfo
> retList
= new ArrayList
<ImportFileInfo
>();
141 retList
.addAll(fTraces
);
147 * @see org.eclipse.linuxtools.internal.lttng2.ui.views.control.dialogs.IImportDialog#getProject()
150 public IProject
getProject() {
151 return fProjects
.get(fProjectIndex
);
156 * @see org.eclipse.linuxtools.internal.lttng2.ui.views.control.dialogs.IImportDialog#setSession(org.eclipse.linuxtools.internal.lttng2.ui.views.control.model.impl.TraceSessionComponent)
159 public void setSession(TraceSessionComponent session
) {
163 // ------------------------------------------------------------------------
165 // ------------------------------------------------------------------------
168 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
171 protected void configureShell(Shell newShell
) {
172 super.configureShell(newShell
);
173 newShell
.setText(Messages
.TraceControl_ImportDialogTitle
);
174 newShell
.setImage(Activator
.getDefault().loadIcon(IMPORT_ICON_FILE
));
179 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
182 protected Control
createDialogArea(Composite parent
) {
185 fDialogComposite
= new Composite(parent
, SWT
.NONE
);
186 GridLayout layout
= new GridLayout(1, true);
187 fDialogComposite
.setLayout(layout
);
188 fDialogComposite
.setLayoutData(new GridData(GridData
.FILL_BOTH
));
191 if (fSession
.isStreamedTrace()) {
192 createLocalComposite();
194 createRemoteComposite();
196 } catch (CoreException e
) {
197 createErrorComposite(parent
, e
.fillInStackTrace());
198 return fDialogComposite
;
199 } catch (SystemMessageException e
) {
200 createErrorComposite(parent
, e
.fillInStackTrace());
201 return fDialogComposite
;
203 return fDialogComposite
;
208 * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
211 protected void createButtonsForButtonBar(Composite parent
) {
212 createButton(parent
, IDialogConstants
.CANCEL_ID
, "&Cancel", true); //$NON-NLS-1$
213 fImportLocallyButton
= createButton(parent
, IDialogConstants
.OK_ID
, "&Ok", true); //$NON-NLS-1$
214 if (fSession
.isStreamedTrace()) {
215 fImportLocallyButton
.setText("&Next..."); //$NON-NLS-1$
221 * @see org.eclipse.jface.dialogs.Dialog#okPressed()
224 protected void okPressed() {
227 // Validate input data
230 fProjectIndex
= fCombo
.getSelectionIndex();
232 if (fProjectIndex
< 0) {
233 MessageDialog
.openError(getShell(),
234 Messages
.TraceControl_ImportDialogTitle
,
235 Messages
.TraceControl_ImportDialogNoProjectSelectedError
);
239 if (fSession
.isStreamedTrace()) {
240 // For streaming use standard import wizard from TMF because exact location
241 // is not available (lttng backend limitation)
242 IProject project
= fProjects
.get(fCombo
.getSelectionIndex());
243 ImportTraceWizard wizard
= new ImportTraceWizard();
244 wizard
.init(PlatformUI
.getWorkbench(), new StructuredSelection(project
));
245 WizardDialog dialog
= new WizardDialog(getShell(), wizard
);
246 if (dialog
.open() == Window
.OK
) {
249 super.cancelPressed();
253 IProject project
= fProjects
.get(fProjectIndex
);
254 IFolder traceFolder
= project
.getFolder(TmfTraceFolder
.TRACE_FOLDER_NAME
);
256 if (!traceFolder
.exists()) {
257 // Invalid LTTng 2.0 project
258 MessageDialog
.openError(getShell(),
259 Messages
.TraceControl_ImportDialogTitle
,
260 Messages
.TraceControl_ImportDialogInvalidTracingProject
+ " (" + TmfTraceFolder
.TRACE_FOLDER_NAME
+ ")"); //$NON-NLS-1$//$NON-NLS-2$
264 boolean overwriteAll
= fOverwriteButton
.getSelection();
266 Object
[] checked
= fFolderViewer
.getCheckedElements();
267 for (int i
= 0; i
< checked
.length
; i
++) {
268 IRemoteFile file
= (IRemoteFile
) checked
[i
];
270 // Only add actual trace directories
271 if (file
.isDirectory() && !UST_PARENT_DIRECTORY
.equals(file
.getName())) {
273 ImportFileInfo info
= new ImportFileInfo(file
, file
.getName(), overwriteAll
);
274 String traceName
= info
.getLocalTraceName();
275 IFolder folder
= traceFolder
.getFolder(traceName
);
277 // Verify if trace directory already exists (and not overwrite)
278 if (folder
.exists() && !overwriteAll
) {
280 // Ask user for overwrite or new name
281 IImportConfirmationDialog conf
= TraceControlDialogFactory
.getInstance().getImportConfirmationDialog();
282 conf
.setTraceName(traceName
);
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());
298 if (fTraces
.isEmpty()) {
299 MessageDialog
.openError(getShell(),
300 Messages
.TraceControl_ImportDialogTitle
,
301 Messages
.TraceControl_ImportDialogNoTraceSelectedError
);
306 // validation successful -> call super.okPressed()
310 // ------------------------------------------------------------------------
311 // Helper methods and classes
312 // ------------------------------------------------------------------------
314 * Helper class for the contents of a folder in a tracing project
316 * @author Bernd Hufmann
318 public static class FolderContentProvider
extends WorkbenchContentProvider
{
320 public Object
[] getChildren(Object o
) {
321 if (o
instanceof IRemoteFile
) {
322 IRemoteFile element
= (IRemoteFile
) o
;
323 // For our purpose, we need folders + files
324 if (!element
.isDirectory()) {
325 return new Object
[0];
328 return super.getChildren(o
);
333 * Creates a dialog composite with an error message which can be used
334 * when an exception occurred during creation time of the dialog box.
335 * @param parent - a parent composite
336 * @param e - a error causing exception
338 private void createErrorComposite(Composite parent
, Throwable e
) {
340 fDialogComposite
.dispose();
342 fDialogComposite
= new Composite(parent
, SWT
.NONE
);
343 GridLayout layout
= new GridLayout(1, true);
344 fDialogComposite
.setLayout(layout
);
345 fDialogComposite
.setLayoutData(new GridData(GridData
.FILL_BOTH
));
347 Text errorText
= new Text(fDialogComposite
, SWT
.MULTI
);
348 StringBuffer error
= new StringBuffer();
349 error
.append(Messages
.TraceControl_ImportDialogCreationError
);
350 error
.append(System
.getProperty("line.separator")); //$NON-NLS-1$
351 error
.append(System
.getProperty("line.separator")); //$NON-NLS-1$
352 error
.append(e
.toString());
353 errorText
.setText(error
.toString());
354 errorText
.setLayoutData(new GridData(GridData
.FILL_BOTH
));
357 private void createRemoteComposite() throws CoreException
, SystemMessageException
{
358 Group contextGroup
= new Group(fDialogComposite
, SWT
.SHADOW_NONE
);
359 contextGroup
.setText(Messages
.TraceControl_ImportDialogTracesGroupName
);
360 GridLayout layout
= new GridLayout(1, true);
361 contextGroup
.setLayout(layout
);
362 contextGroup
.setLayoutData(new GridData(GridData
.FILL_BOTH
));
364 IRemoteSystemProxy proxy
= fSession
.getTargetNode().getRemoteSystemProxy();
366 IFileServiceSubSystem fsss
= proxy
.getFileServiceSubSystem();
368 IRemoteFile remoteFolder
= fsss
.getRemoteFileObject(fSession
.getSessionPath(), new NullProgressMonitor());
370 fFolderViewer
= new CheckboxTreeViewer(contextGroup
, SWT
.BORDER
);
371 GridData data
= new GridData(GridData
.FILL_BOTH
);
372 Tree tree
= fFolderViewer
.getTree();
373 tree
.setLayoutData(data
);
374 tree
.setFont(fDialogComposite
.getFont());
375 tree
.setToolTipText(Messages
.TraceControl_ImportDialogTracesTooltip
);
377 fFolderViewer
.setContentProvider(new FolderContentProvider());
378 fFolderViewer
.setLabelProvider(new WorkbenchLabelProvider());
380 fFolderViewer
.addCheckStateListener(new ICheckStateListener() {
382 public void checkStateChanged(CheckStateChangedEvent event
) {
383 Object elem
= event
.getElement();
384 if (elem
instanceof IRemoteFile
) {
385 IRemoteFile element
= (IRemoteFile
) elem
;
386 if (!element
.isDirectory()) {
387 // A trick to keep selection of a file in sync with the directory
388 boolean p
= fFolderViewer
.getChecked((element
.getParentRemoteFile()));
389 fFolderViewer
.setChecked(element
, p
);
392 fFolderViewer
.setSubtreeChecked(event
.getElement(), event
.getChecked());
393 if (!event
.getChecked()) {
394 fFolderViewer
.setChecked(element
.getParentRemoteFile(), false);
399 fFolderViewer
.setInput(remoteFolder
);
401 Group projectGroup
= new Group(fDialogComposite
, SWT
.SHADOW_NONE
);
402 projectGroup
.setText(Messages
.TraceControl_ImportDialogProjectsGroupName
);
403 layout
= new GridLayout(1, true);
404 projectGroup
.setLayout(layout
);
405 projectGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
407 fProjects
= new ArrayList
<IProject
>();
408 List
<String
> projectNames
= new ArrayList
<String
>();
409 for (IProject project
: ResourcesPlugin
.getWorkspace().getRoot().getProjects()) {
410 if (project
.isOpen() && project
.hasNature(TmfProjectNature
.ID
)) {
411 fProjects
.add(project
);
412 projectNames
.add(project
.getName());
416 fCombo
= new CCombo(projectGroup
, SWT
.READ_ONLY
);
417 fCombo
.setToolTipText(Messages
.TraceControl_ImportDialogProjectsTooltip
);
418 fCombo
.setLayoutData(new GridData(GridData
.FILL
, GridData
.CENTER
, true, false, 1, 1));
419 fCombo
.setItems(projectNames
.toArray(new String
[projectNames
.size()]));
421 Group overrideGroup
= new Group(fDialogComposite
, SWT
.SHADOW_NONE
);
422 layout
= new GridLayout(1, true);
423 overrideGroup
.setLayout(layout
);
424 overrideGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
426 fOverwriteButton
= new Button(overrideGroup
, SWT
.CHECK
);
427 fOverwriteButton
.setText(Messages
.TraceControl_ImportDialogOverwriteButtonText
);
428 getShell().setMinimumSize(new Point(500, 400));
431 private void createLocalComposite() throws CoreException
{
433 Group projectGroup
= new Group(fDialogComposite
, SWT
.SHADOW_NONE
);
434 projectGroup
.setText(Messages
.TraceControl_ImportDialogProjectsGroupName
);
435 GridLayout layout
= new GridLayout(1, true);
436 projectGroup
.setLayout(layout
);
437 projectGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
439 fProjects
= new ArrayList
<IProject
>();
440 List
<String
> projectNames
= new ArrayList
<String
>();
441 for (IProject project
: ResourcesPlugin
.getWorkspace().getRoot().getProjects()) {
442 if (project
.isOpen() && project
.hasNature(TmfProjectNature
.ID
)) {
443 fProjects
.add(project
);
444 projectNames
.add(project
.getName());
448 fCombo
= new CCombo(projectGroup
, SWT
.READ_ONLY
);
449 fCombo
.setToolTipText(Messages
.TraceControl_ImportDialogProjectsTooltip
);
450 fCombo
.setLayoutData(new GridData(GridData
.FILL
, GridData
.CENTER
, true, false, 1, 1));
451 fCombo
.setItems(projectNames
.toArray(new String
[projectNames
.size()]));
453 // Group overrideGroup = new Group(fDialogComposite, SWT.SHADOW_NONE);
454 // layout = new GridLayout(1, true);
455 // overrideGroup.setLayout(layout);
456 // overrideGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
458 // fOverwriteButton = new Button(overrideGroup, SWT.CHECK);
459 // fOverwriteButton.setText(Messages.TraceControl_ImportDialogOverwriteButtonText);
461 getShell().setMinimumSize(new Point(500, 50));