tmf: Import from archive in the standard import wizard
authorMarc-Andre Laperle <marc-andre.laperle@ericsson.com>
Thu, 17 Jul 2014 18:53:03 +0000 (14:53 -0400)
committerMarc-Andre Laperle <marc-andre.laperle@ericsson.com>
Tue, 5 Aug 2014 21:26:27 +0000 (17:26 -0400)
Change-Id: I80caf396b8bf8cff2a7bc3824da83800097e1130
Signed-off-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/30556
Tested-by: Hudson CI
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
Tested-by: Patrick Tasse <patrick.tasse@gmail.com>
org.eclipse.linuxtools.lttng.help/doc/User-Guide.mediawiki
org.eclipse.linuxtools.lttng.help/doc/images/ProjectImportTraceDialog.png
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/Messages.java
org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/wizards/importtrace/messages.properties

index ec16a7147c0c3da571db7e5502eb880d56a0a6c1..6c947fb2951e9d17df302458e35d57a20f9c0e64 100644 (file)
@@ -210,15 +210,17 @@ To import a set of traces to a trace folder, right-click on the target folder an
 
 [[Image:images/ProjectImportTraceAction.png]]
 
-At this point, the '''Import Trace Wizard''' will show for selecting traces to import. By default, it shows the correct destination directory where the traces will be imported to. Now, specify the location of the traces in the '''Source directory'''. For that click on the button '''Browse''', browse the media to the location of the traces and click on '''OK'''. Then select the traces to import in the list of files and folders. Optionally, select the '''Trace Type''' from the drop-down menu.
+At this point, the '''Import Trace Wizard''' will show for selecting traces to import. By default, it shows the correct destination directory where the traces will be imported to. Now, specify the location of the traces in the '''Root directory'''. For that click on the button '''Browse''', browse the media to the location of the traces and click on '''OK'''. Then select the traces to import in the list of files and folders.
 
-If '''Trace Type''' is set to '''<Automatic Detection>''', the wizard will attempt to detect the trace types of the selected files. The automatic detection algorithm validates a trace against all known trace types. If multiple trace types are valid, a trace type is chosen based on a confidence criteria. The validation process and the computation of the confidence level are trace type specific. Optionally, '''Import unrecognized traces''' can be selected to import trace files that could not be automatically detected by '''<Automatic Detection>'''.
+Traces can also be imported from an archive file such as a zip or a tar file by selecting the '''Select archive file''' option then by clicking '''Browse'''. Then select the traces to import in the list of files and folders as usual.
+
+Optionally, select the '''Trace Type''' from the drop-down menu. If '''Trace Type''' is set to '''<Automatic Detection>''', the wizard will attempt to detect the trace types of the selected files. The automatic detection algorithm validates a trace against all known trace types. If multiple trace types are valid, a trace type is chosen based on a confidence criteria. The validation process and the computation of the confidence level are trace type specific. Optionally, '''Import unrecognized traces''' can be selected to import trace files that could not be automatically detected by '''<Automatic Detection>'''.
 
 Select or deselect the checkboxes for '''Overwrite existing trace without warning''', '''Create links in workspace''' and '''Preserve folder structure'''. When all options are configured, click on '''Finish'''.
 
 Note that traces of certain types (e.g. LTTng Kernel) are actually a composite of multiple channel traces grouped under a folder. Either the folder or its files can be selected to import the trace.
 
-The option '''Preserve folder structure''' will create, if necessary, the structure of folders relative to (and excluding) the selected '''Source directory''' into the target trace folder.
+The option '''Preserve folder structure''' will create, if necessary, the structure of folders relative to (and excluding) the selected '''Root directory''' (or '''Archive file''') into the target trace folder.
 
 [[Image:images/ProjectImportTraceDialog.png]]
 
index d6205a3feb431e2eddfe33506c6ab230e4b892e8..9ddcc3e687c618ec89142a3c87154451d55f1b6e 100644 (file)
Binary files a/org.eclipse.linuxtools.lttng.help/doc/images/ProjectImportTraceDialog.png and b/org.eclipse.linuxtools.lttng.help/doc/images/ProjectImportTraceDialog.png differ
index ea78907fe3258994e9958fcbca493aec6d786c17..8872f80bd2d878fb86242af4329f89878c59d87d 100644 (file)
 package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.importtrace;
 
 import java.io.File;
+import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.InvocationTargetException;
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
 
 import org.eclipse.core.resources.IContainer;
 import org.eclipse.core.resources.IFolder;
@@ -47,6 +52,7 @@ import org.eclipse.core.runtime.SubProgressMonitor;
 import org.eclipse.core.runtime.URIUtil;
 import org.eclipse.jface.dialogs.IDialogSettings;
 import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.PixelConverter;
 import org.eclipse.jface.operation.IRunnableWithProgress;
 import org.eclipse.jface.operation.ModalContext;
 import org.eclipse.jface.viewers.CheckStateChangedEvent;
@@ -68,14 +74,14 @@ import org.eclipse.linuxtools.tmf.ui.project.model.TmfTracesFolder;
 import org.eclipse.osgi.util.NLS;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.events.FocusAdapter;
 import org.eclipse.swt.events.FocusEvent;
-import org.eclipse.swt.events.FocusListener;
-import org.eclipse.swt.events.KeyEvent;
-import org.eclipse.swt.events.KeyListener;
 import org.eclipse.swt.events.ModifyEvent;
 import org.eclipse.swt.events.ModifyListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Button;
@@ -83,6 +89,7 @@ import org.eclipse.swt.widgets.Combo;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.DirectoryDialog;
 import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.FileDialog;
 import org.eclipse.swt.widgets.Group;
 import org.eclipse.swt.widgets.Label;
 import org.eclipse.ui.IWorkbench;
@@ -91,6 +98,14 @@ import org.eclipse.ui.dialogs.IOverwriteQuery;
 import org.eclipse.ui.dialogs.WizardResourceImportPage;
 import org.eclipse.ui.internal.ide.DialogUtil;
 import org.eclipse.ui.internal.ide.dialogs.IElementFilter;
+import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileManipulations;
+import org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages;
+import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider;
+import org.eclipse.ui.internal.wizards.datatransfer.TarEntry;
+import org.eclipse.ui.internal.wizards.datatransfer.TarException;
+import org.eclipse.ui.internal.wizards.datatransfer.TarFile;
+import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider;
+import org.eclipse.ui.internal.wizards.datatransfer.ZipLeveledStructureProvider;
 import org.eclipse.ui.model.AdaptableList;
 import org.eclipse.ui.model.WorkbenchContentProvider;
 import org.eclipse.ui.model.WorkbenchLabelProvider;
@@ -124,11 +139,17 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
     // ------------------------------------------------------------------------
     private static final String IMPORT_WIZARD_PAGE = "ImportTraceWizardPage"; //$NON-NLS-1$
     private static final String IMPORT_WIZARD_ROOT_DIRECTORY_ID = IMPORT_WIZARD_PAGE + ".import_root_directory_id"; //$NON-NLS-1$
+    private static final String IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID = IMPORT_WIZARD_PAGE + ".import_archive_file_name_id"; //$NON-NLS-1$
     private static final String IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID = IMPORT_WIZARD_PAGE + ".import_unrecognized_traces_id"; //$NON-NLS-1$
     private static final String IMPORT_WIZARD_PRESERVE_FOLDERS_ID = IMPORT_WIZARD_PAGE + ".import_preserve_folders_id"; //$NON-NLS-1$
