/* ==================================================================
* Created [2009-4-27 下午11:32:55] by Jon.King
* ==================================================================
* TSS
* ==================================================================
* mailTo:jinpujun@hotmail.com
* Copyright (c) Jon.King, 2009-2012
* ==================================================================
*/
package com.jinhe.tss.core.util;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.jinhe.tss.core.exception.BusinessException;
import com.thoughtworks.xstream.XStream;
/**
* <p>
* BeanUtil.java
* </p>
*
* 定义一些用来操作实体的工具方法
*/
public class BeanUtil {
private static Log log = LogFactory.getLog(BeanUtil.class);
/**
* 对象属性复制工具
*
* @param to
* 目标拷贝对象
* @param from
* 拷贝源
*/
public static void copy(Object to, Object from) {
try {
PropertyUtils.copyProperties(to, from);
} catch (IllegalAccessException e) {
throw new BusinessException("拷贝时出错,用反射机制时属性或者方法不能被访问。", e);
} catch (InvocationTargetException e) {
throw new BusinessException("拷贝时出错,用反射机制调用方法时。", e);
} catch (NoSuchMethodException e) {
throw new BusinessException("拷贝时出错,用反射机制调用方法时方法不存在。", e);
}
}
/**
* 对象属性复制工具
*
* @param to
* 目标拷贝对象
* @param from
* 拷贝源
* @param ignore
* 需要忽略的属性
*/
public static void copy(Object to, Object from, String[] ignore) {
List<String> list = Arrays.asList(ignore);
PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(to);
for (int i = 0; i < descr.length; i++) {
PropertyDescriptor d = descr[i];
if (d.getWriteMethod() == null) continue;
if (list.contains(d.getName())) continue;
try {
Object value = PropertyUtils.getProperty(from, d.getName());
PropertyUtils.setProperty(to, d.getName(), value);
} catch (Exception e) {
log.error("属性名:" + d.getName() + " 在实体间拷贝时出错", e);
throw new BusinessException("属性名:" + d.getName() + " 在实体间拷贝时出错", e);
}
}
}
/**
* 将对象中的属性按属性名/属性值的方式存入到Map中。
*
* @param bean
* @param map
*/
public static void addBeanProperties2Map(Object bean, Map<String, Object> map){
addBeanProperties2Map(bean, map, new String[]{ });
}
/**
* 将对象中的属性按属性名/属性值的方式存入到Map中。
*
* @param bean
* @param map
* @param ignore
*/
public static void addBeanProperties2Map(Object bean, Map<String, Object> map, String[] ignore){
List<String> list = Arrays.asList(ignore);
PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(bean);
for (int i = 0; i < descr.length; i++) {
PropertyDescriptor d = descr[i];
String propertyName = d.getName();
// 既有get又有set方法的属性的值才被读取
if (d.getWriteMethod() == null || d.getReadMethod() == null) continue;
if (list.contains(propertyName)) continue;
try { // put value into Map
map.put(propertyName, PropertyUtils.getProperty(bean, propertyName));
} catch (Exception e) {
log.info("获取属性名为:" + propertyName + " 的值时出错", e);
}
}
}
/**
* 按照Map中的key和bean中的属性名一一对应,将Map中数据设定到实体对象bean中
*
* @param bean
* @param attrsMap
*/
public static void setDataToBean(Object bean, Map<String, ?> attrsMap) {
PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(bean);
for (int i = 0; i < descr.length; i++) {
PropertyDescriptor d = descr[i];
// 如果当前属性没有对应的可写的方法,则跳过到下一属性
if (d.getWriteMethod() == null) continue;
// 如果Map的key值中无当前属性值,则跳过到下一属性
if (!attrsMap.containsKey(d.getName())) continue;
try {
Class<?> clazz = d.getPropertyType();
Object value = attrsMap.get(d.getName());
/*
* 如果属性的类型不是java.lang.String且值为空,则不将map中该属性的值设置到实体中,
* 防止象Long型的guId,如果为空则值为null setProperty(....)会出错
*/
if (value == null
|| (!String.class.equals(clazz) && "".equals(value))) {
continue;
}
if (clazz.equals(Date.class)
&& value.getClass().equals(String.class)) {
value = DateUtil.parse((String) value);
//value = ((String)value).replace('-', '/'); //日期类型的2006-5-12转换成2006/5/12
}
if (value.getClass().equals(clazz)) { // value一般为前台传入,类型多为String型
PropertyUtils.setProperty(bean, d.getName(), value);
} else {
PropertyUtils.setProperty(bean, d.getName(), clazz
.getConstructor(new Class[] { String.class })
.newInstance(new Object[] { value }));
}
} catch (Exception e) {
log.error("属性名:" + d.getName() + " 设置到实体中时出错", e);
throw new BusinessException( "属性名:" + d.getName() + " 设置到实体中时出错", e);
}
}
}
/**
* <p>
* 获取实体对象的所有属性
* </p>
* @param bean 实体对象
* @return Map 属性集合
*/
public static Map<String, Object> getProperties(Object bean){
return getProperties(bean, new HashSet<String>());
}
/**
* <p>
* 获取实体对象的某些属性
* </p>
* @param bean 实体对象
* @param ignores Set 忽略的属性名集合
* @return Map 属性集合
*/
public static Map<String, Object> getProperties(Object bean, Set<String> ignores) {
Map<String, Object> map = new HashMap<String, Object>();
PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(bean);
for (int i = 0; i < descr.length; i++) {
PropertyDescriptor d = descr[i];
if (d.getReadMethod() == null) // 如果当前属性没有对应的可读的方法,则跳过
continue;
String name = d.getName();
if (ignores.contains(name)) // 如果为忽略处理属性,则跳过
continue;
map.put(name, getPropertyValue(bean, name));
}
return map;
}
/**
* 根据对象的class名,创建相应的Class对象
*
* @param className
* @return
*/
public static Class<?> createClassByName(String className) {
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
throw new BusinessException("实体: " + className + " 无法加载", e);
}
}
/**
* 根据对象的class名,创建相应的对象
*
* @param className
* @return
*/
public static Object newInstanceByName(String className) {
try {
return Class.forName(className).newInstance();
} catch (InstantiationException e) {
throw new BusinessException("实例化失败:" + className, e);
} catch (IllegalAccessException e) {
throw new BusinessException("没有合适的构造函数,实例化失败:" + className, e);
} catch (ClassNotFoundException e) {
throw new BusinessException("类文件无法找到,实例化失败:" + className, e);
}
}
/**
* <p>
* 通过带参数的构造函数实例化对象
* </p>
*
* @param className
* String
* @param clazzes
* Class[]
* @param args
* Object[]
* @return Object
*/
public static Object newInstanceByName(String className, Class<?>[] clazzes,
Object[] args) {
Class<?> clazz = createClassByName(className);
try {
return clazz.getConstructor(clazzes).newInstance(args);
} catch (IllegalArgumentException e) {
throw new BusinessException("非法参数类型,实例化失败:" + className, e);
} catch (SecurityException e) {
throw new BusinessException("安全性限制,实例化失败:" + className, e);
} catch (InstantiationException e) {
throw new BusinessException("实例化失败:" + className, e);
} catch (IllegalAccessException e) {
throw new BusinessException("没有相应的构造函数,实例化失败:" + className, e);
} catch (InvocationTargetException e) {
throw new BusinessException("非法调用,实例化失败:" + className, e);
} catch (NoSuchMethodException e) {
throw new BusinessException("没有相应的构造函数,实例化失败:" + className, e);
}
}
/**
* 根据Class对象创建Object对象
*
* @param clazz
* @return
*/
public static Object newInstance(Class<?> clazz) {
try {
return clazz.newInstance();
} catch (InstantiationException e) {
throw new BusinessException("实例化失败:" + clazz.getName(), e);
} catch (IllegalAccessException e) {
throw new BusinessException("实例化失败:" + clazz.getName(), e);
}
}
/**
* 判断属性是否在实体中
*
* @param bean
* @param propertyName
* @return
*/
public static boolean isPropertyInBean(Object bean, String propertyName) {
PropertyDescriptor[] descr = PropertyUtils.getPropertyDescriptors(bean);
for (int i = 0; i < descr.length; i++) {
PropertyDescriptor d = descr[i];
if (propertyName.equals(d.getName())) {
return true;
}
}
return false;
}
/**
* 判断对象是否继承某个接口
*
* @param clazz
* @param interfaceClazz
* @return true/false
*/
public static boolean isImplInterface(Class<?> clazz, Class<?> interfaceClazz) {
//TODO 需要改进,如果接口继承了其它接口,或者超类继承了接口,getInterfaces()将取不到,它只能取到向上一层的接口
return Arrays.asList(clazz.getInterfaces()).contains(interfaceClazz);
}
/**
* <p>
* 将对象格式化为XML字符串
* </p>
* @param bean Object Java对象
* @return String XML字符串
*/
public static String toXml(Object bean) {
XStream xs = new XStream();
return xs.toXML(bean);
}
/**
* 获取对象中指定属性的值
* @param obj
* @param propertyName
* @return
*/
public static Object getPropertyValue(Object obj, String propertyName) {
try {
return PropertyUtils.getProperty(obj, propertyName);
} catch (IllegalAccessException e) {
throw new BusinessException("没有权限访问相应属性:" + propertyName, e);
} catch (InvocationTargetException e) {
throw new BusinessException("访问属性:" + propertyName + "时出错", e);
} catch (NoSuchMethodException e) {
throw new BusinessException("属性:" + propertyName + "没有相应的GET方法", e);
}
}
}