Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8199d1f69f | ||
|
|
b1773a6bc1 | ||
|
|
65763cbaa5 |
@@ -22,5 +22,3 @@
|
||||
|
||||
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
|
||||
**/*.iml
|
||||
|
||||
@@ -64,27 +64,27 @@ public class DefaultDispatcher<Context, Data> implements Dispatcher<Context, Dat
|
||||
log.error("{} 处理器列表为空.", name);
|
||||
return;
|
||||
}
|
||||
this.name = name == null ? "" : name;
|
||||
this.name = name;
|
||||
this.handlerMap = new HashMap<>();
|
||||
this.matcher = matcher;
|
||||
|
||||
for (Handler handler : handlerList) {
|
||||
Match match = handler.getClass().getAnnotation(Match.class);
|
||||
if (null == match) {
|
||||
log.warn("{} 类: {} 缺失Match注解", this.name, handler.getClass().getName());
|
||||
log.warn("类: {} 缺失Match注解", handler.getClass().getName());
|
||||
continue;
|
||||
}
|
||||
if (StringUtil.isEmpty(match.type())) {
|
||||
log.warn("{} 类: {} match注解缺失type参数!", this.name, handler.getClass().getName());
|
||||
log.warn("类: {} match注解缺失type参数!", handler.getClass().getName());
|
||||
continue;
|
||||
}
|
||||
if (handlerMap.containsKey(match.type())) {
|
||||
log.warn("{} 类: {} match注解type值{} 存在重复!", this.name, handler.getClass().getName(), match.type());
|
||||
log.warn("类: {} match注解type值{} 存在重复!", handler.getClass().getName(), match.type());
|
||||
continue;
|
||||
}
|
||||
handlerMap.put(match.type(), handler);
|
||||
}
|
||||
log.info("{} 处理器初始化完成", this.name);
|
||||
log.info("{} 处理器初始化完成", name);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,19 +94,19 @@ public class DefaultDispatcher<Context, Data> implements Dispatcher<Context, Dat
|
||||
}
|
||||
String type = matcher.apply(data);
|
||||
if (null == type) {
|
||||
log.warn("{} 获取匹配类型失败 data:{]", this.name, JSONObject.toJSONString(data));
|
||||
log.warn("获取匹配类型失败 data:{]", JSONObject.toJSONString(data));
|
||||
return;
|
||||
}
|
||||
Handler<Context,Data> handler = handlerMap.get(type);
|
||||
if (null == handler) {
|
||||
log.warn("{} 找不到匹配的处理器 type:{}", this.name, type);
|
||||
log.warn("找不到匹配的处理器 type:{}", type);
|
||||
return;
|
||||
}
|
||||
String handlerName = handler.name();
|
||||
if (StringUtil.isEmpty(handlerName)) {
|
||||
handlerName = TypeUtil.getSimpleName(handler.getClass());
|
||||
String name = handler.name();
|
||||
if (StringUtil.isEmpty(name)) {
|
||||
name = TypeUtil.getSimpleName(handler.getClass());
|
||||
}
|
||||
log.debug("{} 处理器[{}]执行.", this.name, handlerName);
|
||||
log.debug("处理器[{}]执行.", name);
|
||||
handler.handle(context, data);
|
||||
}
|
||||
}
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/**
|
||||
* Copyright (c) 2022 aoshiguchen
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package fun.asgc.neutrino.core.constant;
|
||||
|
||||
/**
|
||||
* 类型不匹配值(后期计划改为"类型距离")
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
public interface TypeNotMatchingValueConstant {
|
||||
|
||||
/**
|
||||
* 最小值,表示完全匹配
|
||||
*/
|
||||
int MIN = 0;
|
||||
|
||||
/**
|
||||
* 最大值,表示完全不匹配
|
||||
*/
|
||||
int MAX = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* 完全匹配
|
||||
*/
|
||||
int COMPLETE = MIN;
|
||||
|
||||
/**
|
||||
* 完全不匹配
|
||||
*/
|
||||
int NOT = MAX;
|
||||
|
||||
/**
|
||||
* 包装匹配
|
||||
*/
|
||||
int WRAP = 1;
|
||||
|
||||
/**
|
||||
* 解包装匹配
|
||||
*/
|
||||
int UNWRAP = 2;
|
||||
|
||||
/**
|
||||
* 超类匹配起始值
|
||||
* 每增加1层,值加1
|
||||
*/
|
||||
int SUPER_CLASS_MIN = 100000;
|
||||
|
||||
/**
|
||||
* 超类最大层级(假定继承层级不会超过40万)
|
||||
*/
|
||||
int SUPER_CLASS_MAX_LEVEL = 400000;
|
||||
|
||||
/**
|
||||
* 超类匹配结束值
|
||||
*/
|
||||
int SUPER_CLASS_MAX = SUPER_CLASS_MIN + SUPER_CLASS_MAX_LEVEL - 1;
|
||||
|
||||
/**
|
||||
* 类型提升起始值
|
||||
*/
|
||||
int ASCENSION_MIN = 600000;
|
||||
|
||||
/**
|
||||
* 类型提升层级
|
||||
*/
|
||||
int ASCENSION_LEVEL = 10000;
|
||||
|
||||
/**
|
||||
* 类型提升最大值
|
||||
*/
|
||||
int ASCENSION_MAX = ASCENSION_MIN + ASCENSION_LEVEL - 1;
|
||||
|
||||
/**
|
||||
* 自定义类型转换起始值
|
||||
*/
|
||||
int CUSTOM_MIN = 10000000;
|
||||
|
||||
/**
|
||||
* 自定义类型转换层级
|
||||
*/
|
||||
int CUSTOM_LEVEL = 10000000;
|
||||
|
||||
/**
|
||||
* 自定义类型转换结束值
|
||||
*/
|
||||
int CUSTOM_MAX = CUSTOM_MIN + CUSTOM_LEVEL - 1;
|
||||
}
|
||||
@@ -67,8 +67,8 @@ public class Bean implements LifeCycle {
|
||||
}
|
||||
isInit = true;
|
||||
|
||||
Set<Method> methods = ReflectUtil.getMethods(clazz);
|
||||
if (CollectionUtil.notEmpty(methods)) {
|
||||
Method[] methods = ReflectUtil.getMethods(clazz);
|
||||
if (null != methods && methods.length > 0) {
|
||||
for (Method method : methods) {
|
||||
if (method.isAnnotationPresent(Init.class) && method.getParameters().length == 0) {
|
||||
try {
|
||||
@@ -86,8 +86,8 @@ public class Bean implements LifeCycle {
|
||||
if (!hasInstance()) {
|
||||
return;
|
||||
}
|
||||
Set<Method> methods = ReflectUtil.getMethods(clazz);
|
||||
if (CollectionUtil.notEmpty(methods)) {
|
||||
Method[] methods = ReflectUtil.getMethods(clazz);
|
||||
if (null != methods && methods.length > 0) {
|
||||
for (Method method : methods) {
|
||||
if (method.isAnnotationPresent(Destroy.class) && method.getParameters().length == 0) {
|
||||
try {
|
||||
@@ -131,9 +131,9 @@ public class Bean implements LifeCycle {
|
||||
}
|
||||
|
||||
private void inject(ApplicationContext context) {
|
||||
Set<Method> methods = ReflectUtil.getMethods(clazz);
|
||||
if (CollectionUtil.notEmpty(methods)) {
|
||||
methods.stream().forEach(method -> {
|
||||
Method[] methods = ReflectUtil.getMethods(clazz);
|
||||
if (null != methods && methods.length > 0) {
|
||||
Stream.of(methods).forEach(method -> {
|
||||
fun.asgc.neutrino.core.annotation.Bean bean = method.getAnnotation(fun.asgc.neutrino.core.annotation.Bean.class);
|
||||
if (null == bean) {
|
||||
return;
|
||||
|
||||
+9
-10
@@ -19,20 +19,19 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package fun.asgc.neutrino.core.type;
|
||||
|
||||
package fun.asgc.neutrino.core.launcher;
|
||||
|
||||
/**
|
||||
* 类型转换器
|
||||
*
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/17
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface TypeConverter {
|
||||
public interface Launcher {
|
||||
|
||||
/**
|
||||
* 类型转换
|
||||
* @param value
|
||||
* @param targetType
|
||||
* @return
|
||||
* 启动
|
||||
*/
|
||||
Object convert(Object value, Class<?> targetType);
|
||||
void launch();
|
||||
|
||||
}
|
||||
@@ -40,38 +40,58 @@ import java.lang.management.ManagementFactory;
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
@Slf4j
|
||||
public class NeutrinoLauncher {
|
||||
public class NeutrinoLauncher implements Launcher {
|
||||
private Environment environment;
|
||||
private ApplicationContainer applicationContainer;
|
||||
private static volatile boolean running = true;
|
||||
private static Object lock = new Object();
|
||||
|
||||
public static SystemUtil.RunContext run(final Class<?> clazz, final String[] args) {
|
||||
public static void run(final Class<?> clazz, final String[] args) {
|
||||
Assert.notNull(clazz, "启动类不能为空!");
|
||||
return new NeutrinoLauncher(clazz, args).launch();
|
||||
|
||||
ThreadUtil.run(() -> {
|
||||
new NeutrinoLauncher(clazz, args).launch();
|
||||
});
|
||||
}
|
||||
|
||||
public static void runSync(final Class<?> clazz, final String[] args) {
|
||||
run(clazz, args).sync();
|
||||
run(clazz, args);
|
||||
|
||||
synchronized (lock) {
|
||||
while (running) {
|
||||
try {
|
||||
lock.wait();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
log.info("Application already stop.");
|
||||
}
|
||||
|
||||
private NeutrinoLauncher(Class<?> clazz, String[] args) {
|
||||
public NeutrinoLauncher(Class<?> clazz, String[] args) {
|
||||
this.environment = new Environment()
|
||||
.setMainClass(clazz)
|
||||
.setMainArgs(args);
|
||||
}
|
||||
|
||||
private SystemUtil.RunContext launch() {
|
||||
@Override
|
||||
public void launch() {
|
||||
StopWatch stopWatch = new StopWatch();
|
||||
stopWatch.start();
|
||||
|
||||
environmentInit();
|
||||
this.applicationContainer = new DefaultApplicationContainer(environment);
|
||||
SystemUtil.RunContext runContext = SystemUtil.waitProcessDestroy(() -> this.applicationContainer.destroy());
|
||||
SystemUtil.addShutdownHook(() -> {
|
||||
synchronized (lock) {
|
||||
this.applicationContainer.destroy();
|
||||
running = false;
|
||||
lock.notify();
|
||||
}
|
||||
});
|
||||
|
||||
stopWatch.stop();
|
||||
printLog(environment, stopWatch);
|
||||
|
||||
return runContext;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,6 +146,6 @@ public class NeutrinoLauncher {
|
||||
if (StringUtil.notEmpty(banner)) {
|
||||
environment.setBanner(banner);
|
||||
}
|
||||
log.info(environment.getBanner());
|
||||
System.out.println(environment.getBanner());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2022 aoshiguchen
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
package fun.asgc.neutrino.core.type;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 类型匹配等级
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/17
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum TypeMatchLevel {
|
||||
// 当且仅当匹配类为空(即匹配对象为null没有类型)时
|
||||
NULL(0, 0, 0, "空匹配"),
|
||||
// 当且仅当匹配类与目标类完全相等
|
||||
PERFECT(1, 1, 1, "完美匹配"),
|
||||
// 当且仅当匹配类为严格基本数据类型,且目标类为对应的包装类型
|
||||
PACKING(2, 100, 100, "装箱匹配"),
|
||||
// 当且仅当目标类为严格基本数据类型,且匹配类为对应的包装类型
|
||||
UNPACKING(3, 200,200,"拆箱匹配"),
|
||||
// 当且仅当匹配类和目标类均为一般基本数据类型(非严格),且目标类型的范围更加宽泛时
|
||||
ASCENSION(4, 1000, 2000, "类型提升匹配"),
|
||||
// 超类匹配,当且仅当目标类是匹配类的超类时
|
||||
SUPER(5, 1000000, 2000000, "超类匹配"),
|
||||
// 内置的扩展匹配
|
||||
EXTENSION(6, 10000000, 50000000, "扩展匹配"),
|
||||
// 自定义匹配
|
||||
CUSTOM(7, 100000000, 500000000, "自定义匹配"),
|
||||
// 不匹配
|
||||
NOT(8, Integer.MAX_VALUE, Integer.MAX_VALUE, "不匹配");
|
||||
private static Map<Integer,TypeMatchLevel> levelMap = Stream.of(TypeMatchLevel.values()).collect(Collectors.toMap(TypeMatchLevel::getLevel, Function.identity()));
|
||||
|
||||
/**
|
||||
* 匹配级别
|
||||
*/
|
||||
private int level;
|
||||
/**
|
||||
* 类型距离最小值
|
||||
*/
|
||||
private int distanceMin;
|
||||
/**
|
||||
* 类型距离最大值
|
||||
*/
|
||||
private int distanceMax;
|
||||
/**
|
||||
* 描述
|
||||
*/
|
||||
private String desc;
|
||||
|
||||
public static TypeMatchLevel byLevel(int level) {
|
||||
return levelMap.get(level);
|
||||
}
|
||||
|
||||
public static TypeMatchLevel byTypeDistance(int typeDistance) {
|
||||
for (TypeMatchLevel item : values()) {
|
||||
if (typeDistance >= item.getDistanceMin() && typeDistance <= item.getDistanceMax()) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2022 aoshiguchen
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package fun.asgc.neutrino.core.type;
|
||||
|
||||
/**
|
||||
* 值类型匹配器
|
||||
*
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/17
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface TypeMatcher {
|
||||
|
||||
/**
|
||||
* 匹配
|
||||
* @param clazz
|
||||
* @param targetClass
|
||||
* @return
|
||||
*/
|
||||
TypeMatchInfo match(Class<?> clazz, Class<?> targetClass);
|
||||
|
||||
}
|
||||
@@ -1,387 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd.
|
||||
* <p>
|
||||
* All right reserved.
|
||||
* <p>
|
||||
* This software is the confidential and proprietary
|
||||
* information of Zeyi Company of China.
|
||||
* ("Confidential Information"). You shall not disclose
|
||||
* such Confidential Information and shall use it only
|
||||
* in accordance with the terms of the contract agreement
|
||||
* you entered into with Zeyi inc.
|
||||
*/
|
||||
package fun.asgc.neutrino.core.type;
|
||||
|
||||
import fun.asgc.neutrino.core.util.Assert;
|
||||
import fun.asgc.neutrino.core.util.StringUtil;
|
||||
import fun.asgc.neutrino.core.util.TypeUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: wen.y
|
||||
* @date: 2022/6/17
|
||||
*/
|
||||
public class TypeMatchers {
|
||||
/**
|
||||
* 默认的基本匹配器列表
|
||||
*/
|
||||
private static List<TypeMatcher> defaultTypeMatcherList = Collections.synchronizedList(new ArrayList<>());
|
||||
/**
|
||||
* 默认内置扩展的匹配器列表
|
||||
*/
|
||||
private static List<TypeMatcher> extensionMatcherList = Collections.synchronizedList(new ArrayList<>());
|
||||
/**
|
||||
* 用户自定义的匹配器列表
|
||||
*/
|
||||
private List<TypeMatcher> customTypeMatcherList = Collections.synchronizedList(new ArrayList<>());
|
||||
/**
|
||||
* 是否启用内置扩展匹配器
|
||||
*/
|
||||
private volatile boolean enableExtensionMatcher = true;
|
||||
|
||||
static {
|
||||
// 空匹配
|
||||
defaultTypeMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (null == clazz) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.NULL.getDistanceMin());
|
||||
matchInfo.setTypeConverter((value, type) -> TypeUtil.getDefaultValue(type));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 完美匹配
|
||||
defaultTypeMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (clazz == targetClass) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.PERFECT.getDistanceMin());
|
||||
matchInfo.setTypeConverter((value, type) -> value);
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 装箱匹配
|
||||
defaultTypeMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isStrictBasicType(clazz) && TypeUtil.getWrapType(clazz) == targetClass) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.PACKING.getDistanceMin());
|
||||
matchInfo.setTypeConverter((value, type) -> value);
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 拆箱匹配
|
||||
defaultTypeMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isStrictBasicType(targetClass) && TypeUtil.getWrapType(targetClass) == clazz) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.UNPACKING.getDistanceMin());
|
||||
matchInfo.setTypeConverter((value, type) -> value);
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 类型提升匹配
|
||||
defaultTypeMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
int index1 = TypeUtil.basicTypeList.indexOf(clazz);
|
||||
int index2 = TypeUtil.basicTypeList.indexOf(targetClass);
|
||||
if (index2 > index1 && index1 >= 0) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.ASCENSION.getDistanceMin() + (index2 - index1));
|
||||
matchInfo.setTypeConverter((value, type) -> {
|
||||
if (value == type || TypeUtil.getWrapType(value.getClass()) == type) {
|
||||
return value;
|
||||
}
|
||||
if (TypeUtil.isBoolean(value.getClass())) {
|
||||
return ((boolean)value) ? 1 : 0;
|
||||
}
|
||||
if (TypeUtil.isBoolean(type)) {
|
||||
return TypeUtil.isChar(value.getClass()) ? ((char)value == 0 ? false : true) :
|
||||
(((Number)value).intValue() == 0 ? false : true);
|
||||
}
|
||||
if (TypeUtil.isChar(type)) {
|
||||
return (char)(int)value;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 超类匹配
|
||||
defaultTypeMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (targetClass.isAssignableFrom(clazz)) {
|
||||
int level = TypeUtil.getInheritLevel(targetClass, clazz);
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.SUPER.getDistanceMin() + level);
|
||||
matchInfo.setTypeConverter((value, type) -> value);
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 内置扩展匹配 --------
|
||||
// 字符串
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isNormalBasicType(clazz) && targetClass == String.class) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 100);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> String.valueOf(value)));
|
||||
}
|
||||
if (TypeUtil.isChar(targetClass) && TypeUtil.isString(clazz)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 101);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> ((String)value).charAt(0)));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// Boolean
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isBoolean(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 110);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> ((String)value).toLowerCase().equals("true")));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// Number
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isByte(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 111);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Byte.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isShort(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 112);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Short.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isInteger(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 113);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Integer.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isLong(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 114);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Long.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isFloat(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 115);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Float.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isDouble(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 116);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Double.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 日期1
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isLong(clazz) && TypeUtil.isDate(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 200);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> {
|
||||
if (targetClass == java.util.Date.class) {
|
||||
return new java.util.Date((long)value);
|
||||
} else {
|
||||
return new java.sql.Date((long)value);
|
||||
}
|
||||
}));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 日期2
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isLong(targetClass) && TypeUtil.isDate(clazz)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 300);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> ((java.util.Date)value).getTime()));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// Object[] -> List
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (List.class == targetClass && clazz.isArray()) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 400);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> Stream.of((Object[])value).collect(Collectors.toList())));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// List -> Object[]
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (List.class.isAssignableFrom(clazz) && targetClass.isArray()) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 500);
|
||||
matchInfo.setTypeConverter((value, targetType) -> ((List)value).toArray());
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// Object[] -> Set
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (Set.class == targetClass && clazz.isArray()) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 600);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> Stream.of((Object[])value).collect(Collectors.toSet())));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// Set -> Object[]
|
||||
extensionMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (Set.class.isAssignableFrom(clazz) && targetClass.isArray()) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 700);
|
||||
matchInfo.setTypeConverter((value, targetType) -> ((Set)value).toArray());
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册自定义类型匹配器具
|
||||
* @param typeMatcher
|
||||
*/
|
||||
public void registerCustomTypeMatcher(TypeMatcher typeMatcher) {
|
||||
customTypeMatcherList.add(typeMatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配
|
||||
* @param clazz
|
||||
* @param targetClass
|
||||
* @return
|
||||
*/
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
// 先匹配自定义的
|
||||
for (TypeMatcher matcher : customTypeMatcherList) {
|
||||
TypeMatchInfo typeMatchInfo = matcher.match(clazz, targetClass);
|
||||
if (typeMatchInfo.isMatched()) {
|
||||
return typeMatchInfo;
|
||||
}
|
||||
}
|
||||
// 再匹配内置默认的
|
||||
for (TypeMatcher matcher : defaultTypeMatcherList) {
|
||||
TypeMatchInfo typeMatchInfo = matcher.match(clazz, targetClass);
|
||||
if (typeMatchInfo.isMatched()) {
|
||||
return typeMatchInfo;
|
||||
}
|
||||
}
|
||||
if (enableExtensionMatcher) {
|
||||
// 再匹配内置扩展的
|
||||
for (TypeMatcher matcher : extensionMatcherList) {
|
||||
TypeMatchInfo typeMatchInfo = matcher.match(clazz, targetClass);
|
||||
if (typeMatchInfo.isMatched()) {
|
||||
return typeMatchInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isEnableExtensionMatcher() {
|
||||
return enableExtensionMatcher;
|
||||
}
|
||||
|
||||
public void setEnableExtensionMatcher(boolean enableExtensionMatcher) {
|
||||
this.enableExtensionMatcher = enableExtensionMatcher;
|
||||
}
|
||||
|
||||
/**
|
||||
* 类型转换
|
||||
* @param value
|
||||
* @param targetType
|
||||
* @return
|
||||
*/
|
||||
public Object conversion(Object value, Class<?> targetType) {
|
||||
Assert.notNull(targetType, "目标类型不能为空!");
|
||||
TypeMatchInfo typeMatchInfo = match(value == null ? null : value.getClass(), targetType);
|
||||
if (null == typeMatchInfo || typeMatchInfo.isNotMatch()) {
|
||||
return null;
|
||||
}
|
||||
return typeMatchInfo.getTypeConverter().convert(value, targetType);
|
||||
}
|
||||
}
|
||||
@@ -210,32 +210,4 @@ public class ClassUtil {
|
||||
}
|
||||
return annotation;
|
||||
}
|
||||
|
||||
public static boolean isPublic(Class<?> clazz) {
|
||||
return Modifier.isPublic(clazz.getModifiers());
|
||||
}
|
||||
|
||||
public static boolean isPrivate(Class<?> clazz) {
|
||||
return Modifier.isPrivate(clazz.getModifiers());
|
||||
}
|
||||
|
||||
public static boolean isProtected(Class<?> clazz) {
|
||||
return Modifier.isProtected(clazz.getModifiers());
|
||||
}
|
||||
|
||||
public static boolean isFinal(Class<?> clazz) {
|
||||
return Modifier.isFinal(clazz.getModifiers());
|
||||
}
|
||||
|
||||
public static boolean isAbstract(Class<?> clazz) {
|
||||
return Modifier.isAbstract(clazz.getModifiers());
|
||||
}
|
||||
|
||||
public static boolean isStatic(Class<?> clazz) {
|
||||
return Modifier.isStatic(clazz.getModifiers());
|
||||
}
|
||||
|
||||
public static boolean isInterface(Class<?> clazz) {
|
||||
return clazz.isInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ package fun.asgc.neutrino.core.util;
|
||||
import com.google.common.collect.Sets;
|
||||
import fun.asgc.neutrino.core.cache.Cache;
|
||||
import fun.asgc.neutrino.core.cache.MemoryCache;
|
||||
import fun.asgc.neutrino.core.type.TypeMatchLevel;
|
||||
import fun.asgc.neutrino.core.constant.TypeNotMatchingValueConstant;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -41,11 +41,11 @@ import java.util.stream.Stream;
|
||||
*/
|
||||
public class ReflectUtil {
|
||||
|
||||
private static Cache<Class<?>, Set<Field>> fieldsCache = new MemoryCache<>();
|
||||
private static Cache<Class<?>, Set<Field>> declaredFieldsCache = new MemoryCache<>();
|
||||
private static Cache<Class<?>, Field[]> fieldsCache = new MemoryCache<>();
|
||||
private static Cache<Class<?>, Field[]> declaredFieldsCache = new MemoryCache<>();
|
||||
private static Cache<Class<?>, Set<Field>> inheritChainDeclaredFieldSetCache = new MemoryCache<>();
|
||||
private static Cache<Class<?>, Set<Method>> methodsCache = new MemoryCache<>();
|
||||
private static Cache<Class<?>, Set<Method>> declaredMethodsCache = new MemoryCache<>();
|
||||
private static Cache<Class<?>, Method[]> methodsCache = new MemoryCache<>();
|
||||
private static Cache<Class<?>, Method[]> declaredMethodsCache = new MemoryCache<>();
|
||||
private static Cache<Field,Method> getMethodCache = new MemoryCache<>();
|
||||
private static Cache<Field,Method> setMethodCache = new MemoryCache<>();
|
||||
|
||||
@@ -54,15 +54,8 @@ public class ReflectUtil {
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Set<Field> getFields(Class<?> clazz) {
|
||||
return kvProcess(fieldsCache, clazz, c -> {
|
||||
Field[] fields = c.getFields();
|
||||
Set<Field> fieldSet = new HashSet<>();
|
||||
if (ArrayUtil.notEmpty(fields)) {
|
||||
fieldSet = Stream.of(fields).collect(Collectors.toSet());
|
||||
}
|
||||
return fieldSet;
|
||||
});
|
||||
public static Field[] getFields(Class<?> clazz) {
|
||||
return kvProcess(fieldsCache, clazz, c -> c.getFields());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,15 +63,8 @@ public class ReflectUtil {
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Set<Field> getDeclaredFields(Class<?> clazz) {
|
||||
return kvProcess(declaredFieldsCache, clazz, c -> {
|
||||
Field[] fields = c.getDeclaredFields();
|
||||
Set<Field> fieldSet = new HashSet<>();
|
||||
if (ArrayUtil.notEmpty(fields)) {
|
||||
fieldSet = Stream.of(fields).collect(Collectors.toSet());
|
||||
}
|
||||
return fieldSet;
|
||||
});
|
||||
public static Field[] getDeclaredFields(Class<?> clazz) {
|
||||
return kvProcess(declaredFieldsCache, clazz, c -> c.getDeclaredFields());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,8 +89,8 @@ public class ReflectUtil {
|
||||
Set<Field> set = new HashSet<>();
|
||||
Set<Class<?>> ignores = null == ignoreClasses ? new HashSet<>() : ignoreClasses;
|
||||
while (null != c && !ignores.contains(c)) {
|
||||
Set<Field> fields = getDeclaredFields(c);
|
||||
if (CollectionUtil.notEmpty(fields)) {
|
||||
Field[] fields = getDeclaredFields(c);
|
||||
if (null != fields && fields.length > 0) {
|
||||
for (Field field : fields) {
|
||||
if (field.getName().equals("this$0") || nameSet.contains(field.getName())) {
|
||||
continue;
|
||||
@@ -126,15 +112,8 @@ public class ReflectUtil {
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Set<Method> getMethods(Class<?> clazz) {
|
||||
return kvProcess(methodsCache, clazz, c -> {
|
||||
Method[] methods = c.getMethods();
|
||||
Set<Method> methodSet = new HashSet<>();
|
||||
if (ArrayUtil.notEmpty(methods)) {
|
||||
methodSet = Stream.of(methods).collect(Collectors.toSet());
|
||||
}
|
||||
return methodSet;
|
||||
});
|
||||
public static Method[] getMethods(Class<?> clazz) {
|
||||
return kvProcess(methodsCache, clazz, c -> c.getMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,15 +121,8 @@ public class ReflectUtil {
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Set<Method> getDeclaredMethods(Class<?> clazz) {
|
||||
return kvProcess(declaredMethodsCache, clazz, c -> {
|
||||
Method[] methods = c.getDeclaredMethods();
|
||||
Set<Method> methodSet = new HashSet<>();
|
||||
if (ArrayUtil.notEmpty(methods)) {
|
||||
methodSet = Stream.of(methods).collect(Collectors.toSet());
|
||||
}
|
||||
return methodSet;
|
||||
});
|
||||
public static Method[] getDeclaredMethods(Class<?> clazz) {
|
||||
return kvProcess(declaredMethodsCache, clazz, c -> c.getDeclaredMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,7 +172,7 @@ public class ReflectUtil {
|
||||
public static Method getGetMethod(Field field) {
|
||||
return kvProcess(getMethodCache, field, f -> {
|
||||
String getMethodName = getGetMethodName(field);
|
||||
return getMethods(field.getDeclaringClass()).stream()
|
||||
return Stream.of(getMethods(field.getDeclaringClass()))
|
||||
.filter(method -> method.getName().equals(getMethodName) && method.getParameters().length == 0)
|
||||
.findFirst().get();
|
||||
});
|
||||
@@ -230,24 +202,24 @@ public class ReflectUtil {
|
||||
public static Method getSetMethod(Field field) {
|
||||
return kvProcess(setMethodCache, field, f -> {
|
||||
String setMethodName = getSetMethodName(field);
|
||||
Optional<Method> methodOptional = getMethods(field.getDeclaringClass()).stream()
|
||||
Optional<Method> methodOptional = Stream.of(getMethods(field.getDeclaringClass()))
|
||||
.filter(method -> method.getName().equals(setMethodName) && method.getParameters().length == 1 && method.getParameterTypes()[0] == field.getType())
|
||||
.findFirst();
|
||||
if (methodOptional.isPresent()) {
|
||||
return methodOptional.get();
|
||||
}
|
||||
int level = TypeMatchLevel.NOT.getDistanceMax();
|
||||
int level = TypeNotMatchingValueConstant.MAX;
|
||||
Method method = null;
|
||||
for (Method m : getMethods(field.getDeclaringClass())) {
|
||||
if (m.getName().equals(setMethodName) && m.getParameters().length == 1) {
|
||||
int curLevel = TypeUtil.typeMatch(m.getParameterTypes()[0], field.getType()).getTypeDistance();
|
||||
int curLevel = TypeUtil.typeMatch(m.getParameterTypes()[0], field.getType()).getNotMatchingValue();
|
||||
if (curLevel < level) {
|
||||
level = curLevel;
|
||||
method = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (level < TypeMatchLevel.NOT.getDistanceMin() && method != null) {
|
||||
if (level < TypeNotMatchingValueConstant.MAX && method != null) {
|
||||
return method;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -114,22 +114,6 @@ public class StringUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isNumeric(String cs) {
|
||||
if (isEmpty(cs)) {
|
||||
return false;
|
||||
} else {
|
||||
int sz = cs.length();
|
||||
|
||||
for(int i = 0; i < sz; ++i) {
|
||||
if (!Character.isDigit(cs.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param str
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
package fun.asgc.neutrino.core.util;
|
||||
|
||||
import fun.asgc.neutrino.core.base.CodeBlock;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: aoshiguchen
|
||||
@@ -35,52 +33,4 @@ public class SystemUtil {
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(runnable));
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待进程销毁
|
||||
* @return
|
||||
*/
|
||||
public static RunContext waitProcessDestroy() {
|
||||
return waitProcessDestroy(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待进程销毁
|
||||
* @param destroy
|
||||
* @return
|
||||
*/
|
||||
public static RunContext waitProcessDestroy(CodeBlock destroy) {
|
||||
RunContext context = new RunContext();
|
||||
SystemUtil.addShutdownHook(() -> {
|
||||
synchronized (context) {
|
||||
if (null != destroy) {
|
||||
destroy.execute();
|
||||
}
|
||||
context.stop();
|
||||
context.notify();
|
||||
}
|
||||
});
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
public static class RunContext {
|
||||
private volatile boolean running = true;
|
||||
|
||||
public void sync() {
|
||||
synchronized (this) {
|
||||
while (running) {
|
||||
try {
|
||||
this.wait();
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void stop() {
|
||||
this.running = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+15
-27
@@ -20,24 +20,27 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package fun.asgc.neutrino.core.type;
|
||||
package fun.asgc.neutrino.core.util;
|
||||
|
||||
import fun.asgc.neutrino.core.constant.TypeNotMatchingValueConstant;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/16
|
||||
*/
|
||||
@Accessors(chain = true)
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Data
|
||||
public class TypeMatchInfo {
|
||||
public class TypeMatchingInfo {
|
||||
|
||||
/**
|
||||
* 目标类型类型
|
||||
* 字段类型
|
||||
*/
|
||||
private Class<?> targetType;
|
||||
private Class<?> fieldType;
|
||||
|
||||
/**
|
||||
* 值类型
|
||||
@@ -45,32 +48,17 @@ public class TypeMatchInfo {
|
||||
private Class<?> valueType;
|
||||
|
||||
/**
|
||||
* 类型距离
|
||||
* 不匹配值
|
||||
*/
|
||||
private int typeDistance;
|
||||
private Integer notMatchingValue;
|
||||
|
||||
/**
|
||||
* 类型匹配器
|
||||
*/
|
||||
private TypeMatcher typeMatcher;
|
||||
|
||||
/**
|
||||
* 类型转换器
|
||||
*/
|
||||
private TypeConverter typeConverter;
|
||||
|
||||
public TypeMatchInfo(Class<?> valueType, Class<?> targetType, TypeMatcher typeMatcher) {
|
||||
public TypeMatchingInfo(Class<?> fieldType, Class<?> valueType) {
|
||||
this.fieldType = fieldType;
|
||||
this.valueType = valueType;
|
||||
this.targetType = targetType;
|
||||
this.typeMatcher = typeMatcher;
|
||||
this.typeDistance = TypeMatchLevel.NOT.getDistanceMin();
|
||||
this.notMatchingValue = TypeNotMatchingValueConstant.NOT;
|
||||
}
|
||||
|
||||
public boolean isNotMatch() {
|
||||
return !isMatched();
|
||||
}
|
||||
|
||||
public boolean isMatched() {
|
||||
return TypeMatchLevel.byTypeDistance(this.typeDistance) != null && typeConverter != null;
|
||||
return TypeNotMatchingValueConstant.NOT == notMatchingValue;
|
||||
}
|
||||
}
|
||||
@@ -23,11 +23,13 @@
|
||||
package fun.asgc.neutrino.core.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import fun.asgc.neutrino.core.type.TypeMatchInfo;
|
||||
import fun.asgc.neutrino.core.type.TypeMatchers;
|
||||
import com.google.common.collect.Sets;
|
||||
import fun.asgc.neutrino.core.constant.TypeNotMatchingValueConstant;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -51,7 +53,6 @@ public class TypeUtil {
|
||||
this.add(boolean.class);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 一般意义上的基本数据类型
|
||||
*/
|
||||
@@ -73,7 +74,7 @@ public class TypeUtil {
|
||||
/**
|
||||
* 基本类型的映射
|
||||
*/
|
||||
private static final Map<Class<?>, Class<?>> basicTypeMap = new HashMap<Class<?>, Class<?>>() {
|
||||
public static final Map<Class<?>, Class<?>> basicTypeMap = new HashMap<Class<?>, Class<?>>() {
|
||||
{
|
||||
this.put(byte.class, byte.class);
|
||||
this.put(short.class, short.class);
|
||||
@@ -98,7 +99,7 @@ public class TypeUtil {
|
||||
/**
|
||||
* 包装类型的映射
|
||||
*/
|
||||
private static final Map<Class<?>, Class<?>> wrapTypeMap = new HashMap<Class<?>, Class<?>>() {
|
||||
public static final Map<Class<?>, Class<?>> wrapTypeMap = new HashMap<Class<?>, Class<?>>() {
|
||||
{
|
||||
this.put(byte.class, Byte.class);
|
||||
this.put(short.class, Short.class);
|
||||
@@ -129,26 +130,6 @@ public class TypeUtil {
|
||||
Boolean.class, Byte.class, Short.class, Character.class, Integer.class, Long.class, Float.class, Double.class
|
||||
);
|
||||
|
||||
/**
|
||||
* 默认值
|
||||
*/
|
||||
private static final Map<Class<?>, Object> defaultValueMap = new HashMap<Class<?>, Object>() {
|
||||
{
|
||||
this.put(byte.class, 0);
|
||||
this.put(short.class, 0);
|
||||
this.put(int.class, 0);
|
||||
this.put(long.class, 0);
|
||||
this.put(float.class, 0);
|
||||
this.put(double.class, 0);
|
||||
this.put(char.class, 0);
|
||||
this.put(boolean.class, false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 默认的类型匹配器
|
||||
*/
|
||||
private static final TypeMatchers defaultTypeMatchers = new TypeMatchers();
|
||||
|
||||
/**
|
||||
* 获取字段类型
|
||||
@@ -196,15 +177,6 @@ public class TypeUtil {
|
||||
return normalBasicType.contains(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是数字
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNumber(Class<?> clazz) {
|
||||
return Number.class.isAssignableFrom(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是一般基本类型
|
||||
* @param field
|
||||
@@ -238,15 +210,7 @@ public class TypeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static boolean isByte(Field field) {
|
||||
return isByte(getFieldType(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是byte类型
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isByte(Class clazz) {
|
||||
Class<?> clazz = getFieldType(field);
|
||||
return clazz == byte.class || clazz == Byte.class;
|
||||
}
|
||||
|
||||
@@ -256,15 +220,7 @@ public class TypeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static boolean isShort(Field field) {
|
||||
return isShort(getFieldType(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是short类型
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isShort(Class clazz) {
|
||||
Class<?> clazz = getFieldType(field);
|
||||
return clazz == short.class || clazz == Short.class;
|
||||
}
|
||||
|
||||
@@ -274,15 +230,7 @@ public class TypeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInteger(Field field) {
|
||||
return isInteger(getFieldType(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是integer类型
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isInteger(Class clazz) {
|
||||
Class<?> clazz = getFieldType(field);
|
||||
return clazz == int.class || clazz == Integer.class;
|
||||
}
|
||||
|
||||
@@ -292,15 +240,7 @@ public class TypeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static boolean isLong(Field field) {
|
||||
return isLong(getFieldType(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是long类型
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isLong(Class<?> clazz) {
|
||||
Class<?> clazz = getFieldType(field);
|
||||
return clazz == long.class || clazz == Long.class;
|
||||
}
|
||||
|
||||
@@ -310,15 +250,7 @@ public class TypeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static boolean isFloat(Field field) {
|
||||
return isFloat(getFieldType(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是float类型
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isFloat(Class<?> clazz) {
|
||||
Class<?> clazz = getFieldType(field);
|
||||
return clazz == float.class || clazz == Float.class;
|
||||
}
|
||||
|
||||
@@ -328,15 +260,7 @@ public class TypeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static boolean isDouble(Field field) {
|
||||
return isDouble(getFieldType(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是double类型
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isDouble(Class<?> clazz) {
|
||||
Class<?> clazz = getFieldType(field);
|
||||
return clazz == double.class || clazz == Double.class;
|
||||
}
|
||||
|
||||
@@ -366,36 +290,10 @@ public class TypeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static boolean isString(Field field) {
|
||||
return isString(getFieldType(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是String类型
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isString(Class clazz) {
|
||||
Class<?> clazz = getFieldType(field);
|
||||
return clazz == String.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是日期类型
|
||||
* @param field
|
||||
* @return
|
||||
*/
|
||||
public static boolean isDate(Field field) {
|
||||
return isDate(getFieldType(field));
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是日期类型
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isDate(Class<?> clazz) {
|
||||
return clazz == java.util.Date.class || clazz == java.sql.Date.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否是布尔值
|
||||
* @param clazz
|
||||
@@ -473,18 +371,8 @@ public class TypeUtil {
|
||||
return name.substring(0, 1).toLowerCase() + name.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取默认值
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Object getDefaultValue(Class<?> clazz) {
|
||||
return defaultValueMap.get(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取继承层级
|
||||
* 此处假定继承层级最多为100层,避免计算太过耗时
|
||||
* @param superClass
|
||||
* @param childClass
|
||||
* @return
|
||||
@@ -495,7 +383,7 @@ public class TypeUtil {
|
||||
}
|
||||
List<Pair<Class<?>, Integer>> list = new LinkedList<>();
|
||||
list.add(Pair.of(childClass, 0));
|
||||
while (CollectionUtil.notEmpty(list) && list.get(0).getFirst() != superClass && list.get(0).getSecond() < 100) {
|
||||
while (CollectionUtil.notEmpty(list) && list.get(0).getFirst() != superClass && list.get(0).getSecond() < TypeNotMatchingValueConstant.SUPER_CLASS_MAX) {
|
||||
Pair<Class<?>, Integer> current = list.remove(0);
|
||||
Class<?> clazz = current.getFirst();
|
||||
int level = current.getSecond();
|
||||
@@ -509,9 +397,9 @@ public class TypeUtil {
|
||||
}
|
||||
}
|
||||
if (list.isEmpty()) {
|
||||
return 100;
|
||||
return TypeNotMatchingValueConstant.SUPER_CLASS_MAX;
|
||||
}
|
||||
return Math.min(list.get(0).getSecond(), 100);
|
||||
return Math.min(list.get(0).getSecond(), TypeNotMatchingValueConstant.SUPER_CLASS_MAX);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -520,10 +408,122 @@ public class TypeUtil {
|
||||
* @param valueType
|
||||
* @return
|
||||
*/
|
||||
public static TypeMatchInfo typeMatch(Class<?> fieldType, Class<?> valueType) {
|
||||
public static TypeMatchingInfo typeMatch(Class<?> fieldType, Class<?> valueType) {
|
||||
Assert.notNull(fieldType, "字段类型不能为空!");
|
||||
Assert.notNull(valueType, "值类型不能为空!");
|
||||
return new TypeMatchInfo(fieldType, valueType, null);
|
||||
|
||||
// 1、完全匹配
|
||||
if (fieldType == valueType) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.COMPLETE);
|
||||
}
|
||||
// 2、包装匹配
|
||||
if (isStrictBasicType(valueType) && getWrapType(valueType) == fieldType) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.WRAP);
|
||||
}
|
||||
// 3、解包装匹配
|
||||
if (isStrictBasicType(fieldType) && getWrapType(fieldType) == valueType) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.UNWRAP);
|
||||
}
|
||||
// 4、超类匹配
|
||||
if (fieldType.isAssignableFrom(valueType)) {
|
||||
int inheritLevel = getInheritLevel(fieldType, valueType);
|
||||
if (-1 == inheritLevel) {
|
||||
throw new RuntimeException(String.format("超类匹配异常! fieldType:%s valueType:%s", fieldType.getName(), valueType.getName()));
|
||||
}
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.SUPER_CLASS_MIN + inheritLevel - 1);
|
||||
}
|
||||
// 5、类型提升
|
||||
if (isNormalBasicType(fieldType) && isNormalBasicType(valueType)) {
|
||||
int index1 = basicTypeList.indexOf(fieldType);
|
||||
int index2 = basicTypeList.indexOf(valueType);
|
||||
if (index1 > index2 && index2 > 0) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.ASCENSION_MIN + (index1 - index2) - 1);
|
||||
}
|
||||
}
|
||||
// 6、自定义转换
|
||||
if (fieldType == Date.class || fieldType == java.sql.Date.class) {
|
||||
if (valueType == long.class) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN);
|
||||
} else if (valueType == long.class) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 1);
|
||||
}
|
||||
}
|
||||
if (fieldType == Long.class || fieldType == long.class) {
|
||||
if (valueType == Date.class) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 1000);
|
||||
} else if (valueType == java.sql.Date.class) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 1001);
|
||||
}
|
||||
}
|
||||
if (fieldType == String.class) {
|
||||
if (valueType == char.class) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 2000);
|
||||
} else if (valueType == Character.class) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 2001);
|
||||
} else if (Number.class.isAssignableFrom(valueType)) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 2002);
|
||||
}
|
||||
}
|
||||
if (Iterable.class.isAssignableFrom(fieldType) && Iterable.class.isAssignableFrom(valueType)) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 3000);
|
||||
}
|
||||
if (Iterable.class.isAssignableFrom(fieldType) && String[].class == valueType) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 4000);
|
||||
}
|
||||
if (Iterable.class.isAssignableFrom(valueType) && String[].class == fieldType) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 5000);
|
||||
}
|
||||
if (Iterable.class.isAssignableFrom(fieldType) && Integer[].class == valueType) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 6000);
|
||||
}
|
||||
if (Iterable.class.isAssignableFrom(valueType) && Integer[].class == fieldType) {
|
||||
return new TypeMatchingInfo(fieldType, valueType, TypeNotMatchingValueConstant.CUSTOM_MIN + 7000);
|
||||
}
|
||||
|
||||
return new TypeMatchingInfo(fieldType, valueType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 类型提升
|
||||
* @param value
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Object ascensionType(Object value, Class<?> clazz) {
|
||||
Class<?> valueType = value.getClass();
|
||||
int index1 = basicTypeList.indexOf(valueType);
|
||||
int index2 = basicTypeList.indexOf(clazz);
|
||||
if (-1 == index1 || -1 == index2 || index1 >= index2) {
|
||||
return value;
|
||||
}
|
||||
if (getWrapType(valueType) == clazz || getWrapType(clazz) == valueType) {
|
||||
return value;
|
||||
}
|
||||
if (isChar(clazz)) {
|
||||
return value;
|
||||
}
|
||||
String strValue;
|
||||
if (isBoolean(valueType)) {
|
||||
strValue = ((Boolean)value) ? "0" : "1";
|
||||
} else if (isChar(valueType)){
|
||||
strValue = (int)((Character)value) + "";
|
||||
} else {
|
||||
strValue = String.valueOf(value);
|
||||
}
|
||||
if (isBoolean(clazz)) {
|
||||
return "0".equals(strValue);
|
||||
}
|
||||
Method method = ReflectUtil.getValueOfMethod(clazz, String.class);
|
||||
if (null == method) {
|
||||
return value;
|
||||
}
|
||||
|
||||
try {
|
||||
return method.invoke(null, strValue);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -533,6 +533,55 @@ public class TypeUtil {
|
||||
* @return
|
||||
*/
|
||||
public static Object conversion(Object value, Class<?> targetType) {
|
||||
return defaultTypeMatchers.conversion(value, targetType);
|
||||
Assert.notNull(targetType, "目标类型不能为空!");
|
||||
if (null == value) {
|
||||
return null;
|
||||
}
|
||||
Class<?> valueType = value.getClass();
|
||||
TypeMatchingInfo matchingInfo = typeMatch(targetType, valueType);
|
||||
if (matchingInfo.isNotMatch()) {
|
||||
return null;
|
||||
}
|
||||
// 超类
|
||||
if (matchingInfo.getNotMatchingValue() <= TypeNotMatchingValueConstant.SUPER_CLASS_MAX) {
|
||||
return value;
|
||||
}
|
||||
// 类型提升
|
||||
if (matchingInfo.getNotMatchingValue() <= TypeNotMatchingValueConstant.ASCENSION_MAX) {
|
||||
return TypeUtil.ascensionType(value, targetType);
|
||||
}
|
||||
if (matchingInfo.getNotMatchingValue() >= TypeNotMatchingValueConstant.CUSTOM_MIN && matchingInfo.getNotMatchingValue() <= TypeNotMatchingValueConstant.CUSTOM_MAX) {
|
||||
// 自定义转换
|
||||
if (targetType == Date.class) {
|
||||
if (valueType == long.class || value == Long.class) {
|
||||
return new Date((Long) value);
|
||||
}
|
||||
} else if (targetType == java.sql.Date.class) {
|
||||
if (valueType == long.class || value == Long.class) {
|
||||
return new java.sql.Date((Long) value);
|
||||
}
|
||||
} else if (targetType == Long.class || targetType == long.class) {
|
||||
if (valueType == java.sql.Date.class || valueType == Date.class) {
|
||||
return ((Date) value).getTime();
|
||||
}
|
||||
} else if (targetType == String.class) {
|
||||
if (valueType == char.class || valueType == Character.class || Number.class.isAssignableFrom(valueType)) {
|
||||
return String.valueOf(value);
|
||||
}
|
||||
} else if (Iterable.class.isAssignableFrom(targetType) && Iterable.class.isAssignableFrom(valueType)) {
|
||||
if (Set.class.isAssignableFrom(targetType)) {
|
||||
return Sets.newHashSet((Iterable) value);
|
||||
}
|
||||
} else if (Iterable.class.isAssignableFrom(valueType) && String[].class == targetType) {
|
||||
if (List.class.isAssignableFrom(valueType)) {
|
||||
return ((List<Object>) value).stream().map(String::valueOf).collect(Collectors.toList()).toArray(new String[]{});
|
||||
}
|
||||
} else if (Iterable.class.isAssignableFrom(valueType) && Integer[].class == targetType) {
|
||||
if (List.class.isAssignableFrom(valueType)) {
|
||||
return ((List<Object>) value).stream().map(String::valueOf).map(Integer::valueOf).collect(Collectors.toList()).toArray(new Integer[]{});
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd.
|
||||
* <p>
|
||||
* All right reserved.
|
||||
* <p>
|
||||
* This software is the confidential and proprietary
|
||||
* information of Zeyi Company of China.
|
||||
* ("Confidential Information"). You shall not disclose
|
||||
* such Confidential Information and shall use it only
|
||||
* in accordance with the terms of the contract agreement
|
||||
* you entered into with Zeyi inc.
|
||||
*/
|
||||
package fun.asgc.neutrino.core.util;
|
||||
|
||||
import lombok.Data;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: wen.y
|
||||
* @date: 2022/6/20
|
||||
*/
|
||||
public class LockUtilTest {
|
||||
private static volatile A a;
|
||||
|
||||
/**
|
||||
* 没有双重校验锁,并发执行容易产生多个实例
|
||||
*/
|
||||
@Test
|
||||
public void test1() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ThreadUtil.run(() -> {
|
||||
if (a == null) {
|
||||
a = new A();
|
||||
}
|
||||
});
|
||||
}
|
||||
SystemUtil.waitProcessDestroy().sync();
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用双重校验锁,并发执行,只产生一个实例
|
||||
*/
|
||||
@Test
|
||||
public void test2() {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
ThreadUtil.run(() -> {
|
||||
LockUtil.doubleCheckProcess(() -> a == null,
|
||||
LockUtilTest.class,
|
||||
() -> a = new A());
|
||||
});
|
||||
}
|
||||
SystemUtil.waitProcessDestroy().sync();
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class A {
|
||||
public A() {
|
||||
System.out.println("new instance.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd.
|
||||
* <p>
|
||||
* All right reserved.
|
||||
* <p>
|
||||
* This software is the confidential and proprietary
|
||||
* information of Zeyi Company of China.
|
||||
* ("Confidential Information"). You shall not disclose
|
||||
* such Confidential Information and shall use it only
|
||||
* in accordance with the terms of the contract agreement
|
||||
* you entered into with Zeyi inc.
|
||||
*/
|
||||
package fun.asgc.neutrino.core.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: wen.y
|
||||
* @date: 2022/6/20
|
||||
*/
|
||||
public class SystemUtilTest {
|
||||
|
||||
@Test
|
||||
public void run() {
|
||||
ThreadUtil.run(() -> {
|
||||
for (int i = 0; i < 10; i ++) {
|
||||
try {
|
||||
System.out.println(i);
|
||||
Thread.sleep(1000);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
SystemUtil.waitProcessDestroy(() -> System.out.println("进程销毁")).sync();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2018-2022 Zeyi information technology (Shanghai) Co., Ltd.
|
||||
* <p>
|
||||
* All right reserved.
|
||||
* <p>
|
||||
* This software is the confidential and proprietary
|
||||
* information of Zeyi Company of China.
|
||||
* ("Confidential Information"). You shall not disclose
|
||||
* such Confidential Information and shall use it only
|
||||
* in accordance with the terms of the contract agreement
|
||||
* you entered into with Zeyi inc.
|
||||
*/
|
||||
package fun.asgc.neutrino.core.util;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import fun.asgc.neutrino.core.type.*;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: wen.y
|
||||
* @date: 2022/6/17
|
||||
*/
|
||||
public class TypeUtilTest {
|
||||
|
||||
private static TypeMatchers typeMatchers = new TypeMatchers();
|
||||
|
||||
static {
|
||||
typeMatchers.registerCustomTypeMatcher(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo typeMatchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (clazz == String.class && targetClass == Animal.class) {
|
||||
typeMatchInfo.setTypeDistance(TypeMatchLevel.CUSTOM.getDistanceMin() + 1);
|
||||
typeMatchInfo.setTypeConverter(((value, targetType) -> new Animal().setName((String)value)));
|
||||
}
|
||||
return typeMatchInfo;
|
||||
}
|
||||
});
|
||||
typeMatchers.registerCustomTypeMatcher(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo typeMatchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (clazz == String.class && targetClass == Cat.class) {
|
||||
typeMatchInfo.setTypeDistance(TypeMatchLevel.CUSTOM.getDistanceMin() + 2);
|
||||
typeMatchInfo.setTypeConverter((value, targetType) -> {
|
||||
String[] tmp = ((String)value).split(":");
|
||||
Cat cat = new Cat();
|
||||
if (tmp.length >= 1) {
|
||||
cat.setName(tmp[0]);
|
||||
}
|
||||
if (tmp.length >= 2) {
|
||||
cat.setAge(Integer.valueOf(tmp[1]));
|
||||
}
|
||||
return cat;
|
||||
});
|
||||
}
|
||||
return typeMatchInfo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conversionNull() {
|
||||
System.out.println(typeMatchers.conversion(null, boolean.class));
|
||||
System.out.println(typeMatchers.conversion(null, byte.class));
|
||||
System.out.println(typeMatchers.conversion(null, short.class));
|
||||
System.out.println(typeMatchers.conversion(null, char.class));
|
||||
System.out.println(typeMatchers.conversion(null, int.class));
|
||||
System.out.println(typeMatchers.conversion(null, long.class));
|
||||
System.out.println(typeMatchers.conversion(null, float.class));
|
||||
System.out.println(typeMatchers.conversion(null, double.class));
|
||||
System.out.println(typeMatchers.conversion(null, Boolean.class));
|
||||
System.out.println(typeMatchers.conversion(null, Byte.class));
|
||||
System.out.println(typeMatchers.conversion(null, Short.class));
|
||||
System.out.println(typeMatchers.conversion(null, Character.class));
|
||||
System.out.println(typeMatchers.conversion(null, Integer.class));
|
||||
System.out.println(typeMatchers.conversion(null, Long.class));
|
||||
System.out.println(typeMatchers.conversion(null, Float.class));
|
||||
System.out.println(typeMatchers.conversion(null, Double.class));
|
||||
System.out.println(typeMatchers.conversion(null, String.class));
|
||||
System.out.println(typeMatchers.conversion(null, List.class));
|
||||
|
||||
System.out.println(typeMatchers.conversion(null, Animal.class));
|
||||
System.out.println(typeMatchers.conversion(null, Cat.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conversionString() {
|
||||
System.out.println(typeMatchers.conversion("true", boolean.class));
|
||||
System.out.println(typeMatchers.conversion("100", byte.class));
|
||||
System.out.println(typeMatchers.conversion("101", short.class));
|
||||
System.out.println(typeMatchers.conversion("a", char.class));
|
||||
System.out.println(typeMatchers.conversion("1000", int.class));
|
||||
System.out.println(typeMatchers.conversion("500000", long.class));
|
||||
System.out.println(typeMatchers.conversion("1.3", float.class));
|
||||
System.out.println(typeMatchers.conversion("566.0099", double.class));
|
||||
System.out.println(typeMatchers.conversion("false", Boolean.class));
|
||||
System.out.println(typeMatchers.conversion("88", Byte.class));
|
||||
System.out.println(typeMatchers.conversion("444", Short.class));
|
||||
System.out.println(typeMatchers.conversion("B", Character.class));
|
||||
System.out.println(typeMatchers.conversion("99", Integer.class));
|
||||
System.out.println(typeMatchers.conversion("5666666", Long.class));
|
||||
System.out.println(typeMatchers.conversion("10.24", Float.class));
|
||||
System.out.println(typeMatchers.conversion("3.1415926", Double.class));
|
||||
System.out.println(typeMatchers.conversion('a', String.class));
|
||||
|
||||
System.out.println(typeMatchers.conversion("aabb", Animal.class));
|
||||
System.out.println(typeMatchers.conversion("aabb:10", Cat.class));
|
||||
|
||||
System.out.println(typeMatchers.conversion(new String[]{"11","22","33","22"}, List.class));
|
||||
System.out.println(typeMatchers.conversion(new Integer[]{10, 20, 30,20}, List.class));
|
||||
System.out.println(typeMatchers.conversion(new Boolean[]{true, true, false}, List.class));
|
||||
System.out.println(typeMatchers.conversion(new Animal[]{new Animal("aa"), new Animal("bb"), new Animal("cc"),}, List.class));
|
||||
|
||||
System.out.println(typeMatchers.conversion(Lists.newArrayList("11","22","33","22"), Object[].class));
|
||||
|
||||
System.out.println(typeMatchers.conversion(new String[]{"11","22","33","22"}, Set.class));
|
||||
System.out.println(typeMatchers.conversion(new Integer[]{10, 20, 30,20}, Set.class));
|
||||
System.out.println(typeMatchers.conversion(new Boolean[]{true, true, false}, Set.class));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conversionInt() {
|
||||
typeMatchers.setEnableExtensionMatcher(false);
|
||||
|
||||
System.out.println(typeMatchers.conversion(100, boolean.class));
|
||||
System.out.println(typeMatchers.conversion(101, byte.class));
|
||||
System.out.println(typeMatchers.conversion(102, short.class));
|
||||
System.out.println(typeMatchers.conversion(103, char.class));
|
||||
System.out.println(typeMatchers.conversion(104, int.class));
|
||||
System.out.println(typeMatchers.conversion(105, long.class));
|
||||
System.out.println(typeMatchers.conversion(106, float.class));
|
||||
System.out.println(typeMatchers.conversion(107, double.class));
|
||||
System.out.println(typeMatchers.conversion(108, Boolean.class));
|
||||
System.out.println(typeMatchers.conversion(109, Byte.class));
|
||||
System.out.println(typeMatchers.conversion(110, Short.class));
|
||||
System.out.println(typeMatchers.conversion(111, Character.class));
|
||||
System.out.println(typeMatchers.conversion(112, Integer.class));
|
||||
System.out.println(typeMatchers.conversion(113, Long.class));
|
||||
System.out.println(typeMatchers.conversion(114, Float.class));
|
||||
System.out.println(typeMatchers.conversion(115, Double.class));
|
||||
System.out.println(typeMatchers.conversion(116, String.class));
|
||||
System.out.println(typeMatchers.conversion(200, List.class));
|
||||
|
||||
System.out.println(typeMatchers.conversion(117, Animal.class));
|
||||
System.out.println(typeMatchers.conversion(118, Cat.class));
|
||||
}
|
||||
|
||||
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
public static class Animal {
|
||||
private String name;
|
||||
public Animal() {
|
||||
|
||||
}
|
||||
public Animal(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@Accessors(chain = true)
|
||||
@Data
|
||||
private static class Cat extends Animal {
|
||||
private int age;
|
||||
}
|
||||
}
|
||||
@@ -34,7 +34,7 @@ import fun.asgc.neutrino.core.launcher.NeutrinoLauncher;
|
||||
public class ProxyClient {
|
||||
|
||||
public static void main(String[] args) {
|
||||
NeutrinoLauncher.run(ProxyClient.class, args);
|
||||
NeutrinoLauncher.runSync(ProxyClient.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import fun.asgc.neutrino.core.launcher.NeutrinoLauncher;
|
||||
public class ProxyServer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
NeutrinoLauncher.run(ProxyServer.class, args);
|
||||
NeutrinoLauncher.runSync(ProxyServer.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user