| /******************************************************************************* |
| * Copyright (c) 2004, 2005 IBM Corporation and others. |
| * Copyright (c) 2005 Red Hat, Inc. |
| * 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 |
| * Red Hat, Inc - extensive changes to allow importing of Archive Files |
| * Philippe Ombredanne (pombredanne@nexb.com) |
| * - Bug 101180 [Import/Export] Import Existing Project into Workspace default widget is back button , should be text field |
| *******************************************************************************/ |
| package org.eclipse.ui.internal.wizards.datatransfer; |
| |
| 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.Iterator; |
| import java.util.List; |
| import java.util.zip.ZipException; |
| import java.util.zip.ZipFile; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IProjectDescription; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspace; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.core.runtime.SubProgressMonitor; |
| import org.eclipse.jface.dialogs.Dialog; |
| import org.eclipse.jface.dialogs.ErrorDialog; |
| import org.eclipse.jface.dialogs.IDialogConstants; |
| import org.eclipse.jface.dialogs.IDialogSettings; |
| import org.eclipse.jface.dialogs.MessageDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.jface.viewers.CheckboxTreeViewer; |
| import org.eclipse.jface.viewers.ITreeContentProvider; |
| import org.eclipse.jface.viewers.LabelProvider; |
| import org.eclipse.jface.viewers.Viewer; |
| import org.eclipse.jface.viewers.ViewerSorter; |
| import org.eclipse.jface.wizard.WizardPage; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.events.FocusAdapter; |
| 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; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.DirectoryDialog; |
| import org.eclipse.swt.widgets.FileDialog; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.actions.WorkspaceModifyOperation; |
| import org.eclipse.ui.dialogs.IOverwriteQuery; |
| import org.eclipse.ui.internal.ide.IDEApplication; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchMessages; |
| import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin; |
| import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider; |
| import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider; |
| import org.eclipse.ui.wizards.datatransfer.ImportOperation; |
| |
| /** |
| * The WizardProjectsImportPage is the page that allows the user to import |
| * projects from a particular location. |
| */ |
| public class WizardProjectsImportPage extends WizardPage implements |
| IOverwriteQuery { |
| |
| /** |
| * Class declared public only for test suite. |
| * |
| */ |
| public class ProjectRecord { |
| File projectSystemFile; |
| |
| Object projectArchiveFile; |
| |
| String projectName; |
| |
| Object parent; |
| |
| int level; |
| |
| IProjectDescription description; |
| |
| ILeveledImportStructureProvider provider; |
| |
| /** |
| * Create a record for a project based on the info in the file. |
| * |
| * @param file |
| */ |
| ProjectRecord(File file) { |
| projectSystemFile = file; |
| setProjectName(); |
| } |
| |
| /** |
| * @param file |
| * The Object representing the .project file |
| * @param parent |
| * The parent folder of the .project file |
| * @param level |
| * The number of levels deep in the provider the file is |
| * @param entryProvider |
| * The provider for the archive file that contains it |
| */ |
| ProjectRecord(Object file, Object parent, int level, |
| ILeveledImportStructureProvider entryProvider) { |
| this.projectArchiveFile = file; |
| this.parent = parent; |
| this.level = level; |
| this.provider = entryProvider; |
| setProjectName(); |
| } |
| |
| /** |
| * Set the name of the project based on the projectFile. |
| */ |
| private void setProjectName() { |
| IProjectDescription newDescription = null; |
| try { |
| if (projectArchiveFile != null) { |
| InputStream stream = provider |
| .getContents(projectArchiveFile); |
| newDescription = IDEWorkbenchPlugin.getPluginWorkspace() |
| .loadProjectDescription(stream); |
| stream.close(); |
| } else { |
| IPath path = new Path(projectSystemFile.getPath()); |
| newDescription = IDEWorkbenchPlugin.getPluginWorkspace() |
| .loadProjectDescription(path); |
| } |
| } catch (CoreException e) { |
| // no good couldn't get the name |
| } catch (IOException e) { |
| // no good couldn't get the name |
| } |
| |
| if (newDescription == null) { |
| this.description = null; |
| projectName = ""; //$NON-NLS-1$ |
| } else { |
| this.description = newDescription; |
| projectName = this.description.getName(); |
| } |
| } |
| |
| /** |
| * Get the name of the project |
| * |
| * @return String |
| */ |
| public String getProjectName() { |
| return projectName; |
| } |
| } |
| |
| // dialog store id constants |
| private final static String STORE_COPY_PROJECT_ID = "WizardProjectsImportPage.STORE_COPY_PROJECT_ID"; //$NON-NLS-1$ |
| |
| private final static String STORE_ARCHIVE_SELECTED = "WizardProjectsImportPage.STORE_ARCHIVE_SELECTED"; //$NON-NLS-1$ |
| |
| private Text directoryPathField; |
| |
| private CheckboxTreeViewer projectsList; |
| |
| private Button copyCheckbox; |
| |
| private boolean copyFiles = false; |
| |
| private ProjectRecord[] selectedProjects = new ProjectRecord[0]; |
| |
| // Keep track of the directory that we browsed to last time |
| // the wizard was invoked. |
| private static String previouslyBrowsedDirectory = ""; //$NON-NLS-1$ |
| |
| // Keep track of the archive that we browsed to last time |
| // the wizard was invoked. |
| private static String previouslyBrowsedArchive = ""; //$NON-NLS-1$ |
| |
| private Button projectFromDirectoryRadio; |
| |
| private Button projectFromArchiveRadio; |
| |
| private Text archivePathField; |
| |
| private Button browseDirectoriesButton; |
| |
| private Button browseArchivesButton; |
| |
| private IProject[] wsProjects; |
| |
| // constant from WizardArchiveFileResourceImportPage1 |
| private static final String[] FILE_IMPORT_MASK = { |
| "*.jar;*.zip;*.tar;*.tar.gz;*.tgz", "*.*" }; //$NON-NLS-1$ //$NON-NLS-2$ |
| |
| //The last selected path to mimize searches |
| private String lastPath; |
| |
| /** |
| * Creates a new project creation wizard page. |
| * |
| */ |
| public WizardProjectsImportPage() { |
| this("wizardExternalProjectsPage"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Create a new instance of the receiver. |
| * |
| * @param pageName |
| */ |
| public WizardProjectsImportPage(String pageName) { |
| super(pageName); |
| setPageComplete(false); |
| setTitle(DataTransferMessages.WizardProjectsImportPage_ImportProjectsTitle); |
| setDescription(DataTransferMessages.WizardProjectsImportPage_ImportProjectsDescription); |
| } |
| |
| /** |
| * Create a new instance of the receiver. |
| * |
| * @param pageName |
| * @param title |
| * @param titleImage |
| */ |
| public WizardProjectsImportPage(String pageName, String title, |
| ImageDescriptor titleImage) { |
| super(pageName, title, titleImage); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) |
| */ |
| public void createControl(Composite parent) { |
| |
| initializeDialogUnits(parent); |
| |
| Composite workArea = new Composite(parent, SWT.NONE); |
| setControl(workArea); |
| |
| workArea.setLayout(new GridLayout()); |
| workArea.setLayoutData(new GridData(GridData.FILL_BOTH |
| | GridData.GRAB_HORIZONTAL | GridData.GRAB_VERTICAL)); |
| |
| createProjectsRoot(workArea); |
| createProjectsList(workArea); |
| createOptionsArea(workArea); |
| restoreWidgetValues(); |
| Dialog.applyDialogFont(workArea); |
| |
| } |
| |
| /** |
| * Create the area with the extra options. |
| * @param workArea |
| */ |
| private void createOptionsArea(Composite workArea){ |
| Composite optionsGroup = new Composite(workArea, SWT.NONE); |
| optionsGroup.setLayout(new GridLayout()); |
| optionsGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| copyCheckbox = new Button(optionsGroup, SWT.CHECK); |
| copyCheckbox.setText(DataTransferMessages.WizardProjectsImportPage_CopyProjectsIntoWorkspace); |
| copyCheckbox.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| copyCheckbox.addSelectionListener(new SelectionAdapter(){ |
| public void widgetSelected(SelectionEvent e) { |
| copyFiles = copyCheckbox.getSelection(); |
| } |
| }); |
| } |
| |
| /** |
| * Create the checkbox list for the found projects. |
| * |
| * @param workArea |
| */ |
| private void createProjectsList(Composite workArea) { |
| |
| Label title = new Label(workArea, SWT.NONE); |
| title |
| .setText(DataTransferMessages.WizardProjectsImportPage_ProjectsListTitle); |
| |
| Composite listComposite = new Composite(workArea, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 2; |
| layout.marginWidth = 0; |
| layout.makeColumnsEqualWidth = false; |
| listComposite.setLayout(layout); |
| |
| listComposite.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL |
| | GridData.GRAB_VERTICAL | GridData.FILL_BOTH)); |
| |
| projectsList = new CheckboxTreeViewer(listComposite, SWT.BORDER); |
| GridData listData = new GridData(GridData.GRAB_HORIZONTAL |
| | GridData.GRAB_VERTICAL | GridData.FILL_BOTH); |
| projectsList.getControl().setLayoutData(listData); |
| |
| projectsList.setContentProvider(new ITreeContentProvider() { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object) |
| */ |
| public Object[] getChildren(Object parentElement) { |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object) |
| */ |
| public Object[] getElements(Object inputElement) { |
| return getValidProjects(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object) |
| */ |
| public boolean hasChildren(Object element) { |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object) |
| */ |
| public Object getParent(Object element) { |
| return null; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.viewers.IContentProvider#dispose() |
| */ |
| public void dispose() { |
| |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, |
| * java.lang.Object, java.lang.Object) |
| */ |
| public void inputChanged(Viewer viewer, Object oldInput, |
| Object newInput) { |
| } |
| |
| }); |
| |
| projectsList.setLabelProvider(new LabelProvider() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object) |
| */ |
| public String getText(Object element) { |
| return ((ProjectRecord) element).getProjectName(); |
| } |
| }); |
| |
| projectsList.setInput(this); |
| projectsList.setSorter(new ViewerSorter()); |
| createSelectionButtons(listComposite); |
| } |
| |
| /** |
| * Create the selection buttons in the listComposite. |
| * |
| * @param listComposite |
| */ |
| private void createSelectionButtons(Composite listComposite) { |
| Composite buttonsComposite = new Composite(listComposite, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.marginWidth = 0; |
| layout.marginHeight = 0; |
| buttonsComposite.setLayout(layout); |
| |
| buttonsComposite.setLayoutData(new GridData( |
| GridData.VERTICAL_ALIGN_BEGINNING)); |
| |
| Button selectAll = new Button(buttonsComposite, SWT.PUSH); |
| selectAll.setText(DataTransferMessages.DataTransfer_selectAll); |
| selectAll.addSelectionListener(new SelectionAdapter() { |
| public void widgetSelected(SelectionEvent e) { |
| projectsList.setCheckedElements(selectedProjects); |
| } |
| }); |
| Dialog.applyDialogFont(selectAll); |
| setButtonLayoutData(selectAll); |
| |
| Button deselectAll = new Button(buttonsComposite, SWT.PUSH); |
| deselectAll.setText(DataTransferMessages.DataTransfer_deselectAll); |
| deselectAll.addSelectionListener(new SelectionAdapter() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| */ |
| public void widgetSelected(SelectionEvent e) { |
| |
| projectsList.setCheckedElements(new Object[0]); |
| |
| } |
| }); |
| Dialog.applyDialogFont(deselectAll); |
| setButtonLayoutData(deselectAll); |
| |
| Button refresh = new Button(buttonsComposite, SWT.PUSH); |
| refresh.setText(DataTransferMessages.DataTransfer_refresh); |
| refresh.addSelectionListener(new SelectionAdapter() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| */ |
| public void widgetSelected(SelectionEvent e) { |
| if (projectFromDirectoryRadio.getSelection()) |
| updateProjectsList(directoryPathField.getText().trim()); |
| else |
| updateProjectsList(archivePathField.getText().trim()); |
| } |
| }); |
| Dialog.applyDialogFont(refresh); |
| setButtonLayoutData(refresh); |
| } |
| |
| /** |
| * Create the area where you select the root directory for the projects. |
| * |
| * @param workArea |
| * Composite |
| */ |
| private void createProjectsRoot(Composite workArea) { |
| |
| // project specification group |
| Composite projectGroup = new Composite(workArea, SWT.NONE); |
| GridLayout layout = new GridLayout(); |
| layout.numColumns = 3; |
| layout.makeColumnsEqualWidth = false; |
| layout.marginWidth = 0; |
| projectGroup.setLayout(layout); |
| projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); |
| |
| // new project from directory radio button |
| projectFromDirectoryRadio = new Button(projectGroup, SWT.RADIO); |
| projectFromDirectoryRadio |
| .setText(DataTransferMessages.WizardProjectsImportPage_RootSelectTitle); |
| |
| // project location entry field |
| this.directoryPathField = new Text(projectGroup, SWT.BORDER); |
| |
| this.directoryPathField.setLayoutData(new GridData( |
| GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL)); |
| |
| // browse button |
| browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); |
| browseDirectoriesButton |
| .setText(DataTransferMessages.DataTransfer_browse); |
| setButtonLayoutData(browseDirectoriesButton); |
| |
| // new project from archive radio button |
| projectFromArchiveRadio = new Button(projectGroup, SWT.RADIO); |
| projectFromArchiveRadio |
| .setText(DataTransferMessages.WizardProjectsImportPage_ArchiveSelectTitle); |
| |
| // project location entry field |
| archivePathField = new Text(projectGroup, SWT.BORDER); |
| |
| archivePathField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL |
| | GridData.GRAB_HORIZONTAL)); |
| // browse button |
| browseArchivesButton = new Button(projectGroup, SWT.PUSH); |
| browseArchivesButton.setText(DataTransferMessages.DataTransfer_browse); |
| setButtonLayoutData(browseArchivesButton); |
| |
| projectFromDirectoryRadio.setSelection(true); |
| archivePathField.setEnabled(false); |
| browseArchivesButton.setEnabled(false); |
| |
| browseDirectoriesButton.addSelectionListener(new SelectionAdapter() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.SelectionAdapter#widgetS |
| * elected(org.eclipse.swt.events.SelectionEvent) |
| */ |
| public void widgetSelected(SelectionEvent e) { |
| handleLocationDirectoryButtonPressed(); |
| } |
| |
| }); |
| |
| browseArchivesButton.addSelectionListener(new SelectionAdapter() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| */ |
| public void widgetSelected(SelectionEvent e) { |
| handleLocationArchiveButtonPressed(); |
| } |
| |
| }); |
| |
| directoryPathField.addTraverseListener(new TraverseListener() { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent) |
| */ |
| public void keyTraversed(TraverseEvent e) { |
| if (e.detail == SWT.TRAVERSE_RETURN) { |
| e.doit = false; |
| updateProjectsList(directoryPathField.getText().trim()); |
| } |
| } |
| |
| }); |
| |
| directoryPathField.addFocusListener(new FocusAdapter() { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) |
| */ |
| public void focusLost(org.eclipse.swt.events.FocusEvent e) { |
| updateProjectsList(directoryPathField.getText().trim()); |
| } |
| |
| }); |
| |
| archivePathField.addTraverseListener(new TraverseListener() { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.TraverseListener#keyTraversed(org.eclipse.swt.events.TraverseEvent) |
| */ |
| public void keyTraversed(TraverseEvent e) { |
| if (e.detail == SWT.TRAVERSE_RETURN) { |
| e.doit = false; |
| updateProjectsList(archivePathField.getText().trim()); |
| } |
| } |
| |
| }); |
| |
| archivePathField.addFocusListener(new FocusAdapter() { |
| /* (non-Javadoc) |
| * @see org.eclipse.swt.events.FocusListener#focusLost(org.eclipse.swt.events.FocusEvent) |
| */ |
| public void focusLost(org.eclipse.swt.events.FocusEvent e) { |
| updateProjectsList(archivePathField.getText().trim()); |
| } |
| }); |
| |
| projectFromDirectoryRadio.addSelectionListener(new SelectionAdapter() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| */ |
| public void widgetSelected(SelectionEvent e) { |
| directoryRadioSelected(); |
| } |
| }); |
| |
| projectFromArchiveRadio.addSelectionListener(new SelectionAdapter() { |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent) |
| */ |
| public void widgetSelected(SelectionEvent e) { |
| archiveRadioSelected(); |
| } |
| }); |
| } |
| |
| private void archiveRadioSelected(){ |
| if (projectFromArchiveRadio.getSelection()) { |
| directoryPathField.setEnabled(false); |
| browseDirectoriesButton.setEnabled(false); |
| archivePathField.setEnabled(true); |
| browseArchivesButton.setEnabled(true); |
| updateProjectsList(archivePathField.getText()); |
| archivePathField.setFocus(); |
| copyCheckbox.setSelection(true); |
| copyCheckbox.setEnabled(false); |
| } |
| } |
| |
| private void directoryRadioSelected(){ |
| if (projectFromDirectoryRadio.getSelection()) { |
| directoryPathField.setEnabled(true); |
| browseDirectoriesButton.setEnabled(true); |
| archivePathField.setEnabled(false); |
| browseArchivesButton.setEnabled(false); |
| updateProjectsList(directoryPathField.getText()); |
| directoryPathField.setFocus(); |
| copyCheckbox.setEnabled(true); |
| copyCheckbox.setSelection(copyFiles); |
| } |
| } |
| |
| |
| /* (non-Javadoc) |
| * Method declared on IDialogPage. Set the focus on path fields when page becomes visible. |
| */ |
| public void setVisible(boolean visible) { |
| super.setVisible(visible); |
| if (visible && this.projectFromDirectoryRadio.getSelection()) { |
| this.directoryPathField.setFocus(); |
| } |
| if (visible && this.projectFromArchiveRadio.getSelection()) { |
| this.archivePathField.setFocus(); |
| } |
| } |
| |
| /** |
| * Update the list of projects based on path. |
| * Method declared public only for test suite. |
| * |
| * @param path |
| */ |
| public void updateProjectsList(final String path) { |
| |
| if(path.equals(lastPath))//Do not select the same path again |
| return; |
| |
| lastPath = path; |
| |
| // on an empty path empty selectedProjects |
| if (path == null || path.length() == 0) { |
| selectedProjects = new ProjectRecord[0]; |
| projectsList.refresh(true); |
| projectsList.setCheckedElements(selectedProjects); |
| setPageComplete(getValidProjects().length > 0); |
| return; |
| } |
| // We can't access the radio button from the inner class so get the |
| // status beforehand |
| final boolean dirSelected = this.projectFromDirectoryRadio |
| .getSelection(); |
| try { |
| getContainer().run(true, true, new IRunnableWithProgress() { |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public void run(IProgressMonitor monitor) { |
| |
| monitor |
| .beginTask( |
| DataTransferMessages.WizardProjectsImportPage_SearchingMessage, |
| 100); |
| File directory = new File(path); |
| selectedProjects = new ProjectRecord[0]; |
| Collection files = new ArrayList(); |
| monitor.worked(10); |
| if (!dirSelected |
| && ArchiveFileManipulations.isTarFile(path)) { |
| TarFile sourceTarFile = getSpecifiedTarSourceFile(path); |
| if (sourceTarFile == null) { |
| return; |
| } |
| |
| TarLeveledStructureProvider provider = ArchiveFileManipulations |
| .getTarStructureProvider(sourceTarFile, |
| getContainer().getShell()); |
| Object child = provider.getRoot(); |
| |
| if (!collectProjectFilesFromProvider(files, provider, |
| child, 0, monitor)) |
| return; |
| Iterator filesIterator = files.iterator(); |
| selectedProjects = new ProjectRecord[files.size()]; |
| int index = 0; |
| monitor.worked(50); |
| monitor |
| .subTask(DataTransferMessages.WizardProjectsImportPage_ProcessingMessage); |
| while (filesIterator.hasNext()) |
| selectedProjects[index++] = (ProjectRecord) filesIterator |
| .next(); |
| } else if (!dirSelected |
| && ArchiveFileManipulations.isZipFile(path)) { |
| ZipFile sourceFile = getSpecifiedZipSourceFile(path); |
| if (sourceFile == null) { |
| return; |
| } |
| ZipLeveledStructureProvider provider = ArchiveFileManipulations |
| .getZipStructureProvider(sourceFile, |
| getContainer().getShell()); |
| Object child = provider.getRoot(); |
| |
| if (!collectProjectFilesFromProvider(files, provider, |
| child, 0, monitor)) |
| return; |
| Iterator filesIterator = files.iterator(); |
| selectedProjects = new ProjectRecord[files.size()]; |
| int index = 0; |
| monitor.worked(50); |
| monitor |
| .subTask(DataTransferMessages.WizardProjectsImportPage_ProcessingMessage); |
| while (filesIterator.hasNext()) |
| selectedProjects[index++] = (ProjectRecord) filesIterator |
| .next(); |
| } |
| |
| else if (dirSelected && directory.isDirectory()) { |
| |
| if (!collectProjectFilesFromDirectory(files, directory, |
| monitor)) |
| return; |
| Iterator filesIterator = files.iterator(); |
| selectedProjects = new ProjectRecord[files.size()]; |
| int index = 0; |
| monitor.worked(50); |
| monitor |
| .subTask(DataTransferMessages.WizardProjectsImportPage_ProcessingMessage); |
| while (filesIterator.hasNext()) { |
| File file = (File) filesIterator.next(); |
| selectedProjects[index] = new ProjectRecord(file); |
| index++; |
| } |
| } else |
| monitor.worked(60); |
| monitor.done(); |
| } |
| |
| }); |
| } catch (InvocationTargetException e) { |
| IDEWorkbenchPlugin.log(e.getMessage(), e); |
| } catch (InterruptedException e) { |
| // Nothing to do if the user interrupts. |
| } |
| |
| projectsList.refresh(true); |
| projectsList.setCheckedElements(getValidProjects()); |
| setPageComplete(getValidProjects().length > 0); |
| } |
| |
| /** |
| * 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(archivePathField.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(DataTransferMessages.ZipImport_badFormat); |
| } catch (IOException e) { |
| displayErrorDialog(DataTransferMessages.ZipImport_couldNotRead); |
| } |
| |
| archivePathField.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(archivePathField.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(DataTransferMessages.TarImport_badFormat); |
| } catch (IOException e) { |
| displayErrorDialog(DataTransferMessages.ZipImport_couldNotRead); |
| } |
| |
| archivePathField.setFocus(); |
| return null; |
| } |
| |
| /** |
| * Display an error dialog with the specified message. |
| * |
| * @param message |
| * the error message |
| */ |
| protected void displayErrorDialog(String message) { |
| MessageDialog.openError(getContainer().getShell(), |
| getErrorDialogTitle(), message); |
| } |
| |
| /** |
| * Get the title for an error dialog. Subclasses should override. |
| */ |
| protected String getErrorDialogTitle() { |
| return IDEWorkbenchMessages.WizardExportPage_internalErrorTitle; |
| } |
| |
| /** |
| * Collect the list of .project files that are under directory into files. |
| * |
| * @param files |
| * @param directory |
| * @param monitor |
| * The monitor to report to |
| * @return boolean <code>true</code> if the operation was completed. |
| */ |
| private boolean collectProjectFilesFromDirectory(Collection files, |
| File directory, IProgressMonitor monitor) { |
| |
| if (monitor.isCanceled()) |
| return false; |
| monitor.subTask(NLS.bind( |
| DataTransferMessages.WizardProjectsImportPage_CheckingMessage, |
| directory.getPath())); |
| File[] contents = directory.listFiles(); |
| // first look for project description files |
| final String dotProject = IProjectDescription.DESCRIPTION_FILE_NAME; |
| for (int i = 0; i < contents.length; i++) { |
| File file = contents[i]; |
| if (file.isFile() && file.getName().equals(dotProject)) { |
| files.add(file); |
| // don't search sub-directories since we can't have nested |
| // projects |
| return true; |
| } |
| } |
| // no project description found, so recurse into sub-directories |
| for (int i = 0; i < contents.length; i++) { |
| if (contents[i].isDirectory()) |
| if (!contents[i].getName().equals( |
| IDEApplication.METADATA_FOLDER)) |
| collectProjectFilesFromDirectory(files, contents[i], |
| monitor); |
| } |
| return true; |
| } |
| |
| /** |
| * Collect the list of .project files that are under directory into files. |
| * |
| * @param files |
| * @param monitor |
| * The monitor to report to |
| * @return boolean <code>true</code> if the operation was completed. |
| */ |
| private boolean collectProjectFilesFromProvider(Collection files, |
| ILeveledImportStructureProvider provider, Object entry, int level, |
| IProgressMonitor monitor) { |
| |
| if (monitor.isCanceled()) |
| return false; |
| monitor.subTask(NLS.bind( |
| DataTransferMessages.WizardProjectsImportPage_CheckingMessage, |
| provider.getLabel(entry))); |
| List children = provider.getChildren(entry); |
| if (children == null) { |
| children = new ArrayList(1); |
| } |
| Iterator childrenEnum = children.iterator(); |
| while (childrenEnum.hasNext()) { |
| Object child = childrenEnum.next(); |
| if (provider.isFolder(child)) |
| collectProjectFilesFromProvider(files, provider, child, |
| level + 1, monitor); |
| String elementLabel = provider.getLabel(child); |
| if (elementLabel.equals(IProjectDescription.DESCRIPTION_FILE_NAME)) |
| files.add(new ProjectRecord(child, entry, level, provider)); |
| } |
| return true; |
| } |
| |
| /** |
| * The browse button has been selected. Select the location. |
| */ |
| protected void handleLocationDirectoryButtonPressed() { |
| |
| DirectoryDialog dialog = new DirectoryDialog(directoryPathField |
| .getShell()); |
| dialog |
| .setMessage(DataTransferMessages.WizardProjectsImportPage_SelectDialogTitle); |
| |
| String dirName = directoryPathField.getText().trim(); |
| if (dirName.length() == 0) |
| dirName = previouslyBrowsedDirectory; |
| |
| if (dirName.length() == 0) |
| dialog.setFilterPath(IDEWorkbenchPlugin.getPluginWorkspace() |
| .getRoot().getLocation().toOSString()); |
| else { |
| File path = new File(dirName); |
| if (path.exists()) |
| dialog.setFilterPath(new Path(dirName).toOSString()); |
| } |
| |
| String selectedDirectory = dialog.open(); |
| if (selectedDirectory != null) { |
| previouslyBrowsedDirectory = selectedDirectory; |
| directoryPathField.setText(previouslyBrowsedDirectory); |
| updateProjectsList(selectedDirectory); |
| } |
| |
| } |
| |
| /** |
| * The browse button has been selected. Select the location. |
| */ |
| protected void handleLocationArchiveButtonPressed() { |
| |
| FileDialog dialog = new FileDialog(archivePathField.getShell()); |
| dialog.setFilterExtensions(FILE_IMPORT_MASK); |
| dialog |
| .setText(DataTransferMessages.WizardProjectsImportPage_SelectArchiveDialogTitle); |
| |
| String fileName = archivePathField.getText().trim(); |
| if (fileName.length() == 0) |
| fileName = previouslyBrowsedArchive; |
| |
| if (fileName.length() == 0) |
| dialog.setFilterPath(IDEWorkbenchPlugin.getPluginWorkspace() |
| .getRoot().getLocation().toOSString()); |
| else { |
| File path = new File(fileName); |
| if (path.exists()) |
| dialog.setFilterPath(new Path(fileName).toOSString()); |
| } |
| |
| String selectedArchive = dialog.open(); |
| if (selectedArchive != null) { |
| previouslyBrowsedArchive = selectedArchive; |
| archivePathField.setText(previouslyBrowsedArchive); |
| updateProjectsList(selectedArchive); |
| } |
| |
| } |
| |
| /** |
| * Create the selected projects |
| * |
| * @return boolean <code>true</code> if all project creations were |
| * successful. |
| */ |
| public boolean createProjects() { |
| saveWidgetValues(); |
| final Object[] selected = projectsList.getCheckedElements(); |
| WorkspaceModifyOperation op = new WorkspaceModifyOperation() { |
| protected void execute(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| try { |
| monitor.beginTask("", selected.length); //$NON-NLS-1$ |
| if (monitor.isCanceled()) |
| throw new OperationCanceledException(); |
| for (int i = 0; i < selected.length; i++) |
| createExistingProject((ProjectRecord) selected[i], new SubProgressMonitor(monitor, 1)); |
| } finally { |
| monitor.done(); |
| } |
| } |
| }; |
| // run the new project creation operation |
| try { |
| getContainer().run(true, true, op); |
| } catch (InterruptedException e) { |
| return false; |
| } catch (InvocationTargetException e) { |
| // one of the steps resulted in a core exception |
| Throwable t = e.getTargetException(); |
| String message = DataTransferMessages.WizardExternalProjectImportPage_errorMessage; |
| IStatus status; |
| if (t instanceof CoreException) |
| status = ((CoreException)t).getStatus(); |
| else |
| status = new Status(IStatus.ERROR, IDEWorkbenchPlugin.IDE_WORKBENCH, 1, message, t); |
| ErrorDialog.openError(getShell(), |
| message, |
| null, |
| status); |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * Create the project described in record. If it is successful return true. |
| * |
| * @param record |
| * @return boolean <code>true</code> if successful |
| * @throws InterruptedException |
| */ |
| private boolean createExistingProject(final ProjectRecord record, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { |
| String projectName = record.getProjectName(); |
| final IWorkspace workspace = ResourcesPlugin.getWorkspace(); |
| final IProject project = workspace.getRoot().getProject(projectName); |
| if (record.description == null) { |
| // error case |
| record.description = workspace.newProjectDescription(projectName); |
| IPath locationPath = new Path(record.projectSystemFile |
| .getAbsolutePath()); |
| // IPath locationPath = new |
| // Path(record.projectFile.getFullPath(record.projectFile.getRoot())); |
| |
| // If it is under the root use the default location |
| if (Platform.getLocation().isPrefixOf(locationPath)) |
| record.description.setLocation(null); |
| else |
| record.description.setLocation(locationPath); |
| } else |
| record.description.setName(projectName); |
| if (record.projectArchiveFile != null) { |
| //import from archive |
| ArrayList fileSystemObjects = new ArrayList(); |
| getFilesForProject(fileSystemObjects, record.provider, |
| record.parent); |
| record.provider.setStrip(record.level); |
| ImportOperation operation = new ImportOperation(project |
| .getFullPath(), record.provider.getRoot(), record.provider, |
| this, fileSystemObjects); |
| operation.setContext(getShell()); |
| operation.run(monitor); |
| return true; |
| } |
| //import from file system |
| File importSource = null; |
| if (copyFiles){ |
| // import project from location copying files - use default project location for this workspace |
| URI locationURI = record.description.getLocationURI(); |
| // if location is null, project already exists in this location or |
| // some error condition occured. |
| if (locationURI != null){ |
| importSource = new File(locationURI); |
| IProjectDescription desc = workspace.newProjectDescription(projectName); |
| desc.setBuildSpec(record.description.getBuildSpec()); |
| desc.setNatureIds(record.description.getNatureIds()); |
| desc.setDynamicReferences(record.description.getDynamicReferences()); |
| desc.setReferencedProjects(record.description.getReferencedProjects()); |
| record.description = desc; |
| } |
| } |
| |
| try { |
| monitor.beginTask( |
| DataTransferMessages.WizardProjectsImportPage_CreateProjectsTask, |
| 100); |
| project.create(record.description, new SubProgressMonitor( |
| monitor, 30)); |
| project.open(IResource.BACKGROUND_REFRESH, |
| new SubProgressMonitor(monitor, 70)); |
| } catch (CoreException e) { |
| throw new InvocationTargetException(e); |
| } finally { |
| monitor.done(); |
| } |
| |
| // import operation to import project files if copy checkbox is selected |
| if (copyFiles && importSource != null){ |
| List filesToImport = new ArrayList(); |
| FileSystemStructureProvider provider = FileSystemStructureProvider.INSTANCE; |
| getFilesForProject(filesToImport, provider, importSource); |
| ImportOperation operation = new ImportOperation(project.getFullPath(), |
| importSource, |
| FileSystemStructureProvider.INSTANCE, this, filesToImport); |
| operation.setContext(getShell()); |
| operation.setOverwriteResources(true); // need to overwrite .project, .classpath files |
| operation.setCreateContainerStructure(false); |
| operation.run(monitor); |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Return a list of all files in the project |
| * |
| * @param provider |
| * The provider for the parent file |
| * @param entry |
| * The root directory of the project |
| * @return A list of all files in the project |
| */ |
| protected boolean getFilesForProject(Collection files, |
| IImportStructureProvider provider, Object entry) { |
| List children = provider.getChildren(entry); |
| Iterator childrenEnum = children.iterator(); |
| |
| while (childrenEnum.hasNext()) { |
| Object child = childrenEnum.next(); |
| // Add the child, this way we get every files except the project |
| // folder itself which we don't want |
| files.add(child); |
| // We don't have isDirectory for tar so must check for children |
| // instead |
| if (provider.isFolder(child)) |
| getFilesForProject(files, provider, child); |
| } |
| return true; |
| } |
| |
| /** |
| * Execute the passed import operation. Answer a boolean indicating success. |
| * |
| * @return true if the operation executed successfully, false otherwise |
| */ |
| protected boolean executeImportOperation(ImportOperation op) { |
| // initializeOperation(op); |
| try { |
| getContainer().run(true, true, op); |
| } catch (InterruptedException e) { |
| return false; |
| } catch (InvocationTargetException e) { |
| // displayErrorDialog(e.getTargetException()); |
| return false; |
| } |
| |
| IStatus status = op.getStatus(); |
| if (!status.isOK()) { |
| ErrorDialog.openError(getContainer().getShell(), |
| DataTransferMessages.FileImport_importProblems, null, // no |
| // special |
| // message |
| status); |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * 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( |
| IDEWorkbenchMessages.WizardDataTransfer_existsQuestion, |
| pathString); |
| |
| else |
| messageString = NLS |
| .bind( |
| IDEWorkbenchMessages.WizardDataTransfer_overwriteNameAndPathQuestion, |
| path.lastSegment(), path.removeLastSegments(1) |
| .toOSString()); |
| |
| final MessageDialog dialog = new MessageDialog(getContainer() |
| .getShell(), 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); |
| 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()]; |
| } |
| |
| /** |
| * Method used for test suite. |
| * @return Button the Import from Directory RadioButton |
| */ |
| public Button getProjectFromDirectoryRadio() { |
| return projectFromDirectoryRadio; |
| } |
| |
| /** |
| * Method used for test suite. |
| * @return CheckboxTreeViewer the viewer containing all the projects found |
| */ |
| public CheckboxTreeViewer getProjectsList() { |
| return projectsList; |
| } |
| |
| /** |
| * Retrieve all the projects in the current workspace. |
| * |
| * @return IProject[] array of IProject in the current workspace |
| */ |
| private IProject[] getProjectsInWorkspace(){ |
| if (wsProjects == null) |
| wsProjects = IDEWorkbenchPlugin.getPluginWorkspace().getRoot().getProjects(); |
| return wsProjects; |
| } |
| |
| /** |
| * Get the array of valid project records that can be imported |
| * from the source workspace or archive, selected by the user. |
| * If a project with the same name exists in both the source workspace and the |
| * current workspace, it will not appear in the list of projects to import and |
| * thus cannot be selected for import. |
| * |
| * Method declared public for test suite. |
| * |
| * @return ProjectRecord[] array of projects that can be imported into the workspace |
| */ |
| public ProjectRecord[] getValidProjects(){ |
| List validProjects = new ArrayList(); |
| for (int i = 0; i < selectedProjects.length; i++){ |
| if (!isProjectInWorkspace(selectedProjects[i].getProjectName())) |
| validProjects.add(selectedProjects[i]); |
| } |
| return (ProjectRecord[]) validProjects.toArray(new ProjectRecord[validProjects.size()]); |
| } |
| |
| /** |
| * Determine if the project with the given name is in the current workspace. |
| * |
| * @param projectName String the project name to check |
| * @return boolean true if the project with the given name is in this workspace |
| */ |
| private boolean isProjectInWorkspace(String projectName){ |
| if (projectName == null) |
| return false; |
| IProject[] workspaceProjects = getProjectsInWorkspace(); |
| for (int i = 0; i <workspaceProjects.length; i++){ |
| if (projectName.equals(workspaceProjects[i].getName())) |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Use the dialog store to restore widget values to the values that they held |
| * last time this wizard was used to completion. |
| * |
| * Method declared public only for use of tests. |
| */ |
| public void restoreWidgetValues() { |
| IDialogSettings settings = getDialogSettings(); |
| if (settings != null) { |
| // checkbox |
| copyFiles = settings.getBoolean(STORE_COPY_PROJECT_ID); |
| copyCheckbox.setSelection(copyFiles); |
| |
| // radio selection |
| boolean archiveSelected = settings.getBoolean(STORE_ARCHIVE_SELECTED); |
| projectFromDirectoryRadio.setSelection(!archiveSelected); |
| projectFromArchiveRadio.setSelection(archiveSelected); |
| if (archiveSelected) |
| archiveRadioSelected(); |
| else |
| directoryRadioSelected(); |
| } |
| } |
| |
| /** |
| * Since Finish was pressed, write widget values to the dialog store so that they |
| * will persist into the next invocation of this wizard page. |
| * |
| * Method declared public only for use of tests. |
| */ |
| public void saveWidgetValues() { |
| IDialogSettings settings = getDialogSettings(); |
| if (settings != null) { |
| settings.put(STORE_COPY_PROJECT_ID, |
| copyCheckbox.getSelection()); |
| |
| settings.put(STORE_ARCHIVE_SELECTED, |
| projectFromArchiveRadio.getSelection()); |
| } |
| } |
| |
| /** |
| * Method used for test suite. |
| * @return Button copy checkbox |
| */ |
| public Button getCopyCheckbox() { |
| return copyCheckbox; |
| } |
| } |