Java tutorial
/******************************************************************************* * 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.ui.wizards.imports; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.zip.ZipException; import java.util.zip.ZipFile; import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; 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.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.layout.PixelConverter; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.viewers.CheckStateChangedEvent; import org.eclipse.jface.viewers.CheckboxTreeViewer; import org.eclipse.jface.viewers.ICheckStateListener; import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; 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.graphics.Color; 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.StatusUtil; import org.eclipse.ui.internal.wizards.datatransfer.ArchiveFileManipulations; import org.eclipse.ui.internal.wizards.datatransfer.ILeveledImportStructureProvider; import org.eclipse.ui.internal.wizards.datatransfer.TarException; import org.eclipse.ui.internal.wizards.datatransfer.TarFile; import org.eclipse.ui.internal.wizards.datatransfer.TarLeveledStructureProvider; import org.eclipse.ui.internal.wizards.datatransfer.ZipLeveledStructureProvider; import org.eclipse.ui.statushandlers.StatusManager; import org.eclipse.rcptt.internal.ui.Messages; import org.eclipse.rcptt.internal.ui.Q7UIPlugin; @SuppressWarnings("restriction") public abstract class BaseProjectsImportPage extends WizardPage implements IOverwriteQuery { /** * The name of the folder containing metadata information for the workspace. */ public static final String METADATA_FOLDER = ".metadata"; //$NON-NLS-1$ /** * The import structure provider. * * @since 3.4 */ protected ILeveledImportStructureProvider structureProvider; /** * @since 3.5 * */ private final class ProjectLabelProvider extends LabelProvider implements IColorProvider { public String getText(Object element) { return ((ProjectRecord) element).getProjectLabel(); } public Color getBackground(Object element) { return null; } public Color getForeground(Object element) { ProjectRecord projectRecord = (ProjectRecord) element; if (projectRecord.hasConflicts) return getShell().getDisplay().getSystemColor(SWT.COLOR_GRAY); return null; } } private final static String STORE_ARCHIVE_SELECTED = "WizardProjectsImportPage.STORE_ARCHIVE_SELECTED"; //$NON-NLS-1$ private Text directoryPathField; private CheckboxTreeViewer projectsList; 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; // 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 minimize searches private String lastPath; // The last time that the file or folder at the selected path was modified // to mimize searches private long lastModified; // The initial path to set private String initialPath; public BaseProjectsImportPage() { this(null); } /** * More (many more) parameters. * * @param pageName * @param initialPath * @param currentSelection * @since 3.5 */ public BaseProjectsImportPage(String initialPath) { super("wizardExternalProjectsPage"); //$NON-NLS-1$ this.initialPath = initialPath; setPageComplete(false); setTitle(Messages.BaseProjectsImportPage_Title); setDescription(Messages.BaseProjectsImportPage_Description); } /* * (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); restoreWidgetValues(); Dialog.applyDialogFont(workArea); } /** * Create the checkbox list for the found projects. * * @param workArea */ private void createProjectsList(Composite workArea) { Label title = new Label(workArea, SWT.NONE); title.setText(Messages.BaseProjectsImportPage_ProjectsLabel); 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 gridData = new GridData(SWT.FILL, SWT.FILL, true, true); gridData.widthHint = new PixelConverter(projectsList.getControl()).convertWidthInCharsToPixels(25); gridData.heightHint = new PixelConverter(projectsList.getControl()).convertHeightInCharsToPixels(10); projectsList.getControl().setLayoutData(gridData); 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 getProjectRecords(); } /* * (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 ProjectLabelProvider()); projectsList.addCheckStateListener(new ICheckStateListener() { /* * (non-Javadoc) * * @see * org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged * (org.eclipse.jface.viewers.CheckStateChangedEvent) */ public void checkStateChanged(CheckStateChangedEvent event) { ProjectRecord element = (ProjectRecord) event.getElement(); if (element.hasConflicts) { projectsList.setChecked(element, false); } setPageComplete(projectsList.getCheckedElements().length > 0); } }); projectsList.setInput(this); projectsList.setComparator(new ViewerComparator()); 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(Messages.BaseProjectsImportPage_SelectAllButton); selectAll.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent e) { for (int i = 0; i < selectedProjects.length; i++) { if (selectedProjects[i].hasConflicts) projectsList.setChecked(selectedProjects[i], false); else projectsList.setChecked(selectedProjects[i], true); } setPageComplete(projectsList.getCheckedElements().length > 0); } }); Dialog.applyDialogFont(selectAll); setButtonLayoutData(selectAll); Button deselectAll = new Button(buttonsComposite, SWT.PUSH); deselectAll.setText(Messages.BaseProjectsImportPage_DeselectAllButton); 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]); setPageComplete(false); } }); Dialog.applyDialogFont(deselectAll); setButtonLayoutData(deselectAll); Button refresh = new Button(buttonsComposite, SWT.PUSH); refresh.setText(Messages.BaseProjectsImportPage_RefreshButton); 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(Messages.BaseProjectsImportPage_SelectRootDirRadioButton); // project location entry field this.directoryPathField = new Text(projectGroup, SWT.BORDER); GridData directoryPathData = new GridData(SWT.FILL, SWT.NONE, true, false); directoryPathData.widthHint = new PixelConverter(directoryPathField).convertWidthInCharsToPixels(25); directoryPathField.setLayoutData(directoryPathData); // browse button browseDirectoriesButton = new Button(projectGroup, SWT.PUSH); browseDirectoriesButton.setText(Messages.BaseProjectsImportPage_BrowseButton); setButtonLayoutData(browseDirectoriesButton); // new project from archive radio button projectFromArchiveRadio = new Button(projectGroup, SWT.RADIO); projectFromArchiveRadio.setText(Messages.BaseProjectsImportPage_SelectArchiveFileRagioButton); // project location entry field archivePathField = new Text(projectGroup, SWT.BORDER); GridData archivePathData = new GridData(SWT.FILL, SWT.NONE, true, false); archivePathData.widthHint = new PixelConverter(archivePathField).convertWidthInCharsToPixels(25); archivePathField.setLayoutData(archivePathData); // browse button browseArchivesButton = new Button(projectGroup, SWT.PUSH); browseArchivesButton.setText(Messages.BaseProjectsImportPage_BrowseButton); 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(); } } private void directoryRadioSelected() { if (projectFromDirectoryRadio.getSelection()) { directoryPathField.setEnabled(true); browseDirectoriesButton.setEnabled(true); archivePathField.setEnabled(false); browseArchivesButton.setEnabled(false); updateProjectsList(directoryPathField.getText()); directoryPathField.setFocus(); } } /* * (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) { // on an empty path empty selectedProjects if (path == null || path.length() == 0) { setMessage(Messages.BaseProjectsImportPage_NoDirSpecifiedMsg); selectedProjects = new ProjectRecord[0]; projectsList.refresh(true); projectsList.setCheckedElements(selectedProjects); setPageComplete(projectsList.getCheckedElements().length > 0); lastPath = path; return; } final File directory = new File(path); long modified = directory.lastModified(); if (path.equals(lastPath) && lastModified == modified) { // since the file/folder was not modified and the path did not // change, no refreshing is required return; } lastPath = path; lastModified = modified; // 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(Messages.BaseProjectsImportPage_12, 100); selectedProjects = new ProjectRecord[0]; Collection<Object> files = new ArrayList<Object>(); monitor.worked(10); if (!dirSelected && ArchiveFileManipulations.isTarFile(path)) { TarFile sourceTarFile = getSpecifiedTarSourceFile(path); if (sourceTarFile == null) { return; } structureProvider = new TarLeveledStructureProvider(sourceTarFile); Object child = structureProvider.getRoot(); if (!collectProjectFilesFromProvider(files, child, 0, monitor)) { return; } Iterator<Object> filesIterator = files.iterator(); selectedProjects = new ProjectRecord[files.size()]; int index = 0; monitor.worked(50); monitor.subTask(Messages.BaseProjectsImportPage_13); while (filesIterator.hasNext()) { selectedProjects[index++] = (ProjectRecord) filesIterator.next(); } } else if (!dirSelected && ArchiveFileManipulations.isZipFile(path)) { ZipFile sourceFile = getSpecifiedZipSourceFile(path); if (sourceFile == null) { return; } structureProvider = new ZipLeveledStructureProvider(sourceFile); Object child = structureProvider.getRoot(); if (!collectProjectFilesFromProvider(files, child, 0, monitor)) { return; } Iterator<Object> filesIterator = files.iterator(); selectedProjects = new ProjectRecord[files.size()]; int index = 0; monitor.worked(50); monitor.subTask(Messages.BaseProjectsImportPage_14); while (filesIterator.hasNext()) { selectedProjects[index++] = (ProjectRecord) filesIterator.next(); } } else if (dirSelected && directory.isDirectory()) { if (!collectProjectFilesFromDirectory(files, directory, null, monitor)) { return; } Iterator<Object> filesIterator = files.iterator(); selectedProjects = new ProjectRecord[files.size()]; int index = 0; monitor.worked(50); monitor.subTask(Messages.BaseProjectsImportPage_15); while (filesIterator.hasNext()) { File file = (File) filesIterator.next(); selectedProjects[index] = new ProjectRecord(file); index++; } } else { monitor.worked(60); } monitor.done(); } }); } catch (InvocationTargetException e) { Q7UIPlugin.log(e); } catch (InterruptedException e) { // Nothing to do if the user interrupts. } projectsList.refresh(true); ProjectRecord[] projects = getProjectRecords(); boolean displayWarning = false; for (int i = 0; i < projects.length; i++) { if (projects[i].hasConflicts) { displayWarning = true; projectsList.setGrayed(projects[i], true); } else { projectsList.setChecked(projects[i], true); } } if (displayWarning) { setMessage(Messages.BaseProjectsImportPage_16, WARNING); } else { setMessage(Messages.BaseProjectsImportPage_17); } setPageComplete(projectsList.getCheckedElements().length > 0); if (selectedProjects.length == 0) { setMessage(Messages.BaseProjectsImportPage_18, WARNING); } } /** * 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(Messages.BaseProjectsImportPage_19); } catch (IOException e) { displayErrorDialog(Messages.BaseProjectsImportPage_20); } 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. */ private TarFile getSpecifiedTarSourceFile(String fileName) { if (fileName.length() == 0) { return null; } try { return new TarFile(fileName); } catch (TarException e) { displayErrorDialog(Messages.BaseProjectsImportPage_21); } catch (IOException e) { displayErrorDialog(Messages.BaseProjectsImportPage_22); } archivePathField.setFocus(); return null; } /** * 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); } /** * Get the title for an error dialog. Subclasses should override. */ protected String getErrorDialogTitle() { return Messages.BaseProjectsImportPage_23; } /** * Collect the list of .project files that are under directory into files. * * @param files * @param directory * @param directoriesVisited * Set of canonical paths of directories, used as recursion guard * @param monitor * The monitor to report to * @return boolean <code>true</code> if the operation was completed. */ private boolean collectProjectFilesFromDirectory(Collection<Object> files, File directory, Set<String> directoriesVisited, IProgressMonitor monitor) { if (monitor.isCanceled()) { return false; } monitor.subTask(NLS.bind(Messages.BaseProjectsImportPage_24, directory.getPath())); File[] contents = directory.listFiles(); if (contents == null) return false; // Initialize recursion guard for recursive symbolic links if (directoriesVisited == null) { directoriesVisited = new HashSet<String>(); try { directoriesVisited.add(directory.getCanonicalPath()); } catch (IOException exception) { StatusManager.getManager() .handle(StatusUtil.newStatus(IStatus.ERROR, exception.getLocalizedMessage(), exception)); } } // 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(METADATA_FOLDER)) { try { String canonicalPath = contents[i].getCanonicalPath(); if (!directoriesVisited.add(canonicalPath)) { // already been here --> do not recurse continue; } } catch (IOException exception) { StatusManager.getManager().handle( StatusUtil.newStatus(IStatus.ERROR, exception.getLocalizedMessage(), exception)); } collectProjectFilesFromDirectory(files, contents[i], directoriesVisited, 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<Object> files, Object entry, int level, IProgressMonitor monitor) { if (monitor.isCanceled()) { return false; } monitor.subTask(NLS.bind(Messages.BaseProjectsImportPage_25, structureProvider.getLabel(entry))); List<?> children = structureProvider.getChildren(entry); if (children == null) { children = new ArrayList<Object>(1); } Iterator<?> childrenEnum = children.iterator(); while (childrenEnum.hasNext()) { Object child = childrenEnum.next(); if (structureProvider.isFolder(child)) { collectProjectFilesFromProvider(files, child, level + 1, monitor); } String elementLabel = structureProvider.getLabel(child); if (elementLabel.equals(IProjectDescription.DESCRIPTION_FILE_NAME)) { files.add(new ProjectRecord(structureProvider, child, entry, level)); } } return true; } /** * The browse button has been selected. Select the location. */ protected void handleLocationDirectoryButtonPressed() { DirectoryDialog dialog = new DirectoryDialog(directoryPathField.getShell(), SWT.SHEET); dialog.setMessage(Messages.BaseProjectsImportPage_26); String dirName = directoryPathField.getText().trim(); if (dirName.length() == 0) { dirName = previouslyBrowsedDirectory; } if (dirName.length() == 0) { dialog.setFilterPath(ResourcesPlugin.getWorkspace().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(), SWT.SHEET); dialog.setFilterExtensions(FILE_IMPORT_MASK); dialog.setText(Messages.BaseProjectsImportPage_27); String fileName = archivePathField.getText().trim(); if (fileName.length() == 0) { fileName = previouslyBrowsedArchive; } if (fileName.length() == 0) { dialog.setFilterPath(ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString()); } else { File path = new File(fileName).getParentFile(); if (path != null && path.exists()) { dialog.setFilterPath(path.toString()); } } 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 = Messages.BaseProjectsImportPage_28; IStatus status; if (t instanceof CoreException) { status = ((CoreException) t).getStatus(); } else { status = new Status(IStatus.ERROR, Q7UIPlugin.PLUGIN_ID, 1, message, t); } ErrorDialog.openError(getShell(), message, null, status); return false; } ArchiveFileManipulations.closeStructureProvider(structureProvider, getShell()); return true; } /** * Performs clean-up if the user cancels the wizard without doing anything */ public void performCancel() { ArchiveFileManipulations.closeStructureProvider(structureProvider, getShell()); } /** * Create the project described in record. If it is successful return true. * * @param record * @return boolean <code>true</code> if successful * @throws InterruptedException */ protected abstract boolean createExistingProject(final ProjectRecord record, IProgressMonitor monitor) throws InvocationTargetException, InterruptedException; /** * 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(Messages.BaseProjectsImportPage_29, pathString); } else { messageString = NLS.bind(Messages.BaseProjectsImportPage_30, path.lastSegment(), path.removeLastSegments(1).toOSString()); } final MessageDialog dialog = new MessageDialog(getContainer().getShell(), Messages.BaseProjectsImportPage_31, 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()]; } /** * 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; } /** * Get the array of 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, then * the hasConflicts flag would be set on that project record. * * Method declared public for test suite. * * @return ProjectRecord[] array of projects that can be imported into the * workspace */ public ProjectRecord[] getProjectRecords() { List<ProjectRecord> projectRecords = new ArrayList<ProjectRecord>(); for (int i = 0; i < selectedProjects.length; i++) { if (isProjectExists(selectedProjects[i].getProjectName())) { selectedProjects[i].hasConflicts = true; } projectRecords.add(selectedProjects[i]); } return projectRecords.toArray(new ProjectRecord[projectRecords.size()]); } /** * Determine if the project with the given name exists. * * @param projectName * String the project name to check * @return boolean true if the project with the given name exists */ protected abstract boolean isProjectExists(String projectName); /** * Use the dialog store to restore widget values to the values that they * held last time this wizard was used to completion, or alternatively, if * an initial path is specified, use it to select values. * * Method declared public only for use of tests. */ public void restoreWidgetValues() { // First, check to see if we have resore settings, and // take care of the checkbox IDialogSettings settings = getDialogSettings(); if (settings != null) { } // Second, check to see if we don't have an initial path, // and if we do have restore settings. If so, set the // radio selection properly to restore settings if (initialPath == null && settings != null) { // radio selection boolean archiveSelected = settings.getBoolean(STORE_ARCHIVE_SELECTED); projectFromDirectoryRadio.setSelection(!archiveSelected); projectFromArchiveRadio.setSelection(archiveSelected); if (archiveSelected) { archiveRadioSelected(); } else { directoryRadioSelected(); } } // Third, if we do have an initial path, set the proper // path and radio buttons to the initial value. Move // cursor to the end of the path so user can see the // most relevant part (directory / archive name) else if (initialPath != null) { boolean dir = new File(initialPath).isDirectory(); projectFromDirectoryRadio.setSelection(dir); projectFromArchiveRadio.setSelection(!dir); if (dir) { directoryPathField.setText(initialPath); directoryPathField.setSelection(initialPath.length()); directoryRadioSelected(); } else { archivePathField.setText(initialPath); archivePathField.setSelection(initialPath.length()); archiveRadioSelected(); } } } /** * 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_ARCHIVE_SELECTED, projectFromArchiveRadio.getSelection()); } } }