一个Bean属性拷贝的工具类

package com.fpi.spring.qaepb.cps.util;



import java.beans.IntrospectionException;

import java.beans.PropertyDescriptor;

import java.io.ByteArrayInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;



import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;



import com.fpi.spring.qaepb.cps.entity.po.Project;

import com.fpi.spring.qaepb.cps.entity.po.ProjectApproval;



/**

 * bean的属性拷贝工具类

 * 

 * @date 2013-12-17

 * 

 * @author yang_qiao

 * 

 * @version 1.0

 */

public class BeanUtils {



    private static final Log logger = LogFactory.getLog(BeanUtils.class);



    /** bean嵌套 */

    private static final String NESTED = ".";



    /**

     * 复制bean的属性(支持嵌套属性,以点号分割)

     * 

     * @param source

     *            拷贝属性的源对象

     * 

     * @param dest

     *            拷贝属性的目的地对象

     * 

     * @param includeProperties

     *            拷贝的属性列表

     * 

     * @author yang_qiao

     * 

     * @throws InvocationTargetException

     * 

     * @throws IllegalAccessException

     * 

     * @throws IllegalArgumentException

     * 

     * @throws InstantiationException

     * 

     * @throws IntrospectionException

     * 

     * @date 2013-12-18

     */

    public static final void copyIncludeProperties(final Object source,

            Object dest, final String[] includeProperties)

            throws IllegalArgumentException, IllegalAccessException,

            InvocationTargetException, InstantiationException,

            IntrospectionException {

        if (includeProperties == null || includeProperties.length == 0) {

            throw new IllegalArgumentException("未传入要拷贝的属性列表");

        }

        if (source == null) {

            throw new IllegalArgumentException("要拷贝的源对象为空");

        }

        if (dest == null) {

            throw new IllegalArgumentException("要拷贝的目的对象为空");

        }

        // 日志信息

        if (logger.isTraceEnabled()) {

            logger.trace("[source bean: " + source.getClass().getName() + " ]");

            logger.trace("[destination bean: " + dest.getClass().getName()

                    + " ]");

        }

        // 拷贝

        for (String property : includeProperties) {

            PropertyDescriptor sourcePropertyDescriptor = null;

            PropertyDescriptor destPropertyDescriptor = null;

            if (isSimpleProperty(property)) { // 简单属性

                sourcePropertyDescriptor = getProperty(property, source);

                destPropertyDescriptor = getProperty(property, dest);

                if (sourcePropertyDescriptor == null) {

                    throw new IllegalArgumentException("要拷贝的源对象不存在该属性");

                }

                if (destPropertyDescriptor == null) {

                    throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");

                }

                copyProperty(property, source, dest);

            } else { // 嵌套bean属性

                Object target = dest;

                Object realSource = source;

                String[] nestedProperty = getNestedProperty(property);

                if (nestedProperty != null && nestedProperty.length > 1) {

                    for (int i = 0; i < nestedProperty.length - 1; i++) {

                        sourcePropertyDescriptor = getProperty(

                                nestedProperty[i], realSource);

                        destPropertyDescriptor = getProperty(nestedProperty[i],

                                target);

                        if (sourcePropertyDescriptor == null) {

                            throw new IllegalArgumentException("要拷贝的源对象不存在该属性");

                        }

                        if (destPropertyDescriptor == null) {

                            throw new IllegalArgumentException(

                                    "要拷贝到的目标对象不存在该属性");

                        }

                        Method readMethod = sourcePropertyDescriptor

                                .getReadMethod();

                        realSource = readMethod.invoke(realSource);

                        readMethod = destPropertyDescriptor.getReadMethod();

                        Method writeMethod = destPropertyDescriptor

                                .getWriteMethod();

                        Object value = readMethod.invoke(target);

                        if (value == null) {

                            value = destPropertyDescriptor.getPropertyType()

                                    .newInstance();

                            writeMethod.invoke(target, value);

                        }

                        target = value;

                    }

                    final String prop = nestedProperty[nestedProperty.length - 1];

                    sourcePropertyDescriptor = getProperty(prop, realSource);

                    destPropertyDescriptor = getProperty(prop, target);

                    if (sourcePropertyDescriptor == null) {

                        throw new IllegalArgumentException("要拷贝的源对象不存在该属性");

                    }

                    if (destPropertyDescriptor == null) {

                        throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");

                    }

                    copyProperty(prop, realSource, target);

                }

            }

        }

    }



