| | |
| | | package com.vci.starter.web.util; |
| | | |
| | | import com.vci.starter.web.toolmodel.DateConverter; |
| | | import org.apache.commons.lang3.StringUtils; |
| | | import org.slf4j.Logger; |
| | | import org.slf4j.LoggerFactory; |
| | | import org.springframework.cglib.beans.BeanCopier; |
| | | import org.springframework.cglib.core.Converter; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.lang.reflect.Field; |
| | | import java.util.*; |
| | | import java.util.concurrent.ConcurrentHashMap; |
| | | import java.util.concurrent.ConcurrentMap; |
| | | |
| | | /** |
| | | * 业务类型专用的拷贝工具,这个是浅拷贝, |
| | |
| | | * 日志 |
| | | */ |
| | | private static Logger logger = LoggerFactory.getLogger(BeanUtilForVCI.class); |
| | | |
| | | /** |
| | | * 存放拷贝对象的缓存 |
| | | */ |
| | | private static final ConcurrentMap<String, BeanCopier> beanCopierMap = new ConcurrentHashMap<>(); |
| | | |
| | | /** |
| | | * 拷贝数据 |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 获取类拷贝的对象 |
| | | * @param source 源对象类 |
| | | * @param target 目标对象类 |
| | | * @param useConverter 是否使用转换器 |
| | | * @return 拷贝对象 |
| | | */ |
| | | public static BeanCopier getBeanCopier(Class<?> source, Class<?> target,boolean useConverter) { |
| | | String beanCopierKey = generateBeanKey(source, target); |
| | | if (beanCopierMap.containsKey(beanCopierKey)) { |
| | | return beanCopierMap.get(beanCopierKey); |
| | | } else { |
| | | BeanCopier beanCopier = BeanCopier.create(source, target, useConverter); |
| | | beanCopierMap.putIfAbsent(beanCopierKey, beanCopier); |
| | | } |
| | | return beanCopierMap.get(beanCopierKey); |
| | | } |
| | | |
| | | /** |
| | | * 生成两个类的key,用于存放到缓存之中 |
| | | * @param source 源对象类型 |
| | | * @param target 目标对象类 |
| | | * @return 两个类的名称连接到一起后的名字 |
| | | */ |
| | | public static String generateBeanKey(Class<?> source, Class<?> target) { |
| | | return source.getName() + "@" + target.getName(); |
| | | } |
| | | |
| | | /** |
| | | * 两个对象之间转换 |
| | | * @param source 源对象 |
| | | * @param target 目标对象 |
| | | * @param useConvert 是否使用默认的转换器,请在出现属性名称相同而类型不同,或者有对象类型,集合属性时才转换 |
| | | */ |
| | | public static void convert(Object source,Object target,boolean useConvert){ |
| | | if(source != null && target !=null){ |
| | | BeanCopier beanCopier = getBeanCopier(source.getClass(),target.getClass(),useConvert); |
| | | beanCopier.copy(source,target,useConvert?new DeepCopyConverter(target):null); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 两个对象之间转换 |
| | | * @param source 源对象 |
| | | * @param target 目标对象 |
| | | * @return 目标对象 |
| | | */ |
| | | public static void convert(Object source,Object target){ |
| | | convert(source,target,true); |
| | | } |
| | | |
| | | /** |
| | | * 深度拷贝转换器 |
| | | */ |
| | | public static class DeepCopyConverter implements Converter { |
| | | |
| | | /** |
| | | * 目标对象 |
| | | */ |
| | | private Object target; |
| | | |
| | | /** |
| | | * 构造方法 |
| | | * @param target 目标对象 |
| | | */ |
| | | public DeepCopyConverter(Object target) { |
| | | this.target = target; |
| | | } |
| | | |
| | | /** |
| | | * 执行拷贝 |
| | | * @param value 源对象的属性的值 |
| | | * @param targetClazz 目标对象的属性的类 |
| | | * @param methodName set方法的名字 |
| | | * @return 转换后的值 |
| | | */ |
| | | @Override |
| | | public Object convert(Object value, Class targetClazz, Object methodName) { |
| | | if (value instanceof List) { |
| | | List values = (List) value; |
| | | List retList = new ArrayList<>(values.size()); |
| | | copyForCollection(values,retList,methodName); |
| | | return retList; |
| | | } else if(value instanceof Set){ |
| | | Set values = (Set) value; |
| | | Set retSet = new HashSet<>(); |
| | | copyForCollection(values,retSet,methodName); |
| | | } else if(value instanceof Vector){ |
| | | Vector values = (Vector)value; |
| | | Vector retVector = new Vector(); |
| | | copyForCollection(values,retVector,methodName); |
| | | }else if (value instanceof Map) { |
| | | Map values = (Map)value; |
| | | Map retMap = new HashMap(); |
| | | for (final Object key : values.keySet()) { |
| | | Object mapValue = values.get(key); |
| | | String tempFieldName = methodName.toString().replace("set", |
| | | ""); |
| | | String fieldName = tempFieldName.substring(0, 1) |
| | | .toLowerCase() + tempFieldName.substring(1); |
| | | Class clazz = ClassUtilForVCI.getElementType(target.getClass(), fieldName); |
| | | Object targetAttr = null; |
| | | try{ |
| | | targetAttr = clazz.newInstance(); |
| | | }catch (Throwable e){ |
| | | //新的对象的属性初始化出错 |
| | | } |
| | | BeanUtilForVCI.convert(mapValue, targetAttr); |
| | | retMap.put(key,targetAttr); |
| | | } |
| | | } else if (!ClassUtilForVCI.isPrimitive(targetClazz)) { |
| | | //这个是对象类型 |
| | | Object targetAttr = null; |
| | | try{ |
| | | targetAttr = targetClazz.newInstance(); |
| | | }catch (Throwable e){ |
| | | //新的对象属性初始化出错 |
| | | } |
| | | BeanUtilForVCI.convert(value, targetAttr); |
| | | return targetAttr; |
| | | } |
| | | if(value instanceof Boolean && targetClazz.equals(String.class)){ |
| | | //从boolean拷贝到string |
| | | return String.valueOf(value); |
| | | } |
| | | if(value instanceof String && (targetClazz.equals(Boolean.class) |
| | | || targetClazz.equals(boolean.class))){ |
| | | //从String拷贝到boolean |
| | | if("true".equalsIgnoreCase((String)value)){ |
| | | return true; |
| | | }else{ |
| | | return false; |
| | | } |
| | | } |
| | | if(value instanceof Date && targetClazz.equals(String.class)){ |
| | | //时间格式 |
| | | return VciDateUtil.date2Str((Date)value,VciDateUtil.DateTimeMillFormat); |
| | | } |
| | | if(value instanceof String && targetClazz.equals(Date.class)){ |
| | | //转换 |
| | | DateConverter dateConverter = new DateConverter(); |
| | | dateConverter.setAsText((String)value); |
| | | return dateConverter.getValue(); |
| | | } |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * 处理集合属性 |
| | | * @param sourceCollection 源对象中集合属性的的值 |
| | | * @param targetCollection 目标对象的集合属性的值 |
| | | * @param methodName setter方法 |
| | | */ |
| | | private void copyForCollection(Collection<?> sourceCollection,Collection targetCollection,Object methodName){ |
| | | for (final Object source : sourceCollection) { |
| | | if(source instanceof Collection){ |
| | | List<Object> targetValues = new ArrayList<>(); |
| | | copyForCollection((Collection<?>)source,targetValues,methodName); |
| | | targetCollection.add(targetValues); |
| | | }else if(source instanceof Map){ |
| | | String tempFieldName = methodName.toString().replace("set", |
| | | ""); |
| | | String fieldName = tempFieldName.substring(0, 1) |
| | | .toLowerCase() + tempFieldName.substring(1); |
| | | Class clazz = ClassUtilForVCI.getElementType(target.getClass(), fieldName); |
| | | Object targetAttr = null; |
| | | try { |
| | | targetAttr = clazz.newInstance(); |
| | | } catch (Throwable e) { |
| | | //新的对象的属性初始化出错 |
| | | } |
| | | Map map = (Map) source; |
| | | for(Object key : map.keySet()){ |
| | | VciBaseUtil.setValueForField(key.toString(),targetAttr,VciBaseUtil.getStringValueFromObject(map.get(key))); |
| | | } |
| | | targetCollection.add(targetAttr); |
| | | }else { |
| | | String tempFieldName = methodName.toString().replace("set", |
| | | ""); |
| | | String fieldName = tempFieldName.substring(0, 1) |
| | | .toLowerCase() + tempFieldName.substring(1); |
| | | Class clazz = ClassUtilForVCI.getElementType(target.getClass(), fieldName); |
| | | Object targetAttr = null; |
| | | try { |
| | | targetAttr = clazz.newInstance(); |
| | | } catch (Throwable e) { |
| | | //新的对象的属性初始化出错 |
| | | } |
| | | BeanUtilForVCI.convert(source, targetAttr); |
| | | targetCollection.add(targetAttr); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |