package com.easyooo.framework.common.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import net.sf.cglib.beans.BeanCopier;
import net.sf.cglib.beans.BeanMap;
import net.sf.cglib.beans.BulkBean;
import net.sf.cglib.core.Converter;
import org.springframework.util.StringUtils;
/**
* 简单包装了CGlib对Bean的反射操作
*
*
* @author Killer
*/
public final class CglibUtil {
/**
* 将from实体bean的属性值拷贝至to实体类的同名属性值, 可使用自定义转换器,
* 如果使用了转换器,则由转换器完成所有的属性拷贝
*
* @param from 源对象
* @param to 目标对象
* @param converter
*/
public static void copy(Object from, Object to, Converter converter) {
if (from == null || to == null) {
return;
}
boolean useConverter = (converter != null ? true : false);
BeanCopier copier = BeanCopier.create(from.getClass(), to.getClass(),
useConverter);
copier.copy(from, to, converter);
}
/**
* 将源对象属性拷贝至目标属性值,只有同名同类型的才会被拷贝
* @param from
* @param to
*/
public static void copy(Object from, Object to) {
copy(from, to, null);
}
/**
* 将Bean属性值封装至Map
* @param bean
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Map describe(Object bean){
Map target = new HashMap();
target.putAll(BeanMap.create(bean));
return target;
}
/**
* 获取Bean中部分属性值
* @param bean
* @param propertyNames 属性名称
*/
public static <T> Object[] getPropertyValue(Object bean, String... propertyNames){
if(bean == null || propertyNames.length == 0){
return null;
}
Map<?,?> beanMap = describe(bean);
Object[] obj = new Object[propertyNames.length];
for (int i = 0; i < obj.length; i++) {
obj[i] = beanMap.get(propertyNames[i]);
}
return obj;
}
@SuppressWarnings("unchecked")
public static <T> T getPropertyValue(Object bean, String propertyName){
if(StringUtils.isEmpty(propertyName)){
return null;
}
Object[] obj = getPropertyValue(bean, new String[]{propertyName});
if(obj == null || obj[0] == null){
return null;
}
return (T)(obj[0]);
}
/**
* 反射设置多个属性值
* @see #genGetterMethodName(String)
* @see #genSetterMethodName(String)
*/
public static <T> void setPropertyValues(Object bean, String[] names, Object[] values){
if(bean == null)
return;
if(names == null || names.length == 0)
return;
if(values == null)
return;
if(names.length != values.length){
throw new IllegalArgumentException("names length is "
+ names.length + ", but values length is " + values.length);
}
String[] getters = new String[names.length];
String[] setters = new String[names.length];
Class<?>[] types = new Class<?>[names.length];
for (int i = 0; i < names.length; i++) {
if(values[i] == null){
continue;
}
String name = names[i];
getters[i] = genGetterMethodName(name);
setters[i] = genSetterMethodName(name);
types[i] = values[i].getClass();
}
BulkBean bb = BulkBean.create(bean.getClass(), getters, setters, types);
bb.setPropertyValues(bean, values);
}
/**
* 反射设置单个属性值
* @see #setPropertyValues(Object, String[], Object[])
*/
public static void setPropertyValue(Object bean, String propertyName, Object value){
setPropertyValues(bean, new String[]{propertyName}, new Object[]{value});
}
/**
* 将map的值拷贝至对象中, 如果类型不一致将会导致转换异常
* @param from
* @param to
*/
@SuppressWarnings("rawtypes")
public static void populate(Map from, Object to)
throws IllegalAccessException, IllegalArgumentException,
InvocationTargetException{
if(from == null || from.size() == 0 || to == null){
return ;
}
Method[] methods = to.getClass().getDeclaredMethods();
for (Object obj: from.entrySet()) {
Map.Entry entry = (Map.Entry)obj;
Object value = entry.getValue();
String propertyName = entry.getKey().toString();
for (Method method : methods) {
if(method.getName().equals(genSetterMethodName(propertyName))){
method.invoke(to, value);
break;
}
}
}
}
/**
* 生成Getter方法名称,仅支持驼峰命名规则
*/
public static String genGetterMethodName(String propertyName){
return "get" + StringUtils.capitalize(propertyName);
}
/**
* 生成Setter方法名称,仅支持驼峰命名规则
*/
public static String genSetterMethodName(String propertyName){
return "set" + StringUtils.capitalize(propertyName);
}
}