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. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
随机推荐
- html5 javascript 新增加的高级选择器更精准更实用
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- request.getParameter()获取不到数据
HTML中的form表单有一个关键属性 Content-Type=application/x-www-form-urlencoded 或multipart/form-data. 1. Content- ...
- mysql两条sql合并查询总数
select IFNULL(c.nodeCount,0) + IFNULL(c.phyCount,0) as totalCount from ( select count(*) nodeCount, ...
- 在HTML5的 input:file 上传文件类型控制 遇到的问题
1.input:file 属性的介绍 先瞅代码吧 <form> <input type="file" name="pic" accept=& ...
- json-server基本使用
**一.前后端并行开发的痛点** 前端需要等待后端开发完接口以后 再根据接口来完成前端的业务逻辑 **二.解决方法** 在本地模拟后端接口用来测试前端效果 这种做法称之为构建前端Mock **三.js ...
- 【一些容易忘记的node的npm命令】【收集】
更新npm到最新版本 npm update -g npm 安装依赖包时命令的一些区别 npm install xxx -g //(全局安装) npm install xxx --save-dev // ...
- SQL语句汇总——数据修改、数据查询
首先创建一张表如下,创建表的方法在上篇介绍过了,这里就不再赘述. 添加新数据: INSERT INTO <表名> (<列名列表>) VALUES (<值列表>) ...
- maven maven-war-plugin 解决java war项目间的依赖(两个war都可独立部署运行,maven 3.2.x亲测)
最近整理基础框架,有些项目不想分布式,所以基础框架必须同时可独立部署,也可直接被作为依赖和业务工程打到一起,记录下解决war项目依赖的要点,一开始用warpath,结果报找不到,有些帖子还是17年的, ...
- element-ui checkbox传默认值的问题
新入职一家公司了,准备把项目中遇到的问题随时记录下来.以前遇到的问题解决了没有记录,导致面试的时候问项目中遇到那些问题时,好多都忘了. 今天记录一下element-ui 的 checkbox 传递默认 ...
- C# HttpWebResponse WebClient 基础连接已经关闭: 发送时发生错误.
https://blog.csdn.net/sun49842566/article/details/82802297 net 4.0 设置: ServicePointManager.SecurityP ...