1 /*******************************************************************************
2 * Copyright (c) 2009, 2015 Ericsson and others.
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 * Francois Chouinard - Initial API and implementation
11 * Francois Chouinard - Got rid of dependency on internal platform class
12 * Francois Chouinard - Complete re-design
13 * Anna Dushistova(Montavista) - [383047] NPE while importing a CFT trace
14 * Matthew Khouzam - Moved out some common functions
15 * Patrick Tasse - Add sorting of file system elements
16 * Bernd Hufmann - Re-design of trace selection and trace validation
17 * Marc-Andre Laperle - Preserve folder structure on import
18 * Marc-Andre Laperle - Extract archives during import
19 * Marc-Andre Laperle - Add support for Gzip (non-Tar)
20 *******************************************************************************/
22 package org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.wizards
.importtrace
;
25 import java
.lang
.reflect
.InvocationTargetException
;
26 import java
.util
.Collection
;
27 import java
.util
.LinkedList
;
28 import java
.util
.List
;
30 import org
.eclipse
.core
.resources
.IContainer
;
31 import org
.eclipse
.core
.resources
.IFolder
;
32 import org
.eclipse
.core
.resources
.IProject
;
33 import org
.eclipse
.core
.resources
.ResourcesPlugin
;
34 import org
.eclipse
.core
.runtime
.CoreException
;
35 import org
.eclipse
.core
.runtime
.IPath
;
36 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
37 import org
.eclipse
.core
.runtime
.IStatus
;
38 import org
.eclipse
.core
.runtime
.NullProgressMonitor
;
39 import org
.eclipse
.core
.runtime
.Path
;
40 import org
.eclipse
.core
.runtime
.Platform
;
41 import org
.eclipse
.core
.runtime
.Status
;
42 import org
.eclipse
.core
.runtime
.SubMonitor
;
43 import org
.eclipse
.jface
.dialogs
.IDialogSettings
;
44 import org
.eclipse
.jface
.layout
.PixelConverter
;
45 import org
.eclipse
.jface
.operation
.IRunnableWithProgress
;
46 import org
.eclipse
.jface
.viewers
.CheckStateChangedEvent
;
47 import org
.eclipse
.jface
.viewers
.ICheckStateListener
;
48 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
49 import org
.eclipse
.jface
.viewers
.ITreeContentProvider
;
50 import org
.eclipse
.swt
.SWT
;
51 import org
.eclipse
.swt
.custom
.BusyIndicator
;
52 import org
.eclipse
.swt
.events
.FocusAdapter
;
53 import org
.eclipse
.swt
.events
.FocusEvent
;
54 import org
.eclipse
.swt
.events
.ModifyEvent
;
55 import org
.eclipse
.swt
.events
.ModifyListener
;
56 import org
.eclipse
.swt
.events
.SelectionAdapter
;
57 import org
.eclipse
.swt
.events
.SelectionEvent
;
58 import org
.eclipse
.swt
.events
.TraverseEvent
;
59 import org
.eclipse
.swt
.events
.TraverseListener
;
60 import org
.eclipse
.swt
.layout
.GridData
;
61 import org
.eclipse
.swt
.layout
.GridLayout
;
62 import org
.eclipse
.swt
.widgets
.Button
;
63 import org
.eclipse
.swt
.widgets
.Combo
;
64 import org
.eclipse
.swt
.widgets
.Composite
;
65 import org
.eclipse
.swt
.widgets
.DirectoryDialog
;
66 import org
.eclipse
.swt
.widgets
.Event
;
67 import org
.eclipse
.swt
.widgets
.FileDialog
;
68 import org
.eclipse
.swt
.widgets
.Group
;
69 import org
.eclipse
.swt
.widgets
.Label
;
70 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
71 import org
.eclipse
.tracecompass
.tmf
.core
.TmfCommonConstants
;
72 import org
.eclipse
.tracecompass
.tmf
.core
.TmfProjectNature
;
73 import org
.eclipse
.tracecompass
.tmf
.core
.project
.model
.TmfTraceType
;
74 import org
.eclipse
.tracecompass
.tmf
.core
.util
.Pair
;
75 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectElement
;
76 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfProjectRegistry
;
77 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceFolder
;
78 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTracesFolder
;
79 import org
.eclipse
.ui
.dialogs
.FileSystemElement
;
80 import org
.eclipse
.ui
.dialogs
.WizardResourceImportPage
;
81 import org
.eclipse
.ui
.ide
.dialogs
.IElementFilter
;
82 import org
.eclipse
.ui
.ide
.dialogs
.ResourceTreeAndListGroup
;
83 import org
.eclipse
.ui
.internal
.ide
.DialogUtil
;
84 import org
.eclipse
.ui
.model
.WorkbenchContentProvider
;
85 import org
.eclipse
.ui
.model
.WorkbenchLabelProvider
;
86 import org
.eclipse
.ui
.model
.WorkbenchViewerComparator
;
89 * A variant of the standard resource import wizard for importing traces to
90 * given tracing project. If no project or tracing project was selected the
91 * wizard imports it to the default tracing project which is created if
94 * In our case traces could be files or a directory structure. This wizard
95 * supports both cases. It imports traces for a selected trace type or, if no
96 * trace type is selected, it tries to detect the trace type automatically.
97 * However, the automatic detection is a best-effort and cannot guarantee that
98 * the detection is successful. The reason for this is that there might be
99 * multiple trace types that can be assigned to a single trace.
102 * @author Francois Chouinard
104 @SuppressWarnings("restriction")
105 public class ImportTraceWizardPage
extends WizardResourceImportPage
{
107 // ------------------------------------------------------------------------
109 // ------------------------------------------------------------------------
110 private static final String IMPORT_WIZARD_PAGE_NAME
= "ImportTraceWizardPage"; //$NON-NLS-1$
111 private static final String IMPORT_WIZARD_ROOT_DIRECTORY_ID
= ".import_root_directory_id"; //$NON-NLS-1$;
112 private static final String IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID
= ".import_archive_file_name_id"; //$NON-NLS-1$
113 private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
= ".import_unrecognized_traces_id"; //$NON-NLS-1$
114 private static final String IMPORT_WIZARD_PRESERVE_FOLDERS_ID
= ".import_preserve_folders_id"; //$NON-NLS-1$
115 private static final String IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID
= ".import_from_directory"; //$NON-NLS-1$
117 // constant from WizardArchiveFileResourceImportPage1
118 private static final String
[] FILE_IMPORT_MASK
= { "*.jar;*.zip;*.tar;*.tar.gz;*.tgz;*.gz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
121 * A special trace type value to communicate that automatic trace type
122 * detection will occur instead of setting a specific trace type when
123 * importing the traces.
125 public static final String TRACE_TYPE_AUTO_DETECT
= Messages
.ImportTraceWizard_AutoDetection
;
128 * Preserve the folder structure of the import traces.
130 public static final int OPTION_PRESERVE_FOLDER_STRUCTURE
= 1 << 1;
132 * Create links to the trace files instead of copies.
134 public static final int OPTION_CREATE_LINKS_IN_WORKSPACE
= 1 << 2;
136 * Import files that were not recognized as the selected trace type.
138 public static final int OPTION_IMPORT_UNRECOGNIZED_TRACES
= 1 << 3;
140 * Overwrite existing resources without prompting.
142 public static final int OPTION_OVERWRITE_EXISTING_RESOURCES
= 1 << 4;
144 // ------------------------------------------------------------------------
146 // ------------------------------------------------------------------------
148 // Target import directory ('Traces' folder)
149 private IFolder fTargetFolder
;
150 // Target Trace folder element
151 private TmfTraceFolder fTraceFolderElement
;
152 // Flag to handle destination folder change event
153 private Boolean fIsDestinationChanged
= false;
154 private final Object fSyncObject
= new Object();
155 // Combo box containing trace types
156 private Combo fTraceTypes
;
157 // Button to ignore unrecognized traces or not
158 private Button fImportUnrecognizedButton
;
159 // Button to overwrite existing resources or not
160 private Button fOverwriteExistingResourcesCheckbox
;
161 // Button to link or copy traces to workspace
162 private Button fCreateLinksInWorkspaceButton
;
163 // Button to preserve folder structure
164 private Button fPreserveFolderStructureButton
;
165 private boolean entryChanged
= false;
166 // The import from directory radio button
167 private Button fImportFromDirectoryRadio
;
168 // The import from archive radio button
169 private Button fImportFromArchiveRadio
;
170 // Flag to remember the "create links" checkbox when it gets disabled by
171 // the import from archive radio button
172 private Boolean fPreviousCreateLinksValue
= true;
174 /** The archive name field */
175 protected Combo fArchiveNameField
;
176 /** The archive browse button. */
177 protected Button fArchiveBrowseButton
;
178 /** The directory name field */
179 protected Combo directoryNameField
;
180 /** The directory browse button. */
181 protected Button directoryBrowseButton
;
183 private ResourceTreeAndListGroup fSelectionGroup
;
185 // Keep trace of the selection root so that we can dispose its related
187 private TraceFileSystemElement fSelectionGroupRoot
;
189 // ------------------------------------------------------------------------
191 // ------------------------------------------------------------------------
194 * Constructor. Creates the trace wizard page.
197 * The name of the page.
199 * The current selection
201 protected ImportTraceWizardPage(String name
, IStructuredSelection selection
) {
202 super(name
, selection
);
203 setTitle(Messages
.ImportTraceWizard_FileSystemTitle
);
204 setDescription(Messages
.ImportTraceWizard_ImportTrace
);
206 // Locate the target trace folder
207 IFolder traceFolder
= null;
208 Object element
= selection
.getFirstElement();
210 if (element
instanceof TmfTraceFolder
) {
211 fTraceFolderElement
= (TmfTraceFolder
) element
;
212 traceFolder
= fTraceFolderElement
.getResource();
213 } else if (element
instanceof IProject
) {
214 IProject project
= (IProject
) element
;
216 if (project
.hasNature(TmfProjectNature
.ID
)) {
217 TmfProjectElement projectElement
= TmfProjectRegistry
.getProject(project
, true);
218 fTraceFolderElement
= projectElement
.getTracesFolder();
219 traceFolder
= project
.getFolder(TmfTracesFolder
.TRACES_FOLDER_NAME
);
221 } catch (CoreException e
) {
225 // If no tracing project was selected or trace folder doesn't exist use
226 // default tracing project
227 if (traceFolder
== null) {
228 IProject project
= TmfProjectRegistry
.createProject(
229 TmfCommonConstants
.DEFAULT_TRACE_PROJECT_NAME
, null, new NullProgressMonitor());
230 TmfProjectElement projectElement
= TmfProjectRegistry
.getProject(project
, true);
231 fTraceFolderElement
= projectElement
.getTracesFolder();
232 traceFolder
= project
.getFolder(TmfTracesFolder
.TRACES_FOLDER_NAME
);
235 // Set the target trace folder
236 if (traceFolder
!= null) {
237 fTargetFolder
= traceFolder
;
238 String path
= traceFolder
.getFullPath().toString();
239 setContainerFieldValue(path
);
247 * The current selection
249 public ImportTraceWizardPage(IStructuredSelection selection
) {
250 this(IMPORT_WIZARD_PAGE_NAME
, selection
);
254 * Create the import source selection widget. (Copied from
255 * WizardResourceImportPage but instead always uses the internal
256 * ResourceTreeAndListGroup to keep compatibility with Kepler)
259 protected void createFileSelectionGroup(Composite parent
) {
261 // Just create with a dummy root.
262 fSelectionGroup
= new ResourceTreeAndListGroup(parent
,
263 new FileSystemElement("Dummy", null, true),//$NON-NLS-1$
264 getFolderProvider(), new WorkbenchLabelProvider(),
265 getFileProvider(), new WorkbenchLabelProvider(), SWT
.NONE
,
266 DialogUtil
.inRegularFontMode(parent
));
268 ICheckStateListener listener
= new ICheckStateListener() {
270 public void checkStateChanged(CheckStateChangedEvent event
) {
271 updateWidgetEnablements();
275 WorkbenchViewerComparator comparator
= new WorkbenchViewerComparator();
276 fSelectionGroup
.setTreeComparator(comparator
);
277 fSelectionGroup
.setListComparator(comparator
);
278 fSelectionGroup
.addCheckStateListener(listener
);
282 // ------------------------------------------------------------------------
283 // WizardResourceImportPage
284 // ------------------------------------------------------------------------
287 protected void createSourceGroup(Composite parent
) {
288 createSourceSelectionGroup(parent
);
289 createFileSelectionGroup(parent
);
290 createTraceTypeGroup(parent
);
291 validateSourceGroup();
295 protected ITreeContentProvider
getFileProvider() {
296 return new WorkbenchContentProvider() {
298 public Object
[] getChildren(Object object
) {
299 if (object
instanceof TraceFileSystemElement
) {
300 TraceFileSystemElement element
= (TraceFileSystemElement
) object
;
301 return element
.getFiles().getChildren(element
);
303 return new Object
[0];
309 protected ITreeContentProvider
getFolderProvider() {
310 return new WorkbenchContentProvider() {
312 public Object
[] getChildren(Object o
) {
313 if (o
instanceof TraceFileSystemElement
) {
314 TraceFileSystemElement element
= (TraceFileSystemElement
) o
;
315 return element
.getFolders().getChildren();
317 return new Object
[0];
321 public boolean hasChildren(Object o
) {
322 if (o
instanceof TraceFileSystemElement
) {
323 TraceFileSystemElement element
= (TraceFileSystemElement
) o
;
324 if (element
.isPopulated()) {
325 return getChildren(element
).length
> 0;
327 // If we have not populated then wait until asked
335 // ------------------------------------------------------------------------
336 // Directory Selection Group (forked WizardFileSystemResourceImportPage1)
337 // ------------------------------------------------------------------------
340 * creates the source selection group.
343 * the parent composite
345 protected void createSourceSelectionGroup(Composite parent
) {
347 Composite sourceGroup
= new Composite(parent
, SWT
.NONE
);
348 GridLayout layout
= new GridLayout();
349 layout
.numColumns
= 3;
350 layout
.makeColumnsEqualWidth
= false;
351 layout
.marginWidth
= 0;
352 sourceGroup
.setLayout(layout
);
353 sourceGroup
.setLayoutData(new GridData(GridData
.FILL_HORIZONTAL
));
355 // import from directory radio button
356 fImportFromDirectoryRadio
= new Button(sourceGroup
, SWT
.RADIO
);
357 fImportFromDirectoryRadio
358 .setText(Messages
.ImportTraceWizard_DirectoryLocation
);
360 // import location entry combo
361 directoryNameField
= createPathSelectionCombo(sourceGroup
);
362 createDirectoryBrowseButton(sourceGroup
);
364 // import from archive radio button
365 fImportFromArchiveRadio
= new Button(sourceGroup
, SWT
.RADIO
);
366 fImportFromArchiveRadio
367 .setText(Messages
.ImportTraceWizard_ArchiveLocation
);
369 // import location entry combo
370 fArchiveNameField
= createPathSelectionCombo(sourceGroup
);
371 createArchiveBrowseButton(sourceGroup
);
373 fImportFromDirectoryRadio
.setSelection(true);
374 fArchiveNameField
.setEnabled(false);
375 fArchiveBrowseButton
.setEnabled(false);
377 fImportFromDirectoryRadio
.addSelectionListener(new SelectionAdapter() {
379 public void widgetSelected(SelectionEvent e
) {
380 directoryRadioSelected();
384 fImportFromArchiveRadio
.addSelectionListener(new SelectionAdapter() {
386 public void widgetSelected(SelectionEvent e
) {
387 archiveRadioSelected();
393 * Select or deselect all files in the file selection group
396 * whether or not the files should be checked
398 protected void setFileSelectionGroupChecked(boolean checked
) {
399 if (fSelectionGroup
!= null) {
400 fSelectionGroup
.setAllSelections(checked
);
405 * Create a combo that will be used to select a path to specify the source
406 * of the import. The parent is assumed to have a GridLayout.
409 * the parent composite
410 * @return the created path selection combo
412 protected Combo
createPathSelectionCombo(Composite parent
) {
413 Combo pathSelectionCombo
= new Combo(parent
, SWT
.BORDER
);
415 GridData layoutData
= new GridData(GridData
.HORIZONTAL_ALIGN_FILL
| GridData
.GRAB_HORIZONTAL
);
416 layoutData
.widthHint
= new PixelConverter(pathSelectionCombo
).convertWidthInCharsToPixels(25);
417 pathSelectionCombo
.setLayoutData(layoutData
);
419 TraverseListener traverseListener
= new TraverseListener() {
421 public void keyTraversed(TraverseEvent e
) {
422 if (e
.detail
== SWT
.TRAVERSE_RETURN
) {
424 entryChanged
= false;
425 updateFromSourceField();
430 FocusAdapter focusAdapter
= new FocusAdapter() {
432 public void focusLost(FocusEvent e
) {
433 // Clear the flag to prevent constant update
435 entryChanged
= false;
436 updateFromSourceField();
441 SelectionAdapter selectionAdapter
= new SelectionAdapter() {
443 public void widgetSelected(SelectionEvent e
) {
444 entryChanged
= false;
445 updateFromSourceField();
449 ModifyListener modifyListner
= new ModifyListener() {
451 public void modifyText(ModifyEvent e
) {
456 pathSelectionCombo
.addModifyListener(modifyListner
);
457 pathSelectionCombo
.addTraverseListener(traverseListener
);
458 pathSelectionCombo
.addFocusListener(focusAdapter
);
459 pathSelectionCombo
.addSelectionListener(selectionAdapter
);
461 return pathSelectionCombo
;
465 * Create the directory browse button.
468 * the parent composite
470 protected void createDirectoryBrowseButton(Composite parent
) {
471 directoryBrowseButton
= createPathSelectionBrowseButton(parent
);
472 directoryBrowseButton
.addSelectionListener(new SelectionAdapter() {
474 public void widgetSelected(SelectionEvent e
) {
475 handleSourceDirectoryBrowseButtonPressed();
481 * Create the archive browse button.
484 * the parent composite
486 protected void createArchiveBrowseButton(Composite parent
) {
487 fArchiveBrowseButton
= createPathSelectionBrowseButton(parent
);
488 fArchiveBrowseButton
.addSelectionListener(new SelectionAdapter() {
490 public void widgetSelected(SelectionEvent e
) {
491 handleArchiveBrowseButtonPressed(FILE_IMPORT_MASK
);
497 * Create a browse button that will be used to browse for a path to specify
498 * the source of the import. The parent is assumed to have a GridLayout.
501 * the parent composite
502 * @return the created path selection combo
504 protected Button
createPathSelectionBrowseButton(Composite parent
) {
505 Button pathSelectionBrowseButton
= new Button(parent
, SWT
.PUSH
);
506 pathSelectionBrowseButton
.setText(Messages
.ImportTraceWizard_BrowseButton
);
507 setButtonLayoutData(pathSelectionBrowseButton
);
509 return pathSelectionBrowseButton
;
512 private void archiveRadioSelected() {
513 if (!isImportFromDirectory()) {
514 directoryNameField
.setEnabled(false);
515 directoryBrowseButton
.setEnabled(false);
516 fArchiveNameField
.setEnabled(true);
517 fArchiveBrowseButton
.setEnabled(true);
518 updateFromSourceField();
519 fArchiveNameField
.setFocus();
520 if (fCreateLinksInWorkspaceButton
!= null) {
521 fPreviousCreateLinksValue
= fCreateLinksInWorkspaceButton
.getSelection();
522 fCreateLinksInWorkspaceButton
.setSelection(false);
523 fCreateLinksInWorkspaceButton
.setEnabled(false);
528 private void directoryRadioSelected() {
529 if (isImportFromDirectory()) {
530 directoryNameField
.setEnabled(true);
531 directoryBrowseButton
.setEnabled(true);
532 fArchiveNameField
.setEnabled(false);
533 fArchiveBrowseButton
.setEnabled(false);
534 updateFromSourceField();
535 directoryNameField
.setFocus();
536 if (fCreateLinksInWorkspaceButton
!= null) {
537 fCreateLinksInWorkspaceButton
.setSelection(fPreviousCreateLinksValue
);
538 fCreateLinksInWorkspaceButton
.setEnabled(true);
543 // ------------------------------------------------------------------------
544 // Browse for the source directory
545 // ------------------------------------------------------------------------
548 public void handleEvent(Event event
) {
549 if (event
.widget
== directoryBrowseButton
) {
550 handleSourceDirectoryBrowseButtonPressed();
553 // Avoid overwriting destination path without repeatedly trigger
554 // call of handleEvent();
555 synchronized (fSyncObject
) {
556 if (fIsDestinationChanged
== false) {
557 event
.display
.asyncExec(new Runnable() {
560 synchronized (fSyncObject
) {
561 fIsDestinationChanged
= true;
562 String path
= fTargetFolder
.getFullPath().toString();
563 setContainerFieldValue(path
);
568 fIsDestinationChanged
= false;
571 super.handleEvent(event
);
575 protected void handleContainerBrowseButtonPressed() {
576 // Do nothing so that destination directory cannot be changed.
580 * Handle the button pressed event
582 protected void handleSourceDirectoryBrowseButtonPressed() {
583 String currentSource
= directoryNameField
.getText();
584 DirectoryDialog dialog
= new DirectoryDialog(directoryNameField
.getShell(), SWT
.SAVE
| SWT
.SHEET
);
585 dialog
.setText(Messages
.ImportTraceWizard_SelectTraceDirectoryTitle
);
586 dialog
.setMessage(Messages
.ImportTraceWizard_SelectTraceDirectoryMessage
);
587 dialog
.setFilterPath(getSourceDirectoryName(currentSource
));
589 String selectedDirectory
= dialog
.open();
590 if (selectedDirectory
!= null) {
591 // Just quit if the directory is not valid
592 if ((getSourceDirectory(selectedDirectory
) == null) || selectedDirectory
.equals(currentSource
)) {
595 // If it is valid then proceed to populate
596 setErrorMessage(null);
597 setSourcePath(selectedDirectory
);
602 * Handle the button pressed event
605 * file extensions used to filter files shown to the user
607 protected void handleArchiveBrowseButtonPressed(String
[] extensions
) {
608 FileDialog dialog
= new FileDialog(fArchiveNameField
.getShell(), SWT
.SHEET
);
609 dialog
.setFilterExtensions(extensions
);
610 dialog
.setText(Messages
.ImportTraceWizard_SelectTraceArchiveTitle
);
611 String fileName
= fArchiveNameField
.getText().trim();
612 if (!fileName
.isEmpty()) {
613 File path
= new File(fileName
).getParentFile();
614 if (path
!= null && path
.exists()) {
615 dialog
.setFilterPath(path
.toString());
619 String selectedArchive
= dialog
.open();
620 if (selectedArchive
!= null) {
621 setErrorMessage(null);
622 setSourcePath(selectedArchive
);
623 updateWidgetEnablements();
627 private File
getSourceDirectory() {
628 if (directoryNameField
== null) {
631 return getSourceDirectory(directoryNameField
.getText());
634 private File
getSourceArchiveFile() {
635 if (fArchiveNameField
== null) {
639 return getSourceArchiveFile(fArchiveNameField
.getText());
642 private String
getSourceContainerPath() {
643 if (isImportFromDirectory()) {
644 File sourceDirectory
= getSourceDirectory();
645 if (sourceDirectory
!= null) {
646 return sourceDirectory
.getAbsolutePath();
649 File sourceArchiveFile
= getSourceArchiveFile();
650 if (sourceArchiveFile
!= null) {
651 return sourceArchiveFile
.getParent();
656 private static File
getSourceDirectory(String path
) {
657 File sourceDirectory
= new File(getSourceDirectoryName(path
));
658 if (!sourceDirectory
.exists() || !sourceDirectory
.isDirectory()) {
662 return sourceDirectory
;
665 private static File
getSourceArchiveFile(String path
) {
666 File sourceArchiveFile
= new File(path
);
667 if (!sourceArchiveFile
.exists() || sourceArchiveFile
.isDirectory()) {
671 return sourceArchiveFile
;
674 private static String
getSourceDirectoryName(String sourceName
) {
675 IPath result
= new Path(sourceName
.trim());
676 if (result
.getDevice() != null && result
.segmentCount() == 0) {
677 result
= result
.addTrailingSeparator();
679 result
= result
.removeTrailingSeparator();
681 return result
.toOSString();
684 private void updateFromSourceField() {
685 setSourcePath(getSourceField().getText());
686 updateWidgetEnablements();
689 private Combo
getSourceField() {
690 if (directoryNameField
== null) {
691 return fArchiveNameField
;
694 return directoryNameField
.isEnabled() ? directoryNameField
: fArchiveNameField
;
698 * Set the source path that was selected by the user by various input
699 * methods (Browse button, typing, etc).
701 * Clients can also call this to set the path programmatically (hard-coded
702 * initial path) and this can also be overridden to be notified when the
703 * source path changes.
708 protected void setSourcePath(String path
) {
709 Combo sourceField
= getSourceField();
710 if (sourceField
== null) {
714 if (path
.length() > 0) {
715 String
[] currentItems
= sourceField
.getItems();
716 int selectionIndex
= -1;
717 for (int i
= 0; i
< currentItems
.length
; i
++) {
718 if (currentItems
[i
].equals(path
)) {
722 if (selectionIndex
< 0) {
723 int oldLength
= currentItems
.length
;
724 String
[] newItems
= new String
[oldLength
+ 1];
725 System
.arraycopy(currentItems
, 0, newItems
, 0, oldLength
);
726 newItems
[oldLength
] = path
;
727 sourceField
.setItems(newItems
);
728 selectionIndex
= oldLength
;
730 sourceField
.select(selectionIndex
);
735 // ------------------------------------------------------------------------
736 // File Selection Group (forked WizardFileSystemResourceImportPage1)
737 // ------------------------------------------------------------------------
738 private void resetSelection() {
739 if (fSelectionGroupRoot
!= null) {
740 disposeSelectionGroupRoot();
742 fSelectionGroupRoot
= getFileSystemTree();
743 fSelectionGroup
.setRoot(fSelectionGroupRoot
);
746 private void disposeSelectionGroupRoot() {
747 if (fSelectionGroupRoot
!= null && fSelectionGroupRoot
.getProvider() != null) {
748 FileSystemObjectImportStructureProvider provider
= fSelectionGroupRoot
.getProvider();
750 fSelectionGroupRoot
= null;
754 private TraceFileSystemElement
getFileSystemTree() {
755 Pair
<IFileSystemObject
, FileSystemObjectImportStructureProvider
> rootObjectAndProvider
= ArchiveUtil
.getRootObjectAndProvider(getSourceFile(), getContainer().getShell());
756 if (rootObjectAndProvider
== null) {
759 return selectFiles(rootObjectAndProvider
.getFirst(), rootObjectAndProvider
.getSecond());
762 private TraceFileSystemElement
selectFiles(final IFileSystemObject rootFileSystemObject
,
763 final FileSystemObjectImportStructureProvider structureProvider
) {
764 final TraceFileSystemElement
[] results
= new TraceFileSystemElement
[1];
765 BusyIndicator
.showWhile(getShell().getDisplay(), new Runnable() {
768 // Create the root element from the supplied file system object
769 results
[0] = TraceFileSystemElement
.createRootTraceFileElement(rootFileSystemObject
, structureProvider
);
775 // ------------------------------------------------------------------------
777 // ------------------------------------------------------------------------
778 private final void createTraceTypeGroup(Composite parent
) {
779 Composite composite
= new Composite(parent
, SWT
.NONE
);
780 GridLayout layout
= new GridLayout();
781 layout
.numColumns
= 3;
782 layout
.makeColumnsEqualWidth
= false;
783 composite
.setLayout(layout
);
784 composite
.setFont(parent
.getFont());
785 GridData buttonData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false);
786 composite
.setLayoutData(buttonData
);
788 // Trace type label ("Trace Type:")
789 Label typeLabel
= new Label(composite
, SWT
.NONE
);
790 typeLabel
.setText(Messages
.ImportTraceWizard_TraceType
);
791 typeLabel
.setFont(parent
.getFont());
794 fTraceTypes
= new Combo(composite
, SWT
.BORDER
| SWT
.READ_ONLY
);
795 GridData data
= new GridData(SWT
.FILL
, SWT
.FILL
, true, false, 2, 1);
796 fTraceTypes
.setLayoutData(data
);
797 fTraceTypes
.setFont(parent
.getFont());
799 String
[] availableTraceTypes
= TmfTraceType
.getAvailableTraceTypes();
800 String
[] traceTypeList
= new String
[availableTraceTypes
.length
+ 1];
801 traceTypeList
[0] = TRACE_TYPE_AUTO_DETECT
;
802 for (int i
= 0; i
< availableTraceTypes
.length
; i
++) {
803 traceTypeList
[i
+ 1] = availableTraceTypes
[i
];
805 fTraceTypes
.setItems(traceTypeList
);
806 fTraceTypes
.addSelectionListener(new SelectionAdapter() {
808 public void widgetSelected(SelectionEvent e
) {
809 updateWidgetEnablements();
810 boolean enabled
= fTraceTypes
.getText().equals(TRACE_TYPE_AUTO_DETECT
);
811 fImportUnrecognizedButton
.setEnabled(enabled
);
814 fTraceTypes
.select(0);
816 // Unrecognized checkbox
817 fImportUnrecognizedButton
= new Button(composite
, SWT
.CHECK
);
818 fImportUnrecognizedButton
.setSelection(true);
819 fImportUnrecognizedButton
.setText(Messages
.ImportTraceWizard_ImportUnrecognized
);
822 // ------------------------------------------------------------------------
824 // ------------------------------------------------------------------------
827 protected void createOptionsGroupButtons(Group optionsGroup
) {
829 // Overwrite checkbox
830 fOverwriteExistingResourcesCheckbox
= new Button(optionsGroup
, SWT
.CHECK
);
831 fOverwriteExistingResourcesCheckbox
.setFont(optionsGroup
.getFont());
832 fOverwriteExistingResourcesCheckbox
.setText(Messages
.ImportTraceWizard_OverwriteExistingTrace
);
833 fOverwriteExistingResourcesCheckbox
.setSelection(false);
835 // Create links checkbox
836 fCreateLinksInWorkspaceButton
= new Button(optionsGroup
, SWT
.CHECK
);
837 fCreateLinksInWorkspaceButton
.setFont(optionsGroup
.getFont());
838 fCreateLinksInWorkspaceButton
.setText(Messages
.ImportTraceWizard_CreateLinksInWorkspace
);
839 fCreateLinksInWorkspaceButton
.setSelection(true);
841 fCreateLinksInWorkspaceButton
.addSelectionListener(new SelectionAdapter() {
843 public void widgetSelected(SelectionEvent e
) {
844 updateWidgetEnablements();
848 fPreserveFolderStructureButton
= new Button(optionsGroup
, SWT
.CHECK
);
849 fPreserveFolderStructureButton
.setFont(optionsGroup
.getFont());
850 fPreserveFolderStructureButton
.setText(Messages
.ImportTraceWizard_PreserveFolderStructure
);
851 fPreserveFolderStructureButton
.setSelection(true);
853 updateWidgetEnablements();
856 // ------------------------------------------------------------------------
857 // Determine if the finish button can be enabled
858 // ------------------------------------------------------------------------
860 public boolean validateSourceGroup() {
862 File source
= getSourceFile();
863 if (source
== null) {
864 setMessage(Messages
.ImportTraceWizard_SelectTraceSourceEmpty
);
865 setErrorMessage(null);
869 if (sourceConflictsWithDestination(new Path(source
.getPath()))) {
871 setErrorMessage(getSourceConflictMessage());
875 if (!isImportFromDirectory() && !ArchiveUtil
.ensureTarSourceIsValid(source
.getAbsolutePath(), getContainer().getShell()) && !ArchiveUtil
.ensureZipSourceIsValid(source
.getAbsolutePath(), getContainer().getShell()) && !ArchiveUtil
.ensureGzipSourceIsValid(source
.getAbsolutePath())) {
877 setErrorMessage(Messages
.ImportTraceWizard_BadArchiveFormat
);
881 if (fSelectionGroup
.getCheckedElementCount() == 0) {
883 setErrorMessage(Messages
.ImportTraceWizard_SelectTraceNoneSelected
);
887 IContainer container
= getSpecifiedContainer();
888 if (container
!= null && container
.isVirtual()) {
889 if (Platform
.getPreferencesService().getBoolean(Activator
.PLUGIN_ID
, ResourcesPlugin
.PREF_DISABLE_LINKING
, false, null)) {
891 setErrorMessage(Messages
.ImportTraceWizard_CannotImportFilesUnderAVirtualFolder
);
894 if (fCreateLinksInWorkspaceButton
== null || !fCreateLinksInWorkspaceButton
.getSelection()) {
896 setErrorMessage(Messages
.ImportTraceWizard_HaveToCreateLinksUnderAVirtualFolder
);
901 setErrorMessage(null);
905 private File
getSourceFile() {
906 return isImportFromDirectory() ?
getSourceDirectory() : getSourceArchiveFile();
909 private boolean isImportFromDirectory() {
910 return fImportFromDirectoryRadio
!= null && fImportFromDirectoryRadio
.getSelection();
914 protected void restoreWidgetValues() {
915 super.restoreWidgetValues();
917 IDialogSettings settings
= getDialogSettings();
919 if (fImportUnrecognizedButton
!= null) {
920 if (settings
.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
)) == null) {
923 value
= settings
.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
));
925 fImportUnrecognizedButton
.setSelection(value
);
928 if (fPreserveFolderStructureButton
!= null) {
929 if (settings
.get(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID
)) == null) {
932 value
= settings
.getBoolean(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID
));
934 fPreserveFolderStructureButton
.setSelection(value
);
937 if (settings
.get(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID
)) == null) {
940 value
= settings
.getBoolean(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID
));
943 if (directoryNameField
!= null) {
944 restoreComboValues(directoryNameField
, settings
, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID
));
946 if (fArchiveNameField
!= null) {
947 restoreComboValues(fArchiveNameField
, settings
, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID
));
950 if (fImportFromDirectoryRadio
!= null) {
951 fImportFromDirectoryRadio
.setSelection(value
);
953 directoryRadioSelected();
956 if (fImportFromArchiveRadio
!= null) {
957 fImportFromArchiveRadio
.setSelection(!value
);
959 archiveRadioSelected();
965 protected void saveWidgetValues() {
966 // Persist dialog settings
967 IDialogSettings settings
= getDialogSettings();
968 if (fImportUnrecognizedButton
!= null) {
969 settings
.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID
), fImportUnrecognizedButton
.getSelection());
971 if (fPreserveFolderStructureButton
!= null) {
972 settings
.put(getPageStoreKey(IMPORT_WIZARD_PRESERVE_FOLDERS_ID
), fPreserveFolderStructureButton
.getSelection());
974 settings
.put(getPageStoreKey(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY_ID
), isImportFromDirectory());
976 if (directoryNameField
!= null) {
977 saveComboValues(directoryNameField
, settings
, getPageStoreKey(IMPORT_WIZARD_ROOT_DIRECTORY_ID
));
979 if (fArchiveNameField
!= null) {
980 saveComboValues(fArchiveNameField
, settings
, getPageStoreKey(IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID
));
984 private String
getPageStoreKey(String key
) {
985 return getName() + key
;
988 private static void restoreComboValues(Combo combo
, IDialogSettings settings
, String key
) {
989 String
[] directoryNames
= settings
.getArray(key
);
990 if ((directoryNames
!= null) && (directoryNames
.length
!= 0)) {
991 for (int i
= 0; i
< directoryNames
.length
; i
++) {
992 combo
.add(directoryNames
[i
]);
997 private void saveComboValues(Combo combo
, IDialogSettings settings
, String key
) {
998 // update names history
999 String
[] directoryNames
= settings
.getArray(key
);
1000 if (directoryNames
== null) {
1001 directoryNames
= new String
[0];
1004 String items
[] = combo
.getItems();
1005 for (int i
= 0; i
< items
.length
; i
++) {
1006 directoryNames
= addToHistory(directoryNames
, items
[i
]);
1008 settings
.put(key
, directoryNames
);
1011 // ------------------------------------------------------------------------
1012 // Import the trace(s)
1013 // ------------------------------------------------------------------------
1016 * Finish the import.
1018 * @return <code>true</code> if successful else <code>false</code>
1020 public boolean finish() {
1021 String traceTypeLabel
= getImportTraceTypeId();
1022 final String traceId
= !TRACE_TYPE_AUTO_DETECT
.equals(traceTypeLabel
) ? TmfTraceType
.getTraceTypeId(traceTypeLabel
) : null;
1024 // Save dialog settings
1027 final IPath baseSourceContainerPath
= new Path(getSourceContainerPath());
1028 final boolean importFromArchive
= getSourceArchiveFile() != null;
1029 final int importOptionFlags
= getImportOptionFlags();
1030 final IPath destinationContainerPath
= getContainerFullPath();
1032 final IStatus
[] operationStatus
= new IStatus
[1];
1033 operationStatus
[0] = Status
.OK_STATUS
;
1035 getContainer().run(true, true, new IRunnableWithProgress() {
1037 public void run(IProgressMonitor monitor
) throws InvocationTargetException
, InterruptedException
{
1039 final List
<TraceFileSystemElement
> selectedFileSystemElements
= new LinkedList
<>();
1040 IElementFilter passThroughFilter
= new IElementFilter() {
1043 public void filterElements(Collection elements
, IProgressMonitor m
) {
1044 selectedFileSystemElements
.addAll(elements
);
1048 public void filterElements(Object
[] elements
, IProgressMonitor m
) {
1049 for (int i
= 0; i
< elements
.length
; i
++) {
1050 selectedFileSystemElements
.add((TraceFileSystemElement
) elements
[i
]);
1055 // List fileSystemElements will be filled using the
1056 // passThroughFilter
1057 SubMonitor subMonitor
= SubMonitor
.convert(monitor
, 1);
1058 fSelectionGroup
.getAllCheckedListItems(passThroughFilter
, subMonitor
);
1060 final TraceValidateAndImportOperation operation
= new TraceValidateAndImportOperation(getContainer().getShell(), selectedFileSystemElements
, traceId
, baseSourceContainerPath
, destinationContainerPath
, importFromArchive
,
1061 importOptionFlags
, fTraceFolderElement
);
1062 operation
.run(monitor
);
1064 operationStatus
[0] = operation
.getStatus();
1068 } catch (InvocationTargetException e
) {
1069 operationStatus
[0] = new Status(IStatus
.ERROR
, Activator
.PLUGIN_ID
, Messages
.ImportTraceWizard_ImportProblem
, e
.getTargetException());
1070 } catch (InterruptedException e
) {
1071 operationStatus
[0] = Status
.CANCEL_STATUS
;
1073 if (!operationStatus
[0].isOK()) {
1074 if (operationStatus
[0].getSeverity() == IStatus
.CANCEL
) {
1075 setMessage(Messages
.ImportTraceWizard_ImportOperationCancelled
);
1076 setErrorMessage(null);
1078 Throwable exception
= operationStatus
[0].getException();
1079 if (exception
!= null) {
1080 Activator
.getDefault().logError(exception
.getMessage(), exception
);
1081 displayErrorDialog(operationStatus
[0].getMessage() + ": " + exception
); //$NON-NLS-1$
1084 setErrorMessage(Messages
.ImportTraceWizard_ImportProblem
);
1088 setErrorMessage(null);
1093 * Get the trace type id to import as. This can also return
1094 * {@link #TRACE_TYPE_AUTO_DETECT} to communicate that automatic trace type
1095 * detection will occur instead of setting a specific trace type when
1096 * importing the traces.
1098 * @return the trace type id or {@link #TRACE_TYPE_AUTO_DETECT}
1100 protected String
getImportTraceTypeId() {
1101 return fTraceTypes
.getText();
1105 * Get import options in the form of flags (bits).
1107 * @return the import flags.
1108 * @see #OPTION_CREATE_LINKS_IN_WORKSPACE
1109 * @see #OPTION_IMPORT_UNRECOGNIZED_TRACES
1110 * @see #OPTION_OVERWRITE_EXISTING_RESOURCES
1111 * @see #OPTION_PRESERVE_FOLDER_STRUCTURE
1113 protected int getImportOptionFlags() {
1115 if (fCreateLinksInWorkspaceButton
!= null && fCreateLinksInWorkspaceButton
.getSelection()) {
1116 flags
|= OPTION_CREATE_LINKS_IN_WORKSPACE
;
1118 if (fImportUnrecognizedButton
!= null && fImportUnrecognizedButton
.getSelection()) {
1119 flags
|= OPTION_IMPORT_UNRECOGNIZED_TRACES
;
1121 if (fOverwriteExistingResourcesCheckbox
!= null && fOverwriteExistingResourcesCheckbox
.getSelection()) {
1122 flags
|= OPTION_OVERWRITE_EXISTING_RESOURCES
;
1124 if (fPreserveFolderStructureButton
!= null && fPreserveFolderStructureButton
.getSelection()) {
1125 flags
|= OPTION_PRESERVE_FOLDER_STRUCTURE
;
1131 public void dispose() {
1133 disposeSelectionGroupRoot();