com.vectrace.MercurialEclipse.wizards.ConfigurationWizardMainPage.java Source code

Java tutorial

Introduction

Here is the source code for com.vectrace.MercurialEclipse.wizards.ConfigurationWizardMainPage.java

Source

/*******************************************************************************
 * Copyright (c) 2003, 2006 Subclipse project 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:
 *     Subclipse project committers - initial API and implementation
 *     Bastian Doetsch              - adaptions&additions
 *     Adam Berkes (Intland)        - repository location handling
 *     Zsolt Koppany (Intland)      - bug fixes
 *     Andrei Loskutov   - bug fixes
 ******************************************************************************/
package com.vectrace.MercurialEclipse.wizards;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
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.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

import com.vectrace.MercurialEclipse.MercurialEclipsePlugin;
import com.vectrace.MercurialEclipse.commands.HgPathsClient;
import com.vectrace.MercurialEclipse.exception.HgException;
import com.vectrace.MercurialEclipse.model.HgRoot;
import com.vectrace.MercurialEclipse.model.IHgRepositoryLocation;
import com.vectrace.MercurialEclipse.storage.HgRepositoryLocationManager;
import com.vectrace.MercurialEclipse.storage.HgRepositoryLocationParser;
import com.vectrace.MercurialEclipse.ui.SWTWidgetHelper;

/**
 * Wizard page for entering information about a Hg repository location. This
 * wizard can be initialized using setProperties or using setDialogSettings
 */
public class ConfigurationWizardMainPage extends HgWizardPage {

    private static final String REPO_SEPARATOR = "----------------";
    public static final String PROP_PASSWORD = "password";
    public static final String PROP_USER = "user";
    public static final String PROP_URL = "url";

    private static final int COMBO_HISTORY_LENGTH = 10;

    /**  Dialog store id constant */
    private static final String STORE_USERNAME_ID = "ConfigurationWizardMainPage.STORE_USERNAME_ID"; //$NON-NLS-1$

    private boolean showCredentials;
    private boolean showBundleButton;

    private Combo userCombo;
    protected Text passwordText;

    /** url of the repository we want to add */
    private Combo urlCombo;

    /** local repositories button */
    private Button browseButton;

    private Button browseFileButton;

    private IHgRepositoryLocation initialRepo;
    private Composite authComposite;
    private HgRoot hgRoot;
    private Group urlGroup;

    /**
     * @param pageName
     *            the name of the page
     * @param title
     *            the title of the page
     * @param titleImage
     *            the image for the page
     */
    public ConfigurationWizardMainPage(String pageName, String title, ImageDescriptor titleImage) {
        super(pageName, title, titleImage);
    }

    /**
     * Adds an entry to a history, while taking care of duplicate history items
     * and excessively long histories. The assumption is made that all histories
     * should be of length
     * <code>ConfigurationWizardMainPage.COMBO_HISTORY_LENGTH</code>.
     *
     * @param history
     *            the current history
     * @param newEntry
     *            the entry to add to the history
     * @param limitHistory
     *            number of max entries, -1 if no limit
     * @return the history with the new entry appended
     */
    private static String[] addToHistory(String[] history, String newEntry, int limitHistory) {
        ArrayList<String> list = new ArrayList<String>();
        if (history != null) {
            list.addAll(Arrays.asList(history));
        }

        list.remove(newEntry);
        list.add(0, newEntry);

        // since only one new item was added, we can be over the limit
        // by at most one item
        if (list.size() > COMBO_HISTORY_LENGTH && limitHistory > 0) {
            list.remove(COMBO_HISTORY_LENGTH);
        }

        return list.toArray(new String[list.size()]);
    }

    /**
     * Creates the UI part of the page.
     *
     * @param parent
     *            the parent of the created widgets
     */
    public void createControl(Composite parent) {
        Composite composite = SWTWidgetHelper.createComposite(parent, 1);

        Listener listener = new Listener() {
            public void handleEvent(Event event) {
                urlChanged();
            }
        };

        createUrlControl(composite, listener);

        if (showCredentials) {
            createAuthenticationControl(composite);
        }
        setControl(composite);
        urlCombo.setFocus();

        initializeValues();
        boolean ok = validateFields();
        setPageComplete(ok);
        if (ok) {
            setErrorMessage(null);
        }
    }

