依赖
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.8.4</version>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>guava</artifactId>
<version>2.8.4</version>
</dependency>
代码实现
package com.citydo.jetcache;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;
/**
* CaffeineCache
*/
public class CaffeineCache{
Cache<String, Object> manualCache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(10_000)
.build();
/**
* 获取缓存
* @param key
* @return
*/
private Object getById(String key){
return manualCache.getIfPresent(key);
}
/**
* 添加缓存
* @param key
* @param value
*/
private void addById(String key, String value){
manualCache.put(key, value);
}
/**
* 删除缓存
* @param key
*/
private void invalidate(String key){
manualCache.invalidate(key);
}
}
代码实现
package com.citydo.jetcache;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Arrays;
/**
* SpringCache
* @Cacheable 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
* @CachePut 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
* @Cacheable 不同的是,它每次都会触发真实方法的调用
* @CachEvict 主要针对方法配置,能够根据一定的条件对缓存进行清空
* @author nick
*/
@EnableCaching
@Configuration
public class SpringCache {
@Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
cacheManager.setCaches(Arrays.asList(new ConcurrentMapCache("default")));
return cacheManager;
}
/**
* 获取缓存
* @param id
* @return
*/
@Cacheable(value = "getById", key = "#id")
public int getById(int id){
return id;
}
/**
* 添加缓存
* @param id
*/
@CachePut(value = "getById", key = "#id")
public void addById(int id){ }
}
依赖
<dependency>
<groupId>com.alicp.jetcache</groupId>
<artifactId>jetcache-starter-redis</artifactId>
<version>2.5.3</version>
</dependency>
代码实现
package com.citydo.jetcache;
import com.alicp.jetcache.anno.CacheInvalidate;
import com.alicp.jetcache.anno.CacheUpdate;
import com.alicp.jetcache.anno.Cached;
public interface JetCacheService {
/**
* 查询缓存
* @param userId
* @return
*/
@Cached(name="IdCache-", key="#Id", expire = 3600)
String getById(String userId);
/**
* 更新缓存
* @param Id
*/
@CacheUpdate(name="IdCache-", key="#Id", value="#Id")
void updateUser(String Id);
/**
* 删除缓存
* @param Id
*/
@CacheInvalidate(name="IdCache-", key="#Id")
void deleteId(String Id);
}
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation;
import com.alicp.jetcache.anno.config.EnableMethodCache;
import java.util.concurrent.TimeUnit;
/**
*
* JetCache
* 本地TTL、两级缓存和分布式缓存自动刷新
*/
@EnableMethodCache(basePackages = "com.citydo.jetcache")
@EnableCreateCacheAnnotation
public class JetCache {
private static int count = 0;
/**
* 添加缓存
* @return
*/
@Cached
public int count() {
return count++;
}
/**
* 添加过期时间
* @return
*/
@Cached(expire = 50, cacheType = CacheType.LOCAL, timeUnit = TimeUnit.MILLISECONDS)
public int countWithExpire50() {
return count++;
}
}
Java动态调用Groove代码
package com.citydo.jetcache;
import groovy.lang.GroovyClassLoader;
public class GroovyUtils{
private static GroovyClassLoader loader = new GroovyClassLoader();
public static Class parseClass(String groovy) {
return loader.parseClass(groovy);
}
}
字符串转集合,集合转字符串
package com.citydo.jetcache;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;
public class ListUtils {
private static final String REGEX = ",";
public static List<Integer> string2IntList(String str) {
if (!StringUtils.hasText(str)) {
return new ArrayList<>();
}
List<Integer> intList = new ArrayList<>();
for (String elem :str.split(REGEX)) {
if (!StringUtils.hasText(elem)) {
continue;
}
intList.add(Integer.parseInt(elem));
}
return intList;
}
public static List<String> string2StrList(String str) {
if (!StringUtils.hasText(str)) {
return new ArrayList<>();
}
List<String> strList = new ArrayList<>();
for (String elem: str.split(REGEX)) {
if (!StringUtils.hasText(elem)) {
continue;
}
strList.add(elem);
}
return strList;
}
public static String longList2String(List<Long> longList) {
if (longList == null || longList.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
longList.stream().forEach(e->{
if (e == null) {
return;
}
sb.append(e).append(REGEX);
});
return sb.length() > 0 ? sb.substring(0, sb.length() - 1) : sb.toString();
}
public static String intList2String(List<Integer> intList) {
if (intList == null || intList.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
intList.stream().forEach(e->{
if (e == null) {
return;
}
sb.append(e).append(REGEX);
});
return sb.length() > 0 ? sb.substring(0, sb.length() - 1) : sb.toString();
}
public static String strList2String(List<String> strList) {
if (strList == null || strList.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder();
strList.stream().forEach(e->{
if (!StringUtils.hasText(e)) {
return;
}
sb.append(e).append(REGEX);
});
return sb.length() > 0 ? sb.substring(0, sb.length() - 1) : sb.toString();
}
}
缓存锁
package com.citydo.jetcache;
import java.util.concurrent.ConcurrentHashMap;
public class CacheLockUtils {
private static final ConcurrentHashMap<String, Integer> CACHE_LOCK = new ConcurrentHashMap<>();
public static boolean lock(String key) {
return CACHE_LOCK.putIfAbsent(key, 1) == null;
}
public static void unlock(String key) {
CACHE_LOCK.remove(key);
}
}
线程池工具类
package com.citydo.jetcache;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;
@Slf4j
public class ExecutorUtils {
/**
* The default rejected execution handler
*/
private static final RejectedExecutionHandler defaultHandler = (r, executor) -> {
log.info("Thread rejected task,start run task by caller,current queue size {}", executor.getQueue().size());
if (!executor.isShutdown()) {
r.run();
}
};
/**
* ExecutorHelper默认使用CachedThreadPool作为默认的线程池,但是有风险,不建议使用
*/
private static class DefaultThreadPool {
public static ExecutorService es = Executors.newCachedThreadPool(new DefaultThreadFactory("cache", null));
}
private static ExecutorService getCachedThreadPool() {
return DefaultThreadPool.es;
}
/**
* 停掉默认的线程池
*/
public static void shutdown() {
if (!getCachedThreadPool().isShutdown()) {
getCachedThreadPool().shutdown();
}
}
/**
* 停掉线程池
*
* @param executorService
*/
public static void shutdown(ExecutorService executorService) {
if (!executorService.isShutdown()) {
executorService.shutdown();
}
}
public static ExecutorService newFixedThreadPool(int nThread, String threadName, int capacity) {
return new ThreadPoolExecutor(nThread, nThread, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue(capacity), new DefaultThreadFactory("fixed", threadName), defaultHandler);
}
/**
* 创建线程名称前缀为threadPrefix的线程池
*
* @param threadPrefix
* @return
*/
public static ExecutorService newCachedThreadPool(String threadPrefix) {
return Executors.newCachedThreadPool(new DefaultThreadFactory("cache", threadPrefix));
}
/**
* 创建大小为threadSize的线程池,每个线程名称前缀为threadPrefix
*
* @param threadSize
* @param threadPrefix
* @return
*/
public static ExecutorService newFixedThreadPool(Integer threadSize, String threadPrefix) {
if (threadSize == null) {
return null;
}
return Executors.newFixedThreadPool(threadSize.intValue(), new DefaultThreadFactory("fixed", threadPrefix));
}
/**
* 创建大小为threadSize的缓存线程池,每个线程名称前缀为threadPrefix,超时时间为milliSeconds
*
* @param threadSize
* @param threadPrefix
* @param milliSeconds
* @return
*/
public static ExecutorService newFixedThreadPool(Integer threadSize, String threadPrefix, Long milliSeconds) {
if (threadSize == null) {
return null;
}
return new ThreadPoolExecutor(threadSize, threadSize,
milliSeconds == null ? 0L : milliSeconds, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
new DefaultThreadFactory("fixed", threadPrefix));
}
/**
* 创建大小为threadSize,队列容量为capacity的缓存线程池,每个线程名称前缀为threadPrefix
*
* @param threadSize
* @param threadPrefix
* @param capacity
* @return
*/
public static ExecutorService newFixedThreadPool(Integer threadSize, String threadPrefix, Integer capacity) {
if (threadSize == null) {
return null;
}
return new ThreadPoolExecutor(threadSize, threadSize, 0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(capacity == null ? Integer.MAX_VALUE : capacity),
new DefaultThreadFactory("fixed", threadPrefix), defaultHandler);
}
/**
* 默认线程工厂
*/
private static class DefaultThreadFactory implements ThreadFactory {
private static final AtomicInteger poolNumber = new AtomicInteger(1);
private final ThreadGroup group;
private final AtomicInteger threadNumber = new AtomicInteger(1);
private final String namePrefix;
DefaultThreadFactory(String threadPoolType, String threadPrefix) {
SecurityManager s = System.getSecurityManager();
group = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
namePrefix = "pool" + (threadPoolType == null ? "" : "-" + threadPoolType) + "-" + poolNumber.getAndIncrement() + "-thread-"
+ (threadPrefix == null ? "" : threadPrefix);
}
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
if (t.isDaemon()) {
t.setDaemon(true);
}
if (t.getPriority() != Thread.NORM_PRIORITY) {
t.setPriority(Thread.NORM_PRIORITY);
}
return t;
}
}
/**
* 交给executor执行任务
*
* @param executorService
* @param call
* @return
*/
public static <T> Future<T> execAndReturn(ExecutorService executorService, Callable<T> call) {
return executorService.submit(call);
}
/**
* 交给executor执行任务
*
* @param call
* @return
*/
public static <T> Future<T> execAndReturn(Callable<T> call) {
return execAndReturn(getCachedThreadPool(), call);
}
/**
* 获取future里面的对象,抛出异常,用在对执行结果出错后不影响其他逻辑的地方
*
* @param future
* @return
*/
public static <T> T getFutureObject(Future<T> future) {
T result = null;
try {
result = future.get();
} catch (InterruptedException e) {
log.error("getFutureObject InterruptedException,result=" + result, e.fillInStackTrace());
} catch (ExecutionException e) {
log.error("getFutureObject ExecutionException,result=" + result, e.fillInStackTrace());
}
return result;
}
/**
* 并发执行多个任务
*
* @param executorService
* @param callList
* @return
*/
public static <T> List<T> execListAndReturn(ExecutorService executorService, List<? extends Callable<T>> callList) {
if (callList == null || callList.size() == 0) {
return null;
}
List<T> result = new ArrayList<>();
List<Future<T>> futures = new ArrayList<>();
callList.stream().forEach(e-> futures.add(execAndReturn(executorService, e)));
futures.stream().forEach(t->{
boolean success = false;
T ret = null;
try {
ret = t.get();
result.add(ret);
success = true;
} catch (InterruptedException e) {
log.error("execListAndReturn InterruptedException,ret=" + ret, e.fillInStackTrace());
} catch (ExecutionException e) {
log.error("execListAndReturn ExecutionException,ret=" + ret, e.fillInStackTrace());
} finally {
if (!success) {
result.add(null);
}
}
});
return result;
}
/**
* 并发执行多个任务
*
* @param callList
* @return
*/
public static <T> List<T> execListAndReturn(List<? extends Callable<T>> callList) {
return execListAndReturn(getCachedThreadPool(), callList);
}
/**
* 并发执行多个任务
*
* @param executorService
* @param callMap
* @return
*/
public static <K, V> Map<K, V> execMapAndReturn(ExecutorService executorService, Map<K, ? extends Callable<V>> callMap) {
if (callMap == null || callMap.isEmpty()) {
return null;
}
Set<K> keys = callMap.keySet();
Map<K, V> result = new HashMap<>();
Map<K, Future<V>> futures = new HashMap<>();
keys.stream().forEach(e->{
Callable<V> call = callMap.get(e);
futures.put(e, execAndReturn(executorService, call));
});
keys.stream().forEach(t->{
V val = null;
try {
val = futures.get(t).get();
result.put(t, val);
} catch (InterruptedException e) {
log.error("execMapAndReturn InterruptedException,key=" + t + ",val=" + val, e.fillInStackTrace());
} catch (ExecutionException e) {
log.error("execMapAndReturn ExecutionException,key=" + t + ",val=" + val, e.fillInStackTrace());
} catch (Exception e) {
log.error("execMapAndReturn unknown exception,key=" + t + ",val=" + val, e.fillInStackTrace());
}
});
return result;
}
/**
* 并发执行多个任务
*
* @param callMap
* @return
*/
public static <K, V> Map<K, V> execMapAndReturn(Map<K, ? extends Callable<V>> callMap) {
return execMapAndReturn(getCachedThreadPool(), callMap);
}
}
对象复制新类型和同类型深度克隆工具类
package com.citydo.jetcache;
import org.apache.commons.beanutils.PropertyUtils;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
/**
* 对象复制新类型和同类型深度克隆工具类
*/
public class CopyUtils {
@SuppressWarnings({"unchecked", "rawtypes"})
public static <T> T deepCopy(T obj) {
if (obj == null) {
return null;
} else if (obj instanceof String) {
return (T)(String) obj;
} else if (obj instanceof Integer) {
return (T)(Integer) obj;
} else if (obj instanceof Double) {
return (T)(Double) obj;
} else if (obj instanceof Byte) {
return (T)(Byte) obj;
} else if (obj instanceof Short) {
return (T)(Short) obj;
} else if (obj instanceof Long) {
return (T)(Long) obj;
} else if (obj instanceof Float) {
return (T)(Float) obj;
} else if (obj instanceof Character) {
return (T)(Character) obj;
} else if (obj instanceof Boolean) {
return (T)(Boolean) obj;
} else if (obj instanceof ArrayList<?>) {
return (T) arrayListHandler((ArrayList<?>) obj);
} else if (obj instanceof HashMap<?, ?>) {
return (T) mapHandler((Map<?, ?>) obj);
} else if (obj instanceof ConcurrentHashMap<?, ?>) {
return (T) concurrentMapHandler((Map<?, ?>) obj);
} else if (obj instanceof TreeMap<?, ?>) {
return (T) treeMapHandler((Map<?, ?>) obj);
} else if (obj instanceof LinkedList<?>) {
return (T) linkedListHandler((LinkedList<?>) obj);
} else if (obj instanceof HashSet<?>) {
return (T) hashSetHandler((HashSet<?>) obj);
} else if (isPrimitiveArray(obj)) {
return getPrimitiveArray(obj);
}
T finObj = null;
Class rezClass = obj.getClass();
rezClass.cast(finObj);
try {
Constructor<T> constructor = getCompleteConstructor(rezClass);
finObj = (T) constructor.newInstance(getParamsObjForConstructor(rezClass));
copyFields(rezClass, obj, finObj);
} catch (Exception e) {
e.printStackTrace();
}
return finObj;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static <T> T deepCopy(T obj, Object parrent) {
if (obj == null) {
return null;
} else if (obj instanceof String) {
return (T)String.valueOf((String) obj);
} else if (obj instanceof Integer) {
return (T)Integer.valueOf((Integer) obj);
} else if (obj instanceof Double) {
return (T)Double.valueOf((Double) obj);
} else if (obj instanceof Byte) {
return (T)Byte.valueOf((Byte) obj);
} else if (obj instanceof Short) {
return (T)Short.valueOf((Short) obj);
} else if (obj instanceof Long) {
return (T)Long.valueOf((Long) obj);
} else if (obj instanceof Float) {
return (T)Float.valueOf((Float) obj);
} else if (obj instanceof Character) {
return (T)Character.valueOf((Character) obj);
} else if (obj instanceof Boolean) {
return (T)Boolean.valueOf((Boolean) obj);
} else if (obj instanceof ArrayList<?>) {
return (T) arrayListHandler((ArrayList<?>) obj);
} else if (obj instanceof HashMap<?, ?>) {
return (T) mapHandler((Map<?, ?>) obj);
} else if (obj instanceof ConcurrentHashMap<?, ?>) {
return (T) concurrentMapHandler((Map<?, ?>) obj);
} else if (obj instanceof TreeMap<?, ?>) {
return (T) treeMapHandler((Map<?, ?>) obj);
} else if (obj instanceof LinkedList<?>) {
return (T) linkedListHandler((LinkedList<?>) obj);
} else if (obj instanceof HashSet<?>) {
return (T) hashSetHandler((HashSet<?>) obj);
} else if (isPrimitiveArray(obj)) {
return getPrimitiveArray(obj);
}
T finObj = null;
Class rezClass = obj.getClass();
rezClass.cast(finObj);
try {
Constructor<T> constructor = getCompleteConstructor(rezClass);
finObj = (T) constructor.newInstance(getParamsObjForConstructor(rezClass));
copyFields(rezClass, obj, finObj, parrent);
} catch (Exception e) {
e.printStackTrace();
}
return finObj;
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static ArrayList<?> arrayListHandler(ArrayList<?> obj) {
ArrayList srcList = obj;
ArrayList finList = new ArrayList();
for (int i = 0; i < srcList.size(); i++) {
finList.add(CopyUtils.deepCopy(srcList.get(i)));
}
return finList;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static <K, V> Map<K, V> mapHandler(Map<K, V> obj) {
Map<K, V> src = obj;
Map<K, V> fin = new HashMap<>();
src.entrySet().stream().forEach(e->{
K key = (K) CopyUtils.deepCopy(e.getKey());
V value = (V) CopyUtils.deepCopy(e.getValue());
fin.put(key, value);
});
return fin;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static <K, V> Map<K, V> concurrentMapHandler(Map<K, V> obj) {
Map<K, V> src = obj;
Map<K, V> fin = new ConcurrentHashMap<>();
src.entrySet().stream().forEach(e->{
K key = (K) CopyUtils.deepCopy(e.getKey());
V value = (V) CopyUtils.deepCopy(e.getValue());
fin.put(key, value);
});
return fin;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static <K, V> Map<K, V> treeMapHandler(Map<K, V> obj) {
Map<K, V> src = obj;
Map<K, V> fin = new TreeMap<>();
src.entrySet().stream().forEach(e->{
K key = (K) CopyUtils.deepCopy(e.getKey());
V value = (V) CopyUtils.deepCopy(e.getValue());
fin.put(key, value);
});
return fin;
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static LinkedList<?> linkedListHandler(LinkedList<?> obj) {
LinkedList srcList = obj;
LinkedList finList = new LinkedList<>();
for (int i = 0; i < srcList.size(); i++) {
finList.add(CopyUtils.deepCopy(srcList.get(i)));
}
return finList;
}
@SuppressWarnings({"rawtypes", "unchecked"})
private static HashSet<?> hashSetHandler(HashSet<?> obj) {
HashSet srcList = obj;
HashSet finList = new HashSet<>();
srcList.stream().forEach(e-> finList.add(CopyUtils.deepCopy(e)));
return finList;
}
private static boolean isPrimitiveArray(Object obj) {
if (obj instanceof byte[] ||
obj instanceof short[] ||
obj instanceof int[] ||
obj instanceof long[] ||
obj instanceof float[] ||
obj instanceof double[] ||
obj instanceof char[] ||
obj instanceof boolean[]) {
return true;
} else {
return false;
}
}
private static boolean isPrimitiveArray(String type) {
if ("byte[]".equals(type) ||
"short[]".equals(type) ||
"int[]".equals(type) ||
"long[]".equals(type) ||
"float[]".equals(type) ||
"double[]".equals(type) ||
"char[]".equals(type) ||
"boolean[]".equals(type)) {
return true;
} else {
return false;
}
}
@SuppressWarnings("unchecked")
private static <T> T getPrimitiveArray(T obj) {
if (obj instanceof int[]) {
int[] arr = new int[((int[]) obj).length];
for (int i = 0; i < ((int[]) obj).length; i++) {
arr[i] = ((int[]) obj)[i];
}
return (T) arr;
} else if (obj instanceof byte[]) {
byte[] arr = new byte[((byte[]) obj).length];
for (int i = 0; i < ((byte[]) obj).length; i++) {
arr[i] = ((byte[]) obj)[i];
}
return (T) arr;
} else if (obj instanceof short[]) {
short[] arr = new short[((short[]) obj).length];
for (int i = 0; i < ((short[]) obj).length; i++) {
arr[i] = ((short[]) obj)[i];
}
return (T) arr;
} else if (obj instanceof long[]) {
long[] arr = new long[((long[]) obj).length];
for (int i = 0; i < ((long[]) obj).length; i++) {
arr[i] = ((long[]) obj)[i];
}
return (T) arr;
} else if (obj instanceof float[]) {
float[] arr = new float[((float[]) obj).length];
for (int i = 0; i < ((float[]) obj).length; i++) {
arr[i] = ((float[]) obj)[i];
}
return (T) arr;
} else if (obj instanceof double[]) {
double[] arr = new double[((double[]) obj).length];
for (int i = 0; i < ((double[]) obj).length; i++) {
arr[i] = ((double[]) obj)[i];
}
return (T) arr;
} else if (obj instanceof char[]) {
char[] arr = new char[((char[]) obj).length];
for (int i = 0; i < ((char[]) obj).length; i++) {
arr[i] = ((char[]) obj)[i];
}
return (T) arr;
} else if (obj instanceof boolean[]) {
boolean[] arr = new boolean[((boolean[]) obj).length];
for (int i = 0; i < ((boolean[]) obj).length; i++) {
arr[i] = ((boolean[]) obj)[i];
}
return (T) arr;
}
return null;
}
@SuppressWarnings("unchecked")
private static <T> T getPrimitiveArray(T obj, String type) {
if ("int[]".equals(type)) {
int[] arr = new int[1];
arr[0] = 0;
return (T) arr;
} else if ("byte[]".equals(type)) {
byte[] arr = new byte[1];
arr[0] = 0;
return (T) arr;
} else if ("short[]".equals(type)) {
short[] arr = new short[1];
arr[0] = 0;
return (T) arr;
} else if ("long[]".equals(type)) {
long[] arr = new long[1];
arr[0] = 0;
return (T) arr;
} else if ("float[]".equals(type)) {
float[] arr = new float[1];
arr[0] = 0;
return (T) arr;
} else if ("double[]".equals(type)) {
double[] arr = new double[1];
arr[0] = 0;
return (T) arr;
} else if ("char[]".equals(type)) {
char[] arr = new char[1];
arr[0] = 0;
return (T) arr;
} else if ("boolean[]".equals(type)) {
boolean[] arr = new boolean[1];
arr[0] = false;
return (T) arr;
}
return null;
}
@SuppressWarnings({"unchecked", "rawtypes"})
private static Constructor getCompleteConstructor(Class ourClass)
throws NoSuchMethodException, SecurityException {
Constructor constructor = null;
Class[] params = new Class[ourClass.getDeclaredConstructors()[0].getParameterTypes().length];
for (int i = 0; i < ourClass.getDeclaredConstructors()[0].getParameterTypes().length; i++) {
params[i] = ourClass.getDeclaredConstructors()[0].getParameterTypes()[i];
}
constructor = ourClass.getConstructor(params);
constructor.setAccessible(true);
return constructor;
}
@SuppressWarnings("rawtypes")
private static Object[] getParamsObjForConstructor(Class ourClass)
throws SecurityException {
Constructor constuctor;
constuctor = ourClass.getDeclaredConstructors()[0];
constuctor.setAccessible(true);
Object[] objParams = new Object[constuctor.getParameterTypes().length];
for (int i = 0; i < constuctor.getParameterTypes().length; i++) {
String fieldType = constuctor.getParameterTypes()[i].toString();
if ("int".equalsIgnoreCase(fieldType) ||
"double".equalsIgnoreCase(fieldType) ||
"float".equalsIgnoreCase(fieldType) ||
"byte".equalsIgnoreCase(fieldType) ||
"char".equalsIgnoreCase(fieldType) ||
"long".equalsIgnoreCase(fieldType)) {
objParams[i] = 0;
} else if ("boolean".equalsIgnoreCase(fieldType)) {
objParams[i] = false;
} else if (isPrimitiveArray(constuctor.getParameterTypes()[i].getCanonicalName())) {
objParams[i] = getPrimitiveArray(constuctor.getParameterTypes()[i],
constuctor.getParameterTypes()[i].getCanonicalName()
);
} else {
objParams[i] = null;
}
}
return objParams;
}
@SuppressWarnings("rawtypes")
private static <T> void copyFields(Class ourClass, T srcObj, T finObj)
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
Field[] fields = ourClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
Field modField = Field.class.getDeclaredField("modifiers");
modField.setAccessible(true);
modField.setInt(fields[i], fields[i].getModifiers() & ~Modifier.FINAL);
String fieldType = fields[i].getType().toString();
if ("int".equalsIgnoreCase(fieldType) ||
"double".equalsIgnoreCase(fieldType) ||
"float".equalsIgnoreCase(fieldType) ||
"byte".equalsIgnoreCase(fieldType) ||
"char".equalsIgnoreCase(fieldType) ||
"boolean".equalsIgnoreCase(fieldType) ||
"short".equalsIgnoreCase(fieldType) ||
"long".equalsIgnoreCase(fieldType)) {
fields[i].set(finObj, fields[i].get(srcObj));
} else {
fields[i].set(finObj, CopyUtils.deepCopy(fields[i].get(srcObj), finObj));
}
}
}
@SuppressWarnings("rawtypes")
private static <T> void copyFields(Class ourClass, T srcObj, T finObj, Object parent)
throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
Field[] fields = ourClass.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);
Field modField = Field.class.getDeclaredField("modifiers");
modField.setAccessible(true);
modField.setInt(fields[i], fields[i].getModifiers() & ~Modifier.FINAL);
String fieldType = fields[i].getType().toString();
if ("int".equalsIgnoreCase(fieldType) ||
"double".equalsIgnoreCase(fieldType) ||
"float".equalsIgnoreCase(fieldType) ||
"byte".equalsIgnoreCase(fieldType) ||
"char".equalsIgnoreCase(fieldType) ||
"boolean".equalsIgnoreCase(fieldType) ||
"short".equalsIgnoreCase(fieldType) ||
"long".equalsIgnoreCase(fieldType)) {
fields[i].set(finObj, fields[i].get(srcObj));
} else {
if (fields[i].get(srcObj).toString().equals(parent.toString())) {
fields[i].set(finObj, fields[i].get(srcObj));
} else {
fields[i].set(finObj, CopyUtils.deepCopy(fields[i].get(srcObj), finObj));
}
}
}
}
static void setFinalStaticField(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static Object copyProperties(Object target, Object orig) {
if (target == null || orig == null) {
return target;
}
PropertyDescriptor[] destDesc = PropertyUtils.getPropertyDescriptors(target);
try {
for (int i = 0; i < destDesc.length; i++) {
Class destType = destDesc[i].getPropertyType();
Class origType = PropertyUtils.getPropertyType(orig, destDesc[i].getName());
if (destType != null && destType.equals(origType) && !destType.equals(Class.class)) {
if (!Collection.class.isAssignableFrom(origType)) {
try {
Object value = PropertyUtils.getProperty(orig, destDesc[i].getName());
PropertyUtils.setProperty(target, destDesc[i].getName(), value);
} catch (Exception ex) {
}
}
}
}
return target;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public static Object copyProperties(Object dest, Object orig, String[] ignores) {
if (dest == null || orig == null) {
return dest;
}
PropertyDescriptor[] destDesc = PropertyUtils.getPropertyDescriptors(dest);
try {
for (int i = 0; i < destDesc.length; i++) {
if (contains(ignores, destDesc[i].getName())) {
continue;
}
Class destType = destDesc[i].getPropertyType();
Class origType = PropertyUtils.getPropertyType(orig, destDesc[i].getName());
if (destType != null && destType.equals(origType) && !destType.equals(Class.class)) {
if (!Collection.class.isAssignableFrom(origType)) {
Object value = PropertyUtils.getProperty(orig, destDesc[i].getName());
PropertyUtils.setProperty(dest, destDesc[i].getName(), value);
}
}
}
return dest;
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
static boolean contains(String[] ignores, String name) {
boolean ignored = false;
for (int j = 0; ignores != null && j < ignores.length; j++) {
if (ignores[j].equals(name)) {
ignored = true;
break;
}
}
return ignored;
}
}