/** 
 | 
 *  
 | 
 */ 
 | 
package com.matrix.core.tools; 
 | 
  
 | 
import java.lang.reflect.Field; 
 | 
import java.lang.reflect.InvocationTargetException; 
 | 
import java.lang.reflect.Method; 
 | 
import java.lang.reflect.Modifier; 
 | 
import java.util.ArrayList; 
 | 
import java.util.Collection; 
 | 
import java.util.Date; 
 | 
import java.util.HashMap; 
 | 
import java.util.Iterator; 
 | 
import java.util.List; 
 | 
import java.util.Map; 
 | 
  
 | 
import org.apache.commons.lang.ObjectUtils; 
 | 
import org.springframework.util.CollectionUtils; 
 | 
  
 | 
import com.matrix.core.anotations.Extend; 
 | 
import com.matrix.core.pojo.EntityDTO; 
 | 
  
 | 
/** 
 | 
 * 数据库模型的处理类 
 | 
 *  
 | 
 * @author JIANGYOUYAO 
 | 
 * @email 935090232@qq.com 
 | 
 * @date 2017年11月29日 
 | 
 */ 
 | 
public class ModelUtils { 
 | 
  
 | 
    private static final String TYPE = "TYPE"; 
 | 
  
 | 
    /** 
 | 
     * 比较新旧POJO对象,将修改过的值和字段名放入Map中 
 | 
     *  
 | 
     * @param oldObj 
 | 
     * @param newObj 
 | 
     * @return 
 | 
     * @throws NoSuchMethodException 
 | 
     * @throws SecurityException 
 | 
     * @throws IllegalAccessException 
 | 
     * @throws IllegalArgumentException 
 | 
     * @throws InvocationTargetException 
 | 
     * @throws NoSuchFieldException 
 | 
     */ 
 | 
    @SuppressWarnings("unchecked") 
 | 
    public static final Map<String, Object> comparePojo2Map(Object oldObj, Object newObj) 
 | 
                throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, 
 | 
            InvocationTargetException, NoSuchFieldException { 
 | 
        Map<String, Object> map = new HashMap<>(60); 
 | 
        Class<Object> oldClazz = (Class<Object>) oldObj.getClass(); 
 | 
        Field[] fields = oldClazz.getDeclaredFields(); 
 | 
        List<Field> fieldList = new ArrayList<>(60); 
 | 
        Class<Object> newClazz = (Class<Object>) newObj.getClass(); 
 | 
        if (oldObj instanceof EntityDTO) { 
 | 
            fieldList.add(EntityDTO.class.getDeclaredField("updateBy")); 
 | 
        } 
 | 
        CollectionUtils.mergeArrayIntoCollection(fields, fieldList); 
 | 
        for (Field field : fieldList) { 
 | 
            if (field.getAnnotation(Extend.class) != null || Modifier.isStatic(field.getModifiers())) { 
 | 
                continue; 
 | 
            } 
 | 
            String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1); 
 | 
            Method oldM = (Method) oldClazz.getMethod(getMethodName); 
 | 
            Method newM = (Method) newClazz.getMethod(getMethodName); 
 | 
            // 如果新旧的值不相等 
 | 
            if (newM.invoke(newObj) != null && !ObjectUtils.equals(oldM.invoke(oldObj), newM.invoke(newObj))) { 
 | 
                map.put(field.getName(), newM.invoke(newObj)); 
 | 
            } 
 | 
        } 
 | 
        return map; 
 | 
    } 
 | 
  
 | 
    /** 
 | 
     *  
 | 
     *  判断值是否被修改过 
 | 
     * @author:姜友瑶 
 | 
     * @param oldObj 
 | 
     * @param newObj 
 | 
     * @return 返回类型 boolean 
 | 
     * @throws NoSuchFieldException 
 | 
     * @date 2016年11月11日 
 | 
     */ 
 | 
    @SuppressWarnings({ "unchecked" }) 
 | 
    public static boolean isModified(Object oldObj, Object newObj) throws NoSuchFieldException { 
 | 
        if (oldObj == newObj) { 
 | 
            return true; 
 | 
        } 
 | 
        if (oldObj == null || newObj == null) { 
 | 
            return false; 
 | 
        } 
 | 
        try { 
 | 
            Class<Object> oldClazz = (Class<Object>) oldObj.getClass(); 
 | 
            Field[] fields = oldClazz.getDeclaredFields(); 
 | 
            Class<Object> newClazz = (Class<Object>) newObj.getClass(); 
 | 
            List<Field> fieldList = new ArrayList<>(60); 
 | 
            if (oldObj instanceof EntityDTO) { 
 | 
                fieldList.add(EntityDTO.class.getDeclaredField("updateBy")); 
 | 
            } 
 | 
            CollectionUtils.mergeArrayIntoCollection(fields, fieldList); 
 | 
            // 依次比较所有可以Modify的字段 
 | 
            for (Field field : fieldList) { 
 | 
                // 不是可以修改的字段 
 | 
                if (field.getAnnotation(Extend.class) != null) { 
 | 
                    continue; 
 | 
                } 
 | 
                String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() 
 | 
                        + field.getName().substring(1); 
 | 
                Method oldM = (Method) oldClazz.getMethod(getMethodName); 
 | 
                Method newM = (Method) newClazz.getMethod(getMethodName); 
 | 
                if (isPrimitive(field) || String.class == field.getType() || Date.class == field.getType() 
 | 
                        || field.getType().isEnum()) { 
 | 
                    // 如果字段是基本类型,封装类型,以及String, Date, 枚举,则直接进行比较 
 | 
                    // 如果新旧的值不相等 
 | 
                    if (!ObjectUtils.equals(oldM.invoke(oldObj), newM.invoke(newObj))) { 
 | 
                        return true; 
 | 
                    } 
 | 
                } else if (field.getType().isAssignableFrom(List.class)) { 
 | 
                    // 如果是List 
 | 
                    if (isModifiedList((List<Object>) oldM.invoke(oldObj), (List<Object>) newM.invoke(newObj))) { 
 | 
                        return true; 
 | 
                    } 
 | 
                } else { 
 | 
                    // 其他类型暂时不支持 
 | 
                    throw new RuntimeException("暂时不支持这种类型的修改判断:" + field.getType()); 
 | 
                } 
 | 
            } 
 | 
            return false; 
 | 
        } catch (SecurityException | NoSuchMethodException | IllegalAccessException | IllegalArgumentException 
 | 
                | InvocationTargetException e) { 
 | 
            throw new RuntimeException(e); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    @SuppressWarnings("rawtypes") 
 | 
    private static boolean isPrimitive(Field field) 
 | 
            throws IllegalArgumentException, IllegalAccessException, SecurityException { 
 | 
        if (field.getType().isPrimitive()) { 
 | 
            return true; 
 | 
        } 
 | 
        try { 
 | 
            if (((Class) field.getType().getField(TYPE).get(null)).isPrimitive()) { 
 | 
                return true; 
 | 
            } 
 | 
            return false; 
 | 
        } catch (NoSuchFieldException e) { 
 | 
            return false; 
 | 
        } 
 | 
    } 
 | 
  
 | 
    public static boolean isModifiedList(final Collection<Object> list1, final Collection<Object> list2) 
 | 
            throws NoSuchFieldException { 
 | 
        if (list1 == list2) { 
 | 
            return false; 
 | 
        } 
 | 
        if (list1 == null || list2 == null || list1.size() != list2.size()) { 
 | 
            return true; 
 | 
        } 
 | 
        Iterator<Object> it1 = list1.iterator(); 
 | 
        Iterator<Object> it2 = list2.iterator(); 
 | 
        Object obj1 = null; 
 | 
        Object obj2 = null; 
 | 
        while (it1.hasNext() && it2.hasNext()) { 
 | 
            obj1 = it1.next(); 
 | 
            obj2 = it2.next(); 
 | 
  
 | 
            if (isModified(obj1, obj2)) { 
 | 
                return true; 
 | 
            } 
 | 
        } 
 | 
        return it1.hasNext() || it2.hasNext(); 
 | 
    } 
 | 
  
 | 
} 
 |