com.fastchar.core.FastOverrides Maven / Gradle / Ivy
package com.fastchar.core;
import com.fastchar.annotation.AFastClassFind;
import com.fastchar.annotation.AFastObserver;
import com.fastchar.annotation.AFastPriority;
import com.fastchar.database.operate.FastMySqlDatabaseOperateProvider;
import com.fastchar.exception.FastOverrideException;
import com.fastchar.extend.druid.FastDruidDataSourceProvider;
import com.fastchar.extend.ehcache.FastEhCacheProvider;
import com.fastchar.extend.fastjson.FastJsonProvider;
import com.fastchar.extend.gson.FastGsonProvider;
import com.fastchar.extend.jdbc.FastJdbcDataSourceProvider;
import com.fastchar.extend.redis.FastRedisClusterProvider;
import com.fastchar.extend.redis.FastRedisNormalProvider;
import com.fastchar.local.FastCharLocal_CN;
import com.fastchar.provider.FastFileRenameProvider;
import com.fastchar.provider.FastSecurityProvider;
import com.fastchar.utils.FastBooleanUtils;
import com.fastchar.utils.FastClassUtils;
import com.fastchar.utils.FastMD5Utils;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings({"unchecked", "UnusedReturnValue"})
public final class FastOverrides {
private volatile List classes = new ArrayList<>();
private volatile ConcurrentHashMap> classMap = new ConcurrentHashMap<>();
private volatile ConcurrentHashMap instanceMap = new ConcurrentHashMap<>();
public FastOverrides() {
add(FastSecurityProvider.class);
add(FastFileRenameProvider.class);
add(FastJdbcDataSourceProvider.class);
add(FastDruidDataSourceProvider.class);
add(FastMySqlDatabaseOperateProvider.class);
add(FastGsonProvider.class);
add(FastJsonProvider.class);
add(FastEhCacheProvider.class);
add(FastRedisNormalProvider.class);
add(FastCharLocal_CN.class);
add(FastRedisClusterProvider.class);
}
private ClassInfo getClassInfo(Class targetClass) {
for (ClassInfo aClass : classes) {
if (aClass.targetClass == targetClass) {
return aClass;
}
}
return null;
}
public FastOverrides add(Class targetClass) {
int priority = 0;
if (targetClass.isAnnotationPresent(AFastPriority.class)) {
AFastPriority fastPriority = targetClass.getAnnotation(AFastPriority.class);
priority = fastPriority.value();
}
return add(targetClass, priority);
}
public FastOverrides add(Class targetClass, int priority) {
if (getClassInfo(targetClass) != null) {
return this;
}
if (targetClass.isAnnotationPresent(AFastClassFind.class)) {
AFastClassFind fastFind = targetClass.getAnnotation(AFastClassFind.class);
for (String s : fastFind.value()) {
if (FastClassUtils.getClass(s, false) == null) {
return this;
}
}
}
ClassInfo classInfo = new ClassInfo();
classInfo.targetClass = targetClass;
classInfo.priority = priority;
classes.add(classInfo);
sortClasses();
return this;
}
public FastOverrides setPriority(Class targetClass, int priority) {
ClassInfo classInfo = getClassInfo(targetClass);
if (classInfo == null) {
return this;
}
classInfo.priority = priority;
return this;
}
public FastOverrides removeClass(Class targetClass) {
if (targetClass.isAnnotationPresent(AFastClassFind.class)) {
AFastClassFind fastFind = targetClass.getAnnotation(AFastClassFind.class);
for (String s : fastFind.value()) {
if (FastClassUtils.getClass(s, false) == null) {
return this;
}
}
}
List strings = classMap.get(targetClass.getName());
if (strings != null) {
for (String string : strings) {
instanceMap.remove(string);
}
}
ClassInfo classInfo = getClassInfo(targetClass);
if (classInfo != null) {
classes.remove(classInfo);
}
return this;
}
public T singleInstance(Class targetClass, Object... constructorParams) {
String onlyCode = FastMD5Utils.MD5(targetClass.getName() + Arrays.toString(constructorParams));
return singleInstance(onlyCode, targetClass, constructorParams);
}
public T singleInstance(String onlyCode,Class targetClass, Object... constructorParams) {
targetClass = findClass(targetClass, constructorParams);
if (!classMap.containsKey(targetClass.getName())) {
classMap.put(targetClass.getName(), new ArrayList());
}
classMap.get(targetClass.getName()).add(onlyCode);
if (instanceMap.containsKey(onlyCode)) {
return (T) instanceMap.get(onlyCode);
}
T t = newInstance(targetClass, constructorParams);
if (t.getClass().isAnnotationPresent(AFastObserver.class)) {
FastChar.getObservable().addObserver(t);
}
instanceMap.put(onlyCode, t);
return t;
}
public T newInstance(Class targetClass, Object... constructorParams) {
if (targetClass == null) {
throw new NullPointerException();
}
String errorInfo = "can not instance " + targetClass.getName() + ":" + Arrays.toString(constructorParams);
if (Modifier.isFinal(targetClass.getModifiers())) {
T instance = FastClassUtils.newInstance(targetClass, constructorParams);
if (instance == null) {
throw new FastOverrideException(errorInfo);
}
}
targetClass = findClass(targetClass, constructorParams);
if (Modifier.isInterface(targetClass.getModifiers())) {
throw new FastOverrideException(errorInfo);
}
if (Modifier.isAbstract(targetClass.getModifiers())) {
throw new FastOverrideException(errorInfo);
}
if (Modifier.isPrivate(targetClass.getModifiers())) {
throw new FastOverrideException(errorInfo);
}
if (Modifier.isProtected(targetClass.getModifiers())) {
throw new FastOverrideException(errorInfo);
}
T instance = FastClassUtils.newInstance(targetClass, constructorParams);
if (instance == null) {
throw new FastOverrideException(errorInfo);
}
return instance;
}
private Class findClass(Class targetClass, Object... constructorParams) {
for (int r = classes.size() - 1; r >= 0; r--) {
Class aClass = classes.get(r).targetClass;
if (targetClass.isAssignableFrom(aClass)) {
List overrideMethods = FastClassUtils.getDeclaredMethod(aClass, "isOverride");
if (overrideMethods.size() > 0) {
Method method = overrideMethods.get(0);
List