package org.marketcetera.photon.module.ui;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.marketcetera.module.MXBeanOperationException;
import org.marketcetera.module.ModuleURN;
import org.marketcetera.photon.internal.module.ui.Messages;
import org.marketcetera.photon.module.IModuleAttributeSupport;
import org.marketcetera.photon.module.ModuleSupport;
import org.marketcetera.util.misc.ClassVersion;
/* $License$ */
/**
* Generic preference page for module attributes
*
* @author <a href="mailto:will@marketcetera.com">Will Horn</a>
* @version $Id: ModuleAttributePreferencePage.java 16154 2012-07-14 16:34:05Z colin $
* @since 1.1.0
*/
@ClassVersion("$Id: ModuleAttributePreferencePage.java 16154 2012-07-14 16:34:05Z colin $")
public abstract class ModuleAttributePreferencePage extends PreferencePage {
private static final String PLUGIN_ID = "org.marketcetera.photon.module.ui"; //$NON-NLS-1$
private DataBindingContext mDataBindingContext;
private final List<Field> mFields = new ArrayList<Field>();
private final ModuleURN mURN;
/**
* Constructor.
*
* @param urn
* the ModuleURN of the module being edited
*/
public ModuleAttributePreferencePage(ModuleURN urn) {
mURN = urn;
}
@Override
protected Control createContents(Composite parent) {
Composite composite = new Composite(parent, SWT.NONE);
composite.setFont(parent.getFont());
mDataBindingContext = new DataBindingContext();
createFields(composite);
GridLayoutFactory.fillDefaults().numColumns(2).generateLayout(composite);
return composite;
}
protected abstract void createFields(Composite parent);
/**
* Creates a text field in the UI.
*
* @param parent
* the parent composite
* @param attributeName
* the module's MBean attribute name
* @param labelText
* the label for the attribute
* @param isPassword
* whether a password (masked) field should be created
*/
protected final void createTextField(Composite parent, String attributeName, String labelText,
boolean isPassword) {
Font font = parent.getFont();
Label label = new Label(parent, SWT.LEFT);
label.setFont(font);
label.setText(labelText);
int style = SWT.BORDER | SWT.SINGLE;
if (isPassword) {
style |= SWT.PASSWORD;
}
final Text text = new Text(parent, style);
text.setFont(font);
WritableValue model = WritableValue.withValueType(String.class);
mDataBindingContext.bindValue(SWTObservables.observeText(text, SWT.Modify), model, null,
null);
if (isPassword) {
model.setValue(ModuleSupport.getModuleAttributeSupport().getDefaultFor(mURN,
attributeName));
text.addFocusListener(new FocusAdapter() {
@Override
public void focusGained(FocusEvent e) {
// help the user replace the password text by selecting it
text.selectAll();
}
});
} else {
try {
model.setValue(ModuleSupport.getModuleAttributeSupport().getModuleAttribute(mURN,
attributeName));
} catch (MXBeanOperationException e) {
e.getI18NBoundMessage().error(this, e);
}
}
mFields.add(new Field(attributeName, model, isPassword));
}
@Override
public boolean performOk() {
IModuleAttributeSupport moduleAttributeSupport = ModuleSupport.getModuleAttributeSupport();
MultiStatus status = new MultiStatus(PLUGIN_ID, IStatus.ERROR,
Messages.MODULE_ATTRIBUTE_PREFERENCE_PAGE_UPDATE_FAILURE_SEE_DETAILS.getText(),
null);
for (Field field : mFields) {
IObservableValue observable = field.getObservable();
if (observable.getValue() == null) {
moduleAttributeSupport.removeDefaultFor(mURN, field.getAttributeName());
} else {
moduleAttributeSupport.setDefaultFor(mURN, field.getAttributeName(), observable
.getValue().toString());
}
try {
moduleAttributeSupport.setModuleAttribute(mURN, field.getAttributeName(),
observable.getValue());
} catch (MXBeanOperationException e) {
e.getI18NBoundMessage().error(this, e);
status.add(new Status(IStatus.ERROR, PLUGIN_ID, e.getLocalizedMessage(), e.getCause()));
}
// try to refresh in case something failed
if (!field.isWriteOnly()) {
try {
observable.setValue(moduleAttributeSupport.getModuleAttribute(mURN, field
.getAttributeName()));
} catch (MXBeanOperationException e) {
e.getI18NBoundMessage().error(this, e);
}
}
}
if (status.getChildren().length > 0) {
ErrorDialog.openError(getShell(), null,
Messages.MODULE_ATTRIBUTE_PREFERENCE_PAGE_UPDATE_FAILURE.getText(), status);
}
moduleAttributeSupport.flush();
return true;
}
/**
* Internal class representing a single field in the preference page.
*
* @author <a href="mailto:will@marketcetera.com">Will Horn</a>
* @version $Id: ModuleAttributePreferencePage.java 16154 2012-07-14 16:34:05Z colin $
* @since 1.1.0
*/
@ClassVersion("$Id: ModuleAttributePreferencePage.java 16154 2012-07-14 16:34:05Z colin $")
private static class Field {
final String mAttributeName;
final IObservableValue mObservable;
final boolean mWriteOnly;
Field(String attributeName, IObservableValue observable, boolean writeOnly) {
mAttributeName = attributeName;
mObservable = observable;
mWriteOnly = writeOnly;
}
String getAttributeName() {
return mAttributeName;
}
IObservableValue getObservable() {
return mObservable;
}
boolean isWriteOnly() {
return mWriteOnly;
}
}
@Override
public void dispose() {
if (mDataBindingContext != null) {
mDataBindingContext.dispose();
}
}
}