import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.commons.beanutils.PropertyUtils;
/**
* <p>
* 基本Bean操作的工具类,
* <p>
* 继承自{@link org.apache.commons.beanutils.BeanUtils}
* <p>
* 封装了克隆Bean,拷贝属性,获取属性键值列表等操作。
*/
public class BeanUtils extends org.apache.commons.beanutils.BeanUtils {
/**
* 拷贝orig参数中非空的属性到dest参数对象中,忽略为空的属性
* @param dest 目标对象
* @param orig 源对象
* @throws IllegalAccessException
* @throws InvocationTargetException
* @throws NoSuchMethodException
*/
@SuppressWarnings("unchecked")
public static void copyNotNullProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Map<String, Object> map = describe(orig);
Iterator<Entry<String, Object>> it = map.entrySet().iterator();
while (it.hasNext()) {
Entry<String, Object> entry = it.next();
String name = entry.getKey();
if (entry.getValue() == null) {
continue;
}
if ("class".equals(name)) {
continue; // No point in trying to set an object's class
}
if (PropertyUtils.isReadable(orig, name) && PropertyUtils.isWriteable(dest, name)) {
try {
Object value = PropertyUtils.getSimpleProperty(orig, name);
copyProperty(dest, name, value);
} catch (NoSuchMethodException e) {
}
}
}
}
/**
* 拷贝source中的参数到target中,并忽略掉ignoreProperties指定的属性值。
* @param source 源对象
* @param target 目标对象
* @param ignoreProperties 需要忽略的属性
*/
public static void copyProperties(Object source, Object target, String[] ignoreProperties) {
Class<?> actualEditable = target.getClass();
PropertyDescriptor[] targetPds = PropertyUtils.getPropertyDescriptors(actualEditable);
PropertyDescriptor[] sourcePds = PropertyUtils.getPropertyDescriptors(source.getClass());
List<String> ignoreList = (ignoreProperties != null) ? Arrays.asList(ignoreProperties) : null;
for (int i = 0; i < targetPds.length; i++) {
PropertyDescriptor targetPd = targetPds[i];
if (targetPd.getWriteMethod() != null && (ignoreProperties == null || (!ignoreList.contains(targetPd.getName())))) {
PropertyDescriptor sourcePd = findPropertyDescriptor(sourcePds, targetPd.getName());
if (sourcePd != null && sourcePd.getReadMethod() != null) {
try {
Method readMethod = sourcePd.getReadMethod();
if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
readMethod.setAccessible(true);
}
Object value = readMethod.invoke(source, new Object[0]);
Method writeMethod = targetPd.getWriteMethod();
if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
writeMethod.setAccessible(true);
}
writeMethod.invoke(target, new Object[] {value});
} catch (Throwable ex) {
throw new RuntimeException("Could not copy properties from source to target", ex);
}
}
}
}
}
private static PropertyDescriptor findPropertyDescriptor(PropertyDescriptor[] sourcePds, String name) {
if (sourcePds == null || sourcePds.length < 1) {
return null;
}
for (PropertyDescriptor pd : sourcePds) {
if (pd.getName().equals(name)) {
return pd;
}
}
return null;
}
}