com.aptana.ide.core.ui.wizards.WizardFolderImportPage.java Source code

Java tutorial

Introduction

Here is the source code for com.aptana.ide.core.ui.wizards.WizardFolderImportPage.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package com.aptana.ide.core.ui.wizards;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceStatus;
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.SubProgressMonitor;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.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.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.wizards.datatransfer.DataTransferMessages;
import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;

/**
 * The WizardProjectsImportPage is the page that allows the user to import projects from a particular location.
 */
public class WizardFolderImportPage extends WizardPage implements IOverwriteQuery {
    /**
     * An internal class for projects
     * 
     * @author Ingo Muschenetz
     */
    private static 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, String name) {
            projectSystemFile = file;
            setProjectName(name);
        }

        /**
         * Set the name of the project based on the projectFile.
         */
        private void setProjectName(String name) {
            projectName = name;
        }

        /**
         * Get the name of the project
         * 
         * @return String
         */
        public String getProjectName() {
            return projectName;
        }
    }

    private Text directoryPathField;
    private Text projectNameField;
    private String directoryPath;
    private ModifyListener modifyListener;
    private HashSet<String> projectsNames;

    // 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$

    private Button browseDirectoriesButton;

    /**
     * Creates a new project creation wizard page.
     */
    public WizardFolderImportPage() {
        this("wizardExternalProjectsPage"); //$NON-NLS-1$
    }

    /**
     * Create a new instance of the receiver.
     * 
     * @param pageName
     */
    public WizardFolderImportPage(String pageName) {
        super(pageName);
        setPageComplete(false);
        setTitle(Messages.WizardFolderImportPage_ExistingFolderAsNewProject);
    }

    /**
     * Create a new instance of the receiver.
     * 
     * @param pageName
     * @param title
     * @param titleImage
     */
    public WizardFolderImportPage(String pageName, String title, ImageDescriptor titleImage) {
        super(pageName, title, titleImage);
    }

    /**
     * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite)
     */
    public void createControl(Composite parent) {
        // Collect the existing project names to avoid conflicts.
        IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
        projectsNames = new HashSet<String>();
        for (IProject project : projects) {
            projectsNames.add(project.getName());
        }
        modifyListener = new InputModifyListener();
        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);
        if (directoryPath != null) {
            directoryPathField.setText(directoryPath);
            setProjectName();
            setPageComplete(true);
        }
        Dialog.applyDialogFont(workArea);
        setPageComplete(validate());
    }

    /**
     * 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));

        // project location entry field
        Label l = new Label(projectGroup, SWT.NONE);
        l.setText(Messages.WizardFolderImportPage_SelectFolder);
        this.directoryPathField = new Text(projectGroup, SWT.BORDER);
        this.directoryPathField.addModifyListener(modifyListener);
        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);

        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();
            }

        });

        // project name entry field
        l = new Label(projectGroup, SWT.NONE);
        l.setText(Messages.WizardFolderImportPage_ProjectName);
        projectNameField = new Text(projectGroup, SWT.BORDER);
        projectNameField.addModifyListener(modifyListener);
        projectNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.GRAB_HORIZONTAL));
    }

    /**
     * Input validation.
     */
    protected boolean validate() {
        if (directoryPathField.getText().trim().length() == 0) {
            setErrorMessage("Please select a folder");
            return false;
        } else if (!new File(directoryPathField.getText()).exists()) {
            setErrorMessage("The selected folder does not exist");
            return false;
        } else {
            String name = projectNameField.getText().trim();
            if (name.length() == 0) {
                setErrorMessage("Please provide a project name");
                return false;
            }
            if (projectsNames.contains(name)) {
                setErrorMessage("A project with this name already exists");
                return false;
            }
        }
        setErrorMessage(null);
        return true;
    }

    /**
     * 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.
     * 
     * @return String
     */
    protected String getErrorDialogTitle() {
        return IDEWorkbenchMessages.WizardExportPage_internalErrorTitle;
    }

    /**
     * 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);
        }

        setProjectName();

        setPageComplete(directoryPathField.getText() != null);

    }

    private void setProjectName() {
        if (directoryPathField.getText() != null) {
            IPath path = new Path(directoryPathField.getText());
            if (path.segmentCount() > 0) {
                projectNameField.setText(path.lastSegment());
            }
        }
    }

    /**
     * Create and returns the project. In case the operation fails, <code>null</code> is returned.
     * 
     * @return a new project (or null if failed)
     */
    public IProject createProject() {
        String projectPath = directoryPathField.getText();
        File project = new File(projectPath);
        if (project.exists()) {
            ProjectRecord pr = new ProjectRecord(project, projectNameField.getText());
            return createExistingProject(pr);
        }
        return null;
    }

    /**
     * Create the selected projects
     * 
     * @return boolean <code>true</code> if all project creations were successful.
     * @deprecated since Aptana Studio 1.2.3. Use {@link #createProject()}
     */
    public boolean createProjects() {
        return createProject() != null;
    }

    /**
     * Create the project described in record.
     * 
     * @param record
     * @return an new project if successful, null if failed.
     */
    private IProject createExistingProject(final ProjectRecord record) {

        String projectName = record.getProjectName();
        final IWorkspace workspace = ResourcesPlugin.getWorkspace();
        final IProject project = workspace.getRoot().getProject(projectName);
        if (record.description == null) {
            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);
        }

        WorkspaceModifyOperation op = new WorkspaceModifyOperation() {
            protected void execute(IProgressMonitor monitor) throws CoreException {
                monitor.beginTask("", 2000); //$NON-NLS-1$
                project.create(record.description, new SubProgressMonitor(monitor, 1000));
                if (monitor.isCanceled()) {
                    throw new OperationCanceledException();
                }
                project.open(IResource.BACKGROUND_REFRESH, new SubProgressMonitor(monitor, 1000));
            }
        };
        // run the new project creation operation
        try {
            getContainer().run(true, true, op);
        } catch (InterruptedException e) {
            return null;
        } catch (InvocationTargetException e) {
            // ie.- one of the steps resulted in a core exception
            Throwable t = e.getTargetException();
            if (((CoreException) t).getStatus().getCode() == IResourceStatus.CASE_VARIANT_EXISTS) {
                MessageDialog.openError(getShell(),
                        DataTransferMessages.WizardExternalProjectImportPage_errorMessage,
                        NLS.bind(DataTransferMessages.WizardExternalProjectImportPage_caseVariantExistsError,
                                record.description.getName()));
            } else {
                ErrorDialog.openError(getShell(), DataTransferMessages.WizardExternalProjectImportPage_errorMessage,
                        ((CoreException) t).getLocalizedMessage(), ((CoreException) t).getStatus());
            }
            return null;
        }

        try {
            showView("com.aptana.ide.ui.io.fileExplorerView", PlatformUI.getWorkbench().getActiveWorkbenchWindow()); //$NON-NLS-1$
        } catch (PartInitException e) {
        }

        BasicNewResourceWizard.selectAndReveal(project, PlatformUI.getWorkbench().getActiveWorkbenchWindow());
        return project;
    }

    /**
     * Return a list of all files in the project
     * 
     * @param files
     * @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.
     * 
     * @param op
     * @return boolean
     */
    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()];
    }

    /**
     * @return Returns the directoryPathField.
     */
    public String getDirectoryPath() {
        return directoryPath;
    }

    /**
     * @param directoryPath
     *            The directoryPathField to set.
     */
    public void setDirectoryPath(String directoryPath) {
        this.directoryPath = directoryPath;
        if (directoryPathField != null) {
            directoryPathField.setText(directoryPath);
            setProjectName();
            setPageComplete(true);
        }
    }

    /**
     * Show a specific view
     * 
     * @param viewId
     *            The ID of the view to show
     * @param window
     *            The active window
     * @return The IViewPart of the activated view.
     * @throws PartInitException
     */
    public static IViewPart showView(String viewId, IWorkbenchWindow window) throws PartInitException {
        IWorkbenchPage page = window.getActivePage();
        if (page != null) {
            return page.showView(viewId);
        }
        return null;
    }

    private class InputModifyListener implements ModifyListener {
        public void modifyText(ModifyEvent e) {
            setPageComplete(validate());
        }
    }
}