    /**

     * 复制bean的属性(支持嵌套属性,以点号分割)

     * 

     * @param source

     *            拷贝属性的源对象

     * 

     * @param dest

     *            拷贝属性的目的地对象

     * 

     * @param includeProperties

     *            拷贝的属性列表

     * 

     * @author yang_qiao

     * 

     * @throws IntrospectionException

     * 

     * @throws InvocationTargetException

     * 

     * @throws IllegalAccessException

     * 

     * @throws IllegalArgumentException

     * 

     * @throws InstantiationException

     * 

     * @throws ClassNotFoundException

     * 

     * @throws IOException

     * 

     * @date 2013-12-18

     */

    public static void copyProperties(final Object source, final Object dest,

            final String... excludeProperties) throws IntrospectionException,

            IllegalArgumentException, IllegalAccessException,

            InvocationTargetException, InstantiationException, IOException,

            ClassNotFoundException {

        final Object backupSource = clone(dest);

        if (source == null) {

            throw new IllegalArgumentException("要拷贝的源对象为空");

        }

        if (dest == null) {

            throw new IllegalArgumentException("要拷贝的目的对象为空");

        }

        org.apache.commons.beanutils.BeanUtils.copyProperties(dest, source);

        // 还原排除的属性值

        revertProperties(backupSource, dest, excludeProperties);

    }



    /**

     * 从备份对象中还原属性

     * 

     * @param backup

     *            备份bean

     * 

     * @param target

     *            目标bean

     * 

     * @param properties

     *            属性列表

     * 

     * @author yang_qiao

     * 

     * @throws InvocationTargetException

     * 

     * @throws IllegalAccessException

     * 

     * @throws IllegalArgumentException

     * 

     * @throws IntrospectionException

     * 

     * @throws InstantiationException

     * 

     * @date 2013-12-18

     */

    private static void revertProperties(final Object backup, Object target,

            final String... properties) throws IllegalArgumentException,

            IllegalAccessException, InvocationTargetException,

            IntrospectionException, InstantiationException {

        if (properties == null || properties.length == 0) {

            return;

        }

        if (backup == null) {

            throw new IllegalArgumentException("备份对象为空");

        }

        if (target == null) {

            throw new IllegalArgumentException("目的对象为空");

        }

        // 日志信息

        if (logger.isTraceEnabled()) {

            logger.trace("[source bean: " + backup.getClass().getName() + " ]");

            logger.trace("[destination bean: " + target.getClass().getName()

                    + " ]");

        }

        // 拷贝

        for (String property : properties) {

            PropertyDescriptor sourcePropertyDescriptor = null;

            PropertyDescriptor destPropertyDescriptor = null;

            if (isSimpleProperty(property)) { // 简单属性

                sourcePropertyDescriptor = getProperty(property, backup);

                destPropertyDescriptor = getProperty(property, target);

                if (sourcePropertyDescriptor == null) {

                    throw new IllegalArgumentException("要拷贝的源对象不存在该属性");

                }

                if (destPropertyDescriptor == null) {

                    throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");

                }

                copyProperty(property, backup, target);

            } else { // 嵌套bean属性

                Object targetObj = target;

                Object realBackup = backup;

                String[] nestedProperty = getNestedProperty(property);

                if (nestedProperty != null && nestedProperty.length > 1) {

                    for (int i = 0; i < nestedProperty.length - 1; i++) {

                        sourcePropertyDescriptor = getProperty(

                                nestedProperty[i], realBackup);

                        destPropertyDescriptor = getProperty(nestedProperty[i],

                                targetObj);

                        if (sourcePropertyDescriptor == null) {

                            throw new IllegalArgumentException("要拷贝的源对象不存在该属性");

                        }

                        if (destPropertyDescriptor == null) {

                            throw new IllegalArgumentException(

                                    "要拷贝到的目标对象不存在该属性");

                        }

                        Method readMethod = sourcePropertyDescriptor

                                .getReadMethod();

                        realBackup = readMethod.invoke(realBackup);

                        if (realBackup == null) { // 判断备份对象嵌套属性是否为空

                            realBackup = sourcePropertyDescriptor

                                    .getPropertyType().newInstance();

                        }

                        Method writeMethod = destPropertyDescriptor

                                .getWriteMethod();

                        readMethod = destPropertyDescriptor.getReadMethod();

                        Object value = readMethod.invoke(targetObj);

                        if (value == null) {

                            value = destPropertyDescriptor.getPropertyType()

                                    .newInstance();

                            writeMethod.invoke(targetObj, value);

                        }

                        targetObj = value;

                    }

                    final String prop = nestedProperty[nestedProperty.length - 1];

                    sourcePropertyDescriptor = getProperty(prop, realBackup);

                    destPropertyDescriptor = getProperty(prop, targetObj);

                    if (sourcePropertyDescriptor == null) {

                        throw new IllegalArgumentException("要拷贝的源对象不存在该属性");

                    }

                    if (destPropertyDescriptor == null) {

                        throw new IllegalArgumentException("要拷贝到的目标对象不存在该属性");

                    }

                    copyProperty(prop, realBackup, targetObj);

                }

            }

        }

    }