+    private static final String IMPORT_WIZARD_IMPORT_FROM_DIRECTORY = IMPORT_WIZARD_PAGE + ".import_from_directory"; //$NON-NLS-1$
     private static final String SEPARATOR = ":"; //$NON-NLS-1$
     private static final String AUTO_DETECT = Messages.ImportTraceWizard_AutoDetection;
 
+    // constant from WizardArchiveFileResourceImportPage1
+    private static final String[] FILE_IMPORT_MASK = { "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$
+    private static final String TRACE_IMPORT_TEMP_FOLDER = ".traceImport"; //$NON-NLS-1$
+
     // ------------------------------------------------------------------------
     // Attributes
     // ------------------------------------------------------------------------
@@ -150,6 +171,18 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
     // Button to preserve folder structure
     private Button fPreserveFolderStructureButton;
     private boolean entryChanged = false;
+    // The import from directory radio button
+    private Button fImportFromDirectoryRadio;
+    // The import from archive radio button
+    private Button fImportFromArchiveRadio;
+    // Flag to remember the "create links" checkbox when it gets disabled by
+    // the import from archive radio button
+    private Boolean fPreviousCreateLinksValue = true;
+    /** The archive name field */
+    private Combo fArchiveNameField;
+    /** The archive browse button. */
+    protected Button fArchiveBrowseButton;
+
     /** The directory name field */
     protected Combo directoryNameField;
     /** The directory browse button. */
@@ -164,6 +197,10 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
      */
     private ResourceTreeAndListGroup fSelectionGroup;
 
+    // Keep trace of the selection root so that we can dispose its related
+    // resources
+    private TraceFileSystemElement fSelectionGroupRoot;
+
     // ------------------------------------------------------------------------
     // Constructors
     // ------------------------------------------------------------------------
@@ -265,7 +302,7 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
 
     @Override
     protected void createSourceGroup(Composite parent) {
-        createDirectorySelectionGroup(parent);
+        createSourceSelectionGroup(parent);
         createFileSelectionGroup(parent);
         createTraceTypeGroup(parent);
         validateSourceGroup();
@@ -317,58 +354,85 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
     // ------------------------------------------------------------------------
 
     /**
-     * creates the directory selection group.
+     * creates the source selection group.
      *
      * @param parent
      *            the parent composite
      */
-    protected void createDirectorySelectionGroup(Composite parent) {
+    private void createSourceSelectionGroup(Composite workArea) {
 
-        Composite directoryContainerGroup = new Composite(parent, SWT.NONE);
+        Composite sourceGroup = new Composite(workArea, SWT.NONE);
         GridLayout layout = new GridLayout();
         layout.numColumns = 3;
-        directoryContainerGroup.setLayout(layout);
-        directoryContainerGroup.setFont(parent.getFont());
-        directoryContainerGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
-
-        // Label ("Trace directory:")
-        Label groupLabel = new Label(directoryContainerGroup, SWT.NONE);
-        groupLabel.setText(Messages.ImportTraceWizard_DirectoryLocation);
-        groupLabel.setFont(parent.getFont());
-
-        // Directory name entry field
-        directoryNameField = new Combo(directoryContainerGroup, SWT.BORDER);
-        GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
-        data.widthHint = SIZING_TEXT_FIELD_WIDTH;
-        directoryNameField.setLayoutData(data);
-        directoryNameField.setFont(parent.getFont());
-
-        directoryNameField.addSelectionListener(new SelectionAdapter() {
+        layout.makeColumnsEqualWidth = false;
+        layout.marginWidth = 0;
+        sourceGroup.setLayout(layout);
+        sourceGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        // import from directory radio button
+        fImportFromDirectoryRadio = new Button(sourceGroup, SWT.RADIO);
+        fImportFromDirectoryRadio
+                .setText(Messages.ImportTraceWizard_DirectoryLocation);
+
+        // import location entry combo
+        directoryNameField = new Combo(sourceGroup, SWT.BORDER);
+
+        GridData directoryPathData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
+        directoryPathData.widthHint = new PixelConverter(directoryNameField).convertWidthInCharsToPixels(25);
+        directoryNameField.setLayoutData(directoryPathData);
+
+        // browse button
+        directoryBrowseButton = new Button(sourceGroup, SWT.PUSH);
+        directoryBrowseButton
+                .setText(Messages.ImportTraceWizard_BrowseButton);
+        setButtonLayoutData(directoryBrowseButton);
+
+        // import from archive radio button
+        fImportFromArchiveRadio = new Button(sourceGroup, SWT.RADIO);
+        fImportFromArchiveRadio
+                .setText(Messages.ImportTraceWizard_ArchiveLocation);
+
+        // import location entry combo
+        fArchiveNameField = new Combo(sourceGroup, SWT.BORDER);
+
+        GridData archivePathData = new GridData(GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL);
+        archivePathData.widthHint = new PixelConverter(fArchiveNameField).convertWidthInCharsToPixels(25);
+        fArchiveNameField.setLayoutData(archivePathData); // browse button
+        fArchiveBrowseButton = new Button(sourceGroup, SWT.PUSH);
+        fArchiveBrowseButton.setText(DataTransferMessages.DataTransfer_browse);
+        setButtonLayoutData(fArchiveBrowseButton);
+
+        fImportFromDirectoryRadio.setSelection(true);
+        fArchiveNameField.setEnabled(false);
+        fArchiveBrowseButton.setEnabled(false);
+
+        directoryBrowseButton.addSelectionListener(new SelectionAdapter() {
             @Override
             public void widgetSelected(SelectionEvent e) {
-                updateFromSourceField();
+                handleSourceDirectoryBrowseButtonPressed();
             }
-        });
 
-        directoryNameField.addKeyListener(new KeyListener() {
-            @Override
-            public void keyPressed(KeyEvent e) {
-                if (e.character == SWT.CR) { // Windows...
-                    entryChanged = false;
-                    updateFromSourceField();
-                }
-            }
+        });
 
+        fArchiveBrowseButton.addSelectionListener(new SelectionAdapter() {
             @Override
-            public void keyReleased(KeyEvent e) {
+            public void widgetSelected(SelectionEvent e) {
+                handleArchiveBrowseButtonPressed();
             }
         });
 
-        directoryNameField.addFocusListener(new FocusListener() {
+        TraverseListener traverseListener = new TraverseListener() {
             @Override
-            public void focusGained(FocusEvent e) {
-                // Do nothing when getting focus
+            public void keyTraversed(TraverseEvent e) {
+                if (e.detail == SWT.TRAVERSE_RETURN) {
+                    e.doit = false;
+                    entryChanged = false;
+                    updateFromSourceField();
+                }
             }
+        };
+
+        FocusAdapter focusAdapter = new FocusAdapter() {
             @Override
             public void focusLost(FocusEvent e) {
                 // Clear the flag to prevent constant update
@@ -377,22 +441,72 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
                     updateFromSourceField();
                 }
             }
-        });
+        };
+
+        SelectionAdapter selectionAdapter = new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                entryChanged = false;
+                updateFromSourceField();
+            }
+        };
 
-        directoryNameField.addModifyListener(new ModifyListener() {
+        ModifyListener modifyListner = new ModifyListener() {
             @Override
             public void modifyText(ModifyEvent e) {
                 entryChanged = true;
             }
+        };
+
+        directoryNameField.addModifyListener(modifyListner);
+        directoryNameField.addTraverseListener(traverseListener);
+        directoryNameField.addFocusListener(focusAdapter);
+        directoryNameField.addSelectionListener(selectionAdapter);
+        fArchiveNameField.addModifyListener(modifyListner);
+        fArchiveNameField.addTraverseListener(traverseListener);
+        fArchiveNameField.addFocusListener(focusAdapter);
+        fArchiveNameField.addSelectionListener(selectionAdapter);
+
+        fImportFromDirectoryRadio.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                directoryRadioSelected();
+            }
         });
 
-        // Browse button
-        directoryBrowseButton = new Button(directoryContainerGroup, SWT.PUSH);
-        directoryBrowseButton.setText(Messages.ImportTraceWizard_BrowseButton);
-        directoryBrowseButton.addListener(SWT.Selection, this);
-        directoryBrowseButton.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
-        directoryBrowseButton.setFont(parent.getFont());
-        setButtonLayoutData(directoryBrowseButton);
+        fImportFromArchiveRadio.addSelectionListener(new SelectionAdapter() {
+            @Override
+            public void widgetSelected(SelectionEvent e) {
+                archiveRadioSelected();
+            }
+        });
+    }
+
+    private void archiveRadioSelected() {
+        if (fImportFromArchiveRadio.getSelection()) {
+            directoryNameField.setEnabled(false);
+            directoryBrowseButton.setEnabled(false);
+            fArchiveNameField.setEnabled(true);
+            fArchiveBrowseButton.setEnabled(true);
+            updateFromSourceField();
+            fArchiveNameField.setFocus();
+            fPreviousCreateLinksValue = fCreateLinksInWorkspaceButton.getSelection();
+            fCreateLinksInWorkspaceButton.setSelection(false);
+            fCreateLinksInWorkspaceButton.setEnabled(false);
+        }
+    }
+
+    private void directoryRadioSelected() {
+        if (fImportFromDirectoryRadio.getSelection()) {
+            directoryNameField.setEnabled(true);
+            directoryBrowseButton.setEnabled(true);
+            fArchiveNameField.setEnabled(false);
+            fArchiveBrowseButton.setEnabled(false);
+            updateFromSourceField();
+            directoryNameField.setFocus();
+            fCreateLinksInWorkspaceButton.setSelection(fPreviousCreateLinksValue);
+            fCreateLinksInWorkspaceButton.setEnabled(true);
+        }
     }
 
     // ------------------------------------------------------------------------
@@ -453,10 +567,51 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         }
     }
 
+    /**
+     * Handle the button pressed event
+     */
+    private void handleArchiveBrowseButtonPressed() {
+        FileDialog dialog = new FileDialog(fArchiveNameField.getShell(), SWT.SHEET);
+        dialog.setFilterExtensions(FILE_IMPORT_MASK);
+        dialog.setText(Messages.ImportTraceWizard_SelectTraceArchiveTitle);
+        String fileName = fArchiveNameField.getText().trim();
+        if (!fileName.isEmpty()) {
+            File path = new File(fileName).getParentFile();
+            if (path != null && path.exists()) {
+                dialog.setFilterPath(path.toString());
+            }
+        }
+
+        String selectedArchive = dialog.open();
+        if (selectedArchive != null) {
+            setErrorMessage(null);
+            setSourceName(selectedArchive);
+            updateWidgetEnablements();
+        }
+    }
+
     private File getSourceDirectory() {
         return getSourceDirectory(directoryNameField.getText());
     }
 
+    private File getSourceArchiveFile() {
+        return getSourceArchiveFile(fArchiveNameField.getText());
+    }
+
+    private String getSourceContainerPath() {
+        if (fImportFromDirectoryRadio.getSelection()) {
+            File sourceDirectory = getSourceDirectory();
+            if (sourceDirectory != null) {
+                return sourceDirectory.getAbsolutePath();
+            }
+        }
+        File sourceArchiveFile = getSourceArchiveFile();
+        if (sourceArchiveFile != null) {
+            return sourceArchiveFile.getParent();
+        }
+        return null;
+    }
+
     private static File getSourceDirectory(String path) {
         File sourceDirectory = new File(getSourceDirectoryName(path));
         if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) {
@@ -466,6 +621,15 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         return sourceDirectory;
     }
 
+    private static File getSourceArchiveFile(String path) {
+        File sourceArchiveFile = new File(path);
+        if (!sourceArchiveFile.exists() || sourceArchiveFile.isDirectory()) {
+            return null;
+        }
+
+        return sourceArchiveFile;
+    }
+
     private static String getSourceDirectoryName(String sourceName) {
         IPath result = new Path(sourceName.trim());
         if (result.getDevice() != null && result.segmentCount() == 0) {
@@ -477,13 +641,18 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
     }
 
     private void updateFromSourceField() {
-        setSourceName(directoryNameField.getText());
+        setSourceName(getSourceField().getText());
         updateWidgetEnablements();
     }
 
+    private Combo getSourceField() {
+        return directoryNameField.isEnabled() ? directoryNameField : fArchiveNameField;
+    }
+
     private void setSourceName(String path) {
+        Combo sourceField = getSourceField();
         if (path.length() > 0) {
-            String[] currentItems = directoryNameField.getItems();
+            String[] currentItems = sourceField.getItems();
             int selectionIndex = -1;
             for (int i = 0; i < currentItems.length; i++) {
                 if (currentItems[i].equals(path)) {
@@ -495,10 +664,10 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
                 String[] newItems = new String[oldLength + 1];
                 System.arraycopy(currentItems, 0, newItems, 0, oldLength);
                 newItems[oldLength] = path;
-                directoryNameField.setItems(newItems);
+                sourceField.setItems(newItems);
                 selectionIndex = oldLength;
             }
-            directoryNameField.select(selectionIndex);
+            sourceField.select(selectionIndex);
         }
         resetSelection();
     }
@@ -507,20 +676,212 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
     // File Selection Group (forked WizardFileSystemResourceImportPage1)
     // ------------------------------------------------------------------------
     private void resetSelection() {
-        TraceFileSystemElement root = getFileSystemTree();
-        fSelectionGroup.setRoot(root);
+        if (fSelectionGroupRoot != null) {
+            disposeSelectionGroupRoot();
+        }
+        fSelectionGroupRoot = getFileSystemTree();
+        fSelectionGroup.setRoot(fSelectionGroupRoot);
+    }
+
+    private void disposeSelectionGroupRoot() {
+        if (fSelectionGroupRoot != null && fSelectionGroupRoot.getProvider() != null) {
+            FileSystemObjectImportStructureProvider provider = fSelectionGroupRoot.getProvider();
+            provider.dispose();
+            fSelectionGroupRoot = null;
+        }
     }
 
     private TraceFileSystemElement getFileSystemTree() {
-        File sourceDirectory = getSourceDirectory();
-        if (sourceDirectory == null) {
+        IFileSystemObject rootElement = null;
+        FileSystemObjectImportStructureProvider importStructureProvider = null;
+
+        // Import from directory
+        if (fImportFromDirectoryRadio.getSelection()) {
+            importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
+            File sourceDirectory = getSourceDirectory();
+            if (sourceDirectory == null) {
+                return null;
+            }
+            rootElement = importStructureProvider.getIFileSystemObject(sourceDirectory);
+        } else {
+            // Import from archive
+            FileSystemObjectLeveledImportStructureProvider leveledImportStructureProvider = null;
+            String archivePath = getSourceArchiveFile() != null ? getSourceArchiveFile().getAbsolutePath() : ""; //$NON-NLS-1$
+            if (ArchiveFileManipulations.isTarFile(archivePath)) {
+                if (ensureTarSourceIsValid(archivePath)) {
+                    // We close the file when we dispose the import provider, see disposeSelectionGroupRoot
+                    TarFile tarFile = getSpecifiedTarSourceFile(archivePath);
+                    leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new TarLeveledStructureProvider(tarFile), archivePath);
+                }
+            } else if (ensureZipSourceIsValid(archivePath)) {
+                // We close the file when we dispose the import provider, see disposeSelectionGroupRoot
+                @SuppressWarnings("resource")
+                ZipFile zipFile = getSpecifiedZipSourceFile(archivePath);
+                leveledImportStructureProvider = new FileSystemObjectLeveledImportStructureProvider(new ZipLeveledStructureProvider(zipFile), archivePath);
+            }
+            if (leveledImportStructureProvider == null) {
+                return null;
+            }
+            rootElement = leveledImportStructureProvider.getRoot();
+            importStructureProvider = leveledImportStructureProvider;
+        }
+
+        if (rootElement == null) {
+            return null;
+        }
+
+        return selectFiles(rootElement, importStructureProvider);
+    }
+
+    /**
+     * An import provider that makes use of the IFileSystemObject abstraction
+     * instead of using plain file system objects (File, TarEntry, ZipEntry)
+     */
+    private static class FileSystemObjectImportStructureProvider implements IImportStructureProvider {
+
+        private IImportStructureProvider fImportProvider;
+        private String fArchivePath;
+        private FileSystemObjectImportStructureProvider(IImportStructureProvider importStructureProvider, String archivePath) {
+            fImportProvider = importStructureProvider;
+            fArchivePath = archivePath;
+        }
+
+        @Override
+        public List<IFileSystemObject> getChildren(Object element) {
+            @SuppressWarnings("rawtypes")
+            List children = fImportProvider.getChildren(((IFileSystemObject)element).getRawFileSystemObject());
+            List<IFileSystemObject> adapted = new ArrayList<>(children.size());
+            for (Object o : children) {
+                adapted.add(getIFileSystemObject(o));
+            }
+            return adapted;
+        }
+
+       public IFileSystemObject getIFileSystemObject(Object o) {
+            if (o instanceof File) {
+                return new FileFileSystemObject((File)o);
+            } else if (o instanceof TarEntry) {
+                return new TarFileSystemObject((TarEntry) o, fArchivePath);
+            } else if (o instanceof ZipEntry) {
+                return new ZipFileSystemObject((ZipEntry) o, fArchivePath);
+            }
+
+            throw new IllegalArgumentException("Object type not handled"); //$NON-NLS-1$
+        }
+
+        @Override
+        public InputStream getContents(Object element) {
+            return fImportProvider.getContents(((IFileSystemObject)element).getRawFileSystemObject());
+        }
+
+        @Override
+        public String getFullPath(Object element) {
+            return fImportProvider.getFullPath(((IFileSystemObject)element).getRawFileSystemObject());
+        }
+
+        @Override
+        public String getLabel(Object element) {
+            return fImportProvider.getLabel(((IFileSystemObject)element).getRawFileSystemObject());
+        }
+
+        @Override
+        public boolean isFolder(Object element) {
+            return fImportProvider.isFolder(((IFileSystemObject)element).getRawFileSystemObject());
+        }
+
+        /**
+         * Disposes of the resources associated with the provider.
+         */
+        public void dispose() {
+        }
+    }
+
+    /**
+     * An import provider that both supports using IFileSystemObject and adds
+     * "archive functionality" by delegating to a leveled import provider
+     * (TarLeveledStructureProvider, ZipLeveledStructureProvider)
+     */
+    private static class FileSystemObjectLeveledImportStructureProvider extends FileSystemObjectImportStructureProvider implements ILeveledImportStructureProvider {
+
+        private ILeveledImportStructureProvider fLeveledImportProvider;
+
+        private FileSystemObjectLeveledImportStructureProvider(ILeveledImportStructureProvider importStructureProvider, String archivePath) {
+            super(importStructureProvider, archivePath);
+            fLeveledImportProvider = importStructureProvider;
+        }
+
+        @Override
+        public IFileSystemObject getRoot() {
+            return getIFileSystemObject(fLeveledImportProvider.getRoot());
+        }
+
+        @Override
+        public void setStrip(int level) {
+            fLeveledImportProvider.setStrip(level);
+        }
+
+        @Override
+        public int getStrip() {
+            return fLeveledImportProvider.getStrip();
+        }
+
+        @Override
+        public boolean closeArchive() {
+            return fLeveledImportProvider.closeArchive();
+        }
+    }
+
+    @SuppressWarnings("resource")
+    private boolean ensureZipSourceIsValid(String archivePath) {
+        ZipFile specifiedFile = getSpecifiedZipSourceFile(archivePath);
+        if (specifiedFile == null) {
+            return false;
+        }
+        return ArchiveFileManipulations.closeZipFile(specifiedFile, getShell());
+    }
+
+    private boolean ensureTarSourceIsValid(String archivePath) {
+        TarFile specifiedFile = getSpecifiedTarSourceFile(archivePath);
+        if (specifiedFile == null) {
+            return false;
+        }
+        return ArchiveFileManipulations.closeTarFile(specifiedFile, getShell());
+    }
+
+    private static ZipFile getSpecifiedZipSourceFile(String fileName) {
+        if (fileName.length() == 0) {
+            return null;
+        }
+
+        try {
+            return new ZipFile(fileName);
+        } catch (ZipException e) {
+            // ignore
+        } catch (IOException e) {
+            // ignore
+        }
+
+        return null;
+    }
+
+    private static TarFile getSpecifiedTarSourceFile(String fileName) {
+        if (fileName.length() == 0) {
             return null;
         }
-        return selectFiles(sourceDirectory, FileSystemStructureProvider.INSTANCE);
+
+        try {
+            return new TarFile(fileName);
+        } catch (TarException e) {
+            // ignore
+        } catch (IOException e) {
+            // ignore
+        }
+
+        return null;
     }
 
-    private TraceFileSystemElement selectFiles(final Object rootFileSystemObject,
-            final IImportStructureProvider structureProvider) {
+    private TraceFileSystemElement selectFiles(final IFileSystemObject rootFileSystemObject,
+            final FileSystemObjectImportStructureProvider structureProvider) {
         final TraceFileSystemElement[] results = new TraceFileSystemElement[1];
         BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() {
             @Override
@@ -532,20 +893,24 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         return results[0];
     }
 
-    private static TraceFileSystemElement createRootElement(Object fileSystemObject,
-            IImportStructureProvider provider) {
-
-        boolean isContainer = provider.isFolder(fileSystemObject);
-        String elementLabel = provider.getLabel(fileSystemObject);
+    private static TraceFileSystemElement createRootElement(IFileSystemObject element,
+            FileSystemObjectImportStructureProvider provider) {
+        boolean isContainer = provider.isFolder(element);
+        String elementLabel = provider.getLabel(element);
 
         // Use an empty label so that display of the element's full name
         // doesn't include a confusing label
-        TraceFileSystemElement dummyParent = new TraceFileSystemElement("", null, true);//$NON-NLS-1$
-        dummyParent.setFileSystemObject(((File)fileSystemObject).getParentFile());
+        TraceFileSystemElement dummyParent = new TraceFileSystemElement("", null, true, provider);//$NON-NLS-1$
+        Object dummyParentFileSystemObject = element;
+        Object rawFileSystemObject = element.getRawFileSystemObject();
+        if (rawFileSystemObject instanceof File) {
+            dummyParentFileSystemObject = provider.getIFileSystemObject(((File) rawFileSystemObject).getParentFile());
+        }
+        dummyParent.setFileSystemObject(dummyParentFileSystemObject);
         dummyParent.setPopulated();
         TraceFileSystemElement result = new TraceFileSystemElement(
-                elementLabel, dummyParent, isContainer);
-        result.setFileSystemObject(fileSystemObject);
+                elementLabel, dummyParent, isContainer, provider);
+        result.setFileSystemObject(element);
 
         //Get the files for the element so as to build the first level
         result.getFiles();
@@ -640,18 +1005,27 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
     @Override
     public boolean validateSourceGroup() {
 
-        File sourceDirectory = getSourceDirectory();
-        if (sourceDirectory == null) {
+        File source = fImportFromDirectoryRadio.getSelection() ? getSourceDirectory() : getSourceArchiveFile();
+        if (source == null) {
             setMessage(Messages.ImportTraceWizard_SelectTraceSourceEmpty);
+            setErrorMessage(null);
             return false;
         }
 
-        if (sourceConflictsWithDestination(new Path(sourceDirectory.getPath()))) {
+        if (sourceConflictsWithDestination(new Path(source.getPath()))) {
             setMessage(null);
             setErrorMessage(getSourceConflictMessage());
             return false;
         }
 
+        if (!fImportFromDirectoryRadio.getSelection()) {
+            if (!ensureTarSourceIsValid(source.getAbsolutePath()) && !ensureZipSourceIsValid(source.getAbsolutePath())) {
+                setMessage(null);
+                setErrorMessage(Messages.ImportTraceWizard_BadArchiveFormat);
+                return false;
+            }
+        }
+
         if (fSelectionGroup.getCheckedElementCount() == 0) {
             setMessage(null);
             setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected);
@@ -696,11 +1070,20 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         }
         fPreserveFolderStructureButton.setSelection(value);
 
-        String[] directoryNames = settings.getArray(IMPORT_WIZARD_ROOT_DIRECTORY_ID);
-        if ((directoryNames != null) && (directoryNames.length != 0)) {
-            for (int i = 0; i < directoryNames.length; i++) {
-                directoryNameField.add(directoryNames[i]);
-            }
+        if (settings.get(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY) == null) {
+            value = true;
+        } else {
+            value = settings.getBoolean(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY);
+        }
+        restoreComboValues(directoryNameField, settings, IMPORT_WIZARD_ROOT_DIRECTORY_ID);
+        restoreComboValues(fArchiveNameField, settings, IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID);
+
+        fImportFromDirectoryRadio.setSelection(value);
+        fImportFromArchiveRadio.setSelection(!value);
+        if (value) {
+            directoryRadioSelected();
+        } else {
+            archiveRadioSelected();
         }
     }
 
@@ -710,18 +1093,33 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         IDialogSettings settings = getDialogSettings();
         settings.put(IMPORT_WIZARD_IMPORT_UNRECOGNIZED_ID, fImportUnrecognizedButton.getSelection());
         settings.put(IMPORT_WIZARD_PRESERVE_FOLDERS_ID, fPreserveFolderStructureButton.getSelection());
+        settings.put(IMPORT_WIZARD_IMPORT_FROM_DIRECTORY, fImportFromDirectoryRadio.getSelection());
+
+        saveComboValues(directoryNameField, settings, IMPORT_WIZARD_ROOT_DIRECTORY_ID);
+        saveComboValues(fArchiveNameField, settings, IMPORT_WIZARD_ARCHIVE_FILE_NAME_ID);
+    }
+
+    private static void restoreComboValues(Combo combo, IDialogSettings settings, String key) {
+        String[] directoryNames = settings.getArray(key);
+        if ((directoryNames != null) && (directoryNames.length != 0)) {
+            for (int i = 0; i < directoryNames.length; i++) {
+                combo.add(directoryNames[i]);
+            }
+        }
+    }
 
-        // update directory names history
-        String[] directoryNames = settings.getArray(IMPORT_WIZARD_ROOT_DIRECTORY_ID);
+    private void saveComboValues(Combo combo, IDialogSettings settings, String key) {
+        // update names history
+        String[] directoryNames = settings.getArray(key);
         if (directoryNames == null) {
             directoryNames = new String[0];
         }
 
-        String items[] = directoryNameField.getItems();
+        String items[] = combo.getItems();
         for (int i = 0; i < items.length; i++) {
             directoryNames = addToHistory(directoryNames, items[i]);
         }
-        settings.put(IMPORT_WIZARD_ROOT_DIRECTORY_ID, directoryNames);
+        settings.put(key, directoryNames);
     }
 
     // ------------------------------------------------------------------------
@@ -747,8 +1145,9 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         // Save dialog settings
         saveWidgetValues();
 
-        IPath baseSourceContainerPath = new Path(getSourceDirectory().getAbsolutePath());
-        final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(traceId, baseSourceContainerPath, getContainerFullPath(),
+        IPath baseSourceContainerPath = new Path(getSourceContainerPath());
+        boolean importFromArchive = getSourceArchiveFile() != null;
+        final TraceValidateAndImportOperation operation = new TraceValidateAndImportOperation(traceId, baseSourceContainerPath, getContainerFullPath(), importFromArchive,
                 fImportUnrecognizedButton.getSelection(), fOverwriteExistingResourcesCheckbox.getSelection(), fCreateLinksInWorkspaceButton.getSelection(), fPreserveFolderStructureButton.getSelection());
 
         IStatus status = Status.OK_STATUS;
@@ -785,6 +1184,11 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         return true;
     }
 
+    @Override
+    public void dispose() {
+        super.dispose();
+        disposeSelectionGroupRoot();
+    }
 
     // ------------------------------------------------------------------------
     // Classes
@@ -795,15 +1199,17 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         private String fTraceType;
         private IPath fDestinationContainerPath;
         private IPath fBaseSourceContainerPath;
+        private boolean fImportFromArchive;
         private boolean fImportUnrecognizedTraces;
         private boolean fLink;
         private boolean fPreserveFolderStructure;
         private ImportConfirmation fConfirmationMode = ImportConfirmation.SKIP;
 
-        private TraceValidateAndImportOperation(String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean doImport, boolean overwrite, boolean link, boolean preserveFolderStructure) {
+        private TraceValidateAndImportOperation(String traceId, IPath baseSourceContainerPath, IPath destinationContainerPath, boolean importFromArchive, boolean doImport, boolean overwrite, boolean link, boolean preserveFolderStructure) {
             fTraceType = traceId;
             fBaseSourceContainerPath = baseSourceContainerPath;
             fDestinationContainerPath = destinationContainerPath;
+            fImportFromArchive = importFromArchive;
             fImportUnrecognizedTraces = doImport;
             if (overwrite) {
                 fConfirmationMode = ImportConfirmation.OVERWRITE_ALL;
@@ -840,14 +1246,37 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
                 ModalContext.checkCanceled(subMonitor);
 
                 Iterator<TraceFileSystemElement> fileSystemElementsIter = fileSystemElements.iterator();
+                IFolder destTempFolder = null;
                 subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size());
+                if (fImportFromArchive) {
+                    // When importing from archive, we first extract the
+                    // *selected* files to a temporary folder then create a new
+                    // Iterator<TraceFileSystemElement> that points to the
+                    // extracted files. This way, the import operator can
+                    // continue as it normally would.
+
+                    subMonitor = SubMonitor.convert(progressMonitor, fileSystemElements.size() * 2);
+                    destTempFolder = fTargetFolder.getProject().getFolder(TRACE_IMPORT_TEMP_FOLDER);
+                    if (destTempFolder.exists()) {
+                        SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+                        destTempFolder.delete(true, monitor);
+                    }
+                    SubProgressMonitor monitor = new SubProgressMonitor(subMonitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK);
+                    destTempFolder.create(IResource.HIDDEN, true, monitor);
+
+                    fileSystemElementsIter = extractSelectedFiles(fileSystemElementsIter, destTempFolder, subMonitor);
+                    // We need to update the source container path because the
+                    // "preserve folder structure" option would create the
+                    // wrong folders otherwise.
+                    fBaseSourceContainerPath = destTempFolder.getLocation();
+                }
 
                 while (fileSystemElementsIter.hasNext()) {
                     ModalContext.checkCanceled(progressMonitor);
                     currentPath = null;
                     TraceFileSystemElement element = fileSystemElementsIter.next();
-                    File fileResource = (File) element.getFileSystemObject();
-                    String resourcePath = fileResource.getAbsolutePath();
+                    IFileSystemObject fileSystemObject = element.getFileSystemObject();
+                    String resourcePath = element.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
                     element.setDestinationContainerPath(computeDestinationContainerPath(new Path(resourcePath)));
 
                     currentPath = resourcePath;
@@ -861,8 +1290,7 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
                         }
                     } else {
                         TraceFileSystemElement parentElement = (TraceFileSystemElement)element.getParent();
-                        File parentFile = (File) parentElement.getFileSystemObject();
-                        String parentPath = parentFile.getAbsolutePath();
+                        String parentPath = parentElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
                         parentElement.setDestinationContainerPath(computeDestinationContainerPath(new Path(parentPath)));
                         currentPath = parentPath;
                         if (!folderElements.containsKey(parentPath)) {
@@ -870,13 +1298,18 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
                                 folderElements.put(parentPath, parentElement);
                                 validateAndImportTrace(parentElement, sub);
                             } else {
-                                if (fileResource.exists()) {
+                                if (fileSystemObject.exists()) {
                                     validateAndImportTrace(element, sub);
                                 }
                             }
                         }
                     }
                 }
+
+                if (destTempFolder != null && destTempFolder.exists()) {
+                    destTempFolder.delete(true, progressMonitor);
+                }
+
                 setStatus(Status.OK_STATUS);
             } catch (InterruptedException e) {
                 setStatus(Status.CANCEL_STATUS);
@@ -888,6 +1321,78 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
             }
         }
 
+        private Iterator<TraceFileSystemElement> extractSelectedFiles(Iterator<TraceFileSystemElement> fileSystemElementsIter, IFolder tempFolder, IProgressMonitor progressMonitor) throws InterruptedException,
+                InvocationTargetException {
+            List<TraceFileSystemElement> subList = new ArrayList<>();
+            // Collect all the elements
+            while (fileSystemElementsIter.hasNext()) {
+                ModalContext.checkCanceled(progressMonitor);
+                TraceFileSystemElement element = fileSystemElementsIter.next();
+                if (element.isDirectory()) {
+                    Object[] array = element.getFiles().getChildren();
+                    for (int i = 0; i < array.length; i++) {
+                        subList.add((TraceFileSystemElement)array[i]);
+                    }
+                }
+                subList.add(element);
+            }
+
+            // Find a sensible root element
+            TraceFileSystemElement root = subList.get(0);
+            while (root.getParent() != null) {
+                root = (TraceFileSystemElement) root.getParent();
+            }
+
+            ImportProvider fileSystemStructureProvider = new ImportProvider();
+
+            IOverwriteQuery myQueryImpl = new IOverwriteQuery() {
+                @Override
+                public String queryOverwrite(String file) {
+                    return IOverwriteQuery.NO_ALL;
+                }
+            };
+
+            progressMonitor.setTaskName(Messages.ImportTraceWizard_ExtractImportOperationTaskName);
+            IPath containerPath = tempFolder.getFullPath();
+            ImportOperation operation = new ImportOperation(containerPath, root, fileSystemStructureProvider, myQueryImpl, subList);
+            operation.setContext(getShell());
+
+            operation.setCreateContainerStructure(true);
+            operation.setOverwriteResources(false);
+            operation.setVirtualFolders(false);
+
+            operation.run(new SubProgressMonitor(progressMonitor, subList.size(), SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
+
+            // Create the new import provider and root element based on the extracted temp folder
+            FileSystemObjectImportStructureProvider importStructureProvider = new FileSystemObjectImportStructureProvider(FileSystemStructureProvider.INSTANCE, null);
+            IFileSystemObject rootElement = importStructureProvider.getIFileSystemObject(new File(tempFolder.getLocation().toOSString()));
+            TraceFileSystemElement createRootElement = createRootElement(rootElement, importStructureProvider);
+            List<TraceFileSystemElement> list = new ArrayList<>();
+            getAllChildren(list, createRootElement);
+            Iterator<TraceFileSystemElement> extractedElementsIter = list.iterator();
+            return extractedElementsIter;
+        }
+
+        /**
+         * Get all the TraceFileSystemElements recursively.
+         *
+         * @param result
+         *            the list accumulating the result
+         * @param rootElement
+         *            the root element of the file system to be imported
+         */
+        private void getAllChildren(List<TraceFileSystemElement> result, TraceFileSystemElement rootElement) {
+            AdaptableList files = rootElement.getFiles();
+            for (Object file : files.getChildren()) {
+                result.add((TraceFileSystemElement) file);
+            }
+
+            AdaptableList folders = rootElement.getFolders();
+            for (Object folder : folders.getChildren()) {
+                getAllChildren(result, (TraceFileSystemElement)folder);
+            }
+        }
+
         private IPath computeDestinationContainerPath(Path resourcePath) {
             IPath destinationContainerPath = fDestinationContainerPath;
 
@@ -910,8 +1415,8 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
 
         private void validateAndImportTrace(TraceFileSystemElement fileSystemElement, IProgressMonitor monitor)
                 throws TmfTraceImportException, CoreException, InvocationTargetException, InterruptedException {
-            File file = (File) fileSystemElement.getFileSystemObject();
-            String path = file.getAbsolutePath();
+            String parentContainerPath = fBaseSourceContainerPath.toOSString();
+            String path = fileSystemElement.getFileSystemObject().getAbsolutePath(parentContainerPath);
             TraceTypeHelper traceTypeHelper = null;
 
             if (fTraceType == null) {
@@ -1021,7 +1526,7 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
                 }
             };
 
-            monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + ((File)fileSystemElement.getFileSystemObject()).getAbsolutePath()); //$NON-NLS-1$
+            monitor.setTaskName(Messages.ImportTraceWizard_ImportOperationTaskName + " " + fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString())); //$NON-NLS-1$
             ImportOperation operation = new ImportOperation(containerPath, parentFolder, fileSystemStructureProvider, myQueryImpl, subList);
             operation.setContext(getShell());
 
@@ -1031,31 +1536,17 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
             operation.setVirtualFolders(false);
 
             operation.run(new SubProgressMonitor(monitor, 1, SubProgressMonitor.PREPEND_MAIN_LABEL_TO_SUBTASK));
-
-            File file = (File) fileSystemElement.getFileSystemObject();
-            String sourceLocation = null;
-            IResource sourceResource;
-            if (file.isDirectory()) {
-                sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(file.getAbsolutePath()));
-            } else {
-                sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(file.getAbsolutePath()));
-            }
-            if (sourceResource != null && sourceResource.exists()) {
-                sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION);
-            }
-            if (sourceLocation == null) {
-                sourceLocation = URIUtil.toUnencodedString(file.toURI());
-            }
-
+            String sourceLocation = fileSystemElement.getFileSystemObject().getSourceLocation();
             IResource resource = ResourcesPlugin.getWorkspace().getRoot().findMember(tracePath);
-            resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation);
+            if (sourceLocation != null) {
+                resource.setPersistentProperty(TmfCommonConstants.SOURCE_LOCATION, sourceLocation);
+            }
 
             return resource;
         }
 
-        private boolean isDirectoryTrace(FileSystemElement fileSystemElement) {
-            File file = (File) fileSystemElement.getFileSystemObject();
-            String path = file.getAbsolutePath();
+        private boolean isDirectoryTrace(TraceFileSystemElement fileSystemElement) {
+            String path = fileSystemElement.getFileSystemObject().getAbsolutePath(fBaseSourceContainerPath.toOSString());
             if (TmfTraceType.isDirectoryTrace(path)) {
                 return true;
             }
@@ -1117,7 +1608,7 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
          */
         private IPath getInitialDestinationPath(TraceFileSystemElement fileSystemElement) {
             IPath traceFolderPath = fileSystemElement.getDestinationContainerPath();
-            return traceFolderPath.append(((File)fileSystemElement.getFileSystemObject()).getName());
+            return traceFolderPath.append(fileSystemElement.getFileSystemObject().getLabel());
         }
 
         private void rename(TraceFileSystemElement fileSystemElement) {
@@ -1184,9 +1675,11 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         private boolean fIsPopulated = false;
         private String fLabel = null;
         private IPath fDestinationContainerPath;
+        private FileSystemObjectImportStructureProvider fProvider;
 
-        public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory) {
+        public TraceFileSystemElement(String name, FileSystemElement parent, boolean isDirectory, FileSystemObjectImportStructureProvider provider) {
             super(name, parent, isDirectory);
+            fProvider = provider;
         }
 
         public void setDestinationContainerPath(IPath destinationContainerPath) {
@@ -1233,13 +1726,7 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
          */
         public String getLabel() {
             if (fLabel == null) {
-                //Get the name - if it is empty then return the path as it is a file root
-                File file = (File) getFileSystemObject();
-                String name = file.getName();
-                if (name.length() == 0) {
-                    return file.getPath();
-                }
-                return name;
+                return getFileSystemObject().getLabel();
             }
             return fLabel;
         }
@@ -1257,23 +1744,185 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
          * Populates the children of the specified parent <code>FileSystemElement</code>
          */
         private void populateElementChildren() {
-            FileSystemStructureProvider provider = FileSystemStructureProvider.INSTANCE;
-            List<File> allchildren = provider.getChildren(this.getFileSystemObject());
-            File child = null;
+            List<IFileSystemObject> allchildren = fProvider.getChildren(this.getFileSystemObject());
+            Object child = null;
             TraceFileSystemElement newelement = null;
-            Iterator<File> iter = allchildren.iterator();
+            Iterator<IFileSystemObject> iter = allchildren.iterator();
             while(iter.hasNext()) {
                 child = iter.next();
-                newelement = new TraceFileSystemElement(provider.getLabel(child), this, provider.isFolder(child));
+                newelement = new TraceFileSystemElement(fProvider.getLabel(child), this, fProvider.isFolder(child), fProvider);
                 newelement.setFileSystemObject(child);
             }
             setPopulated();
         }
+
+        public FileSystemObjectImportStructureProvider getProvider() {
+            return fProvider;
+        }
+
+        @Override
+        public IFileSystemObject getFileSystemObject() {
+            Object fileSystemObject = super.getFileSystemObject();
+            return (IFileSystemObject) fileSystemObject;
+        }
     }
 
-    private class ImportProvider implements IImportStructureProvider {
+    /**
+     * This interface abstracts the differences between different kinds of
+     * FileSystemObjects such as File, TarEntry and ZipEntry. This allows
+     * clients (TraceFileSystemElement, TraceValidateAndImportOperation) to
+     * handle all the types transparently.
+     */
+    private interface IFileSystemObject {
+        String getLabel();
+        String getAbsolutePath(String parentContainerPath);
+        String getSourceLocation();
+        Object getRawFileSystemObject();
+        boolean exists();
+    }
+
+    /**
+     * The "File" implementation of an IFileSystemObject
+     */
+    private static class FileFileSystemObject implements IFileSystemObject {
+
+        private File fFileSystemObject;
+
+        private FileFileSystemObject(File fileSystemObject) {
+            fFileSystemObject = fileSystemObject;
+        }
+
+        @Override
+        public String getLabel() {
+            String name = fFileSystemObject.getName();
+            if (name.length() == 0) {
+                return fFileSystemObject.getPath();
+            }
+            return name;
+        }
+
+        @Override
+        public String getAbsolutePath(String parentContainerPath) {
+            return fFileSystemObject.getAbsolutePath();
+        }
+
+        @Override
+        public boolean exists() {
+            return fFileSystemObject.exists();
+        }
+
+        @Override
+        public String getSourceLocation() {
+            IResource sourceResource;
+            String sourceLocation = null;
+            if (fFileSystemObject.isDirectory()) {
+                sourceResource = ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath()));
+            } else {
+                sourceResource = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(Path.fromOSString(fFileSystemObject.getAbsolutePath()));
+            }
+            if (sourceResource != null && sourceResource.exists()) {
+                try {
+                    sourceLocation = sourceResource.getPersistentProperty(TmfCommonConstants.SOURCE_LOCATION);
+                } catch (CoreException e) {
+                    // Something went wrong with the already existing resource.
+                    // This is not a problem, we'll assign a new location below.
+                }
+            }
+            if (sourceLocation == null) {
+                sourceLocation = URIUtil.toUnencodedString(fFileSystemObject.toURI());
+            }
+            return sourceLocation;
+        }
+
+        @Override
+        public Object getRawFileSystemObject() {
+            return fFileSystemObject;
+        }
+    }
+
+    /**
+     * The "Tar" implementation of an IFileSystemObject
+     */
+    private static class TarFileSystemObject implements IFileSystemObject {
+
+        private TarEntry fFileSystemObject;
+        private String fArchivePath;
+
+        private TarFileSystemObject(TarEntry fileSystemObject, String archivePath) {
+            fFileSystemObject = fileSystemObject;
+            fArchivePath = archivePath;
+        }
 
-        private FileSystemStructureProvider provider = FileSystemStructureProvider.INSTANCE;
+        @Override
+        public String getLabel() {
+            return new Path(fFileSystemObject.getName()).lastSegment();
+        }
+
+        @Override
+        public String getAbsolutePath(String parentContainerPath) {
+            return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString();
+        }
+
+        @Override
+        public boolean exists() {
+            return true;
+        }
+
+        @Override
+        public String getSourceLocation() {
+            URI uri = new File(fArchivePath).toURI();
+            IPath entryPath = new Path(fFileSystemObject.getName());
+            return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath));
+        }
+
+        @Override
+        public Object getRawFileSystemObject() {
+            return fFileSystemObject;
+        }
+    }
+
+    /**
+     * The "Zip" implementation of an IFileSystemObject
+     */
+    private static class ZipFileSystemObject implements IFileSystemObject {
+
+        private ZipEntry fFileSystemObject;
+        private String fArchivePath;
+
+        private ZipFileSystemObject(ZipEntry fileSystemObject, String archivePath) {
+            fFileSystemObject = fileSystemObject;
+            fArchivePath = archivePath;
+        }
+
+        @Override
+        public String getLabel() {
+            return new Path(fFileSystemObject.getName()).lastSegment();
+        }
+
+        @Override
+        public String getAbsolutePath(String parentContainerPath) {
+            return new Path(parentContainerPath).append(fFileSystemObject.getName()).toOSString();
+        }
+
+        @Override
+        public boolean exists() {
+            return true;
+        }
+
+        @Override
+        public String getSourceLocation() {
+            URI uri = new File(fArchivePath).toURI();
+            IPath entryPath = new Path(fFileSystemObject.getName());
+            return URIUtil.toUnencodedString(URIUtil.toJarURI(uri, entryPath));
+        }
+
+        @Override
+        public Object getRawFileSystemObject() {
+            return fFileSystemObject;
+        }
+    }
+
+    private class ImportProvider implements IImportStructureProvider {
 
         ImportProvider() {
         }
@@ -1298,13 +1947,13 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
         @Override
         public InputStream getContents(Object element) {
             TraceFileSystemElement resource = (TraceFileSystemElement)element;
-            return provider.getContents(resource.getFileSystemObject());
+            return resource.getProvider().getContents(resource.getFileSystemObject());
         }
 
         @Override
         public String getFullPath(Object element) {
             TraceFileSystemElement resource = (TraceFileSystemElement)element;
-            return provider.getFullPath(resource.getFileSystemObject());
+            return resource.getProvider().getFullPath(resource.getFileSystemObject());
         }
 
         @Override
index c047b8e75016dfba02511d4ad58ab0e36ec2be2f..c66cc968fde32018a46fa4cbeca35d47daa41a80 100644 (file)
@@ -40,10 +40,18 @@ public class Messages extends NLS {
      * The label of the directory location (import trace wizard)
     */
     public static String ImportTraceWizard_DirectoryLocation;
+    /**
+     * The label of the archive location (import trace wizard)
+    */
+    public static String ImportTraceWizard_ArchiveLocation;
     /**
      * The title of the select trace directory dialog (import trace wizard)
      */
     public static String ImportTraceWizard_SelectTraceDirectoryTitle;
+    /**
+     * The title of the select trace archive dialog (import trace wizard)
+     */
+    public static String ImportTraceWizard_SelectTraceArchiveTitle;
     /**
      * The message of the select trace directory dialog (import trace wizard)
      */
@@ -104,6 +112,10 @@ public class Messages extends NLS {
      * The error message when trace source is empty (import trace wizard).
      */
     public static String ImportTraceWizard_SelectTraceSourceEmpty;
+    /**
+     * The error message when the specified archive file is not valid.
+     */
+    public static String ImportTraceWizard_BadArchiveFormat;
     /**
      * The error message when no trace is selected (import trace wizard).
      */
@@ -144,6 +156,10 @@ public class Messages extends NLS {
      * The import operation task name.
      */
     public static String ImportTraceWizard_ImportOperationTaskName;
+    /**
+     * The extract import operation task name
+     */
+    public static String ImportTraceWizard_ExtractImportOperationTaskName;
     /**
      * The label to indicate that trace type auto detection shall be used.
      */
index 84adfcdfaaf43a39f2f3fb24ad95e3a9231b927b..f3fdaf8e0c85d2739153136e0483bb3221eaacb3 100644 (file)
 ImportTraceWizard_DialogTitle=Trace Import
 ImportTraceWizard_FileSystemTitle=File system
 ImportTraceWizard_ImportTrace=Import a trace from the local file system
-ImportTraceWizard_DirectoryLocation=Source directory:
+ImportTraceWizard_DirectoryLocation=Select roo&t directory:
+ImportTraceWizard_ArchiveLocation=Select &archive file:
 ImportTraceWizard_BrowseButton=B&rowse...
 ImportTraceWizard_TraceType=Trace Type:
 ImportTraceWizard_SelectTraceDirectoryTitle=Select trace directory
+ImportTraceWizard_SelectTraceArchiveTitle=Select trace archive file
 ImportTraceWizard_SelectTraceDirectoryMessage=Select directory to import trace from
 ImportTraceWizard_OverwriteExistingTrace=Overwrite existing trace without warning
 ImportTraceWizard_CreateLinksInWorkspace=Create lin&ks in workspace
@@ -32,6 +34,7 @@ ImportTraceWizard_ImportConfigurationSkip=Skip
 ImportTraceWizard_ImportConfigurationSkipAll=Skip All
 ImportTraceWizard_InvalidTraceDirectory=Invalid trace directory
 ImportTraceWizard_SelectTraceSourceEmpty=Source must not be empty
+ImportTraceWizard_BadArchiveFormat=Source file is not a valid tar or zip file.
 ImportTraceWizard_SelectTraceNoneSelected=No trace selected
 ImportTraceWizard_ImportProblem=Import problem
 ImportTraceWizard_CannotImportFilesUnderAVirtualFolder=Can not import trace under a virtual folder
@@ -41,6 +44,7 @@ ImportTraceWizard_ImportUnrecognized=Import unrecognized traces
 ImportTraceWizard_ImportOperationCancelled=Import operation cancelled
 ImportTraceWizard_TraceTypeNotFound=No trace type helper found
 ImportTraceWizard_ImportOperationTaskName=Importing
+ImportTraceWizard_ExtractImportOperationTaskName=Extracting files
 ImportTraceWizard_AutoDetection=<Automatic Detection>
 
 # BatchImportTraceWizard
This page took 0.078284 seconds and 5 git commands to generate.