org.eclipse.xwt.databinding.JFaceXWTDataBinding.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.xwt.databinding.JFaceXWTDataBinding.java

Source

/*******************************************************************************
 * Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
 *     Soyatec - initial API and implementation
 *******************************************************************************/
package org.eclipse.xwt.databinding;

import java.beans.BeanInfo;
import java.beans.PropertyChangeListener;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.core.databinding.property.value.SimpleValueProperty;
import org.eclipse.core.internal.databinding.property.value.SimplePropertyObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.databinding.viewers.ViewersObservables;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.xwt.IDataProvider;
import org.eclipse.xwt.XWT;
import org.eclipse.xwt.XWTException;
import org.eclipse.xwt.internal.core.ScopeManager;
import org.eclipse.xwt.internal.core.UpdateSourceTrigger;
import org.eclipse.xwt.internal.databinding.menuitem.MenuItemEnabledObservableValue;
import org.eclipse.xwt.internal.databinding.menuitem.MenuItemSelectionObservableValue;
import org.eclipse.xwt.internal.utils.LoggerManager;
import org.eclipse.xwt.internal.utils.UserData;
import org.eclipse.xwt.javabean.metadata.properties.EventProperty;
import org.eclipse.xwt.metadata.IMetaclass;
import org.eclipse.xwt.metadata.IProperty;

/**
 * 
 * @author yyang (yves.yang@soyatec.com)
 */
@SuppressWarnings("all")
public class JFaceXWTDataBinding {
    static final String ENABLED = "enabled";
    static final String SELECTION = "selection";

    static final String TEXT = "text";
    public static final Class<?>[] CONTROL_ARGUMENT_TYPES = new Class[] { Control.class };
    public static final Class<?>[] VIEWER_ARGUMENT_TYPES = new Class[] { Viewer.class };

    static String[] VIEWERS_PROPERTIES = null;
    static {
        Method[] methods = ViewerProperties.class.getDeclaredMethods();
        VIEWERS_PROPERTIES = new String[methods.length];
        for (int i = 0; i < methods.length; i++) {
            VIEWERS_PROPERTIES[i] = methods[i].getName();
        }
    }

    public static boolean isViewerProperty(String propertyName) {
        for (String name : VIEWERS_PROPERTIES) {
            if (name.equals(propertyName)) {
                return true;
            }
        }
        return false;
    }

    public static Class<?> getValueType(Class<?> type, String propertyName) {
        if (type == null || propertyName == null || propertyName.indexOf(".") != -1) {
            return null;
        }
        try {
            IMetaclass metaclass = XWT.getMetaclass(type);
            IProperty property = metaclass.findProperty(propertyName);
            if (property != null) {
                return property.getType();
            }
        } catch (Exception e) {
            LoggerManager.log(e);
        }
        return null;
    }