    /**

     * 对象克隆

     * 

     * @author yang_qiao

     * 

     * @date 2013-12-18

     */

    private static Object clone(final Object value) throws IOException,

            ClassNotFoundException {

        // 字节数组输出流,暂存到内存中

        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        // 序列化

        ObjectOutputStream oos = new ObjectOutputStream(bos);

        oos.writeObject(value);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());

        ObjectInputStream ois = new ObjectInputStream(bis);

        // 反序列化

        return ois.readObject();

    }



    /**

     * 判断是否为简单属性,是,返回ture

     * 

     * @author yang_qiao

     * 

     * @date 2013-12-18

     */

    private static boolean isSimpleProperty(final String property) {

        return !property.contains(NESTED);

    }



    /**

     * 获取目标bean的属性

     * 

     * @author yang_qiao

     * 

     * @date 2013-12-17

     */

    private static PropertyDescriptor getProperty(final String propertyName,

            final Object target) {

        if (target == null) {

            new IllegalArgumentException("查询属性的对象为空");

        }

        if (propertyName == null || "".equals(propertyName)) {

            new IllegalArgumentException("查询属性不能为空值");

        }

        PropertyDescriptor propertyDescriptor = null;

        try {

            propertyDescriptor = new PropertyDescriptor(propertyName,

                    target.getClass());

        } catch (IntrospectionException e) {

            logger.info("不存在该属性");

            return null;

        }

        return propertyDescriptor;

    }



    /**

     * 单个属性复制--原数据源和目的数据源必须要有该属性方可

     * 

     * @author yang_qiao

     * 

     * @throws InvocationTargetException

     * 

     * @throws IllegalAccessException

     * 

     * @throws IllegalArgumentException

     * 

     * @throws IntrospectionException

     * 

     * @date 2013-12-17

     */

    public static void copyProperty(final String propertyName,

            final Object source, Object dest) throws IllegalArgumentException,

            IllegalAccessException, InvocationTargetException,

            IntrospectionException {

        PropertyDescriptor property;

        property = new PropertyDescriptor(propertyName, source.getClass());

        Method getMethod = property.getReadMethod();

        Object value = getMethod.invoke(source);

        property = new PropertyDescriptor(propertyName, dest.getClass());

        Method setMethod = property.getWriteMethod();

        setMethod.invoke(dest, value);

    }



    /**

     * 获取嵌套Bean的属性

     * 

     * @author yang_qiao

     * 

     * @date 2013-12-18

     */

    public static String[] getNestedProperty(final String nestedProperty) {

        if (nestedProperty == null || "".equals(nestedProperty)) {

            new IllegalArgumentException("参数为空值");

        }

        return nestedProperty.split("\\" + NESTED);

    }



    public static void main(String[] args) throws IllegalArgumentException,

            IllegalAccessException, InvocationTargetException,

            InstantiationException, IntrospectionException, IOException,

            ClassNotFoundException {

        Project oldProject = new Project();

        Project newProject = new Project();

        ProjectApproval projectApproval = new ProjectApproval();

        projectApproval.setFirstCheckComment("jsoncheck");

        projectApproval.setExplorationComment("shitCheck");

        oldProject.setProjectApproval(projectApproval);

        oldProject.setBuildAddress("json");

        oldProject.setContact("json");

        final String[] includeProperties = new String[] { "contact",

                "projectApproval.firstCheckComment",

                "projectApproval.explorationComment" };

        BeanUtils.copyIncludeProperties(oldProject, newProject,

                includeProperties);

        System.out.println(newProject.getContact());

        System.out.println(newProject.getProjectApproval()

                .getFirstCheckComment());

        System.out.println(newProject.getProjectApproval()

                .getExplorationComment());

        System.out.println(newProject.getApprovalStatus());

        System.out.println(newProject.getBuildAddress());



        System.out.println("================================");



        oldProject = new Project();

        newProject = new Project();

        projectApproval = new ProjectApproval();

        projectApproval.setFirstCheckComment("jsoncheck_");

        projectApproval.setExplorationComment("shitCheck_");

        oldProject.setProjectApproval(projectApproval);

        oldProject.setBuildAddress("json_");

        oldProject.setContact("json_");

        final String[] excludeProperties = null;

        BeanUtils.copyProperties(oldProject, newProject, excludeProperties);

        System.out.println(newProject.getContact());

        System.out.println(newProject.getProjectApproval()

                .getExplorationComment());

        System.out.println(newProject.getProjectApproval()

                .getFirstCheckComment());

        System.out.println(newProject.getApprovalStatus());

        System.out.println(newProject.getBuildAddress());



    }



}

 

你可能感兴趣的:(bean)