Java tutorial
/* ***************************************************************************** * Copyright (c) 2007-2009 Bioclipse Project * 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: * ******************************************************************************/ package net.bioclipse.usermanager; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import net.bioclipse.usermanager.AccountType.Property; import org.apache.log4j.Logger; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; import org.eclipse.core.runtime.IExtensionPoint; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.fieldassist.ControlDecoration; import org.eclipse.jface.fieldassist.FieldDecorationRegistry; 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.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Image; 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.Group; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.PlatformUI; /** * * @author Klas Jnsson (aka "konditorn") * */ public class AccountPropertiesPage { /* I've left some out-comment code in this class. That code adds an extra * field for properties marked as secret*/ private Composite accountComposite, propComposite; private Collection<Property> properties; private Label[] accountLabels; private Text[] accountTxt; private Label accountNameLabel; private Text accountNameTxt; private Button testLoginButton; private ArrayList<Text> requiredFields = new ArrayList<Text>(); private Image reqImage = FieldDecorationRegistry.getDefault() .getFieldDecoration(FieldDecorationRegistry.DEC_REQUIRED).getImage(); private AccountType accountType; private NewAccountWizardPage mainPage; private UserContainer sandbox; private String accountId = ""; private HashMap<String, String> accountProperties = new HashMap<String, String>(); private Group accountPropGroup; private ITestAccountLogin testLogin = null; private Logger logger = Logger.getLogger(this.getClass()); public AccountPropertiesPage(Composite parent, AccountType accountType, NewAccountWizardPage nawp, UserContainer sandbox) { this.sandbox = sandbox; int noOfFields = 0, i = 0; mainPage = nawp; Iterator<Property> propertyIter; Property temp; this.accountType = accountType; properties = accountType.getProperties(); // for (propertyIter = properties.iterator(); propertyIter.hasNext(); ) { // if (propertyIter.next().isSecret()) // noOfSecretFields++; // } noOfFields = properties.size();// + noOfSecretFields; accountComposite = new Composite(parent, SWT.NONE); accountComposite.setLayout(new GridLayout(1, false)); GridData txtData = new GridData(SWT.FILL, SWT.NONE, true, true); Composite accountNameComposite = new Composite(accountComposite, SWT.NONE); accountNameComposite.setLayout(new GridLayout(2, false)); accountNameLabel = new Label(accountNameComposite, SWT.NONE); accountNameLabel.setText("Account name: "); accountNameTxt = new Text(accountNameComposite, SWT.BORDER); accountNameTxt.setLayoutData(txtData); accountNameTxt.setText(accountType.getName()); accountNameTxt.addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { accountId = accountNameTxt.getText(); mainPage.setPageComplete(isAllRequierdPropertiesFilledIn()); } }); accountPropGroup = new Group(accountComposite, SWT.SHADOW_ETCHED_IN); accountPropGroup.setText("Third-part account properties"); accountLabels = new Label[noOfFields]; accountTxt = new Text[noOfFields]; txtData.widthHint = 220; if (accountType.hasLogo()) { accountPropGroup.setLayout(new GridLayout(2, false)); } else accountPropGroup.setLayout(new GridLayout(1, false)); propComposite = new Composite(accountPropGroup, SWT.NONE); propComposite.setLayout(new GridLayout(2, false)); propertyIter = properties.iterator(); while (propertyIter.hasNext()) { temp = propertyIter.next(); if (temp.isSecret()) { addComponents(i, SWT.BORDER | SWT.PASSWORD, temp.isRequired(), temp.getName(), temp.getDefaultValue()); // i++; // addComponents(i, SWT.BORDER | SWT.PASSWORD, temp.isRequired(), // "Repeat " + temp.getName()); // final int my_i = i; // final ControlDecoration deco = new ControlDecoration( // accountTxt[my_i], SWT.TOP | SWT.RIGHT); // deco.setDescriptionText("The value has to be the same as " + // "the value above"); // deco.setImage(errImage); // deco.setShowOnlyOnFocus(false); // deco.hide(); // accountTxt[i].addKeyListener(new KeyListener() { // // @Override // public void keyReleased(KeyEvent e) { // if (!(accountTxt[my_i-1].getText().equals( // accountTxt[my_i].getText()))) { // deco.show(); // errorFlag = true; // mainPage.setErrorMessage("The value has to be " + // "the same as the value above"); // } else { // deco.hide(); // if (isAllRequierdPropertiesFilledIn()) { // mainPage.setErrorMessage(null); // errorFlag = false; // } else { // errorFlag = true; // createMissingFieldsError(); // } // // } // // } // // @Override // public void keyPressed(KeyEvent e) { // } // }); } else { addComponents(i, SWT.BORDER, temp.isRequired(), temp.getName(), temp.getDefaultValue()); } i++; } if (accountType.hasLogo()) { Label logo = new Label(accountPropGroup, SWT.TOP); ImageDescriptor imDesc = ImageDescriptor.createFromURL(accountType.getLogoPath()); Image im = imDesc.createImage(); logo.setImage(im); } if (createTestConnection()) { // new Label(accountPropGroup, SWT.NONE).setText( "Dummy1" ); if (accountType.hasLogo()) { new Label(accountPropGroup, SWT.NONE); } testLoginButton = new Button(accountPropGroup, SWT.PUSH); testLoginButton.setText("Test log-in"); testLoginButton.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { testConnection(); } @Override public void widgetDefaultSelected(SelectionEvent e) { } }); } mainPage.setPageComplete(isAllRequierdPropertiesFilledIn()); accountPropGroup.setFocus(); } /** * This method look if the plug-in is providing any class for testing the * properties. If so it creates this class. * * @return True if it finds a test class and succeed with creating the class */ private boolean createTestConnection() { IExtensionRegistry registry = Platform.getExtensionRegistry(); if (registry == null) { /* Could not find extension point. If Bioclipse is not running * this is normal. */ return false; } IExtensionPoint extensionPoint = registry.getExtensionPoint("net.bioclipse.usermanager.testLogin"); if (extensionPoint == null) return false; IExtension[] extensions = extensionPoint.getExtensions(); for (IExtension extension : extensions) { IConfigurationElement[] configelements = extension.getConfigurationElements(); for (IConfigurationElement element : configelements) { try { Object obj = element.createExecutableExtension("testClass"); if (obj instanceof ITestAccountLogin) { if (((ITestAccountLogin) obj).getAccountType().equals(accountType.getName())) testLogin = (ITestAccountLogin) obj; } } catch (CoreException e) { logger.debug("Could not find any test-Class for this plugin: " + e.getMessage()); } } } return (testLogin != null); } /** * This method does the work behind the test-button: It collects the values * of the different properties and send them in a hash map to the test- * class. I then shows a message-dialog with the result of the test login. */ private void testConnection() { String resultMessage = ""; if (testLogin != null) { HashMap<String, String> properties = new HashMap<String, String>(); // Let's collect the properties from the fields... for (int i = 0; i < accountLabels.length; i++) { /* This if-statement make sure that repeated fields (e.g. "Repeat * password") don't end up as a property of the new account.*/ if (!(accountLabels[i].getText().startsWith("Repeat "))) { properties.put(accountLabels[i].getText().substring(0, accountLabels[i].getText().length() - 1), accountTxt[i].getText()); } } if (testLogin.login(properties)) resultMessage = "Login test succeeded"; else resultMessage = "Login test failed.\nPlease make sure all required fields filled has valid values"; } else { /* If the testLogin is null, then the test button should not appear, * and to reach this method you have to push that button... * I.e. it should not be possibly to end up here...*/ logger.error("Ops: The test button was pushed, but should not existed."); resultMessage = "Something whent wrong, terribly wrong... Mohaha"; } MessageDialog.openInformation(mainPage.getShell(), "Test login", resultMessage); } /** * A help method to reuse code instead of writing it several times. * * @param index The index of accountLabels and acccountTxt arrays * @param style The style of the text-field, e.g. SWT.PASSWORD * @param required A boolean to set i true if the field is required to be * filled in * @param labelTxt The text shown by the label in front of the text-field */ private void addComponents(int index, int style, boolean required, String labelTxt, String defaultValue) { GridData txtData = new GridData(SWT.FILL, SWT.NONE, true, true); txtData.widthHint = 220; accountLabels[index] = new Label(propComposite, SWT.NONE | SWT.RIGHT); accountLabels[index].setText(labelTxt + ":"); accountTxt[index] = new Text(propComposite, style); accountTxt[index].setToolTipText( accountLabels[index].getText().substring(0, (accountLabels[index].getText().length() - 1))); accountTxt[index].setLayoutData(txtData); accountTxt[index].setText(defaultValue); accountTxt[index].addModifyListener(new ModifyListener() { @Override public void modifyText(ModifyEvent e) { if (isAllRequierdPropertiesFilledIn()) { mainPage.setErrorMessage(null); } else { createMissingFieldsError(); } mainPage.setPageComplete(isAllRequierdPropertiesFilledIn()); } }); if (required) { setReqDeco(accountLabels[index]); requiredFields.add(accountTxt[index]); } } /** * This method create an error-message to let the user know which of the * required fields that isn't fill in. */ public void createMissingFieldsError() { String errorMessage = "Please fill in the following field"; ArrayList<String> unfilledFields = getRequiredPropertiesLeft(); if (unfilledFields.size() == 1) errorMessage += ": " + unfilledFields.get(0); else if (unfilledFields.size() > 1) { errorMessage += "s:\n" + createErrorMessage(unfilledFields); } else if (!isAllRequierdPropertiesFilledIn()) errorMessage = "Now you're way of..."; else errorMessage = "WTF?"; mainPage.setErrorMessage(errorMessage); } /** * An recursive method that to get the names of the required fields that * aren't filled in yet. * * @param unfilledFields An ArrayList containing the names of the un-filled * fields. * @return the names of the un-filled (required) fields */ private String createErrorMessage(ArrayList<String> unfilledFields) { if (unfilledFields.size() == 2) return unfilledFields.get(0) + " and " + unfilledFields.get(1); else { String field = unfilledFields.get(0); unfilledFields.remove(0); return field + ", " + createErrorMessage(unfilledFields); } } /** * Just a help method to avoid writing this stuff every time a field is * required to fill-in. * @param req The label that wants a required image */ private void setReqDeco(Label req) { ControlDecoration deco = new ControlDecoration(req, SWT.TOP | SWT.RIGHT); deco.setDescriptionText("This value has to be filed in."); deco.setImage(reqImage); deco.setShowOnlyOnFocus(false); } /** * This is get the composite created in the constructor. * * @return A composite with the fields necessary to create an account */ public Composite getAccountPropertiesPage() { return accountComposite; } /** * Set the focus to the first Text-field of the composite. */ public void giveFocus() { if (accountTxt.length > 0) accountTxt[0].forceFocus(); } private String createAccountId() { // String accountId = ""; // int i = 0; // if (!sandbox.isLoggedIn()) // return accountId; // // accountId = accountType.getName() + "_" + 0; // while (sandbox.accountExists(accountId)){ // i++; // accountId = accountType.getName() + "_" + i; // } return accountType.getName(); } protected void upDateAccountName() { if (accountId.isEmpty()) accountId = createAccountId(); accountNameTxt.setText(accountId); } /** * Create an account with the properties values that has been written in the * respective text-field. */ public boolean createAccount() { if (sandbox.accountExists(getAccountId())) { MessageDialog.openInformation(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), "Name trouble", "You already have an account named " + getAccountId() + ", please choose an other name."); return false; } // Collection<Account> accounts = sandbox.getLoggedInUser().getAccounts().values(); // Iterator<Account> itr = accounts.iterator(); // Account account; // while (itr.hasNext()) { // account = itr.next(); // if ( account.getAccountType().equals( accountType ) ) { // MessageDialog.openInformation( PlatformUI.getWorkbench() // .getActiveWorkbenchWindow() // .getShell(), // "Account type already used", // "There is already an account of " + // "that type." ); // return false; // } // } int i = 0; HashMap<String, String> properties = new HashMap<String, String>(); if (accountId.isEmpty()) { accountId = createAccountId(); } for (i = 0; i < accountLabels.length; i++) { /* This if-statement make sure that repeated fields (e.g. "Repeat * password") don't end up as a property of the new account.*/ if (!(accountLabels[i].getText().startsWith("Repeat "))) { properties.put(accountLabels[i].getText().substring(0, accountLabels[i].getText().length() - 1), accountTxt[i].getText()); } } sandbox.createAccount(accountId, properties, accountType); return true; } /** * This method reports if all of the necessary fields are filled in. * * @return True if all the the necessary fields are filled in */ public Boolean isAllRequierdPropertiesFilledIn() { Iterator<Text> itr = requiredFields.iterator(); while (itr.hasNext()) { if (itr.next().getText().isEmpty()) { return false; } } return true; } /** * Returns the names of the required fields that hasn't been filed in yet. * If all of them are filled in it returns null. * * @return the names of the required fields that hasn't been filed in yet */ public ArrayList<String> getRequiredPropertiesLeft() { Iterator<Text> itr = requiredFields.iterator(); ArrayList<String> requiredPropertiesLeft = new ArrayList<String>(); while (itr.hasNext()) { Text temp = itr.next(); if (temp.getText().isEmpty()) requiredPropertiesLeft.add(temp.getToolTipText()); } return requiredPropertiesLeft; } public void dispose() { dispose(); } protected AccountType getAccountType() { return accountType; } protected String getAccountId() { return accountId; } protected HashMap<String, String> getProperties() { return accountProperties; } }