package cn.org.rapid_framework.generator.util; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.math.BigDecimal; import java.math.BigInteger; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; public class BeanHelper { /** * @see #org.apache.commons.beanutils.PropertyUtils.describe(obj) */ public static Map describe(Object obj,String... ignoreProperties) { if (obj instanceof Map) return (Map) obj; Map map = new HashMap(); PropertyDescriptor[] descriptors = getPropertyDescriptors(obj.getClass()); for(int i = 0; i < descriptors.length; i++ ) { String name = descriptors[i].getName(); if(contains(ignoreProperties,name)) { continue; } Method readMethod = descriptors[i].getReadMethod(); if (readMethod != null) { try { long start = System.currentTimeMillis(); map.put(name, readMethod.invoke(obj, new Object[]{})); long cost = start - System.currentTimeMillis(); }catch(Exception e){ GLogger.warn("error get property value,name:"+name+" on bean:"+obj,e); } } } return map; } private static boolean contains(String[] array, String str) { if(array == null) { return false; } if(str == null) { return false; } for(String ignore : array) { if(str.equals(ignore)) { return true; } } return false; } public static PropertyDescriptor getPropertyDescriptor(Class beanClass,String propertyName,boolean ignoreCase) { for(PropertyDescriptor pd : getPropertyDescriptors(beanClass)) { if(ignoreCase) { if(pd.getName().equalsIgnoreCase(propertyName)) { return pd; } }else { if(pd.getName().equals(propertyName)) { return pd; } } } return null; } public static PropertyDescriptor[] getPropertyDescriptors(Class beanClass) { BeanInfo beanInfo = null; try { beanInfo = Introspector.getBeanInfo(beanClass); } catch (IntrospectionException e) { return (new PropertyDescriptor[0]); } PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors(); if (descriptors == null) { descriptors = new PropertyDescriptor[0]; } return descriptors; } public static void copyProperties(Object target, Object source) { copyProperties(target,source,false); } public static void copyProperties(Object target, Object source,boolean ignoreCase) { copyProperties(target,source,ignoreCase,null); } public static void copyProperties(Object target, Map source) { copyProperties(target,source,false); } public static void copyProperties(Object target, Map source,boolean ignoreCase) { Set<String> keys = source.keySet(); for(String key : keys) { PropertyDescriptor pd = getPropertyDescriptor(target.getClass(), key, ignoreCase); if(pd == null) { throw new IllegalArgumentException("not found property:'"+key+"' on class:"+target.getClass()); } setProperty(target, pd, source.get(key)); } } public static void copyProperties(Object target, Object source,boolean ignoreCase,String[] ignoreProperties) { if(target instanceof Map) { throw new UnsupportedOperationException("target is Map unsuported"); } PropertyDescriptor[] targetPds = getPropertyDescriptors(target.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())))) { try { if(source instanceof Map) { Map map = (Map)source; if(MapHelper.containsKey(map, targetPd.getName(), ignoreCase)) { Object value = MapHelper.getValue(map, targetPd.getName(), ignoreCase); setProperty(target, targetPd, value); } }else { PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName(),ignoreCase); if (sourcePd != null && sourcePd.getReadMethod() != null) { Object value = getProperty(source, sourcePd); setProperty(target, targetPd, value); } } } catch (Throwable ex) { throw new IllegalArgumentException("Could not copy properties on:"+targetPd.getDisplayName(),ex); } } } } static class MapHelper { public static Object getValue(Map map,String property, boolean ignoreCase) { if(ignoreCase) { for(Object key : map.keySet()) { if(property.equalsIgnoreCase(key.toString())) { return map.get(key); } } return null; }else { return map.get(property); } } public static boolean containsKey(Map map,String property, boolean ignoreCase) { if(ignoreCase) { for(Object key : map.keySet()) { if(property.equalsIgnoreCase(key.toString())) { return true; } } return false; }else { return map.containsKey(property); } } } private static Object getProperty(Object source, PropertyDescriptor sourcePd)throws IllegalAccessException,InvocationTargetException { Method readMethod = sourcePd.getReadMethod(); if (!Modifier.isPublic(readMethod.getDeclaringClass() .getModifiers())) { readMethod.setAccessible(true); } Object value = readMethod.invoke(source, new Object[0]); return value; } public static void setProperty(Object target, String propertyName, Object value) { PropertyDescriptor pd = getPropertyDescriptor(target.getClass(),propertyName,false); if(pd == null) throw new IllegalArgumentException("not found property:"+propertyName+" on class:"+target.getClass()); setProperty(target, pd, value); } public static void setProperty(Object target, String propertyName, Object value,boolean ignoreCase) { PropertyDescriptor pd = getPropertyDescriptor(target.getClass(),propertyName,ignoreCase); if(pd == null) throw new IllegalArgumentException("not found property:"+propertyName+" on class:"+target.getClass()); setProperty(target, pd, value); } public static <T> T newInstance(Class<T> clazz) { try { return clazz.newInstance(); } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } } private static void setProperty(Object target, PropertyDescriptor propertyDescriptor, Object value) { if(propertyDescriptor == null) { throw new IllegalArgumentException("propertyDescriptor must be not null"); } if(target == null) { throw new IllegalArgumentException("target must be not null"); } Method writeMethod = propertyDescriptor.getWriteMethod(); if(writeMethod == null) { throw new IllegalArgumentException("not found write method for property:"+propertyDescriptor.getName()+" on class:"+target.getClass()); } if (!Modifier.isPublic(writeMethod.getDeclaringClass() .getModifiers())) { writeMethod.setAccessible(true); } try { writeMethod.invoke(target, new Object[] { convert(value,writeMethod.getParameterTypes()[0]) }); }catch(Exception e) { throw new RuntimeException("error set property:"+propertyDescriptor.getName()+" on class:"+target.getClass(),e); } } private static Object convert(Object value, Class<?> targetType) { if(value == null) return null; if(targetType == String.class) { return value.toString(); }else { return convert(value.toString(),targetType); } } private static Object convert(String value,Class<?> targetType) { if(targetType == Byte.class || targetType == byte.class) { return new Byte(value); } if(targetType == Short.class || targetType == short.class) { return new Short(value); } if(targetType == Integer.class || targetType == int.class) { return new Integer(value); } if(targetType == Long.class || targetType == long.class) { return new Long(value); } if(targetType == Float.class || targetType == float.class) { return new Float(value); } if(targetType == Double.class || targetType == double.class) { return new Double(value); } if(targetType == BigDecimal.class) { return new BigDecimal(value); } if(targetType == BigInteger.class) { return BigInteger.valueOf(Long.parseLong(value)); } if(targetType == Boolean.class || targetType == boolean.class) { return new Boolean(value); } if(targetType == boolean.class) { return new Boolean(value); } if(targetType == char.class) { return value.charAt(0); } if(DateHelper.isDateType(targetType)) { return DateHelper.parseDate(value,targetType,"yyyyMMdd","yyyy-MM-dd","yyyyMMddHHmmSS","yyyy-MM-dd HH:mm:ss","HH:mm:ss"); } throw new IllegalArgumentException("cannot convert value:"+value +" to targetType:"+targetType); } }