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. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
随机推荐
- Lua 求当前月份的最大天数
[1]实现代码 -- 第一种方式:简写 , day = })) print('The first way result : dayAmount = ' .. dayAmount) -- 第二种方式:分 ...
- <转>jmeter(二十一)jmeter常用插件介绍
本博客转载自:http://www.cnblogs.com/imyalost/category/846346.html 个人感觉不错,对jmeter讲解非常详细,担心以后找不到了,所以转发出来,留着慢 ...
- python爬虫——对爬到的数据进行清洗的一些姿势(5)
做爬虫,当然就要用数据.想拿数据进行分析,首先清洗数据.这个清洗数据包括清除无用数据列和维度,删除相同数据,对数据进行勘误之类的. 从各大不同新闻网站可以爬到重复新闻...这个可以有.之前为了对爬到的 ...
- nginx-高并发配置 第七章
一 .nginx 服务配置优化: 1.nginx进程数,建议按照cpu数目来指定,一般为它的倍数.worker_processes 定义了nginx对外提供web服务时的worker进程数.最优值取决 ...
- springboot跑定时任务
使用@Scheduled注解实现 1.在启动类上加上@EnableScheduling 开启定时任务 2.新建一个任务类,在方法上添加@Scheduled注解 @Componentpublic cla ...
- mysql的并发控制
并发即指在同一时刻,多个操作并行执行.MySQL对并发的处理主要应用了两种机制——是"锁"和"多版本控制". 1.并发控制 MySQL提供两个级别的并发控制:服 ...
- 剑指offer(36)两个链表中的第一个公共节点
题目描述 输入两个链表,找出它们的第一个公共结点. 题目分析 我发现关于链表的题都涉及双指针,大家做的时候记得用双指针. 题目理解了就很好做了,比较简单,先在长的链表上跑,知道长的和短的一样长,再一起 ...
- (转)Awesome Human Pose Estimation
Awesome Human Pose Estimation 2018-10-08 11:02:35 Copied from: https://github.com/cbsudux/awesome-hu ...
- 导出html table 数据到Excel
其实只需要复制 粘贴.... <script type="text/javascript" src="http://code.jquery.com/jquery- ...
- 浅谈JS中的原型对象和原型链
我们知道原型是一个对象,其他对象可以用它实现属性继承,除了prototype,又有__proto__ 1. prototype和__proto__的区别 prototype是函数才有的属性 ...