/******************************************************************************* * Copyright (c) 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Zend Technologies *******************************************************************************/ package org.eclipse.php.internal.ui.phar.wizard; import java.io.File; import java.io.IOException; import java.util.List; import java.util.zip.ZipException; import java.util.zip.ZipFile; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.php.internal.core.phar.PharException; import org.eclipse.php.internal.core.phar.PharFile; import org.eclipse.php.internal.core.tar.TarException; import org.eclipse.php.internal.core.tar.TarFile; import org.eclipse.php.internal.ui.IPHPHelpContextIds; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider; import org.eclipse.ui.internal.wizards.datatransfer.MinimizedFileSystemElement; import org.eclipse.ui.internal.wizards.datatransfer.WizardFileSystemResourceImportPage1; import org.eclipse.ui.internal.wizards.datatransfer.ZipLeveledStructureProvider; import org.eclipse.ui.model.AdaptableList; import org.eclipse.ui.model.WorkbenchContentProvider; import org.eclipse.ui.wizards.datatransfer.ImportOperation; public class WizardPharFileResourceImportPage1 extends WizardFileSystemResourceImportPage1 implements Listener { ILeveledImportStructureProvider structureProvider; // constants private static final String[] FILE_IMPORT_MASK = { "*.phar;*.zip;*.tar;*.tar.gz;*.tgz;*.tar.bz2", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$ // dialog store id constants private final static String STORE_SOURCE_NAMES_ID = "WizardZipFileResourceImportPage1.STORE_SOURCE_NAMES_ID"; //$NON-NLS-1$ private final static String STORE_OVERWRITE_EXISTING_RESOURCES_ID = "WizardZipFileResourceImportPage1.STORE_OVERWRITE_EXISTING_RESOURCES_ID"; //$NON-NLS-1$ private final static String STORE_SELECTED_TYPES_ID = "WizardZipFileResourceImportPage1.STORE_SELECTED_TYPES_ID"; //$NON-NLS-1$ private final String[] fileImportMask; /** * Creates an instance of this class * * @param aWorkbench * IWorkbench * @param selection * IStructuredSelection */ public WizardPharFileResourceImportPage1(IWorkbench aWorkbench, IStructuredSelection selection) { this(aWorkbench, selection, null); } /** * Creates an instance of this class * * @param aWorkbench * IWorkbench * @param selection * IStructuredSelection * @param fileImportMask * != null: override default mask */ public WizardPharFileResourceImportPage1(IWorkbench aWorkbench, IStructuredSelection selection, String[] fileImportMask) { super("zipFileImportPage1", aWorkbench, selection); //$NON-NLS-1$ setTitle(PharImportMessages.ArchiveExport_exportTitle); setDescription(PharImportMessages.ArchiveImport_description); if (fileImportMask == null) this.fileImportMask = FILE_IMPORT_MASK; else this.fileImportMask = fileImportMask; } /** * Called when the user presses the Cancel button. Return a boolean * indicating permission to close the wizard. * * @return boolean */ public boolean cancel() { disposeStructureProvider(); return true; } /** * (non-Javadoc) Method declared on IDialogPage. */ @Override public void createControl(Composite parent) { super.createControl(parent); PlatformUI.getWorkbench().getHelpSystem().setHelp(getControl(), IPHPHelpContextIds.PHAR_FILE_IMPORT_WIZARD_PAGE); } /** * Create the options specification widgets. There is only one in this case * so create no group. * * @param parent * org.eclipse.swt.widgets.Composite */ @Override protected void createOptionsGroup(Composite parent) { // overwrite... checkbox overwriteExistingResourcesCheckbox = new Button(parent, SWT.CHECK); overwriteExistingResourcesCheckbox.setText(PharImportMessages.FileImport_overwriteExisting); overwriteExistingResourcesCheckbox.setFont(parent.getFont()); } private boolean validateSourceFile(String fileName) { if (ArchiveFileManipulations.isPharFile(fileName)) { PharFile pharFile = getSpecifiedPharSourceFile(fileName); if (pharFile != null) { ArchiveFileManipulations.closePharFile(pharFile, getShell()); return true; } return false; } if (ArchiveFileManipulations.isTarFile(fileName)) { TarFile tarFile = getSpecifiedTarSourceFile(fileName); if (tarFile != null) { ArchiveFileManipulations.closeTarFile(tarFile, getShell()); return true; } return false; } ZipFile zipFile = getSpecifiedZipSourceFile(fileName); if (zipFile != null) { ArchiveFileManipulations.closeZipFile(zipFile, getShell()); return true; } return false; } private PharFile getSpecifiedPharSourceFile(String fileName) { if (fileName.length() == 0) { return null; } try { return new PharFile(new File(fileName)); } catch (PharException e) { displayErrorDialog(e.getLocalizedMessage()); } catch (IOException e) { displayErrorDialog(PharImportMessages.ZipImport_couldNotRead); } sourceNameField.setFocus(); return null; } /** * Answer a boolean indicating whether the specified source currently exists * and is valid (ie.- proper format) */ private boolean ensureZipSourceIsValid() { ZipFile specifiedFile = getSpecifiedZipSourceFile(); if (specifiedFile == null) { return false; } return ArchiveFileManipulations.closeZipFile(specifiedFile, getShell()); } private boolean ensureTarSourceIsValid() { TarFile specifiedFile = getSpecifiedTarSourceFile(); if (specifiedFile == null) { return false; } return ArchiveFileManipulations.closeTarFile(specifiedFile, getShell()); } private boolean ensurePharSourceIsValid() { PharFile specifiedFile = getSpecifiedPharSourceFile(); if (specifiedFile == null) { return false; } return ArchiveFileManipulations.closePharFile(specifiedFile, getShell()); } /** * Answer a boolean indicating whether the specified source currently exists * and is valid (ie.- proper format) */ @Override protected boolean ensureSourceIsValid() { if (ArchiveFileManipulations.isPharFile(sourceNameField.getText())) { return ensurePharSourceIsValid(); } if (ArchiveFileManipulations.isTarFile(sourceNameField.getText())) { return ensureTarSourceIsValid(); } return ensureZipSourceIsValid(); } /** * The Finish button was pressed. Try to do the required work now and answer * a boolean indicating success. If <code>false</code> is returned then the * wizard will not close. * * @return boolean */ @Override public boolean finish() { if (!super.finish()) { return false; } disposeStructureProvider(); return true; } /** * Closes the structure provider and sets the field to <code>null</code>. * * @since 3.4 */ private void disposeStructureProvider() { ArchiveFileManipulations.closeStructureProvider(structureProvider, getShell()); structureProvider = null; } /** * Returns a content provider for <code>FileSystemElement</code>s that * returns only files as children. */ @Override protected ITreeContentProvider getFileProvider() { return new WorkbenchContentProvider() { @Override public Object[] getChildren(Object o) { if (o instanceof MinimizedFileSystemElement) { MinimizedFileSystemElement element = (MinimizedFileSystemElement) o; AdaptableList l = element.getFiles(structureProvider); return l.getChildren(element); } return new Object[0]; } }; } /** * Answer the root FileSystemElement that represents the contents of the * currently-specified .zip file. If this FileSystemElement is not currently * defined then create and return it. */ @Override protected MinimizedFileSystemElement getFileSystemTree() { disposeStructureProvider(); // TODO FOR PHAR if (ArchiveFileManipulations.isPharFile(sourceNameField.getText())) { PharFile sourceTarFile = getSpecifiedPharSourceFile(); if (sourceTarFile == null) { return null; } structureProvider = new PharLeveledStructureProvider(sourceTarFile); return selectFiles(structureProvider.getRoot(), structureProvider); } if (ArchiveFileManipulations.isTarFile(sourceNameField.getText())) { TarFile sourceTarFile = getSpecifiedTarSourceFile(); if (sourceTarFile == null) { return null; } structureProvider = new TarLeveledStructureProvider(sourceTarFile); return selectFiles(structureProvider.getRoot(), structureProvider); } ZipFile sourceFile = getSpecifiedZipSourceFile(); if (sourceFile == null) { return null; } structureProvider = new ZipLeveledStructureProvider(sourceFile); return selectFiles(structureProvider.getRoot(), structureProvider); } /** * Returns a content provider for <code>FileSystemElement</code>s that * returns only folders as children. */ @Override protected ITreeContentProvider getFolderProvider() { return new WorkbenchContentProvider() { @Override public Object[] getChildren(Object o) { if (o instanceof MinimizedFileSystemElement) { MinimizedFileSystemElement element = (MinimizedFileSystemElement) o; AdaptableList l = element.getFolders(structureProvider); return l.getChildren(element); } return new Object[0]; } @Override public boolean hasChildren(Object o) { if (o instanceof MinimizedFileSystemElement) { // MinimizedFileSystemElement element = // (MinimizedFileSystemElement) o; // if (element.isPopulated()) { // return getChildren(element).length > 0; // } // If we have not populated then wait until asked return true; } return false; } }; } /** * Answer the string to display as the label for the source specification * field */ @Override protected String getSourceLabel() { return PharImportMessages.ArchiveImport_fromFile; } /** * Answer a handle to the zip file currently specified as being the source. * Return null if this file does not exist or is not of valid format. */ protected ZipFile getSpecifiedZipSourceFile() { return getSpecifiedZipSourceFile(sourceNameField.getText()); } /** * Answer a handle to the zip file currently specified as being the source. * Return null if this file does not exist or is not of valid format. */ private ZipFile getSpecifiedZipSourceFile(String fileName) { if (fileName.length() == 0) { return null; } try { return new ZipFile(fileName); } catch (ZipException e) { displayErrorDialog(PharImportMessages.ZipImport_badFormat); } catch (IOException e) { displayErrorDialog(PharImportMessages.ZipImport_couldNotRead); } sourceNameField.setFocus(); return null; } /** * Answer a handle to the zip file currently specified as being the source. * Return null if this file does not exist or is not of valid format. */ protected TarFile getSpecifiedTarSourceFile() { return getSpecifiedTarSourceFile(sourceNameField.getText()); } protected PharFile getSpecifiedPharSourceFile() { return getSpecifiedPharSourceFile(sourceNameField.getText()); } /** * Answer a handle to the zip file currently specified as being the source. * Return null if this file does not exist or is not of valid format. */ private TarFile getSpecifiedTarSourceFile(String fileName) { if (fileName.length() == 0) { return null; } try { return new TarFile(fileName); } catch (TarException e) { displayErrorDialog(PharImportMessages.TarImport_badFormat); } catch (IOException e) { displayErrorDialog(PharImportMessages.ZipImport_couldNotRead); } sourceNameField.setFocus(); return null; } /** * Open a FileDialog so that the user can specify the source file to import * from */ @Override protected void handleSourceBrowseButtonPressed() { String selectedFile = queryZipFileToImport(); if (selectedFile != null) { // Be sure it is valid before we go setting any names if (!selectedFile.equals(sourceNameField.getText()) && validateSourceFile(selectedFile)) { setSourceName(selectedFile); selectionGroup.setFocus(); } } } /** * Import the resources with extensions as specified by the user */ @Override protected boolean importResources(List fileSystemObjects) { // TODO FOR PHAR ILeveledImportStructureProvider importStructureProvider = null; if (ArchiveFileManipulations.isPharFile(sourceNameField.getText())) { if (ensurePharSourceIsValid()) { PharFile pharFile = getSpecifiedPharSourceFile(); importStructureProvider = new PharLeveledStructureProvider(pharFile); } } else if (ArchiveFileManipulations.isTarFile(sourceNameField.getText())) { if (ensureTarSourceIsValid()) { TarFile tarFile = getSpecifiedTarSourceFile(); importStructureProvider = new TarLeveledStructureProvider(tarFile); } } else if (ensureZipSourceIsValid()) { ZipFile zipFile = getSpecifiedZipSourceFile(); importStructureProvider = new ZipLeveledStructureProvider(zipFile); } if (importStructureProvider == null) { return false; } ImportOperation operation = new ImportOperation(getContainerFullPath(), importStructureProvider.getRoot(), importStructureProvider, this, fileSystemObjects); operation.setContext(getShell()); if (!executeImportOperation(operation)) return false; ArchiveFileManipulations.closeStructureProvider(importStructureProvider, getShell()); return true; } /** * Initializes the specified operation appropriately. */ @Override protected void initializeOperation(ImportOperation op) { op.setOverwriteResources(overwriteExistingResourcesCheckbox.getSelection()); } /** * Opens a file selection dialog and returns a string representing the * selected file, or <code>null</code> if the dialog was canceled. */ protected String queryZipFileToImport() { FileDialog dialog = new FileDialog(sourceNameField.getShell(), SWT.OPEN | SWT.SHEET); dialog.setFilterExtensions(this.fileImportMask); dialog.setText(PharImportMessages.ArchiveImportSource_title); String currentSourceString = sourceNameField.getText(); int lastSeparatorIndex = currentSourceString.lastIndexOf(File.separator); if (lastSeparatorIndex != -1) { dialog.setFilterPath(currentSourceString.substring(0, lastSeparatorIndex)); } return dialog.open(); } /** * Repopulate the view based on the currently entered directory. */ @Override protected void resetSelection() { super.resetSelection(); setAllSelections(true); } /** * Use the dialog store to restore widget values to the values that they * held last time this wizard was used to completion */ @Override protected void restoreWidgetValues() { IDialogSettings settings = getDialogSettings(); if (settings != null) { String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID); if (sourceNames == null) { return; // ie.- no settings stored } // set filenames history for (int i = 0; i < sourceNames.length; i++) { sourceNameField.add(sourceNames[i]); } // radio buttons and checkboxes overwriteExistingResourcesCheckbox.setSelection(settings.getBoolean(STORE_OVERWRITE_EXISTING_RESOURCES_ID)); } } /** * Since Finish was pressed, write widget values to the dialog store so that * they will persist into the next invocation of this wizard page. * * Note that this method is identical to the one that appears in the * superclass. This is necessary because proper overriding of instance * variables is not occurring. */ @Override protected void saveWidgetValues() { IDialogSettings settings = getDialogSettings(); if (settings != null) { // update source names history String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID); if (sourceNames == null) { sourceNames = new String[0]; } sourceNames = addToHistory(sourceNames, sourceNameField.getText()); settings.put(STORE_SOURCE_NAMES_ID, sourceNames); // update specific types to import history String[] selectedTypesNames = settings.getArray(STORE_SELECTED_TYPES_ID); if (selectedTypesNames == null) { selectedTypesNames = new String[0]; } settings.put(STORE_OVERWRITE_EXISTING_RESOURCES_ID, overwriteExistingResourcesCheckbox.getSelection()); } } /** * Answer a boolean indicating whether self's source specification widgets * currently all contain valid values. */ @Override protected boolean validateSourceGroup() { // If there is nothing being provided to the input then there is a // problem if (structureProvider == null) { setMessage(SOURCE_EMPTY_MESSAGE); enableButtonGroup(false); return false; } List resourcesToExport = selectionGroup.getAllWhiteCheckedItems(); if (resourcesToExport.size() == 0) { setErrorMessage(PharImportMessages.FileImport_noneSelected); return false; } enableButtonGroup(true); setErrorMessage(null); return true; } }