| /******************************************************************************* |
| * Copyright (c) 2009, 2014 Xored Software Inc 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: |
| * Xored Software Inc - initial API and implementation and/or initial documentation |
| *******************************************************************************/ |
| package org.eclipse.rcptt.resources.ui.wizards; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Hashtable; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.viewers.CheckStateChangedEvent; |
| import org.eclipse.jface.viewers.ICheckStateListener; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.wizard.WizardPage; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.rcptt.core.persistence.IPersistenceModel; |
| import org.eclipse.rcptt.core.persistence.PersistenceManager; |
| import org.eclipse.rcptt.resources.ImportUtils; |
| import org.eclipse.rcptt.resources.WSUtils; |
| import org.eclipse.rcptt.ui.utils.MinimizedFileSystemElement; |
| import org.eclipse.rcptt.util.FileUtil; |
| import org.eclipse.rcptt.workspace.WSContainer; |
| import org.eclipse.rcptt.workspace.WSFile; |
| import org.eclipse.rcptt.workspace.WSFolder; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.custom.BusyIndicator; |
| 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.SelectionAdapter; |
| import org.eclipse.swt.events.SelectionEvent; |
| import org.eclipse.swt.events.SelectionListener; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Button; |
| 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.Group; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Listener; |
| import org.eclipse.swt.widgets.Shell; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.swt.widgets.Widget; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.dialogs.FileSystemElement; |
| import org.eclipse.ui.dialogs.IOverwriteQuery; |
| import org.eclipse.ui.dialogs.TypeFilteringDialog; |
| import org.eclipse.ui.ide.dialogs.ResourceTreeAndListGroup; |
| import org.eclipse.ui.model.WorkbenchContentProvider; |
| import org.eclipse.ui.model.WorkbenchLabelProvider; |
| import org.eclipse.ui.model.WorkbenchViewerComparator; |
| import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; |
| |
| @SuppressWarnings({ "rawtypes", "restriction" }) |
| public class WizardFileSystemResourceImportPage1 extends WizardPage implements |
| Listener, IOverwriteQuery { |
| // widgets |
| protected Combo sourceNameField; |
| |
| protected Button overwriteExistingResourcesCheckbox; |
| |
| protected Button createContainerStructureButton; |
| |
| protected Button createOnlySelectedButton; |
| |
| protected Button sourceBrowseButton; |
| |
| protected Button selectTypesButton; |
| |
| protected Button selectAllButton; |
| |
| protected Button deselectAllButton; |
| |
| // widgets |
| private Text containerNameField; |
| |
| protected java.util.List selectedTypes = new ArrayList(); |
| |
| /** |
| * The <code>selectionGroup</code> field should have been created with a |
| * private modifier. Subclasses should not access this field directly. |
| */ |
| |
| protected ResourceTreeAndListGroup selectionGroup; |
| |
| // A boolean to indicate if the user has typed anything |
| private boolean entryChanged = false; |
| |
| private org.eclipse.ui.internal.ide.filesystem.FileSystemStructureProvider fileSystemStructureProvider = new org.eclipse.ui.internal.ide.filesystem.FileSystemStructureProvider(); |
| |
| protected static final int COMBO_HISTORY_LENGTH = 5; |
| |
| // dialog store id constants |
| private final static String STORE_SOURCE_NAMES_ID = "WizardFileSystemResourceImportPage1.STORE_SOURCE_NAMES_ID";//$NON-NLS-1$ |
| |
| private final static String STORE_OVERWRITE_EXISTING_RESOURCES_ID = "WizardFileSystemResourceImportPage1.STORE_OVERWRITE_EXISTING_RESOURCES_ID";//$NON-NLS-1$ |
| |
| private final static String STORE_CREATE_CONTAINER_STRUCTURE_ID = "WizardFileSystemResourceImportPage1.STORE_CREATE_CONTAINER_STRUCTURE_ID";//$NON-NLS-1$ |
| |
| private static final String SELECT_TYPES_TITLE = org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.DataTransfer_selectTypes; |
| |
| private static final String SELECT_ALL_TITLE = org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.DataTransfer_selectAll; |
| |
| private static final String DESELECT_ALL_TITLE = org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.DataTransfer_deselectAll; |
| |
| private static final String SELECT_SOURCE_TITLE = org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.FileImport_selectSourceTitle; |
| |
| private static final String SELECT_SOURCE_MESSAGE = org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.FileImport_selectSource; |
| |
| protected static final String SOURCE_EMPTY_MESSAGE = org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.FileImport_sourceEmpty; |
| |
| // constants |
| protected static final int SIZING_TEXT_FIELD_WIDTH = 250; |
| |
| private WSContainer container; |
| |
| /** |
| * Creates an instance of this class |
| * |
| * @param aWorkbench |
| * IWorkbench |
| * @param selection |
| * IStructuredSelection |
| */ |
| public WizardFileSystemResourceImportPage1(WSContainer container) { |
| super("fileSystemImportPage1"); |
| setTitle("File system"); |
| setDescription("Import resources from the local file system."); |
| this.container = container; |
| } |
| |
| /** |
| * Creates a new button with the given id. |
| * <p> |
| * The <code>Dialog</code> implementation of this framework method creates a |
| * standard push button, registers for selection events including button |
| * presses and registers default buttons with its shell. The button id is |
| * stored as the buttons client data. Note that the parent's layout is |
| * assumed to be a GridLayout and the number of columns in this layout is |
| * incremented. Subclasses may override. |
| * </p> |
| * |
| * @param parent |
| * the parent composite |
| * @param id |
| * the id of the button (see <code>IDialogConstants.*_ID</code> |
| * constants for standard dialog button ids) |
| * @param label |
| * the label from the button |
| * @param defaultButton |
| * <code>true</code> if the button is to be the default button, |
| * and <code>false</code> otherwise |
| */ |
| protected Button createButton(Composite parent, int id, String label, |
| boolean defaultButton) { |
| // increment the number of columns in the button bar |
| ((GridLayout) parent.getLayout()).numColumns++; |
| |
| Button button = new Button(parent, SWT.PUSH); |
| button.setFont(parent.getFont()); |
| |
| GridData buttonData = new GridData(GridData.FILL_HORIZONTAL); |
| button.setLayoutData(buttonData); |
| |
| button.setData(new Integer(id)); |
| button.setText(label); |
| |
| if (defaultButton) { |
| Shell shell = parent.getShell(); |
| if (shell != null) { |
| shell.setDefaultButton(button); |
| } |
| button.setFocus(); |
| } |
| return button; |
| } |
| |
| /** |
| * Creates the buttons for selecting specific types or selecting all or none |
| * of the elements. |
| * |
| * @param parent |
| * the parent control |
| */ |
| protected final void createButtonsGroup(Composite parent) { |
| // top level group |
| Composite buttonComposite = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 3; |
| layout.makeColumnsEqualWidth = true; |
| buttonComposite.setLayout(layout); |
| buttonComposite.setFont(parent.getFont()); |
| GridData buttonData = new GridData(GridData.VERTICAL_ALIGN_FILL |
| | GridData.HORIZONTAL_ALIGN_FILL); |
| buttonData.horizontalSpan = 2; |
| buttonComposite.setLayoutData(buttonData); |
| |
| // types edit button |
| selectTypesButton = createButton(buttonComposite, |
| IDialogConstants.SELECT_TYPES_ID, SELECT_TYPES_TITLE, false); |
| |
| SelectionListener listener = new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| handleTypesEditButtonPressed(); |
| } |
| }; |
| selectTypesButton.addSelectionListener(listener); |
| setButtonLayoutData(selectTypesButton); |
| |
| selectAllButton = createButton(buttonComposite, |
| IDialogConstants.SELECT_ALL_ID, SELECT_ALL_TITLE, false); |
| |
| listener = new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| setAllSelections(true); |
| updateWidgetEnablements(); |
| } |
| }; |
| selectAllButton.addSelectionListener(listener); |
| setButtonLayoutData(selectAllButton); |
| |
| deselectAllButton = createButton(buttonComposite, |
| IDialogConstants.DESELECT_ALL_ID, DESELECT_ALL_TITLE, false); |
| |
| listener = new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| setAllSelections(false); |
| updateWidgetEnablements(); |
| } |
| }; |
| deselectAllButton.addSelectionListener(listener); |
| setButtonLayoutData(deselectAllButton); |
| |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on IDialogPage. |
| */ |
| public void createControl(Composite parent) { |
| |
| initializeDialogUnits(parent); |
| |
| Composite composite = new Composite(parent, SWT.NULL); |
| composite.setLayout(new GridLayout()); |
| composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL |
| | GridData.HORIZONTAL_ALIGN_FILL)); |
| composite.setSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT)); |
| composite.setFont(parent.getFont()); |
| |
| createSourceGroup(composite); |
| |
| createDestinationGroup(composite); |
| |
| createOptionsGroup(composite); |
| |
| restoreWidgetValues(); |
| updateWidgetEnablements(); |
| setPageComplete(determinePageCompletion()); |
| setErrorMessage(null); // should not initially have error message |
| |
| setControl(composite); |
| validateSourceGroup(); |
| PlatformUI |
| .getWorkbench() |
| .getHelpSystem() |
| .setHelp( |
| getControl(), |
| org.eclipse.ui.internal.wizards.datatransfer.IDataTransferHelpContextIds.FILE_SYSTEM_IMPORT_WIZARD_PAGE); |
| } |
| |
| /** |
| * Create the options specification widgets. |
| * |
| * @param parent |
| * org.eclipse.swt.widgets.Composite |
| */ |
| protected void createOptionsGroup(Composite parent) { |
| // options group |
| Group optionsGroup = new Group(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| optionsGroup.setLayout(layout); |
| optionsGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL |
| | GridData.GRAB_HORIZONTAL)); |
| optionsGroup.setText(org.eclipse.ui.internal.ide.IDEWorkbenchMessages.WizardExportPage_options); |
| optionsGroup.setFont(parent.getFont()); |
| |
| createOptionsGroupButtons(optionsGroup); |
| |
| } |
| |
| /* |
| * @see WizardDataTransferPage.determinePageCompletion. |
| */ |
| protected boolean determinePageCompletion() { |
| // Check for valid projects before making the user do anything |
| boolean complete = validateSourceGroup(); |
| |
| // Avoid draw flicker by not clearing the error |
| // message unless all is valid. |
| if (complete) { |
| setErrorMessage(null); |
| } |
| |
| return complete; |
| } |
| |
| /** |
| * Creates the import destination specification controls. |
| * |
| * @param parent |
| * the parent control |
| */ |
| protected final void createDestinationGroup(Composite parent) { |
| // container specification group |
| Composite containerGroup = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 3; |
| containerGroup.setLayout(layout); |
| containerGroup.setLayoutData(new GridData( |
| GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); |
| containerGroup.setFont(parent.getFont()); |
| |
| // container label |
| Label resourcesLabel = new Label(containerGroup, SWT.NONE); |
| resourcesLabel.setText(org.eclipse.ui.internal.ide.IDEWorkbenchMessages.WizardImportPage_folder); |
| resourcesLabel.setFont(parent.getFont()); |
| |
| // container name entry field |
| containerNameField = new Text(containerGroup, SWT.SINGLE | SWT.BORDER); |
| containerNameField.addListener(SWT.Modify, this); |
| GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL |
| | GridData.GRAB_HORIZONTAL); |
| data.widthHint = SIZING_TEXT_FIELD_WIDTH; |
| containerNameField.setLayoutData(data); |
| containerNameField.setFont(parent.getFont()); |
| containerNameField.setEnabled(false); |
| |
| containerNameField.setText(WSUtils.getPath(container).toString()); |
| } |
| |
| /** |
| * The <code>WizardDataTransfer</code> implementation of this |
| * <code>IOverwriteQuery</code> method asks the user whether the existing |
| * resource at the given path should be overwritten. |
| * |
| * @param pathString |
| * @return the user's reply: one of <code>"YES"</code>, <code>"NO"</code>, |
| * <code>"ALL"</code>, or <code>"CANCEL"</code> |
| */ |
| public String queryOverwrite(String pathString) { |
| |
| Path path = new Path(pathString); |
| |
| String messageString; |
| // Break the message up if there is a file name and a directory |
| // and there are at least 2 segments. |
| if (path.getFileExtension() == null || path.segmentCount() < 2) { |
| messageString = NLS.bind( |
| org.eclipse.ui.internal.ide.IDEWorkbenchMessages.WizardDataTransfer_existsQuestion, |
| pathString); |
| } else { |
| messageString = NLS |
| .bind(org.eclipse.ui.internal.ide.IDEWorkbenchMessages.WizardDataTransfer_overwriteNameAndPathQuestion, |
| path.lastSegment(), path.removeLastSegments(1) |
| .toOSString()); |
| } |
| |
| final MessageDialog dialog = new MessageDialog(getContainer() |
| .getShell(), org.eclipse.ui.internal.ide.IDEWorkbenchMessages.Question, null, |
| messageString, MessageDialog.QUESTION, new String[] { |
| IDialogConstants.YES_LABEL, |
| IDialogConstants.YES_TO_ALL_LABEL, |
| IDialogConstants.NO_LABEL, |
| IDialogConstants.NO_TO_ALL_LABEL, |
| IDialogConstants.CANCEL_LABEL }, 0) { |
| protected int getShellStyle() { |
| return super.getShellStyle() | SWT.SHEET; |
| } |
| }; |
| String[] response = new String[] { YES, ALL, NO, NO_ALL, CANCEL }; |
| // run in syncExec because callback is from an operation, |
| // which is probably not running in the UI thread. |
| getControl().getDisplay().syncExec(new Runnable() { |
| public void run() { |
| dialog.open(); |
| } |
| }); |
| return dialog.getReturnCode() < 0 ? CANCEL : response[dialog |
| .getReturnCode()]; |
| } |
| |
| /** |
| * Create the import options specification widgets. |
| */ |
| protected void createOptionsGroupButtons(Group optionsGroup) { |
| |
| // overwrite... checkbox |
| overwriteExistingResourcesCheckbox = new Button(optionsGroup, SWT.CHECK); |
| overwriteExistingResourcesCheckbox.setFont(optionsGroup.getFont()); |
| overwriteExistingResourcesCheckbox |
| .setText(org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.FileImport_overwriteExisting); |
| |
| // create containers radio |
| createContainerStructureButton = new Button(optionsGroup, SWT.RADIO); |
| createContainerStructureButton.setFont(optionsGroup.getFont()); |
| createContainerStructureButton.setText("Complete folder structure"); |
| createContainerStructureButton.setSelection(false); |
| |
| // create selection only radio |
| createOnlySelectedButton = new Button(optionsGroup, SWT.RADIO); |
| createOnlySelectedButton.setFont(optionsGroup.getFont()); |
| createOnlySelectedButton.setText("Selected folders only"); |
| createOnlySelectedButton.setSelection(true); |
| |
| } |
| |
| /** |
| * Create the group for creating the root directory |
| */ |
| protected void createRootDirectoryGroup(Composite parent) { |
| Composite sourceContainerGroup = new Composite(parent, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 3; |
| sourceContainerGroup.setLayout(layout); |
| sourceContainerGroup.setFont(parent.getFont()); |
| sourceContainerGroup.setLayoutData(new GridData( |
| GridData.HORIZONTAL_ALIGN_FILL | GridData.GRAB_HORIZONTAL)); |
| |
| Label groupLabel = new Label(sourceContainerGroup, SWT.NONE); |
| groupLabel.setText(getSourceLabel()); |
| groupLabel.setFont(parent.getFont()); |
| |
| // source name entry field |
| sourceNameField = new Combo(sourceContainerGroup, SWT.BORDER); |
| GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL |
| | GridData.GRAB_HORIZONTAL); |
| data.widthHint = SIZING_TEXT_FIELD_WIDTH; |
| sourceNameField.setLayoutData(data); |
| sourceNameField.setFont(parent.getFont()); |
| |
| sourceNameField.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| updateFromSourceField(); |
| } |
| }); |
| |
| sourceNameField.addKeyListener(new KeyListener() { |
| /* |
| * @see KeyListener.keyPressed |
| */ |
| public void keyPressed(KeyEvent e) { |
| // If there has been a key pressed then mark as dirty |
| entryChanged = true; |
| } |
| |
| /* |
| * @see KeyListener.keyReleased |
| */ |
| public void keyReleased(KeyEvent e) { |
| } |
| }); |
| |
| sourceNameField.addFocusListener(new FocusListener() { |
| /* |
| * @see FocusListener.focusGained(FocusEvent) |
| */ |
| public void focusGained(FocusEvent e) { |
| // Do nothing when getting focus |
| } |
| |
| /* |
| * @see FocusListener.focusLost(FocusEvent) |
| */ |
| public void focusLost(FocusEvent e) { |
| // Clear the flag to prevent constant update |
| if (entryChanged) { |
| entryChanged = false; |
| updateFromSourceField(); |
| } |
| |
| } |
| }); |
| |
| // source browse button |
| sourceBrowseButton = new Button(sourceContainerGroup, SWT.PUSH); |
| sourceBrowseButton |
| .setText(org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.DataTransfer_browse); |
| sourceBrowseButton.addListener(SWT.Selection, this); |
| sourceBrowseButton.setLayoutData(new GridData( |
| GridData.HORIZONTAL_ALIGN_FILL)); |
| sourceBrowseButton.setFont(parent.getFont()); |
| setButtonLayoutData(sourceBrowseButton); |
| } |
| |
| /** |
| * Update the receiver from the source name field. |
| */ |
| |
| private void updateFromSourceField() { |
| |
| setSourceName(sourceNameField.getText()); |
| // Update enablements when this is selected |
| updateWidgetEnablements(); |
| } |
| |
| /** |
| * Creates and returns a <code>FileSystemElement</code> if the specified |
| * file system object merits one. The criteria for this are: Also create the |
| * children. |
| */ |
| protected MinimizedFileSystemElement createRootElement( |
| Object fileSystemObject, IImportStructureProvider provider) { |
| boolean isContainer = provider.isFolder(fileSystemObject); |
| String elementLabel = provider.getLabel(fileSystemObject); |
| |
| // Use an empty label so that display of the element's full name |
| // doesn't include a confusing label |
| MinimizedFileSystemElement dummyParent = new MinimizedFileSystemElement("", null, true);//$NON-NLS-1$ |
| dummyParent.setPopulated(); |
| MinimizedFileSystemElement result = new MinimizedFileSystemElement( |
| elementLabel, dummyParent, isContainer); |
| result.setFileSystemObject(fileSystemObject); |
| |
| // Get the files for the element so as to build the first level |
| result.getFiles(provider); |
| |
| return dummyParent; |
| } |
| |
| /** |
| * Create the import source specification widgets |
| */ |
| protected void createSourceGroup(Composite parent) { |
| |
| createRootDirectoryGroup(parent); |
| createFileSelectionGroup(parent); |
| createButtonsGroup(parent); |
| } |
| |
| /** |
| * Create the import source selection widget |
| */ |
| protected void createFileSelectionGroup(Composite parent) { |
| |
| // Just create with a dummy root. |
| this.selectionGroup = new org.eclipse.ui.ide.dialogs.ResourceTreeAndListGroup( |
| parent, |
| new FileSystemElement("Dummy", null, true),//$NON-NLS-1$ |
| getFolderProvider(), new WorkbenchLabelProvider(), |
| getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE, |
| org.eclipse.ui.internal.ide.DialogUtil.inRegularFontMode(parent)); |
| |
| ICheckStateListener listener = new ICheckStateListener() { |
| public void checkStateChanged(CheckStateChangedEvent event) { |
| updateWidgetEnablements(); |
| } |
| }; |
| |
| WorkbenchViewerComparator comparator = new WorkbenchViewerComparator(); |
| this.selectionGroup.setTreeComparator(comparator); |
| this.selectionGroup.setListComparator(comparator); |
| this.selectionGroup.addCheckStateListener(listener); |
| |
| } |
| |
| /** |
| * Enable or disable the button group. |
| */ |
| protected void enableButtonGroup(boolean enable) { |
| selectTypesButton.setEnabled(enable); |
| selectAllButton.setEnabled(enable); |
| deselectAllButton.setEnabled(enable); |
| } |
| |
| /** |
| * Answer a boolean indicating whether the specified source currently exists |
| * and is valid |
| */ |
| protected boolean ensureSourceIsValid() { |
| if (new File(getSourceDirectoryName()).isDirectory()) { |
| return true; |
| } |
| |
| setErrorMessage(org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.FileImport_invalidSource); |
| return false; |
| } |
| |
| /** |
| * Display an error dialog with the specified message. |
| * |
| * @param message |
| * the error message |
| */ |
| protected void displayErrorDialog(String message) { |
| MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(), |
| getErrorDialogTitle(), message, SWT.SHEET); |
| } |
| |
| /** |
| * Display an error dislog with the information from the supplied exception. |
| * |
| * @param exception |
| * Throwable |
| */ |
| protected void displayErrorDialog(Throwable exception) { |
| String message = exception.getMessage(); |
| // Some system exceptions have no message |
| if (message == null) { |
| message = NLS.bind( |
| org.eclipse.ui.internal.ide.IDEWorkbenchMessages.WizardDataTransfer_exceptionMessage, |
| exception); |
| } |
| displayErrorDialog(message); |
| } |
| |
| /** |
| * Get the title for an error dialog. Subclasses should override. |
| */ |
| protected String getErrorDialogTitle() { |
| return org.eclipse.ui.internal.ide.IDEWorkbenchMessages.WizardExportPage_internalErrorTitle; |
| } |
| |
| /** |
| * Returns this page's list of currently-specified resources to be imported. |
| * This is the primary resource selection facility accessor for subclasses. |
| * |
| * @return a list of resources currently selected for export (element type: |
| * <code>IResource</code>) |
| */ |
| protected java.util.List getSelectedResources() { |
| return this.selectionGroup.getAllCheckedListItems(); |
| } |
| |
| /** |
| * Returns this page's list of currently-specified resources to be imported |
| * filtered by the org.eclipse.ui.internal.ide.dialogs.IElementFilter. |
| * |
| */ |
| protected void getSelectedResources(org.eclipse.ui.internal.ide.dialogs.IElementFilter filter, |
| IProgressMonitor monitor) throws InterruptedException { |
| this.selectionGroup.getAllCheckedListItems(filter, monitor); |
| } |
| |
| /** |
| * The Finish button was pressed. Try to do the required work now and answer |
| * a boolean indicating success. If false is returned then the wizard will |
| * not close. |
| * |
| * @return boolean |
| */ |
| @SuppressWarnings("unchecked") |
| public boolean finish() { |
| if (!ensureSourceIsValid()) { |
| return false; |
| } |
| |
| saveWidgetValues(); |
| |
| Iterator resourcesEnum = getSelectedResources().iterator(); |
| List fileSystemObjects = new ArrayList(); |
| while (resourcesEnum.hasNext()) { |
| fileSystemObjects.add(((FileSystemElement) resourcesEnum.next()) |
| .getFileSystemObject()); |
| } |
| |
| if (fileSystemObjects.size() > 0) { |
| return importResources(fileSystemObjects); |
| } |
| |
| MessageDialog.openInformation(getContainer().getShell(), |
| org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.DataTransfer_information, |
| org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.FileImport_noneSelected); |
| |
| return false; |
| } |
| |
| /** |
| * Returns a content provider for <code>FileSystemElement</code>s that |
| * returns only files as children. |
| */ |
| protected ITreeContentProvider getFileProvider() { |
| return new WorkbenchContentProvider() { |
| public Object[] getChildren(Object o) { |
| if (o instanceof MinimizedFileSystemElement) { |
| MinimizedFileSystemElement element = (MinimizedFileSystemElement) o; |
| return element.getFiles(fileSystemStructureProvider) |
| .getChildren(element); |
| } |
| return new Object[0]; |
| } |
| }; |
| } |
| |
| /** |
| * Answer the root FileSystemElement that represents the contents of the |
| * currently-specified source. If this FileSystemElement is not currently |
| * defined then create and return it. |
| */ |
| protected MinimizedFileSystemElement getFileSystemTree() { |
| |
| File sourceDirectory = getSourceDirectory(); |
| if (sourceDirectory == null) { |
| return null; |
| } |
| |
| return selectFiles(sourceDirectory, fileSystemStructureProvider); |
| } |
| |
| /** |
| * Returns a content provider for <code>FileSystemElement</code>s that |
| * returns only folders as children. |
| */ |
| protected ITreeContentProvider getFolderProvider() { |
| return new WorkbenchContentProvider() { |
| public Object[] getChildren(Object o) { |
| if (o instanceof MinimizedFileSystemElement) { |
| MinimizedFileSystemElement element = (MinimizedFileSystemElement) o; |
| return element.getFolders(fileSystemStructureProvider) |
| .getChildren(element); |
| } |
| return new Object[0]; |
| } |
| |
| 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; |
| } |
| }; |
| } |
| |
| /** |
| * Returns a File object representing the currently-named source directory |
| * iff it exists as a valid directory, or <code>null</code> otherwise. |
| */ |
| protected File getSourceDirectory() { |
| return getSourceDirectory(this.sourceNameField.getText()); |
| } |
| |
| /** |
| * Returns a File object representing the currently-named source directory |
| * iff it exists as a valid directory, or <code>null</code> otherwise. |
| * |
| * @param path |
| * a String not yet formatted for java.io.File compatability |
| */ |
| private File getSourceDirectory(String path) { |
| File sourceDirectory = new File(getSourceDirectoryName(path)); |
| if (!sourceDirectory.exists() || !sourceDirectory.isDirectory()) { |
| return null; |
| } |
| |
| return sourceDirectory; |
| } |
| |
| /** |
| * Answer the directory name specified as being the import source. Note that |
| * if it ends with a separator then the separator is first removed so that |
| * java treats it as a proper directory |
| */ |
| private String getSourceDirectoryName() { |
| return getSourceDirectoryName(this.sourceNameField.getText()); |
| } |
| |
| /** |
| * Answer the directory name specified as being the import source. Note that |
| * if it ends with a separator then the separator is first removed so that |
| * java treats it as a proper directory |
| */ |
| private String getSourceDirectoryName(String sourceName) { |
| IPath result = new Path(sourceName.trim()); |
| |
| if (result.getDevice() != null && result.segmentCount() == 0) { |
| result = result.addTrailingSeparator(); |
| } else { |
| result = result.removeTrailingSeparator(); |
| } |
| |
| return result.toOSString(); |
| } |
| |
| /** |
| * Answer the string to display as the label for the source specification |
| * field |
| */ |
| protected String getSourceLabel() { |
| return org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.FileImport_fromDirectory; |
| } |
| |
| /** |
| * Handle all events and enablements for widgets in this dialog |
| * |
| * @param event |
| * Event |
| */ |
| @SuppressWarnings("unused") |
| public void handleEvent(Event event) { |
| if (event.widget == sourceBrowseButton) { |
| handleSourceBrowseButtonPressed(); |
| } |
| |
| Widget source = event.widget; |
| |
| updateWidgetEnablements(); |
| } |
| |
| /** |
| * Open an appropriate source browser so that the user can specify a source |
| * to import from |
| */ |
| protected void handleSourceBrowseButtonPressed() { |
| |
| String currentSource = this.sourceNameField.getText(); |
| DirectoryDialog dialog = new DirectoryDialog( |
| sourceNameField.getShell(), SWT.SAVE | SWT.SHEET); |
| dialog.setText(SELECT_SOURCE_TITLE); |
| dialog.setMessage(SELECT_SOURCE_MESSAGE); |
| dialog.setFilterPath(getSourceDirectoryName(currentSource)); |
| |
| String selectedDirectory = dialog.open(); |
| if (selectedDirectory != null) { |
| // Just quit if the directory is not valid |
| if ((getSourceDirectory(selectedDirectory) == null) |
| || selectedDirectory.equals(currentSource)) { |
| return; |
| } |
| // If it is valid then proceed to populate |
| setErrorMessage(null); |
| setSourceName(selectedDirectory); |
| selectionGroup.setFocus(); |
| } |
| } |
| |
| /** |
| * Open a registered type selection dialog and note the selections in the |
| * receivers types-to-export field., Added here so that inner classes can |
| * have access |
| */ |
| @SuppressWarnings("unchecked") |
| protected void handleTypesEditButtonPressed() { |
| |
| TypeFilteringDialog dialog = new TypeFilteringDialog(getContainer() |
| .getShell(), getTypesToImport()); |
| |
| dialog.open(); |
| |
| Object[] newSelectedTypes = dialog.getResult(); |
| if (newSelectedTypes != null) { // ie.- did not press Cancel |
| this.selectedTypes = new ArrayList(newSelectedTypes.length); |
| for (int i = 0; i < newSelectedTypes.length; i++) { |
| this.selectedTypes.add(newSelectedTypes[i]); |
| } |
| |
| setupSelectionsBasedOnSelectedTypes(); |
| } |
| } |
| |
| /** |
| * Returns a collection of the currently-specified resource types for use by |
| * the type selection dialog. |
| */ |
| protected java.util.List getTypesToImport() { |
| |
| return selectedTypes; |
| } |
| |
| /** |
| * Import the resources with extensions as specified by the user |
| */ |
| protected boolean importResources(List fileSystemObjects) { |
| IPath minimalRoot = null; |
| IPersistenceModel model = PersistenceManager.getInstance().getModel( |
| container.eResource()); |
| if (model == null) { |
| return false; |
| } |
| for (Object object : fileSystemObjects) { |
| String lpath = fileSystemStructureProvider.getFullPath(object); |
| IPath path = new Path(lpath).removeLastSegments(1); |
| if (minimalRoot == null) { |
| minimalRoot = path; |
| continue; |
| } |
| while (!minimalRoot.isPrefixOf(path)) { |
| minimalRoot = minimalRoot.removeLastSegments(1); |
| } |
| if (path.segmentCount() < minimalRoot.segmentCount()) { |
| minimalRoot = path; |
| } |
| } |
| for (Object object : fileSystemObjects) { |
| if (!fileSystemStructureProvider.isFolder(object)) { |
| IPath fullPath = new Path( |
| fileSystemStructureProvider.getFullPath(object)) |
| .removeFirstSegments(minimalRoot.segmentCount()); |
| WSContainer folder = getFolder(this.container, |
| fullPath.removeLastSegments(1)); |
| if (folder instanceof WSFolder) { |
| WSFile wsFile = WSUtils.getFile((WSFolder) folder, |
| fullPath.lastSegment(), true); |
| String fName = ImportUtils.getName(wsFile); |
| OutputStream store = model.store(fName); |
| InputStream inputStream = fileSystemStructureProvider |
| .getContents(object); |
| try { |
| FileUtil.copy(inputStream, store); |
| } catch (IOException e) { |
| e.printStackTrace(); |
| } |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| private WSContainer getFolder(WSContainer container, IPath segms) { |
| WSContainer result = (WSFolder) container; |
| for (String part : segms.segments()) { |
| result = WSUtils.getContainer(result, part, true); |
| } |
| return result; |
| } |
| |
| /** |
| * Returns whether the extension provided is an extension that has been |
| * specified for export by the user. |
| * |
| * @param extension |
| * the resource name |
| * @return <code>true</code> if the resource name is suitable for export |
| * based upon its extension |
| */ |
| protected boolean isExportableExtension(String extension) { |
| if (selectedTypes == null) { |
| return true; |
| } |
| |
| Iterator itr = selectedTypes.iterator(); |
| while (itr.hasNext()) { |
| if (extension.equalsIgnoreCase((String) itr.next())) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| /** |
| * Repopulate the view based on the currently entered directory. |
| */ |
| protected void resetSelection() { |
| |
| MinimizedFileSystemElement currentRoot = getFileSystemTree(); |
| this.selectionGroup.setRoot(currentRoot); |
| |
| } |
| |
| /** |
| * Use the dialog store to restore widget values to the values that they |
| * held last time this wizard was used to completion |
| */ |
| protected void restoreWidgetValues() { |
| IDialogSettings settings = getDialogSettings(); |
| if (settings != null) { |
| String[] sourceNames = settings.getArray(STORE_SOURCE_NAMES_ID); |
| if (sourceNames == null) { |
| return; // ie.- no values stored, so stop |
| } |
| |
| // 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)); |
| |
| boolean createStructure = settings |
| .getBoolean(STORE_CREATE_CONTAINER_STRUCTURE_ID); |
| createContainerStructureButton.setSelection(createStructure); |
| createOnlySelectedButton.setSelection(!createStructure); |
| |
| } |
| } |
| |
| /** |
| * Since Finish was pressed, write widget values to the dialog store so that |
| * they will persist into the next invocation of this wizard page |
| */ |
| 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, getSourceDirectoryName()); |
| settings.put(STORE_SOURCE_NAMES_ID, sourceNames); |
| |
| // radio buttons and checkboxes |
| settings.put(STORE_OVERWRITE_EXISTING_RESOURCES_ID, |
| overwriteExistingResourcesCheckbox.getSelection()); |
| |
| settings.put(STORE_CREATE_CONTAINER_STRUCTURE_ID, |
| createContainerStructureButton.getSelection()); |
| |
| } |
| } |
| |
| /** |
| * Adds an entry to a history, while taking care of duplicate history items |
| * and excessively long histories. The assumption is made that all histories |
| * should be of length |
| * <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>. |
| * |
| * @param history |
| * the current history |
| * @param newEntry |
| * the entry to add to the history |
| */ |
| @SuppressWarnings("unchecked") |
| protected String[] addToHistory(String[] history, String newEntry) { |
| java.util.ArrayList l = new java.util.ArrayList(Arrays.asList(history)); |
| addToHistory(l, newEntry); |
| String[] r = new String[l.size()]; |
| l.toArray(r); |
| return r; |
| } |
| |
| /** |
| * Adds an entry to a history, while taking care of duplicate history items |
| * and excessively long histories. The assumption is made that all histories |
| * should be of length |
| * <code>WizardDataTransferPage.COMBO_HISTORY_LENGTH</code>. |
| * |
| * @param history |
| * the current history |
| * @param newEntry |
| * the entry to add to the history |
| */ |
| @SuppressWarnings("unchecked") |
| protected void addToHistory(List history, String newEntry) { |
| history.remove(newEntry); |
| history.add(0, newEntry); |
| |
| // since only one new item was added, we can be over the limit |
| // by at most one item |
| if (history.size() > COMBO_HISTORY_LENGTH) { |
| history.remove(COMBO_HISTORY_LENGTH); |
| } |
| } |
| |
| /** |
| * Invokes a file selection operation using the specified file system and |
| * structure provider. If the user specifies files to be imported then this |
| * selection is cached for later retrieval and is returned. |
| */ |
| protected MinimizedFileSystemElement selectFiles( |
| final Object rootFileSystemObject, |
| final IImportStructureProvider structureProvider) { |
| |
| final MinimizedFileSystemElement[] results = new MinimizedFileSystemElement[1]; |
| |
| BusyIndicator.showWhile(getShell().getDisplay(), new Runnable() { |
| public void run() { |
| // Create the root element from the supplied file system object |
| results[0] = createRootElement(rootFileSystemObject, |
| structureProvider); |
| } |
| }); |
| |
| return results[0]; |
| } |
| |
| /** |
| * Set all of the selections in the selection group to value. Implemented |
| * here to provide access for inner classes. |
| * |
| * @param value |
| * boolean |
| */ |
| protected void setAllSelections(boolean value) { |
| selectionGroup.setAllSelections(value); |
| } |
| |
| /** |
| * Sets the source name of the import to be the supplied path. Adds the name |
| * of the path to the list of items in the source combo and selects it. |
| * |
| * @param path |
| * the path to be added |
| */ |
| protected void setSourceName(String path) { |
| |
| if (path.length() > 0) { |
| |
| String[] currentItems = this.sourceNameField.getItems(); |
| int selectionIndex = -1; |
| for (int i = 0; i < currentItems.length; i++) { |
| if (currentItems[i].equals(path)) { |
| selectionIndex = i; |
| } |
| } |
| if (selectionIndex < 0) { |
| int oldLength = currentItems.length; |
| String[] newItems = new String[oldLength + 1]; |
| System.arraycopy(currentItems, 0, newItems, 0, oldLength); |
| newItems[oldLength] = path; |
| this.sourceNameField.setItems(newItems); |
| selectionIndex = oldLength; |
| } |
| this.sourceNameField.select(selectionIndex); |
| |
| resetSelection(); |
| } |
| } |
| |
| /** |
| * Update the tree to only select those elements that match the selected |
| * types |
| */ |
| protected void setupSelectionsBasedOnSelectedTypes() { |
| ProgressMonitorDialog dialog = new org.eclipse.ui.internal.progress.ProgressMonitorJobsDialog( |
| getContainer().getShell()); |
| final Map selectionMap = new Hashtable(); |
| |
| final org.eclipse.ui.internal.ide.dialogs.IElementFilter filter = new org.eclipse.ui.internal.ide.dialogs.IElementFilter() { |
| |
| public void filterElements(Collection files, |
| IProgressMonitor monitor) throws InterruptedException { |
| if (files == null) { |
| throw new InterruptedException(); |
| } |
| Iterator filesList = files.iterator(); |
| while (filesList.hasNext()) { |
| if (monitor.isCanceled()) { |
| throw new InterruptedException(); |
| } |
| checkFile(filesList.next()); |
| } |
| } |
| |
| public void filterElements(Object[] files, IProgressMonitor monitor) |
| throws InterruptedException { |
| if (files == null) { |
| throw new InterruptedException(); |
| } |
| for (int i = 0; i < files.length; i++) { |
| if (monitor.isCanceled()) { |
| throw new InterruptedException(); |
| } |
| checkFile(files[i]); |
| } |
| } |
| |
| @SuppressWarnings("unchecked") |
| private void checkFile(Object fileElement) { |
| MinimizedFileSystemElement file = (MinimizedFileSystemElement) fileElement; |
| if (isExportableExtension(file.getFileNameExtension())) { |
| List elements = new ArrayList(); |
| FileSystemElement parent = file.getParent(); |
| if (selectionMap.containsKey(parent)) { |
| elements = (List) selectionMap.get(parent); |
| } |
| elements.add(file); |
| selectionMap.put(parent, elements); |
| } |
| } |
| |
| }; |
| |
| IRunnableWithProgress runnable = new IRunnableWithProgress() { |
| public void run(final IProgressMonitor monitor) |
| throws InterruptedException { |
| monitor.beginTask( |
| org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.ImportPage_filterSelections, |
| IProgressMonitor.UNKNOWN); |
| getSelectedResources(filter, monitor); |
| } |
| }; |
| |
| try { |
| dialog.run(true, true, runnable); |
| } catch (InvocationTargetException exception) { |
| // Couldn't start. Do nothing. |
| return; |
| } catch (InterruptedException exception) { |
| // Got interrupted. Do nothing. |
| return; |
| } |
| // make sure that all paint operations caused by closing the progress |
| // dialog get flushed, otherwise extra pixels will remain on the screen |
| // until |
| // updateSelections is completed |
| getShell().update(); |
| // The updateSelections method accesses SWT widgets so cannot be |
| // executed |
| // as part of the above progress dialog operation since the operation |
| // forks |
| // a new process. |
| if (selectionMap != null) { |
| updateSelections(selectionMap); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) Method declared on IDialogPage. Set the selection up when |
| * it becomes visible. |
| */ |
| public void setVisible(boolean visible) { |
| super.setVisible(visible); |
| resetSelection(); |
| if (visible) { |
| this.sourceNameField.setFocus(); |
| } |
| } |
| |
| /** |
| * Update the selections with those in map . Implemented here to give inner |
| * class visibility |
| * |
| * @param map |
| * Map - key tree elements, values Lists of list elements |
| */ |
| protected void updateSelections(final Map map) { |
| Runnable runnable = new Runnable() { |
| public void run() { |
| selectionGroup.updateSelections(map); |
| } |
| }; |
| |
| BusyIndicator.showWhile(getShell().getDisplay(), runnable); |
| } |
| |
| /** |
| * Check if widgets are enabled or disabled by a change in the dialog. |
| * Provided here to give access to inner classes. |
| */ |
| protected void updateWidgetEnablements() { |
| boolean pageComplete = determinePageCompletion(); |
| setPageComplete(pageComplete); |
| if (pageComplete) { |
| setMessage(null); |
| } |
| enableButtonGroup(ensureSourceIsValid()); |
| } |
| |
| /** |
| * Answer a boolean indicating whether self's source specification widgets |
| * currently all contain valid values. |
| */ |
| protected boolean validateSourceGroup() { |
| File sourceDirectory = getSourceDirectory(); |
| if (sourceDirectory == null) { |
| setMessage(SOURCE_EMPTY_MESSAGE); |
| enableButtonGroup(false); |
| return false; |
| } |
| |
| List resourcesToExport = selectionGroup.getAllWhiteCheckedItems(); |
| if (resourcesToExport.size() == 0) { |
| setMessage(null); |
| setErrorMessage(org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages.FileImport_noneSelected); |
| return false; |
| } |
| |
| enableButtonGroup(true); |
| setErrorMessage(null); |
| return true; |
| } |
| |
| /** |
| * Returns the error message for when the source conflicts with the |
| * destination. |
| */ |
| protected final String getSourceConflictMessage() { |
| return (org.eclipse.ui.internal.ide.IDEWorkbenchMessages.WizardImportPage_importOnReceiver); |
| } |
| |
| } |