首页 > 代码库 > Java EntityMapper

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 =http://www.mamicode.com/= 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);        }    }}

 

Java EntityMapper