org.eclipse.ptp.internal.rdt.sync.ui.wizards.SyncMainWizardPage.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ptp.internal.rdt.sync.ui.wizards.SyncMainWizardPage.java

Source

/*******************************************************************************
 * Copyright (c) 2011 Oak Ridge National Laboratory 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:
 *    John Eblen - initial implementation
 *******************************************************************************/
package org.eclipse.ptp.internal.rdt.sync.ui.wizards;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IMessageProvider;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ptp.internal.rdt.sync.ui.RDTSyncUIPlugin;
import org.eclipse.ptp.internal.rdt.sync.ui.SynchronizeWizardExtensionRegistry;
import org.eclipse.ptp.internal.rdt.sync.ui.messages.Messages;
import org.eclipse.ptp.rdt.sync.core.AbstractSyncFileFilter;
import org.eclipse.ptp.rdt.sync.core.resources.RemoteSyncNature;
import org.eclipse.ptp.rdt.sync.ui.ISynchronizeParticipant;
import org.eclipse.ptp.rdt.sync.ui.ISynchronizeWizardExtension;
import org.eclipse.ptp.rdt.sync.ui.widgets.SyncProjectWidget;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.WizardNewProjectCreationPage;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.IIDEHelpContextIds;

/**
 * Main wizard page for creating new synchronized projects. All elements needed for a synchronized project are configured here. This
 * includes: 1) Project name and workspace location 2) Remote connection and directory 3) Project type 4) Local and remote
 * toolchains
 * 
 * Since this wizard page's operation differs greatly from a normal CDT wizard page, this class simply reimplements (overrides) all
 * functionality in the two immediate superclasses (CDTMainWizardPage and WizardNewProjectCreationPage) but borrows much of the code
 * from those two classes. Thus, except for very basic functionality, such as jface methods, this class is self-contained.
 */
public class SyncMainWizardPage extends WizardNewProjectCreationPage {
    private static final int SIZING_TEXT_FIELD_WIDTH = 250;
    private static final String EMPTY_STRING = ""; //$NON-NLS-1$
    private static final String syncConfigSetKey = "sync-config-set"; //$NON-NLS-1$
    private static final String projectNameKey = "project-name"; //$NON-NLS-1$

    private String message;
    private int messageType = IMessageProvider.NONE;
    private String errorMessage;

    private Text fProjectNameText;
    private Combo fProjectSelectionCombo;
    private SyncProjectWidget fSyncWidget;
    private ISynchronizeWizardExtension extension;
    private IWizardPage extWizardPage;
    private final boolean isNewProject;

    /**
     * Creates a new wizard page for creating a new sync project.
     * 
     * @param pageName
     *            the name of this page
     * @return the page
     */
    public static SyncMainWizardPage newProjectPage(String pageName) {
        return new SyncMainWizardPage(pageName, true);
    }

    /**
     * Creates a new wizard page for converting an existing project to a sync project.
     * 
     * @param pageName
     *            the name of this page
     * @return the page
     */
    public static SyncMainWizardPage convertProjectPage(String pageName) {
        return new SyncMainWizardPage(pageName, false);
    }

    /**
     * Private constructor. Clients should use provided static factory methods.
     * 
     * @param pageName
     *            the name of this page
     * @param newProjectFlag
     *            whether a page for a new project or to convert an existing project
     */
    private SyncMainWizardPage(String pageName, boolean isForNewProject) {
        super(pageName);
        isNewProject = isForNewProject;
        setPageComplete(false);
    }

    /**
     * (non-Javadoc) Method declared on IDialogPage.
     */
    @Override
    public void createControl(Composite parent) {
        Composite composite = new Composite(parent, SWT.NULL);

        initializeDialogUnits(parent);
        PlatformUI.getWorkbench().getHelpSystem().setHelp(composite, IIDEHelpContextIds.NEW_PROJECT_WIZARD_PAGE);

        composite.setLayout(new GridLayout());
        composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        setControl(composite);

        if (isNewProject) {
            createProjectInfoGroupForNewProject(composite);
        } else {
            createProjectInfoGroupForExistingProject(composite);
        }

        if (isNewProject) {
            fSyncWidget = SyncProjectWidget.newProjectWidget(composite, SWT.NONE, getWizard().getContainer());
        } else {
            fSyncWidget = SyncProjectWidget.convertProjectWidget(composite, SWT.NONE, getWizard().getContainer());
        }
        fSyncWidget.setLayoutData(new GridData(GridData.FILL_BOTH));
        fSyncWidget.addListener(SWT.Modify, new Listener() {
            @Override
            public void handleEvent(Event e) {
                update();
                getWizard().getContainer().updateMessage();
            }
        });

        setPageComplete(false);
        errorMessage = null;
        message = null;
        messageType = IMessageProvider.NONE;
        Dialog.applyDialogFont(composite);
    }