    public static Object getValue(Object target, String propertyName) {
        if (target == null || propertyName == null || propertyName.indexOf(".") != -1) {
            return target;
        }
        Class<?> type = target.getClass();
        try {
            BeanInfo beanInfo = java.beans.Introspector.getBeanInfo(type);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : propertyDescriptors) {
                if (propertyName.equalsIgnoreCase(pd.getName())) {
                    Method readMethod = pd.getReadMethod();
                    if (readMethod != null) {
                        return readMethod.invoke(target);
                    }
                }
            }
            Field[] fields = type.getDeclaredFields();
            for (Field field : fields) {
                if (propertyName.equalsIgnoreCase(field.getName())) {
                    Object object = field.get(target);
                    return object;
                }
            }
            return UserData.getLocalData(target, propertyName);
        } catch (Exception e) {
            LoggerManager.log(e);
        }
        return null;
    }

    public static void setValue(Object target, String propertyName, Object value) {
        Class<?> type = target.getClass();
        try {
            BeanInfo beanInfo = java.beans.Introspector.getBeanInfo(type);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (PropertyDescriptor pd : propertyDescriptors) {
                if (propertyName.equals(pd.getName())) {
                    Method writeMethod = pd.getWriteMethod();
                    if (writeMethod == null) {
                        return;
                    }
                    if (!writeMethod.isAccessible()) {
                        writeMethod.setAccessible(true);
                    }
                    Class<?>[] parameterTypes = writeMethod.getParameterTypes();
                    Class targetType = parameterTypes[0];
                    if (targetType != value.getClass()) {
                        if (targetType.isEnum() && value instanceof String) {
                            try {
                                writeMethod.invoke(target,
                                        new Object[] { Enum.valueOf(targetType, (String) value) });
                                return;
                            } catch (Exception e) {
                            }
                        }
                        IConverter c = XWT.findConvertor(value.getClass(), targetType);
                        if (c != null) {
                            value = c.convert(value);
                        }
                    }
                    writeMethod.invoke(target, new Object[] { value });
                    return;
                }
            }
            Field[] fields = type.getDeclaredFields();
            for (Field field : fields) {
                if (propertyName.equals(field.getName())) {
                    if (!field.isAccessible()) {
                        field.setAccessible(true);
                    }
                    Class fieldType = field.getType();
                    if (fieldType.isEnum() && value instanceof String) {
                        try {
                            field.set(target, Enum.valueOf(fieldType, (String) value));
                            return;
                        } catch (Exception e) {
                        }
                    }
                    IConverter c = XWT.findConvertor(value.getClass(), fieldType);
                    if (c != null) {
                        value = c.convert(value);
                    }
                    field.set(target, value);
                    return;
                }
            }

            IMetaclass metaclass = XWT.getMetaclass(type);
            IProperty property = metaclass.findProperty(propertyName);
            if (property != null) {
                property.setValue(target, value);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean isPropertyReadOnly(Class<?> type, String propertyName) {
        if (type == null || propertyName == null || propertyName.indexOf(".") != -1) {
            return true;
        }
        try {
            IMetaclass metaclass = XWT.getMetaclass(type);
            IProperty property = metaclass.findProperty(propertyName);
            if (property != null) {
                return property.isReadOnly();
            }
        } catch (Exception e) {
            LoggerManager.log(e);
        }
        return true;
    }

    public static boolean isBeanSupport(Object target) {
        Class<?> type = toType(target);
        Method method = null;
        try {
            try {
                method = type.getMethod("addPropertyChangeListener",
                        new Class[] { String.class, PropertyChangeListener.class });
            } catch (NoSuchMethodException e) {
                method = type.getMethod("addPropertyChangeListener", new Class[] { PropertyChangeListener.class });
            }
        } catch (SecurityException e) {
        } catch (NoSuchMethodException e) {
        }
        return method != null;
    }

    public static Class<?> toType(Object target) {
        Class<?> type = null;
        if (target instanceof IObservableValue) {
            IObservableValue value = (IObservableValue) target;
            Object valueType = value.getValueType();
            if (valueType instanceof Class<?>) {
                type = (Class<?>) valueType;
            }
        } else if (target instanceof Class<?>) {
            type = (Class<?>) target;
        } else if (target instanceof IDataProvider) {
            IDataProvider dataProvider = (IDataProvider) target;
            type = (Class<?>) toType(dataProvider.getData(null));
        } else {
            type = target.getClass();
        }
        if (type == null) {
            return Object.class;
        }
        return type;
    }

    public static boolean isValueProperty(Class<?> object, String propertyName) {
        if (propertyName == null) {
            return false;
        }

        if (Viewer.class.isAssignableFrom(object)) {
            return isViewerValueProperty(object, propertyName);
        } else if (MenuItem.class.isAssignableFrom(object)) {
            //
            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=280157
            // testcase:
            // org.eclipse.xwt.tests.databinding.bindcontrol.BindMenuItem
            //
            if (ENABLED.equalsIgnoreCase(propertyName)) {
                return true;
            } else if (SELECTION.equalsIgnoreCase(propertyName)) {
                return true;
            }
        }
        boolean isProperty = isControlValueProperty(object, propertyName);
        if (isProperty) {
            return true;
        }
        return false;
    }

    public static IObservable observeWidget(Object object, String propertyName,
            UpdateSourceTrigger updateSourceTrigger, int observedKind) {
        if (propertyName == null) {
            return null;
        }
        try {
            switch (observedKind) {
            case ScopeManager.AUTO:
                return observePropertyValue(object, propertyName, updateSourceTrigger);
            case ScopeManager.COLLECTION:
            case ScopeManager.SET:
            case ScopeManager.LIST:
                break;
            case ScopeManager.VALUE:
                return observePropertyValue(object, propertyName, updateSourceTrigger);
            default:
                break;
            }
        } catch (XWTException e) {
        }
        return null;
    }

    protected static IObservable observePropertyValue(Object object, String propertyName,
            UpdateSourceTrigger updateSourceTrigger) {
        if (object instanceof Viewer) {
            if ("input".equals(propertyName)) {
                Viewer viewer = (Viewer) object;
                SimpleValueProperty property = (SimpleValueProperty) ViewerProperties.input();
                IObservableValue observableValue = new SimplePropertyObservableValue(XWT.getRealm(), viewer,
                        property);
                return new TypedViewerObservableValueDecorator(observableValue, viewer);
            } else if ("singleSelection".equals(propertyName)) {
                Viewer viewer = (Viewer) object;
                SimpleValueProperty property = (SimpleValueProperty) ViewerProperties.singleSelection();
                IObservableValue observableValue = new SimplePropertyObservableValue(XWT.getRealm(), viewer,
                        property);
                return new TypedViewerObservableValueDecorator(observableValue, viewer);
            }
            return observePropertyValue((Viewer) object, propertyName, updateSourceTrigger);
        } else if (object instanceof MenuItem) {
            //
            // TODO https://bugs.eclipse.org/bugs/show_bug.cgi?id=280157
            // testcase:
            // org.eclipse.xwt.tests.databinding.bindcontrol.BindMenuItem
            //
            if (ENABLED.equalsIgnoreCase(propertyName)) {
                return new MenuItemEnabledObservableValue((MenuItem) object);
            } else if (SELECTION.equalsIgnoreCase(propertyName)) {
                return new MenuItemSelectionObservableValue((MenuItem) object);
            }
        } else if (object instanceof Control) {
            return observePropertyValue((Control) object, propertyName, updateSourceTrigger);
        }
        return null;
    }

    protected static boolean isControlValueProperty(Class<?> type, String propertyName) {
        if (TEXT.equalsIgnoreCase(propertyName)) {
            if (Text.class.isAssignableFrom(type)) {
                return true;
            }
            // widget button is not supported at 3.4 version.
            if (SWT.getVersion() == 3449 && Button.class.isAssignableFrom(type)) {
                return false;
            }
        }
        String getterName = "observe" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
        Method method;
        try {
            method = SWTObservables.class.getMethod(getterName, CONTROL_ARGUMENT_TYPES);
            if (method == null) {
                for (Method element : SWTObservables.class.getMethods()) {
                    if (element.getParameterTypes().length != 0) {
                        continue;
                    }
                    if (element.getName().equalsIgnoreCase(getterName)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            throw new XWTException(e);
        }
        IMetaclass mateclass = XWT.getMetaclass(type);
        IProperty property = mateclass.findProperty(propertyName);
        if (property instanceof EventProperty) {
            return true;
        }
        return false;
    }

    protected static IObservableValue observePropertyValue(Control control, String propertyName,
            UpdateSourceTrigger updateSourceTrigger) {
        if (TEXT.equalsIgnoreCase(propertyName)) {
            if (control instanceof Text || control instanceof StyledText) {
                int event = SWT.None;
                switch (updateSourceTrigger) {
                case Default:
                    event = SWT.FocusOut;
                    break;
                case LostFocus:
                    event = SWT.FocusOut;
                    break;
                case PropertyChanged:
                    event = SWT.Modify;
                    break;
                default:
                    throw new IllegalStateException("UpdateSourceTrigger of value " + updateSourceTrigger.name());
                }
                IObservableValue observableValue = SWTObservables.observeText(control, event);
                if (observableValue != null) {
                    return observableValue;
                }
            }
            // widget button is not supported at 3.4 version.
            if (SWT.getVersion() == 3449 && control instanceof Button) {
                return null;
            }
            try {
                IObservableValue observableValue = SWTObservables.observeText(control);
                if (observableValue != null) {
                    return observableValue;
                }
            } catch (IllegalArgumentException e) {
                throw new XWTException(e);
            }
        } else {
            if (propertyName == null) {
                return null;
            }
            String getterName = "observe" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
            Method method;
            try {
                method = SWTObservables.class.getMethod(getterName, CONTROL_ARGUMENT_TYPES);
                if (method == null) {
                    for (Method element : SWTObservables.class.getMethods()) {
                        if (element.getParameterTypes().length != 0) {
                            continue;
                        }
                        if (element.getName().equalsIgnoreCase(getterName)) {
                            method = element;
                            break;
                        }
                    }
                }
                if (method != null) {
                    IObservableValue observableValue = (IObservableValue) method.invoke(null, control);
                    if (observableValue != null) {
                        return observableValue;
                    }
                }
            } catch (Exception e) {
                throw new XWTException(e);
            }
        }
        IMetaclass mateclass = XWT.getMetaclass(control);
        IProperty property = mateclass.findProperty(propertyName);
        if (property instanceof EventProperty) {
            return new EventPropertyObservableValue(control, (EventProperty) property);
        }
        return null;
    }

    protected static boolean isViewerValueProperty(Class<?> viewerType, String property) {
        String getterName = "observe" + property.substring(0, 1).toUpperCase() + property.substring(1);
        try {
            Method method = ViewersObservables.class.getMethod(getterName, VIEWER_ARGUMENT_TYPES);
            if (method == null) {
                for (Method element : ViewersObservables.class.getMethods()) {
                    if (element.getParameterTypes().length != 0) {
                        continue;
                    }
                    if (element.getName().equalsIgnoreCase(getterName)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            throw new XWTException(e);
        }
        return false;
    }

    protected static IObservable observePropertyValue(Viewer viewer, String property,
            UpdateSourceTrigger updateSourceTrigger) {
        String getterName = "observe" + property.substring(0, 1).toUpperCase() + property.substring(1);
        Method method;
        try {
            method = ViewersObservables.class.getMethod(getterName, VIEWER_ARGUMENT_TYPES);
            if (method == null) {
                for (Method element : ViewersObservables.class.getMethods()) {
                    if (element.getParameterTypes().length != 0) {
                        continue;
                    }
                    if (element.getName().equalsIgnoreCase(getterName)) {
                        method = element;
                        break;
                    }
                }
            }
            if (method != null) {
                IObservable observableValue = (IObservable) method.invoke(null, viewer);
                if (observableValue != null) {
                    return observableValue;
                }
            }
        } catch (Exception e) {
            throw new XWTException(e);
        }
        return null;
    }
}