Java tutorial
/******************************************************************************* * Copyright (c) 2007 Oracle. * 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: * Oracle - initial API and implementation *******************************************************************************/ package org.eclipse.jpt.jpa.ui.internal.properties; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.eclipse.core.runtime.IStatus; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jpt.common.ui.internal.WorkbenchTools; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Listener; import org.eclipse.ui.dialogs.PropertyPage; import org.eclipse.wst.common.frameworks.datamodel.DataModelEvent; import org.eclipse.wst.common.frameworks.datamodel.IDataModel; import org.eclipse.wst.common.frameworks.datamodel.IDataModelListener; import org.eclipse.wst.common.frameworks.internal.datamodel.ui.DataModelSynchHelper; import org.eclipse.wst.common.frameworks.internal.ui.ValidationStatus; public abstract class DataModelPropertyPage extends PropertyPage implements Listener, IDataModelListener { protected IDataModel model; private ValidationStatus status = new ValidationStatus(); private Map validationMap; private String[] validationPropertyNames; private boolean isValidating = false; protected DataModelSynchHelper synchHelper; private String infopopID; protected DataModelPropertyPage(IDataModel model) { super(); this.model = model; model.addListener(this); synchHelper = initializeSynchHelper(model); } /** * @return */ public DataModelSynchHelper initializeSynchHelper(IDataModel dm) { return new DataModelSynchHelper(dm); } @Override protected Control createContents(Composite parent) { Composite top = createTopLevelComposite(parent); setupInfopop(top); setDefaults(); addListeners(); initializeValidationProperties(); return top; } private void initializeValidationProperties() { validationPropertyNames = getValidationPropertyNames(); if (validationPropertyNames == null || validationPropertyNames.length == 0) validationMap = Collections.EMPTY_MAP; else { validationMap = new HashMap(validationPropertyNames.length); for (int i = 0; i < validationPropertyNames.length; i++) validationMap.put(validationPropertyNames[i], new Integer(i)); } } /** * Subclass should return the model property names that need to be validated on this page in the * order that they should present their messages. * * @return */ protected abstract String[] getValidationPropertyNames(); /** * Return the top level Composite for this page. */ protected abstract Composite createTopLevelComposite(Composite parent); /** * Set up info pop hooks if set. */ protected void setupInfopop(Control parent) { if (getInfopopID() != null) { WorkbenchTools.setHelp(parent, getInfopopID()); } } /** * Setup the default values for this page. Subclasses should override to provide appropriate * defaults. */ protected void setDefaults() { restoreDefaultSettings(); } /** * Subclasses should implement this method if they have default settings that have been stored * and need to be restored. * * @see storeDefaultSettings() */ protected void restoreDefaultSettings() { } /** * Add Listeners to controls at this point to avoid unnecessary events. Subclasses should * override to add listeners to its controls. */ protected void addListeners() { } /** * Exiting the page. Subclasses may extend. */ protected void exit() { } protected boolean getStatus(Integer key) { return status.hasError(key); } /** * Sent when an event that the receiver has registered for occurs. If a subclass overrides this * method, it must call super. * * @param event * the event which occurred */ public void handleEvent(org.eclipse.swt.widgets.Event event) { } /** * Set the error message for this page based on the last error in the ValidationStatus. */ protected void setErrorMessage() { String error = status.getLastErrMsg(); if (error == null) { if (getErrorMessage() != null) setErrorMessage((String) null); String warning = status.getLastWarningMsg(); if (warning == null) { if (getMessage() != null && getMessageType() == IMessageProvider.WARNING) setMessage(null, IMessageProvider.WARNING); else { String info = status.getLastInfoMsg(); if (info == null) { if (getMessage() != null && getMessageType() == IMessageProvider.INFORMATION) setMessage(null, IMessageProvider.INFORMATION); } else if (!info.equals(getMessage())) { setMessage(info, IMessageProvider.INFORMATION); } } } else if (!warning.equals(getMessage())) setMessage(warning, IMessageProvider.WARNING); } else if (!error.equals(getErrorMessage())) setErrorMessage(error); } protected void setErrorStatus(Integer key, String errorMessage) { status.setErrorStatus(key, errorMessage); } protected void setWarningStatus(Integer key, String warningMessage) { status.setWarningStatus(key, warningMessage); } protected void setInfoStatus(Integer key, String infoMessage) { status.setInfoStatus(key, infoMessage); } protected void setOKStatus(Integer key) { status.setOKStatus(key); } /** * This should be called by the Wizard just prior to running the performFinish operation. * Subclasses should override to store their default settings. */ public void storeDefaultSettings() { } /** * The page is now being validated. At this time, each control is validated and then the * controls are updated based on the results in the ValidationStatus which was updated during * <code>validateControls()</code>. Finally, it will display the last error message and it * will set the page complete. Subclasses will not typically override this method. */ protected void validatePage() { if (!isValidating) { isValidating = true; try { validateControlsBase(); updateControls(); setErrorMessage(); setValid(status.getLastErrMsg() == null); } finally { isValidating = false; } } } /** * Validate individual controls. Use validation keys to keep track of errors. * * @see setOKStatus(Integer) and setErrorMessage(Integer, String) */ protected final String validateControlsBase() { if (!validationMap.isEmpty()) { String propName; for (int i = 0; i < validationPropertyNames.length; i++) { propName = validationPropertyNames[i]; Integer valKey = (Integer) validationMap.get(propName); if (valKey != null) validateProperty(propName, valKey); if (!getStatus(valKey)) return propName; } } return null; } /** * @param propertyName * @param validationkey */ private void validateProperty(String propertyName, Integer validationKey) { setOKStatus(validationKey); IStatus status1 = model.validateProperty(propertyName); if (!status1.isOK()) { String message = status1.isMultiStatus() ? status1.getChildren()[0].getMessage() : status1.getMessage(); switch (status1.getSeverity()) { case IStatus.ERROR: setErrorStatus(validationKey, message); break; case IStatus.WARNING: setWarningStatus(validationKey, message); break; case IStatus.INFO: setInfoStatus(validationKey, message); break; } } } /** * Update the enablement of controls after validation. Sublcasses should check the status of * validation keys to determine enablement. */ protected void updateControls() { } /* * If a property changes that we want to validate, force validation on this page. * * @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperationDataModelListener#propertyChanged(java.lang.String, * java.lang.Object, java.lang.Object) */ public void propertyChanged(DataModelEvent event) { String propertyName = event.getPropertyName(); if (validationPropertyNames != null && (event.getFlag() == DataModelEvent.VALUE_CHG || (!isValid() && event.getFlag() == DataModelEvent.VALID_VALUES_CHG))) { for (int i = 0; i < validationPropertyNames.length; i++) { if (validationPropertyNames[i].equals(propertyName)) { validatePage(); break; } } } } /** * @return Returns the model. */ protected IDataModel getDataModel() { return model; } public void dispose() { super.dispose(); if (synchHelper != null) { synchHelper.dispose(); synchHelper = null; } } protected String getInfopopID() { return infopopID; } public void setInfopopID(String infopopID) { this.infopopID = infopopID; } }