    /**
     * Creates controls for selecting an existing project
     * 
     * @param parent
     *            the parent composite
     */
    private final void createProjectInfoGroupForExistingProject(Composite parent) {
        Group localGroup = new Group(parent, SWT.SHADOW_ETCHED_IN);
        localGroup.setText(Messages.SyncProjectWidget_Project_to_convert);
        localGroup.setLayout(new GridLayout(2, false));
        localGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));

        Label label = new Label(localGroup, SWT.NONE);
        label.setText(Messages.SyncProjectWidget_Project_to_convert_label);
        label.setFont(parent.getFont());

        fProjectSelectionCombo = new Combo(localGroup, SWT.READ_ONLY);
        this.populateProjectCombo();
        fProjectSelectionCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
        fProjectSelectionCombo.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetDefaultSelected(SelectionEvent arg0) {
                // nothing to do
            }

            @Override
            public void widgetSelected(SelectionEvent arg0) {
                if (fSyncWidget != null && (validateProjectName() || getProjectName().equals(EMPTY_STRING))) {
                    fSyncWidget.setProjectName(getProjectName());
                    handleProjectSelected(getProject());
                }
                update();
                getWizard().getContainer().updateMessage();
            }
        });
    }

    /**
     * Creates controls for entering a new project name
     * 
     * @param parent
     *            the parent composite
     */
    private final void createProjectInfoGroupForNewProject(Composite parent) {
        Composite projectGroup = new Composite(parent, SWT.NONE);
        GridLayout layout = new GridLayout();
        layout.numColumns = 2;
        projectGroup.setLayout(layout);
        projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        // new project name label
        Label projectNameLabel = new Label(projectGroup, SWT.NONE);
        projectNameLabel.setText(Messages.SyncMainWizardPage_Project_name);
        projectNameLabel.setFont(parent.getFont());

        // new project name entry field
        fProjectNameText = new Text(projectGroup, SWT.BORDER);
        GridData nameData = new GridData(GridData.FILL_HORIZONTAL);
        nameData.widthHint = SIZING_TEXT_FIELD_WIDTH;
        fProjectNameText.setLayoutData(nameData);
        fProjectNameText.setFont(parent.getFont());

        fProjectNameText.addListener(SWT.Modify, new Listener() {
            @Override
            public void handleEvent(Event e) {
                if (fSyncWidget != null && (validateProjectName() || getProjectName().equals(EMPTY_STRING))) {
                    fSyncWidget.setProjectName(getProjectName());
                }
                update();
                getWizard().getContainer().updateMessage();
            }
        });
    }

    /**
     * Returns the currently selected project.
     * This only works for project conversion. For new projects, this function always returns null.
     * @return project
     */
    public IProject getProject() {
        if (isNewProject) {
            return null;
        } else {
            return ResourcesPlugin.getWorkspace().getRoot().getProject(getProjectName());
        }
    }

    /**
     * Returns the current project name specified by the user
     * 
     * @return the project name
     */
    @Override
    public String getProjectName() {
        if (isNewProject) {
            if (fProjectNameText == null) {
                return EMPTY_STRING;
            } else {
                return fProjectNameText.getText().trim();
            }
        } else {
            return fProjectSelectionCombo.getText();
        }
    }

    /**
     * Get the synchronize filter specified for the project
     * 
     * @return sync filter
     */
    public AbstractSyncFileFilter getCustomFileFilter() {
        return fSyncWidget.getCustomFileFilter();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.IDialogPage#getErrorMessage()
     */
    @Override
    public String getErrorMessage() {
        update(); // Necessary to update message when participant changes
        return errorMessage;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.dialogs.WizardNewProjectCreationPage#getLocationPath()
     */
    @Override
    public IPath getLocationPath() {
        return new Path(fSyncWidget.getProjectLocalLocation());
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.dialogs.WizardNewProjectCreationPage#getLocationURI()
     */
    @Override
    public URI getLocationURI() {
        try {
            return new URI("file://" + getLocationPath().toString()); //$NON-NLS-1$
        } catch (URISyntaxException e) {
            RDTSyncUIPlugin.log(e);
            return null;
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.IDialogPage#getMessage()
     */
    @Override
    public String getMessage() {
        update(); // Necessary to update message when participant changes
        return message;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.jface.dialogs.IDialogPage#getMessageType()
     */
    @Override
    public int getMessageType() {
        update(); // Necessary to update message when participant changes
        return messageType;
    }

    /*
     * (non-Javadoc)
     * @see org.eclipse.jface.wizard.WizardPage#getNextPage()
     */
    @Override
    public IWizardPage getNextPage() {
        return extWizardPage;
    }

    private String[] getSyncConfigNames() {
        ArrayList<String> configNames = new ArrayList<String>();
        configNames.add("Local"); //$NON-NLS-1$
        String remoteConfigName = fSyncWidget.getSyncConfigName();
        if (remoteConfigName != null) {
            configNames.add(remoteConfigName);
        }
        return configNames.toArray(new String[0]);
    }

    /**
     * Get the synchronize participant, which contains remote information
     * 
     * @return participant
     */
    public ISynchronizeParticipant getSynchronizeParticipant() {
        return fSyncWidget.getSynchronizeParticipant();
    }

    /**
     * Get the extension wizard page if any
     * @return page or null if no extension page
     */
    public ISynchronizeWizardExtension getExtension() {
        return extension;
    }

    /**
     * Add any extended wizard pages for the given project type
     * @param project
     */
    private void handleProjectSelected(IProject project) {
        ISynchronizeWizardExtension ext = SynchronizeWizardExtensionRegistry
                .getSynchronizeWizardExtensionForProject(project);
        if (ext == null) {
            extWizardPage = null;
        } else {
            extension = ext;
            extWizardPage = ext.createConvertProjectWizardPage();
            IWizard wizard = getWizard();
            assert (wizard instanceof Wizard);
            ((Wizard) wizard).addPage(extWizardPage);
        }
    }

    private void populateProjectCombo() {
        IProject[] allProjects = ResourcesPlugin.getWorkspace().getRoot().getProjects();
        for (IProject p : allProjects) {
            if ((p.isOpen()) && (!RemoteSyncNature.hasNature(p))) {
                fProjectSelectionCombo.add(p.getName());
            }
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.dialogs.WizardNewProjectCreationPage#setInitialProjectName(java.lang.String)
     */
    @Override
    public void setInitialProjectName(String name) {
        // Not possible
    }

    /*
     * see @DialogPage.setVisible(boolean)
     */
    @Override
    public void setVisible(boolean visible) {
        this.getControl().setVisible(visible);
        if (visible) {
            if (isNewProject) {
                fProjectNameText.setFocus();
            } else {
                fProjectSelectionCombo.setFocus();
            }
        }
    }

    /**
     * Numerous tasks to refresh the page:
     * 1) Validate the page, which updates messages
     * 2) Set whether or not page is complete
     * 3) Store data to sync cache for other wizard pages
     */
    private void update() {
        boolean isValid = validatePage();
        setPageComplete(isValid);
        if (isValid) {
            Set<String> configNamesSet = new HashSet<String>();
            for (String name : this.getSyncConfigNames()) {
                configNamesSet.add(name);
            }
            SyncWizardDataCache.setProperty(projectNameKey, getProjectName());
            SyncWizardDataCache.setMultiValueProperty(syncConfigSetKey, configNamesSet);
        }
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.dialogs.WizardNewProjectCreationPage#useDefaults()
     */
    @Override
    public boolean useDefaults() {
        return fSyncWidget.useDefaults();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.ui.dialogs.WizardNewProjectCreationPage#validatePage()
     */
    @Override
    protected boolean validatePage() {
        message = null;
        messageType = IMessageProvider.NONE;
        errorMessage = null;
        if (!validateProjectName()) {
            return false;
        }
        if (!fSyncWidget.isPageComplete()) {
            message = fSyncWidget.getMessage();
            messageType = fSyncWidget.getMessageType();
            errorMessage = fSyncWidget.getErrorMessage();
            return false;
        }
        return true;
    }

    /**
     * @return
     */
    private boolean validateProjectName() {
        // Check if name is empty
        String projectFieldContents = getProjectName();
        if (projectFieldContents.equals(EMPTY_STRING)) {
            message = Messages.SyncMainWizardPage_Project_name_must_be_specified;
            messageType = IMessageProvider.NONE;
            return false;
        }

        // General name check
        IWorkspace workspace = IDEWorkbenchPlugin.getPluginWorkspace();
        IStatus nameStatus = workspace.validateName(projectFieldContents, IResource.PROJECT);
        if (!nameStatus.isOK()) {
            errorMessage = nameStatus.getMessage();
            return false;
        }

        // Do not allow # in the name
        if (getProjectName().indexOf('#') >= 0) {
            errorMessage = Messages.SyncMainWizardPage_Project_name_cannot_contain_hash;
            return false;
        }

        return true;
    }
}