实现JavaBean的属性设置和拷贝

有对象a

a中有对象属性b

b中有基本对象c

则通过参数 a和a.b.c获得c的值

或者b为数组

通过参数 a和a.b[1].c 获得c的值

 

方法  public static Object getProperty(Object bean, String name)为入口

程序代码如下:

import java.beans.BeanInfo;
import java.beans.IndexedPropertyDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;

public class BeanUtils {
 
 private static HashMap descriptorsCache;
    static {
        descriptorsCache = new HashMap();
    }

    public static Map describe(Object bean) throws IllegalAccessException,
                                                      InvocationTargetException,
                                                      NoSuchMethodException      {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
 
        PropertyDescriptor descriptors[] = getPropertyDescriptors(bean);
        Map description = new HashMap(descriptors.length);

        for (int i = 0; i < descriptors.length; i++) {
  
            String name = descriptors[i].getName();
          
            if (descriptors[i].getReadMethod() != null)
                description.put(name, getProperty(bean, name));
        }
        return description;
    }
   

    public static Object getIndexedProperty(Object bean, String name)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");

        int delim = name.indexOf('[');
        int delim2 = name.indexOf(']');

        if (delim < 0 || delim2 <= delim)
            throw new IllegalArgumentException("Invalid indexed property '"
                    + name + "'");
        int index = -1;
        try {
            String subscript = name.substring(delim + 1, delim2);
            index = Integer.parseInt(subscript);
        } catch (NumberFormatException numberformatexception) {
            throw new IllegalArgumentException("Invalid indexed property '"
                    + name + "'");
        }
        name = name.substring(0, delim);

