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);
}
}
}
Java EntityMapper的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- 使用jhipster 加速java web开发
jhipster,中文释义: Java 热爱者! JHipster is a development platform to quickly generate, develop, & depl ...
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...
- Elasticsearch之java的基本操作一
摘要 接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...
- 论:开发者信仰之“天下IT是一家“(Java .NET篇)
比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...
- 故障重现, JAVA进程内存不够时突然挂掉模拟
背景,服务器上的一个JAVA服务进程突然挂掉,查看产生了崩溃日志,如下: # Set larger code cache with -XX:ReservedCodeCacheSize= # This ...
- 死磕内存篇 --- JAVA进程和linux内存间的大小关系
运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- Java多线程基础学习(二)
9. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
随机推荐
- android layout文件优化
性能优化1--UI优化 1.使用系统为我们提供了几个抽象的标签①include:重用include中layout属性指定一个外部布局文件,通过该方式则不需要把这个布局文件在该代码中重复的写一遍了. 若 ...
- IDEA 自动重新载入
IDEA 自动重新载入: Ctrl + F9
- Array 转 Set
Array 转 Set: Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidate ...
- 转:C#使用Dotfuscator混淆代码的加密方法
Author:flymorn Source:flymornCategories:C#编程 PostTime:2011-9-16 1:04:49 正 文: C#编写的代码如果不进行一定程度的混淆和加 ...
- Docker Swarm 环境搭建
Docker Swarm 环境搭建 swarm 使用前提 1.Docker版本1.12+ Docker升级教程:https://www.cnblogs.com/xiangsikai/p/9935894 ...
- IDEA中静态资源无法找到的原因
IDEA中静态资源无法找到, 原因1:同名的文件但是在不同的包里. 原因2:IDEA重启,web清空缓存. 原因3:错误的文件及路径. 原因4:其他原因排除后,可使用绝招重启试试.
- Learning-Python【3】:Python中的基本运算符
一.算数运算 二.比较(关系)运算 比较运算只能在同类型之间进行,其中 int 与 float 同属于数字类型 三.赋值运算 1.增量赋值 2.链式赋值 3.交叉赋值 交换两个数的值,通常要借助第三个 ...
- FI 创建资产接口AS01
FUNCTION ZREIP_CREATE_AS01TSET. *"------------------------------------------------------------- ...
- java基础 (三)之ConcurrentHashMap(转)
一.背景: 线程不安全的HashMap 因为多线程环境下,使用Hashmap进行put操作会引起死循环,导致CPU利用率接近100%,所以在并发情况下不能使用HashMap. 效率低下的H ...
- Java自带RPC实现,RMI框架入门
Java自带RPC实现,RMI框架入门 首先RMI(Remote Method Invocation)是Java特有的一种RPC实现,它能够使部署在不同主机上的Java对象进行通信与方法调用,它是一种 ...