    private void createUrlControl(Composite composite, final Listener listener) {
        Composite urlComposite = SWTWidgetHelper.createComposite(composite, 4);

        urlGroup = SWTWidgetHelper.createGroup(urlComposite,
                Messages.getString("ConfigurationWizardMainPage.urlGroup.title"), 4, //$NON-NLS-1$
                GridData.FILL_HORIZONTAL);

        // repository Url
        SWTWidgetHelper.createLabel(urlGroup, Messages.getString("ConfigurationWizardMainPage.urlLabel.text")); //$NON-NLS-1$
        urlCombo = createEditableCombo(urlGroup);
        urlCombo.addListener(SWT.Modify, listener);

        browseButton = SWTWidgetHelper.createPushButton(urlGroup,
                Messages.getString("ConfigurationWizardMainPage.browseButton.text"), 1); //$NON-NLS-1$
        browseButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                DirectoryDialog dialog = new DirectoryDialog(getShell());
                File localDirectory = getLocalDirectory(getUrlText());
                if (localDirectory != null) {
                    dialog.setFilterPath(localDirectory.getAbsolutePath());
                }
                dialog.setMessage(Messages.getString("ConfigurationWizardMainPage.dialog.message")); //$NON-NLS-1$
                String dir = dialog.open();
                if (dir != null) {
                    dir = dir.trim();
                    getUrlCombo().setText(dir);
                }
            }
        });

        if (showBundleButton) {
            browseFileButton = SWTWidgetHelper.createPushButton(urlGroup,
                    Messages.getString("PullPage.browseFileButton.text"), 1); //$NON-NLS-1$

            browseFileButton.addSelectionListener(new SelectionAdapter() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    FileDialog dialog = new FileDialog(getShell());
                    dialog.setText(Messages.getString("PullPage.bundleDialog.text")); //$NON-NLS-1$
                    String file = dialog.open();
                    if (file != null) {
                        getUrlCombo().setText(file);
                    }
                }
            });
        }

        urlCombo.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {

                IHgRepositoryLocation repo;
                try {
                    // note that repo will not be null, will be blank
                    // repo if no existing one was found
                    repo = MercurialEclipsePlugin.getRepoManager().getRepoLocation(getUrlText());
                } catch (HgException e1) {
                    // Lookup obviously failed, but verification will pick this error up later
                    // no need to report typing error
                    return;
                }
                if (getUserCombo() != null) {
                    String user = repo.getUser();
                    if (user != null && user.length() != 0) {
                        getUserCombo().setText(user);
                    } else {
                        getUserCombo().setText("");
                    }
                }
                if (getPasswordText() != null) {
                    String password = repo.getPassword();
                    if (password != null && password.length() != 0) {
                        passwordText.setText(password);
                    } else {
                        passwordText.setText("");
                    }
                }
            }
        });
    }

    public void setUrlGroupEnabled(boolean enable) {
        if (urlGroup != null) {
            urlGroup.setEnabled(enable);
            Control[] children = urlGroup.getChildren();
            if (children != null) {
                for (Control control : children) {
                    control.setEnabled(enable);
                }
            }
        }
    }

    private void createAuthenticationControl(Composite composite) {
        authComposite = SWTWidgetHelper.createComposite(composite, 2);
        Group g = SWTWidgetHelper.createGroup(authComposite,
                Messages.getString("ConfigurationWizardMainPage.authenticationGroup.title")); //$NON-NLS-1$

        // User name
        SWTWidgetHelper.createLabel(g, Messages.getString("ConfigurationWizardMainPage.userLabel.text")); //$NON-NLS-1$
        userCombo = createEditableCombo(g);

        // Password
        SWTWidgetHelper.createLabel(g, Messages.getString("ConfigurationWizardMainPage.passwordLabel.text")); //$NON-NLS-1$
        passwordText = SWTWidgetHelper.createPasswordField(g);

        userCombo.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent arg0) {
                canFlipToNextPage();
            }
        });

        passwordText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent arg0) {
                canFlipToNextPage();
            }
        });
    }

    protected void setAuthCompositeEnabled(boolean enable) {
        authComposite.setEnabled(enable);
        userCombo.setEnabled(enable);
        passwordText.setEnabled(enable);
    }

    /**
     * Utility method to create an editable combo box
     *
     * @param parent
     *            the parent of the combo box
     * @return the created combo
     */
    protected static Combo createEditableCombo(Composite parent) {
        Combo combo = new Combo(parent, SWT.NULL);
        GridData data = new GridData(GridData.FILL_HORIZONTAL);
        data.widthHint = IDialogConstants.ENTRY_FIELD_WIDTH;
        combo.setLayoutData(data);
        return combo;
    }

    /**
     * @see HgWizardPage#finish
     */
    @Override
    public boolean finish(IProgressMonitor monitor) {
        // Set the result to be the current values
        properties = createProperties();

        saveWidgetValues();
        return true;
    }

    protected Properties createProperties() {
        Properties result = new Properties();
        if (showCredentials) {
            result.setProperty(PROP_USER, getUserText());
            result.setProperty(PROP_PASSWORD, passwordText.getText());
        }
        result.setProperty(PROP_URL, getUrlText());
        return result;
    }

    /**
     * Initializes states of the controls.
     */
    private void initializeValues() {
        // Set remembered values
        IDialogSettings setts = getDialogSettings();
        if (setts != null) {
            String[] hostNames = updateHostNames();
            if (hostNames != null) {
                for (String hn : hostNames) {
                    urlCombo.add(hn);
                }
            }
            if (showCredentials) {
                String[] userNames = setts.getArray(STORE_USERNAME_ID);
                if (userNames != null) {
                    for (String un : userNames) {
                        userCombo.add(un);
                    }
                }
            }
        }

        if (properties != null) {
            if (showCredentials) {
                String user = properties.getProperty(PROP_USER);
                if (user != null) {
                    userCombo.setText(user);
                }

                String password = properties.getProperty(PROP_PASSWORD);
                if (password != null) {
                    passwordText.setText(password);
                }
            }
            String host = properties.getProperty(PROP_URL);
            if (host != null) {
                urlCombo.setText(host);
            }
        }
    }

    /**
     * Saves the widget values for the next time
     */
    private void saveWidgetValues() {
        // Update history
        IDialogSettings dialogSettings = getDialogSettings();
        if (settings != null) {
            if (showCredentials) {
                String[] userNames = dialogSettings.getArray(STORE_USERNAME_ID);
                if (userNames == null) {
                    userNames = new String[0];
                }
                userNames = addToHistory(userNames, getUserText(), COMBO_HISTORY_LENGTH);
                dialogSettings.put(STORE_USERNAME_ID, userNames);
            }
        }
    }

    protected String getUserText() {
        return userCombo.getText().trim();
    }

    protected String getUrlText() {
        String text = urlCombo.getText();
        if (REPO_SEPARATOR.equals(text)) {
            return "";
        }
        text = HgRepositoryLocationParser.trimLocation(text);
        return text;
    }

    private String[] updateHostNames() {
        List<String> newHostNames = new ArrayList<String>();
        Set<IHgRepositoryLocation> repositories;
        Set<IHgRepositoryLocation> all = MercurialEclipsePlugin.getRepoManager().getAllRepoLocations();
        if (hgRoot == null) {
            repositories = new TreeSet<IHgRepositoryLocation>();
        } else {
            repositories = MercurialEclipsePlugin.getRepoManager().getAllRepoLocations(hgRoot);
        }
        //
        // Sort alphabetically as it will be easier on the user.
        List<IHgRepositoryLocation> sortedRepositories = new ArrayList<IHgRepositoryLocation>(repositories.size());
        List<IHgRepositoryLocation> sortedAll = new ArrayList<IHgRepositoryLocation>(all.size());
        for (IHgRepositoryLocation repo : repositories) {
            sortedRepositories.add(repo);
        }
        for (IHgRepositoryLocation repo : all) {
            sortedAll.add(repo);
        }

        sortedRepositories.sort(HgRepositoryLocationManager.getRepoLocationComparator());
        sortedAll.sort(HgRepositoryLocationManager.getRepoLocationComparator());
        //
        //
        for (IHgRepositoryLocation repoLocation : sortedRepositories) {
            if (repoLocation.getLocation() != null) {
                newHostNames.add(repoLocation.getLocation());
            }
        }
        if (repositories.size() > 0) {
            newHostNames.add(REPO_SEPARATOR);
        }
        for (IHgRepositoryLocation repoLocation : sortedAll) {
            String location = repoLocation.getLocation();
            if (location != null && !newHostNames.contains(location)) {
                newHostNames.add(location);
            }
        }
        return newHostNames.toArray(new String[newHostNames.size()]);
    }

    /**
     * Validates the contents of the editable fields and set page completion and
     * error messages appropriately. Call each time url or username is modified
     */
    protected boolean validateFields() {
        // first check the url of the repository
        String url = getUrlText();

        if (url.length() == 0) {
            setErrorMessage(null);
            return false;
        }
        File localDirectory = getLocalDirectory(url);
        if (localDirectory != null) {
            if (!localDirectory.exists()) {
                setErrorMessage("Please provide a valid url or an existing directory!");
                return false;
            }
            File hgRepo = new File(localDirectory, ".hg");
            if (!hgRepo.isDirectory()) {
                setErrorMessage("Directory " + localDirectory + " does not contain a valid hg repository!");
                return false;
            }
        }
        return true;
    }

    /**
     * @param urlString non null
     * @return true if the given url can be threated as local directory
     */
    @SuppressWarnings("static-method")
    protected File getLocalDirectory(String urlString) {
        if (urlString != null) {
            urlString = urlString.trim();
        }

        if (urlString == null || urlString.length() == 0 || urlString.contains("http:")
                || urlString.contains("https:") || urlString.contains("ftp:") || urlString.contains("ssh:")) {
            return null;
        }

        File dir = new File(urlString);
        if (dir.isDirectory()) {
            return dir;
        }

        try {
            // Supporting file:// URLs
            URL url = new URL(urlString);
            return new File(url.getPath());
        } catch (Exception e) {
            return null;
        }
    }

    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        if (visible) {
            if (urlCombo != null) {
                urlCombo.setFocus();
            }
        }
    }

    @Override
    public boolean canFlipToNextPage() {
        return super.canFlipToNextPage();
    }

    public boolean isShowCredentials() {
        return showCredentials;
    }

    public void setShowCredentials(boolean showCredentials) {
        this.showCredentials = showCredentials;
    }

    protected Combo getUserCombo() {
        return userCombo;
    }

    public String getPasswordText() {
        return passwordText.getText();
    }

    protected Combo getUrlCombo() {
        return urlCombo;
    }

    public boolean isShowBundleButton() {
        return showBundleButton;
    }

    public void setShowBundleButton(boolean showBundleButton) {
        this.showBundleButton = showBundleButton;
    }

    protected boolean optionChanged() {
        return urlChanged();
    }

    /**
     * Triggered if the user has changed repository url. Override to implement additional
     * checks after it.
     * @return true, if the filed validation was successful
     */
    protected boolean urlChanged() {
        boolean ok = validateFields();
        setPageComplete(ok);
        if (ok) {
            setErrorMessage(null);
        }
        return ok;
    }

    protected HgRoot getHgRoot() {
        return hgRoot;
    }

    protected void initDefaultLocation() {
        IHgRepositoryLocation defaultLocation = null;
        if (getHgRoot() != null) {
            defaultLocation = getRepoFromRoot();
        }
        if (defaultLocation == null) {
            defaultLocation = getInitialRepo();
        }
        setRepository(defaultLocation);
    }

    protected IHgRepositoryLocation getRepoFromRoot() {
        HgRepositoryLocationManager mgr = MercurialEclipsePlugin.getRepoManager();
        IHgRepositoryLocation defaultLocation = mgr.getDefaultRepoLocation(getHgRoot());
        Set<IHgRepositoryLocation> repos = mgr.getAllRepoLocations(getHgRoot());
        if (defaultLocation == null) {
            for (IHgRepositoryLocation repo : repos) {
                if (HgPathsClient.DEFAULT_PULL.equals(repo.getLogicalName())
                        || HgPathsClient.DEFAULT.equals(repo.getLogicalName())) {
                    defaultLocation = repo;
                    break;
                }
            }
        }
        return defaultLocation;
    }

    public void setRepository(IHgRepositoryLocation repo) {
        if (repo == null) {
            return;
        }
        getUrlCombo().setText(repo.getLocation());

        String user = repo.getUser();
        if (user != null && user.length() != 0) {
            getUserCombo().setText(user);
        }
        String password = repo.getPassword();
        if (password != null && password.length() != 0) {
            passwordText.setText(password);
        }
    }

    @Override
    public void setProperties(Properties properties) {
        super.setProperties(properties);
        if (urlCombo != null && isValid(properties, PROP_URL)) {
            String[] items = urlCombo.getItems();
            if (items != null) {
                String url = properties.getProperty(PROP_URL);
                for (int i = 0; i < items.length; i++) {
                    if (url.equals(items[i])) {
                        urlCombo.select(i);
                        break;
                    }
                }
            }
        }
        if (userCombo != null && isValid(properties, PROP_USER)) {
            String[] items = userCombo.getItems();
            if (items != null) {
                String user = properties.getProperty(PROP_USER);
                for (int i = 0; i < items.length; i++) {
                    if (user.equals(items[i])) {
                        userCombo.select(i);
                        break;
                    }
                }
            }
        }
        if (passwordText != null && isValid(properties, PROP_PASSWORD)) {
            passwordText.setText(properties.getProperty(PROP_PASSWORD));
        }
    }

    private static boolean isValid(Properties properties, String key) {
        String value = properties.getProperty(key);
        return value != null && value.trim().length() > 0;
    }

    public void setInitialRepo(IHgRepositoryLocation initialRepo) {
        this.initialRepo = initialRepo;
    }

    public IHgRepositoryLocation getInitialRepo() {
        return initialRepo;
    }

    public void setHgRoot(HgRoot hgRoot) {
        this.hgRoot = hgRoot;
    }
}