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