内置扩展匹配器相关结构优化
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
/**
|
||||
* 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 java.util.List;
|
||||
|
||||
/**
|
||||
* 匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public interface TypeMatcherGroup {
|
||||
/**
|
||||
* 匹配器列表
|
||||
* @return
|
||||
*/
|
||||
List<TypeMatcher> matchers();
|
||||
|
||||
/**
|
||||
* 获取最小距离
|
||||
* @return
|
||||
*/
|
||||
int getDistanceMin();
|
||||
|
||||
/**
|
||||
* 获取最大距离
|
||||
* @return
|
||||
*/
|
||||
int getDistanceMax();
|
||||
}
|
||||
@@ -21,16 +21,13 @@
|
||||
*/
|
||||
package fun.asgc.neutrino.core.type;
|
||||
|
||||
import fun.asgc.neutrino.core.type.extension.*;
|
||||
import fun.asgc.neutrino.core.util.Assert;
|
||||
import fun.asgc.neutrino.core.util.StringUtil;
|
||||
import fun.asgc.neutrino.core.util.CollectionUtil;
|
||||
import fun.asgc.neutrino.core.util.TypeUtil;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -41,21 +38,122 @@ public class TypeMatchers {
|
||||
/**
|
||||
* 默认的基本匹配器列表
|
||||
*/
|
||||
private static List<TypeMatcher> defaultTypeMatcherList = Collections.synchronizedList(new ArrayList<>());
|
||||
private static List<TypeMatcher> defaultTypeMatcherList = new ArrayList<>();
|
||||
/**
|
||||
* 默认内置扩展的匹配器列表
|
||||
*/
|
||||
private static List<TypeMatcher> extensionMatcherList = Collections.synchronizedList(new ArrayList<>());
|
||||
private static List<TypeMatcher> extensionMatcherList = new ArrayList<>();
|
||||
/**
|
||||
* 内置扩展匹配器组列表
|
||||
*/
|
||||
private static List<TypeMatcherGroup> extensionMatcherGroupList = new ArrayList<>();
|
||||
/**
|
||||
* 用户自定义的匹配器列表
|
||||
*/
|
||||
private List<TypeMatcher> customTypeMatcherList = Collections.synchronizedList(new ArrayList<>());
|
||||
private List<TypeMatcher> customTypeMatcherList = new ArrayList<>();
|
||||
/**
|
||||
* 是否启用内置扩展匹配器
|
||||
*/
|
||||
private volatile boolean enableExtensionMatcher = true;
|
||||
|
||||
static {
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册自定义类型匹配器具
|
||||
* @param typeMatcher
|
||||
*/
|
||||
public synchronized void registerCustomTypeMatcher(TypeMatcher typeMatcher) {
|
||||
customTypeMatcherList.add(typeMatcher);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册内置扩展匹配器组
|
||||
* @param typeMatcherGroup
|
||||
*/
|
||||
public static synchronized void registerExtensionTypeMatcher(TypeMatcherGroup typeMatcherGroup) {
|
||||
if (null == typeMatcherGroup || CollectionUtil.isEmpty(typeMatcherGroup.matchers())) {
|
||||
return;
|
||||
}
|
||||
// 内置扩展匹配器距离区间检测
|
||||
if (typeMatcherGroup.getDistanceMin() < TypeMatchLevel.EXTENSION.getDistanceMin() ||
|
||||
typeMatcherGroup.getDistanceMax() > TypeMatchLevel.EXTENSION.getDistanceMax() ||
|
||||
typeMatcherGroup.getDistanceMax() < typeMatcherGroup.getDistanceMin()) {
|
||||
throw new RuntimeException(String.format("内置扩展器:[%s] 距离区间定义有误!", typeMatcherGroup.getClass().getSimpleName()));
|
||||
}
|
||||
for (TypeMatcherGroup group : extensionMatcherGroupList) {
|
||||
// 距离区间不能重叠
|
||||
if (!(typeMatcherGroup.getDistanceMin() > group.getDistanceMax() || typeMatcherGroup.getDistanceMax() < group.getDistanceMin())) {
|
||||
throw new RuntimeException(String.format("内置扩展器:[%s]与[%s] 距离区间定义有重叠!", typeMatcherGroup.getClass().getSimpleName(), group.getClass().getSimpleName()));
|
||||
}
|
||||
}
|
||||
extensionMatcherGroupList.add(typeMatcherGroup);
|
||||
// 按照距离区间排序
|
||||
extensionMatcherList = extensionMatcherGroupList.stream().sorted(Comparator.comparing(TypeMatcherGroup::getDistanceMin))
|
||||
.map(TypeMatcherGroup::matchers).flatMap(List::stream).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配
|
||||
* @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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*/
|
||||
private static void init() {
|
||||
// 空匹配
|
||||
defaultTypeMatcherList.add(new TypeMatcher() {
|
||||
@Override
|
||||
@@ -149,258 +247,27 @@ public class TypeMatchers {
|
||||
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;
|
||||
}
|
||||
});
|
||||
// 日期
|
||||
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);
|
||||
}
|
||||
}));
|
||||
} else if (LocalDateTime.class.isAssignableFrom(clazz) && TypeUtil.isDate(targetClass)) {
|
||||
matchInfo.setTypeDistance(TypeMatchLevel.EXTENSION.getDistanceMin() + 201);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> {
|
||||
ZoneId zone = ZoneId.systemDefault();
|
||||
Instant instant = ((LocalDateTime)value).atZone(zone).toInstant();
|
||||
return Date.from(instant);
|
||||
}));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// 日期
|
||||
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;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
// 注册内置扩展匹配
|
||||
int extensionMatcherGroupSize = 100000;
|
||||
int extensionMatcherGroupDistance = TypeMatchLevel.EXTENSION.getDistanceMin();
|
||||
|
||||
/**
|
||||
* 注册自定义类型匹配器具
|
||||
* @param typeMatcher
|
||||
*/
|
||||
public void registerCustomTypeMatcher(TypeMatcher typeMatcher) {
|
||||
customTypeMatcherList.add(typeMatcher);
|
||||
}
|
||||
registerExtensionTypeMatcher(new StringMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 0,
|
||||
extensionMatcherGroupDistance + extensionMatcherGroupSize * 1 - 1));
|
||||
registerExtensionTypeMatcher(new BooleanMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 1,
|
||||
extensionMatcherGroupDistance + extensionMatcherGroupSize * 2 - 1));
|
||||
registerExtensionTypeMatcher(new NumberMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 2,
|
||||
extensionMatcherGroupDistance + extensionMatcherGroupSize * 3 - 1));
|
||||
registerExtensionTypeMatcher(new DateMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 3,
|
||||
extensionMatcherGroupDistance + extensionMatcherGroupSize * 4 - 1));
|
||||
registerExtensionTypeMatcher(new ListMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 4,
|
||||
extensionMatcherGroupDistance + extensionMatcherGroupSize * 5 - 1));
|
||||
registerExtensionTypeMatcher(new SetMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 5,
|
||||
extensionMatcherGroupDistance + extensionMatcherGroupSize * 6 - 1));
|
||||
registerExtensionTypeMatcher(new MapMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 6,
|
||||
extensionMatcherGroupDistance + extensionMatcherGroupSize * 7 - 1));
|
||||
registerExtensionTypeMatcher(new ArrayMatcherGroup(extensionMatcherGroupDistance + extensionMatcherGroupSize * 7,
|
||||
extensionMatcherGroupDistance + extensionMatcherGroupSize * 8 - 1));
|
||||
|
||||
/**
|
||||
* 匹配
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
import fun.asgc.neutrino.core.type.TypeMatcher;
|
||||
import fun.asgc.neutrino.core.type.TypeMatcherGroup;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 抽象的扩展类型匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public abstract class AbstractExtensionMatcherGroup implements TypeMatcherGroup {
|
||||
/**
|
||||
* 最小距离
|
||||
*/
|
||||
protected int distanceMin;
|
||||
|
||||
/**
|
||||
* 最大距离
|
||||
*/
|
||||
protected int distanceMax;
|
||||
|
||||
/**
|
||||
* 匹配器列表
|
||||
*/
|
||||
private List<TypeMatcher> matchers;
|
||||
|
||||
public AbstractExtensionMatcherGroup(int distanceMin, int distanceMax) {
|
||||
this.distanceMin = distanceMin;
|
||||
this.distanceMax = distanceMax;
|
||||
this.matchers = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TypeMatcher> matchers() {
|
||||
return matchers;
|
||||
}
|
||||
|
||||
public synchronized void add(TypeMatcher matcher) {
|
||||
if (null != matcher) {
|
||||
this.matchers.add(matcher);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceMin() {
|
||||
return distanceMin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDistanceMax() {
|
||||
return distanceMax;
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
import fun.asgc.neutrino.core.type.TypeMatchInfo;
|
||||
import fun.asgc.neutrino.core.type.TypeMatcher;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 数组匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public class ArrayMatcherGroup extends AbstractExtensionMatcherGroup {
|
||||
|
||||
public ArrayMatcherGroup(int distanceMin, int distanceMax) {
|
||||
super(distanceMin, distanceMax);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
// List -> Object[]
|
||||
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(getDistanceMin());
|
||||
matchInfo.setTypeConverter((value, targetType) -> ((List)value).toArray());
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
|
||||
// Set -> Object[]
|
||||
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(getDistanceMin() + 1);
|
||||
matchInfo.setTypeConverter((value, targetType) -> ((Set)value).toArray());
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
import fun.asgc.neutrino.core.type.TypeMatchInfo;
|
||||
import fun.asgc.neutrino.core.type.TypeMatcher;
|
||||
import fun.asgc.neutrino.core.util.TypeUtil;
|
||||
|
||||
/**
|
||||
* 布尔值匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public class BooleanMatcherGroup extends AbstractExtensionMatcherGroup {
|
||||
|
||||
public BooleanMatcherGroup(int distanceMin, int distanceMax) {
|
||||
super(distanceMin, distanceMax);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
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(getDistanceMin());
|
||||
matchInfo.setTypeConverter(((value, targetType) -> ((String)value).toLowerCase().equals("true")));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
|
||||
import fun.asgc.neutrino.core.type.TypeMatchInfo;
|
||||
import fun.asgc.neutrino.core.type.TypeMatcher;
|
||||
import fun.asgc.neutrino.core.util.TypeUtil;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 日期匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public class DateMatcherGroup extends AbstractExtensionMatcherGroup {
|
||||
|
||||
public DateMatcherGroup(int distanceMin, int distanceMax) {
|
||||
super(distanceMin, distanceMax);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
// Long -> Date
|
||||
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(getDistanceMin());
|
||||
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;
|
||||
}
|
||||
});
|
||||
// LocalDateTime -> Date
|
||||
add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (LocalDateTime.class.isAssignableFrom(clazz) && TypeUtil.isDate(targetClass)) {
|
||||
matchInfo.setTypeDistance(getDistanceMin() + 1);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> {
|
||||
ZoneId zone = ZoneId.systemDefault();
|
||||
Instant instant = ((LocalDateTime)value).atZone(zone).toInstant();
|
||||
return Date.from(instant);
|
||||
}));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
|
||||
import fun.asgc.neutrino.core.type.TypeMatchInfo;
|
||||
import fun.asgc.neutrino.core.type.TypeMatcher;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* list匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public class ListMatcherGroup extends AbstractExtensionMatcherGroup {
|
||||
|
||||
public ListMatcherGroup(int distanceMin, int distanceMax) {
|
||||
super(distanceMin, distanceMax);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
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(getDistanceMin());
|
||||
matchInfo.setTypeConverter(((value, targetType) -> Stream.of((Object[])value).collect(Collectors.toList())));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
/**
|
||||
* Map匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public class MapMatcherGroup extends AbstractExtensionMatcherGroup {
|
||||
|
||||
public MapMatcherGroup(int distanceMin, int distanceMax) {
|
||||
super(distanceMin, distanceMax);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
import fun.asgc.neutrino.core.type.TypeMatchInfo;
|
||||
import fun.asgc.neutrino.core.type.TypeMatcher;
|
||||
import fun.asgc.neutrino.core.util.TypeUtil;
|
||||
|
||||
/**
|
||||
* 字符串匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public class NumberMatcherGroup extends AbstractExtensionMatcherGroup {
|
||||
|
||||
public NumberMatcherGroup(int distanceMin, int distanceMax) {
|
||||
super(distanceMin, distanceMax);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
// String -> Byte
|
||||
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(getDistanceMin());
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Byte.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// String -> Short
|
||||
add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isShort(targetClass)) {
|
||||
matchInfo.setTypeDistance(getDistanceMin() + 1);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Short.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// String -> Integer
|
||||
add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isInteger(targetClass)) {
|
||||
matchInfo.setTypeDistance(getDistanceMin() + 2);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Integer.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// String -> Long
|
||||
add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isLong(targetClass)) {
|
||||
matchInfo.setTypeDistance(getDistanceMin() + 3);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Long.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// String -> Float
|
||||
add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isFloat(targetClass)) {
|
||||
matchInfo.setTypeDistance(getDistanceMin() + 4);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Float.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// String -> Double
|
||||
add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isString(clazz) && TypeUtil.isDouble(targetClass)) {
|
||||
matchInfo.setTypeDistance(getDistanceMin() + 5);
|
||||
matchInfo.setTypeConverter((value, targetType) -> {
|
||||
try {
|
||||
return Double.valueOf((String)value);
|
||||
} catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// date -> Long
|
||||
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(getDistanceMin() + 6);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> ((java.util.Date)value).getTime()));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
import fun.asgc.neutrino.core.type.TypeMatchInfo;
|
||||
import fun.asgc.neutrino.core.type.TypeMatchLevel;
|
||||
import fun.asgc.neutrino.core.type.TypeMatcher;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* set匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public class SetMatcherGroup extends AbstractExtensionMatcherGroup {
|
||||
|
||||
public SetMatcherGroup(int distanceMin, int distanceMax) {
|
||||
super(distanceMin, distanceMax);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
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(getDistanceMin());
|
||||
matchInfo.setTypeConverter(((value, targetType) -> Stream.of((Object[])value).collect(Collectors.toSet())));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* 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.extension;
|
||||
|
||||
import fun.asgc.neutrino.core.type.TypeMatchInfo;
|
||||
import fun.asgc.neutrino.core.type.TypeMatcher;
|
||||
import fun.asgc.neutrino.core.util.TypeUtil;
|
||||
|
||||
/**
|
||||
* 字符串匹配器组
|
||||
* @author: aoshiguchen
|
||||
* @date: 2022/6/29
|
||||
*/
|
||||
public class StringMatcherGroup extends AbstractExtensionMatcherGroup {
|
||||
|
||||
public StringMatcherGroup(int distanceMin, int distanceMax) {
|
||||
super(distanceMin, distanceMax);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
// 基本类型 -> String
|
||||
add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isNormalBasicType(clazz) && TypeUtil.isString(targetClass)) {
|
||||
matchInfo.setTypeDistance(getDistanceMin());
|
||||
matchInfo.setTypeConverter(((value, targetType) -> String.valueOf(value)));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
// String -> char
|
||||
add(new TypeMatcher() {
|
||||
@Override
|
||||
public TypeMatchInfo match(Class<?> clazz, Class<?> targetClass) {
|
||||
TypeMatchInfo matchInfo = new TypeMatchInfo(clazz, targetClass, this);
|
||||
if (TypeUtil.isChar(targetClass) && TypeUtil.isString(clazz)) {
|
||||
matchInfo.setTypeDistance(getDistanceMin() + 1);
|
||||
matchInfo.setTypeConverter(((value, targetType) -> ((String)value).charAt(0)));
|
||||
}
|
||||
return matchInfo;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -128,7 +128,7 @@ public class TypeUtilTest {
|
||||
|
||||
@Test
|
||||
public void conversionInt() {
|
||||
typeMatchers.setEnableExtensionMatcher(false);
|
||||
typeMatchers.setEnableExtensionMatcher(true);
|
||||
|
||||
System.out.println(typeMatchers.conversion(100, boolean.class));
|
||||
System.out.println(typeMatchers.conversion(101, byte.class));
|
||||
|
||||
Reference in New Issue
Block a user