zoukankan      html  css  js  c++  java
  • Java EntityMapper

    package org.rx.util;
    
    import org.rx.common.Func2;
    import org.rx.common.Action2;
    import org.rx.common.Func1;
    import org.rx.common.NQuery;
    import org.rx.security.MD5Util;
    
    import java.lang.reflect.Array;
    import java.lang.reflect.Method;
    import java.util.*;
    import java.util.concurrent.ConcurrentHashMap;
    import java.util.concurrent.ConcurrentMap;
    
    /**
     * Created by wangxiaoming on 2016/3/11.
     */
    public class EntityMapper {
        //region NestedTypes
        private static class MapEntity {
            public Func2<String, String, Boolean> MembersMatcher;
            public Object                         PostProcessor;
            public HashSet<String>                IgnoreNames;
        }
    
        private static class DefaultMatcher implements Func2<String, String, Boolean> {
            @Override
            public Boolean invoke(String arg1, String arg2) {
                return arg1.equals(arg2);
            }
        }
        //endregion
    
        //region Fields
        private static final String                     GET                = "get", SET = "set";
        private static final int                        getDefaultWhenNull = 1 << 0, putNewWhenNull = 1 << 1;
        private static final MapEntity                  Default;
        private static ConcurrentMap<String, MapEntity> Config;
        //endregion
    
        //region Methods
        static {
            Default = new MapEntity();
            Default.IgnoreNames = new HashSet<>();
            Default.IgnoreNames.add("getClass");
            Default.MembersMatcher = new DefaultMatcher();
            Config = new ConcurrentHashMap<>();
        }
    
        private static MapEntity getConfig(Class<?> tFrom, Class<?> tTo, int flags) {
            String key = getKey(tFrom, tTo);
            MapEntity map = Config.get(key);
            if (map == null) {
                if ((flags & getDefaultWhenNull) == getDefaultWhenNull) {
                    return Default;
                }
                if ((flags & putNewWhenNull) == putNewWhenNull) {
                    Config.putIfAbsent(key, map = new MapEntity());
                    map.MembersMatcher = Default.MembersMatcher;
                }
            }
            return map;
        }
    
        private static String getKey(Class<?> tFrom, Class<?> tTo) {
            return MD5Util.md5Hex(tFrom.getName() + tTo.getName());
        }
    
        public static <T> T createInstance(Class<T> type) {
            try {
                return type.newInstance();
            } catch (ReflectiveOperationException ex) {
                throw new RuntimeException(ex);
            }
        }
        //endregion
    
        //region MapMethods
        public synchronized static <TF, TT> void setMembersMatcher(Class<TF> tFrom, Class<TT> tTo,
                                                                   Func2<String, String, Boolean> membersMatcher,
                                                                   Action2<TF, TT> postProcessor) {
            MapEntity map = getConfig(tFrom, tTo, putNewWhenNull);
            map.MembersMatcher = membersMatcher == null ? Default.MembersMatcher : membersMatcher;
            map.PostProcessor = postProcessor;
        }
    
        public synchronized static void setIgnoreMembers(Class<?> tFrom, Class<?> tTo, String... ignoreNames) {
            MapEntity map = getConfig(tFrom, tTo, putNewWhenNull);
            map.IgnoreNames = new HashSet<>(Arrays.asList(ignoreNames));
            map.IgnoreNames.add("getClass");
        }
    
        public static <TF, TT> TT[] map(Collection<TF> from, Class<TT> toType) {
            List<TT> toSet = new ArrayList<>();
            for (Object o : from) {
                toSet.add(map(o, toType));
            }
            TT[] x = (TT[]) Array.newInstance(toType, toSet.size());
            toSet.toArray(x);
            return x;
        }
    
        public static <TF, TT> TT map(TF from, Class<TT> toType) {
            return map(from, createInstance(toType));
        }
    
        public static <TF, TT> TT map(TF from, TT to) {
            return map(from, to, false);
        }
    
        public static <TF, TT> TT map(TF from, TT to, boolean skipNull) {
            Class<?> tFrom = from.getClass(), tTo = to.getClass();
            final MapEntity map = getConfig(tFrom, tTo, getDefaultWhenNull);
    
            NQuery<Method> fq = new NQuery<>(tFrom.getMethods()).where(new Func1<Method, Boolean>() {
                @Override
                public Boolean invoke(Method arg) {
                    String fName = arg.getName();
                    return !map.IgnoreNames.contains(fName) && fName.startsWith(GET);
                }
            });
            NQuery<Method> tq = new NQuery<>(tTo.getMethods()).where(new Func1<Method, Boolean>() {
                @Override
                public Boolean invoke(Method arg) {
                    return arg.getName().startsWith(SET);
                }
            });
    
            for (Method fMethod : fq) {
                String fName = fMethod.getName();
                final String tName = SET + fName.substring(3);
                //App.logInfo("EntityMapper Step1 %s", fName);
    
                Method tMethod = tq.where(new Func1<Method, Boolean>() {
                    @Override
                    public Boolean invoke(Method arg) {
                        return map.MembersMatcher.invoke(tName, arg.getName());
                    }
                }).firstOrDefault();
                Class<?>[] tArgs;
                if (tMethod == null || (tArgs = tMethod.getParameterTypes()).length != 1) {
                    //App.logInfo("EntityMapper %s Miss %s.%s", tTo.getSimpleName(), tFrom.getSimpleName(), tName);
                    continue;
                }
                //App.logInfo("EntityMapper Step2 %s to %s", fName, tName);
    
                try {
                    Object value = fMethod.invoke(from);
                    if (value == null && skipNull) {
                        continue;
                    }
                    value = App.changeType(value, tArgs[0]);
                    tMethod.invoke(to, value);
                } catch (ReflectiveOperationException ex) {
                    throw new RuntimeException(ex);
                }
            }
    
            if (map.PostProcessor != null) {
                Action2<TF, TT> postProcessor = (Action2<TF, TT>) map.PostProcessor;
                postProcessor.invoke(from, to);
            }
            return to;
        }
        //endregion
    
        public static void trim(Object entity) {
            Class<?> type = entity.getClass();
            NQuery<Method> fq = new NQuery<>(type.getMethods()).where(new Func1<Method, Boolean>() {
                @Override
                public Boolean invoke(Method arg) {
                    return arg.getName().startsWith(GET) && arg.getReturnType().equals(String.class);
                }
            });
    
            for (Method method : fq) {
                try {
                    String value = (String) method.invoke(entity);
                    if (App.isNullOrEmpty(value)) {
                        continue;
                    }
                    method = type.getMethod(SET + method.getName().substring(3), String.class);
                    method.invoke(entity, value.trim());
                } catch (ReflectiveOperationException ex) {
                    throw new RuntimeException(ex);
                }
            }
        }
    
        public static Object getProperty(Object entity, String propName) {
            try {
                Method method = entity.getClass()
                        .getMethod(GET + propName.substring(0, 1).toUpperCase() + propName.substring(1));
                return method.invoke(entity);
            } catch (ReflectiveOperationException ex) {
                throw new RuntimeException(ex);
            }
        }
    }
  • 相关阅读:
    hdu 2019 数列有序!
    hdu 2023 求平均成绩
    HDU 5805 NanoApe Loves Sequence (思维题) BestCoder Round #86 1002
    51nod 1264 线段相交
    Gym 100801A Alex Origami Squares (求正方形边长)
    HDU 5512 Pagodas (gcd)
    HDU 5510 Bazinga (字符串匹配)
    UVALive 7269 Snake Carpet (构造)
    UVALive 7270 Osu! Master (阅读理解题)
    UVALive 7267 Mysterious Antiques in Sackler Museum (判断长方形)
  • 原文地址:https://www.cnblogs.com/Googler/p/7340372.html
Copyright © 2011-2022 走看看