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()); } }

最新文章

  1. PostgreSQL全文检索zhparser使用
  2. 在Windows下配置Python+Django+Eclipse开发环境
  3. 一起写一个JSON解析器
  4. 在VMware上安装Ubuntu14.04 , Docker
  5. [转载]传智播客_SQL入门
  6. astyle基本功能介绍
  7. 转:基础总结篇之一:Activity生命周期
  8. 2014第一周五开发问题记URL传参乱码等
  9. Python3基础 用list()查看filter()返回的对象
  10. subline text3常用插件介绍
  11. RabbitMQ系列教程之七:RabbitMQ的 C# 客户端 API 的简介
  12. 如何快速高效地完成一个Android项目?
  13. zip-gzip-bzip2_压缩文件
  14. git pull 报错 You have not concluded your merge (MERGE_HEAD exists).
  15. HTTP协议请求头信息和响应头信息
  16. DML和索引内部结构变化
  17. [IDEA] IntelliJ IDEA 安装教程
  18. 4.Liunx磁盘管理
  19. Appium Desktop Inspector 安卓真机配置(Windows)
  20. android c 读写文件

热门文章

  1. LightOJ 1321 - Sending Packets 简单最短路+期望
  2. 用reduce实现简单的pipe
  3. python学习笔记(六)之操作符
  4. js_跑马灯
  5. JSP九大内置对象,七大动作,三大指令
  6. jq 浏览器窗口大小发生变化时
  7. TCP的3次握手/4次握手
  8. wait与waitpid
  9. JS中Unix时间戳转换日期格式
  10. 【Android开发日记】之入门篇(十五)——ViewPager+自定义无限ViewPager