/*******************************************************************************
* Copyright (c) 2007 Exadel, Inc. and Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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:
* Exadel, Inc. and Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.common.model.ui.attribute.adapter;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.Properties;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.swt.widgets.Shell;
import org.jboss.tools.common.model.ui.IAttributeErrorProvider;
import org.jboss.tools.common.model.ui.IValueChangeListener;
import org.jboss.tools.common.model.ui.IValueProvider;
import org.jboss.tools.common.model.ui.ModelUIPlugin;
import org.jboss.tools.common.model.ui.actions.IActionProvider;
import org.jboss.tools.common.model.ui.attribute.IValueFilter;
import org.jboss.tools.common.model.ui.attribute.editor.ExtendedFieldEditor;
import org.jboss.tools.common.model.ui.attribute.editor.IPropertyEditor;
import org.jboss.tools.common.model.util.ModelFeatureFactory;
import org.jboss.tools.common.meta.XAttribute;
import org.jboss.tools.common.meta.action.XAction;
import org.jboss.tools.common.meta.action.XActionInvoker;
import org.jboss.tools.common.meta.action.XAttributeData;
import org.jboss.tools.common.meta.constraint.impl.XAttributeConstraintProperties;
import org.jboss.tools.common.model.XModel;
import org.jboss.tools.common.model.XModelException;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.impl.XModelImpl;
import org.jboss.tools.common.model.markers.XMarkerManager;
public class DefaultValueAdapter implements IModelPropertyEditorAdapter, IAdaptable {
protected Object value = ""; //$NON-NLS-1$
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
protected PropertyChangeSupport pcs2 = new PropertyChangeSupport(this);
protected XModel model;
protected XAttribute attribute;
protected XModelObject modelObject;
protected XAttributeData attributeData;
protected static final int UNKNOW_TARGET = -1;
protected static final int MODELOBJECT_TARGET = 0;
protected static final int ATTRIBUTEDATA_TARGET = 1;
protected int storeTarget = UNKNOW_TARGET;
protected boolean autoStore = true;
protected boolean storeLocked = false;
protected String invalidValue = null;
protected String lastCorrectValue = null;
protected String currentError = null;
boolean valueFilterChecked = false;
IValueFilter valueFilter = null;
public DefaultValueAdapter() {}
public void store() {
if(isStoreLocked()) return;
if (MODELOBJECT_TARGET == this.storeTarget) {
String v = getStringValue(true);
if(v != null && attribute.isTrimmable()) v = v.trim();
String n = attribute.getName();
if(modelObject.isActive()) {
currentError = ((XModelImpl)modelObject.getModel()).getError(modelObject, n, v);
if(currentError != null) {
invalidValue = getStringValue(true);
lastCorrectValue = modelObject.getAttributeValue(n);
if(pcs2 != null) {
pcs2.firePropertyChange(IPropertyEditor.ERROR, Boolean.FALSE, Boolean.TRUE);
}
fireValueChange(v, v);
return;
} else {
boolean changed = invalidValue != null;
invalidValue = null;
lastCorrectValue = null;
if(changed && pcs2 != null) {
pcs2.firePropertyChange(IPropertyEditor.ERROR, Boolean.TRUE, Boolean.FALSE);
}
}
try {
modelObject.getModel().editObjectAttribute(modelObject, n, v);
} catch (XModelException e) {
throw new IllegalArgumentException(e);
}
} else {
modelObject.setAttributeValue(attribute.getName(), getValue().toString());
}
String v1 = modelObject.getAttributeValue(n);
if(!v1.equals(v)) {
setValue(v1);
fireValueChange(v, v1);
}
} else if(attributeData!=null) {
attributeData.setValue(getStringValue(true));
}
// storeValue();
}
public void load() {
if (MODELOBJECT_TARGET == storeTarget) {
String value = modelObject.getAttributeValue(attribute.getName());
if(currentError != null && invalidValue != null) {
if(value != null && value.equals(lastCorrectValue)) {
return;
}
}
this.setValue(value);
} else {
this.setValue(attributeData.getValue());
}
// loadValue();
}
public void setValue(Object value) {
if(this.value == value || (this.value != null && this.value.equals(value))) return;
Object oldValue = this.value;
this.value = value;
fireValueChange(oldValue, this.value);
}
public void fireValueChange(Object oldValue, Object newValue) {
if(pcs != null) pcs.firePropertyChange(IPropertyEditor.VALUE, oldValue, newValue);
}
public void fireEvent(String propertyName, Object oldValue, Object newValue) {
if(pcs != null) pcs.firePropertyChange(propertyName, oldValue, newValue);
}
// IValueProvider
public void addValueChangeListener(PropertyChangeListener l) {
if (pcs!=null) pcs.addPropertyChangeListener(l);
}
public Object getValue() {
return this.value;
}
public void removeValueChangeListener(PropertyChangeListener l) {
if (pcs!=null) pcs.removePropertyChangeListener(l);
}
public void addErrorStateListener(PropertyChangeListener l) {
if (pcs2!=null) pcs2.addPropertyChangeListener(l);
}
// IValueChangeListener
public void valueChange(PropertyChangeEvent event) {
setValue(event.getNewValue());
// store to model for Slava
if (isAutoStore()) store();
}
// IAdaptable
public Object getAdapter(Class adapter) {
if (adapter == IValueProvider.class) {
return this;
}
if (adapter == IValueChangeListener.class) {
return this;
}
if(adapter == IAttributeErrorProvider.class) {
return this;
}
if(adapter == IValueFilter.class) {
if(valueFilterChecked) return valueFilter;
valueFilterChecked = true;
if(valueFilter == null) {
XAttribute a = (attribute != null) ? attribute : attributeData != null ? attributeData.getAttribute() : null;
if(a == null) return null;
String cls = a.getProperty("valueFilter");
if(cls == null || cls.length() == 0) return null;
try {
valueFilter = (IValueFilter)ModelFeatureFactory.getInstance().createFeatureInstance(cls);
} catch (ClassCastException exc) {
ModelUIPlugin.getPluginLog().logError(exc);
}
if(valueFilter != null) {
if(!valueFilter.init(getModelObject(), a)) {
valueFilter = null;
}
}
return valueFilter;
}
}
if (adapter == IActionProvider.class) {
return getActionProvider();
}
return null;
}
public XAttribute getAttribute() {
return attribute;
}
public void setAttribute(XAttribute attribute) {
this.attribute = attribute;
}
public XAttributeData getAttributeData() {
return attributeData;
}
public void setAttributeData(XAttributeData data) {
attributeData = data;
this.storeTarget = ATTRIBUTEDATA_TARGET;
}
public XModelObject getModelObject() {
return modelObject;
}
public void setModelObject(XModelObject object) {
modelObject = object;
storeTarget = MODELOBJECT_TARGET;
}
public boolean isAutoStore() {
return autoStore;
}
public void setAutoStore(boolean b) {
autoStore = b;
}
public boolean isStoreLocked() {
return storeLocked;
}
public void setStoreLocked(boolean b) {
storeLocked = b;
}
public XModel getModel() {
return model;
}
public void setModel(XModel model) {
this.model = model;
}
public String getStringValue(boolean returnNullAsEmptyString) {
Object o = getValue();
return (o != null) ? o.toString() : (returnNullAsEmptyString) ? "" : null; //$NON-NLS-1$
}
public void dispose() {
pcs = null;
}
public boolean hasErrors() {
if(ATTRIBUTEDATA_TARGET == storeTarget) return false;
if(invalidValue != null && currentError != null) {
return true;
}
return attribute != null && XMarkerManager.getInstance().hasErrors(modelObject, attribute.getName());
}
public String getError() {
if(modelObject == null || attribute == null) return null;
if(ATTRIBUTEDATA_TARGET != storeTarget) {
if(invalidValue != null && currentError != null) {
return currentError;
}
}
return XMarkerManager.getInstance().getError(modelObject, attribute.getName());
}
protected XActionWrapper labelAction;
protected IActionProvider actionProvider;
protected IActionProvider getActionProvider() {
if(actionProvider == null) {
String actionPath = null;
if(attribute != null) {
if(attribute.getConstraint() instanceof XAttributeConstraintProperties) {
actionPath = ((XAttributeConstraintProperties)attribute.getConstraint()).getProperties().getProperty(DefaultTreeSelectionAdapter.LINK_ACTION);
} else {
actionPath = attribute.getProperty(DefaultTreeSelectionAdapter.LINK_ACTION);
}
}
if(actionPath != null) {
actionProvider = new ActionProvider();
XAction xaction = XActionInvoker.getAction(actionPath, modelObject);
labelAction = (xaction != null) ? new XActionWrapper(xaction) : null;
if(labelAction != null) {
labelAction.setXModelObject(getModelObject());
}
}
}
return actionProvider;
}
protected class XActionWrapper extends Action {
private XAction xaction = null;
public XActionWrapper(XAction xaction) {
this.xaction = xaction;
}
public void setXModelObject(XModelObject xmo) {
if (xmo != null && xaction != null) {
// this.setEnabled(xaction.isEnabled(xmo));
this.setEnabled(true);
} else {
this.setEnabled(false);
}
}
public void run() {
if (xaction != null) {
if(xaction.isEnabled(getModelObject())) {
XActionInvoker.invoke(xaction.getPath(), modelObject, new Properties());
} else {
Shell shell = ModelUIPlugin.getDefault().getWorkbench().getActiveWorkbenchWindow().getShell();
MessageDialog.openWarning(shell, "Warning", "Resource does not exist.");
}
}
}
}
protected class ActionProvider implements IActionProvider {
public ActionProvider() {}
public IAction getAction(String actionName) {
if (ExtendedFieldEditor.LABEL_SELECTED.equals(actionName)) {
return labelAction;
}
return null;
}
public IAction[] getActions() {
return new IAction[] {labelAction};
}
public void update(ISelection selection) {}
}
}