        return getIndexedProperty(bean, name, index);
    }

  
    public static Object getIndexedProperty(Object bean, String name, int index)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
      
        PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
        if (descriptor == null)
            throw new NoSuchMethodException("Unknown property '" + name + "'");
        Method readMethod;
       
        if (descriptor instanceof IndexedPropertyDescriptor) {   

            readMethod = ((IndexedPropertyDescriptor) descriptor)
                    .getIndexedReadMethod();

            if (readMethod != null) {
                Object subscript[] = new Object[1];
                subscript[0] = new Integer(index);

                return readMethod.invoke(bean, subscript);
            }
        }
        readMethod = getReadMethod(descriptor);

        if (readMethod == null)
            throw new NoSuchMethodException("Property '" + name
                    + "' has no getter method");

        Object value = readMethod.invoke(bean, new Object[0]);

        if (!value.getClass().isArray())
            throw new IllegalArgumentException("Property '" + name
                    + "' is not indexed");
        else
            return Array.get(value, index);
    }


    public static Object getNestedProperty(Object bean, String name)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {

        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
        do {
            int delim = name.indexOf('.');
 
            if (delim < 0)
                break;
            String next = name.substring(0, delim);
            if (next.indexOf('[') >= 0)

                bean = getIndexedProperty(bean, next);
            else
                bean = getSimpleProperty(bean, next);
            if (bean == null)
                throw new IllegalArgumentException("Null property value for '"
                        + name.substring(0, delim) + "'");
            name = name.substring(delim + 1);
        } while (true);
        if (name.indexOf('[') >= 0)
            return getIndexedProperty(bean, name);
        else
            return getSimpleProperty(bean, name);
    }
   
    public static Object getProperty(Object bean, String name)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        //System.out.println("----------" + bean.getClass().getName() + " name=" + name);
        return getNestedProperty(bean, name);
    }

    public static PropertyDescriptor getPropertyDescriptor(Object bean,
            String name) throws IllegalAccessException,
            InvocationTargetException, NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
        do {
            int period = name.indexOf('.');
            if (period < 0)
                break;
            String next = name.substring(0, period);
            if (next.indexOf('[') >= 0)
                bean = getIndexedProperty(bean, next);
            else
                bean = getSimpleProperty(bean, next);
            if (bean == null)
                throw new IllegalArgumentException("Null property value for '"
                        + name.substring(0, period) + "'");
            name = name.substring(period + 1);
        } while (true);
        //     System.out.println("----start 13--");
        int left = name.indexOf('[');
        if (left >= 0)
            name = name.substring(0, left);
        if (bean == null || name == null)
            return null;
        PropertyDescriptor descriptors[] = getPropertyDescriptors(bean);
        if (descriptors == null)
            return null;
        for (int i = 0; i < descriptors.length; i++)
            if (name.equals(descriptors[i].getName()))
                return descriptors[i];
        return null;
    }

    /**
     * @param bean  对象
     * @return   返回该对象的属性描述集合对象
     */
    public static PropertyDescriptor[] getPropertyDescriptors(Object bean) {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
      
        String beanClassName = bean.getClass().getName();
        PropertyDescriptor descriptors[] = null;
        descriptors = (PropertyDescriptor[]) descriptorsCache
                .get(beanClassName);
        if (descriptors != null)
            return descriptors;

        BeanInfo beanInfo = null;
        try {

            beanInfo = Introspector.getBeanInfo(bean.getClass());
        } catch (IntrospectionException introspectionexception) {
            return new PropertyDescriptor[0];
        }

        descriptors = beanInfo.getPropertyDescriptors();

        if (descriptors == null)
            descriptors = new PropertyDescriptor[0];

        descriptorsCache.put(beanClassName, descriptors);

        return descriptors;
    }

    public static Class getPropertyEditorClass(Object bean, String name)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
        PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
        if (descriptor != null)
            return descriptor.getPropertyEditorClass();
        else
            return null;
    }

    public static Class getPropertyType(Object bean, String name)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
        PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
        if (descriptor == null)
            return null;
        if (descriptor instanceof IndexedPropertyDescriptor)
            return ((IndexedPropertyDescriptor) descriptor)
                    .getIndexedPropertyType();
        else
            return descriptor.getPropertyType();
    }

    public static Method getReadMethod(PropertyDescriptor descriptor) {

        return getAccessibleMethod(descriptor.getReadMethod());
    }

    public static Object getSimpleProperty(Object bean, String name)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");

        if (name.indexOf('.') >= 0)
            throw new IllegalArgumentException(
                    "Nested property names are not allowed");
        if (name.indexOf('[') >= 0)
            throw new IllegalArgumentException(
                    "Indexed property names are not allowed");
        PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
        if (descriptor == null)
            throw new NoSuchMethodException("Unknown property '" + name + "'");
        Method readMethod = getReadMethod(descriptor);
        if (readMethod == null) {
            throw new NoSuchMethodException("Property '" + name
                    + "' has no getter method");
        } else {
            Object value = readMethod.invoke(bean, new Object[0]);
            return value;
        }
    }

    public static Method getWriteMethod(PropertyDescriptor descriptor) {
        return getAccessibleMethod(descriptor.getWriteMethod());
    }

    public static void setIndexedProperty(Object bean, String name, Object value)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
        int delim = name.indexOf('[');
        int delim2 = name.indexOf(']');
        if (delim < 0 || delim2 <= delim)
            throw new IllegalArgumentException("Invalid indexed property '"
                    + name + "'");
        int index = -1;
        try {
            String subscript = name.substring(delim + 1, delim2);
            index = Integer.parseInt(subscript);
        } catch (NumberFormatException numberformatexception) {
            throw new IllegalArgumentException("Invalid indexed property '"
                    + name + "'");
        }
        name = name.substring(0, delim);
        setIndexedProperty(bean, name, index, value);
    }

    public static void setIndexedProperty(Object bean, String name, int index,
            Object value) throws IllegalAccessException,
            InvocationTargetException, NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
        PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
        if (descriptor == null)
            throw new NoSuchMethodException("Unknown property '" + name + "'");
        if (descriptor instanceof IndexedPropertyDescriptor) {
            Method writeMethod = ((IndexedPropertyDescriptor) descriptor)
                    .getIndexedWriteMethod();
            if (writeMethod != null) {
                Object subscript[] = new Object[2];
                subscript[0] = new Integer(index);
                subscript[1] = value;
                writeMethod.invoke(bean, subscript);
                return;
            }
        }
        Method readMethod = descriptor.getReadMethod();
        if (readMethod == null)
            throw new NoSuchMethodException("Property '" + name
                    + "' has no getter method");
        Object array = readMethod.invoke(bean, new Object[0]);
        if (!array.getClass().isArray()) {
            throw new IllegalArgumentException("Property '" + name
                    + "' is not indexed");
        } else {
            Array.set(array, index, value);
            return;
        }
    }

    public static void setNestedProperty(Object bean, String name, Object value)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
        do {
            int delim = name.indexOf('.');
            if (delim < 0)
                break;
            String next = name.substring(0, delim);
            if (next.indexOf('[') >= 0)
                bean = getIndexedProperty(bean, next);
            else
                bean = getSimpleProperty(bean, next);
            if (bean == null)
                throw new IllegalArgumentException("Null property value for '"
                        + name.substring(0, delim) + "'");
            name = name.substring(delim + 1);
        } while (true);
        if (name.indexOf('[') >= 0)
            setIndexedProperty(bean, name, value);
        else
            setSimpleProperty(bean, name, value);
    }

    public static void setProperty(Object bean, String name, Object value)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        setNestedProperty(bean, name, value);
    }

    public static void setSimpleProperty(Object bean, String name, Object value)
            throws IllegalAccessException, InvocationTargetException,
            NoSuchMethodException {
        if (bean == null)
            throw new IllegalArgumentException("No bean specified");
        if (name == null)
            throw new IllegalArgumentException("No name specified");
        if (name.indexOf('.') >= 0)
            throw new IllegalArgumentException(
                    "Nested property names are not allowed");
        if (name.indexOf('[') >= 0)
            throw new IllegalArgumentException(
                    "Indexed property names are not allowed");
        PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
        if (descriptor == null)
            throw new NoSuchMethodException("Unknown property '" + name + "'");
        Method writeMethod = getWriteMethod(descriptor);
        if (writeMethod == null) {
            throw new NoSuchMethodException("Property '" + name
                    + "' has no setter method");
        } else {
            Object values[] = new Object[1];
            values[0] = value;
            writeMethod.invoke(bean, values);
            return;
        }
    }


    private static Method getAccessibleMethod(Method method) {
        if (method == null)
            return null;

        if (!Modifier.isPublic(method.getModifiers()))
            return null;

        Class clazz = method.getDeclaringClass();
        if (Modifier.isPublic(clazz.getModifiers())) {
   
            return method;
        } else {
            String methodName = method.getName();

            Class parameterTypes[] = method.getParameterTypes();
            method = getAccessibleMethodFromInterfaceNest(clazz, method
                    .getName(), method.getParameterTypes());
            return method;
        }
    }


    private static Method getAccessibleMethodFromInterfaceNest(Class clazz,
            String methodName, Class parameterTypes[]) {
        Method method = null;

        Class interfaces[] = clazz.getInterfaces();
        for (int i = 0; i < interfaces.length; i++) {
 
            if (!Modifier.isPublic(interfaces[i].getModifiers()))
                continue;
            try {
                method = interfaces[i].getDeclaredMethod(methodName,
                        parameterTypes);
            } catch (NoSuchMethodException nosuchmethodexception) {
            }

            if (method != null)
                break;

            method = getAccessibleMethodFromInterfaceNest(interfaces[i],
                    methodName, parameterTypes);

            if (method != null)
                break;
        }
        return method;
    }

    public static final char INDEXED_DELIM = 91;
    public static final char INDEXED_DELIM2 = 93;
    public static final char NESTED_DELIM = 46;
    private static int debug = 0;
   
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值