All Downloads are FREE. Search and download functionalities are using the official Maven repository.

webit.script.util.bean.BeanUtil Maven / Gradle / Ivy

There is a newer version: 1.5.2
Show newest version
// Copyright (c) 2013, Webit Team. All Rights Reserved.
package webit.script.util.bean;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import webit.script.util.ClassUtil;
import webit.script.util.StringUtil;
import webit.script.util.collection.ClassIdentityHashMap;

/**
 *
 * @author Zqq
 */
public class BeanUtil {

    private final static ClassIdentityHashMap CACHE = new ClassIdentityHashMap();

    public static Object get(final Object bean, final String name) throws BeanUtilException {

        Getter getter;
        if ((getter = getFieldDescriptor(bean.getClass(), name).getter) != null) {
            return getter.get(bean);
        } else {
            throw new BeanUtilException(StringUtil.concat("Unable to get getter for ", bean.getClass().getName(), "#", name));
        }
    }

    public static void set(final Object bean, final String name, Object value) throws BeanUtilException {
        set(bean, name, value, false);
    }

    public static void set(final Object bean, final String name, Object value, boolean convertIfNeed) throws BeanUtilException {

        Setter setter;
        if ((setter = getFieldDescriptor(bean.getClass(), name).setter) != null) {
            if (convertIfNeed && value != null && value instanceof String) {
                value = Convert.convert((String) value, setter.getPropertyType());
            }
            setter.set(bean, value);
        } else {
            throw new BeanUtilException(StringUtil.concat("Unable to get setter for ", bean.getClass().getName(), "#", name));
        }
    }

    private static FieldDescriptor getFieldDescriptor(final Class cls, final String name) throws BeanUtilException {
        FieldDescriptorsBox box;
        if ((box = CACHE.unsafeGet(cls)) == null) {
            box = CACHE.putIfAbsent(cls, new FieldDescriptorsBox());
        }
        Map descriptors;
        if ((descriptors = box.descriptors) == null) {
            synchronized (box) {
                if ((descriptors = box.descriptors) == null) {
                    descriptors = resolveClassDescriptor(cls);
                    box.descriptors = descriptors;
                }
            }
        }

        FieldDescriptor fieldDescriptor;
        if ((fieldDescriptor = descriptors.get(name)) != null) {
            return fieldDescriptor;
        } else {
            throw new BeanUtilException(StringUtil.concat("Unable to get field: ", cls.getName(), "#", name));
        }
    }

    private static Map resolveClassDescriptor(Class cls) {
        FieldInfo[] fieldInfos = FieldInfoResolver.resolver(cls);
        Map map = new HashMap(fieldInfos.length * 4 / 3 + 1, 0.75f);
        FieldInfo fieldInfo;
        for (int i = 0, len = fieldInfos.length; i < len;) {
            fieldInfo = fieldInfos[i++];
            //Getter
            final Getter getter;
            if (fieldInfo.getGetterMethod() != null) {
                getter = new MethodGetter(fieldInfo.getGetterMethod());
            } else if (fieldInfo.getField() != null) {
                getter = new FieldGetter(fieldInfo.getField());
            } else {
                getter = null;
            }

            final Setter setter;
            if (fieldInfo.getSetterMethod() != null) {
                setter = new MethodSetter(fieldInfo.getSetterMethod());
            } else if (fieldInfo.getField() != null && fieldInfo.isIsFinal() == false) {
                setter = new FieldSetter(fieldInfo.getField());
            } else {
                setter = null;
            }

            map.put(fieldInfo.name, new FieldDescriptor(getter, setter));
        }
        return map;
    }

    private static final class FieldDescriptorsBox {

        Map descriptors;
    }

    private static final class FieldDescriptor {

        final Getter getter;
        final Setter setter;

        FieldDescriptor(Getter getter, Setter setter) {
            this.getter = getter;
            this.setter = setter;
        }
    }

    private static interface Getter {

        Object get(Object bean);
    }

    private static interface Setter {

        Class getPropertyType();

        void set(Object bean, Object value);
    }

    private static final class MethodGetter implements Getter {

        private final Method method;

        MethodGetter(Method method) {
            ClassUtil.setAccessible(method);
            this.method = method;
        }

        public Object get(Object bean) throws BeanUtilException {
            try {
                return this.method.invoke(bean, new Object[0]);
            } catch (Exception ex) {
                throw new BeanUtilException(ex.getMessage());
            }
        }
    }

    private static final class MethodSetter implements Setter {

        private final Method method;
        private final Class fieldType;

        MethodSetter(Method method) {
            ClassUtil.setAccessible(method);
            this.method = method;
            this.fieldType = method.getParameterTypes()[0];
        }

        public Class getPropertyType() {
            return this.fieldType;
        }

        public void set(Object bean, Object value) throws BeanUtilException {
            try {
                this.method.invoke(bean, new Object[]{value});
            } catch (Exception ex) {
                throw new BeanUtilException(ex.getMessage());
            }
        }
    }

    private static final class FieldGetter implements Getter {

        private final Field field;

        FieldGetter(Field field) {
            ClassUtil.setAccessible(field);
            this.field = field;
        }

        public Object get(Object bean) throws BeanUtilException {
            try {
                return this.field.get(bean);
            } catch (Exception ex) {
                throw new BeanUtilException(ex.getMessage());
            }
        }
    }

    private static final class FieldSetter implements Setter {

        private final Field field;
        private final Class fieldType;

        FieldSetter(Field field) {
            ClassUtil.setAccessible(field);
            this.field = field;
            this.fieldType = field.getDeclaringClass();
        }

        public void set(Object bean, Object value) throws BeanUtilException {
            try {
                this.field.set(bean, value);
            } catch (Exception ex) {
                throw new BeanUtilException(ex.getMessage());
            }
        }

        public Class getPropertyType() {
            return this.fieldType;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy