From 01b078231d000dea2b302a5207e9848ff2578c5d Mon Sep 17 00:00:00 2001 From: aoshiguchen <1052045476@qq.com> Date: Wed, 29 Jun 2022 16:33:24 +0800 Subject: [PATCH] =?UTF-8?q?=E5=86=85=E7=BD=AE=E6=89=A9=E5=B1=95=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E5=99=A8=E7=9B=B8=E5=85=B3=E7=BB=93=E6=9E=84=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../neutrino/core/type/TypeMatcherGroup.java | 49 +++ .../asgc/neutrino/core/type/TypeMatchers.java | 383 ++++++------------ .../AbstractExtensionMatcherGroup.java | 77 ++++ .../type/extension/ArrayMatcherGroup.java | 70 ++++ .../type/extension/BooleanMatcherGroup.java | 54 +++ .../core/type/extension/DateMatcherGroup.java | 83 ++++ .../core/type/extension/ListMatcherGroup.java | 58 +++ .../core/type/extension/MapMatcherGroup.java | 40 ++ .../type/extension/NumberMatcherGroup.java | 169 ++++++++ .../core/type/extension/SetMatcherGroup.java | 58 +++ .../type/extension/StringMatcherGroup.java | 67 +++ .../asgc/neutrino/core/util/TypeUtilTest.java | 2 +- 12 files changed, 851 insertions(+), 259 deletions(-) create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/TypeMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/AbstractExtensionMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/ArrayMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/BooleanMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/DateMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/ListMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/MapMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/NumberMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/SetMatcherGroup.java create mode 100644 neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/StringMatcherGroup.java diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/TypeMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/TypeMatcherGroup.java new file mode 100644 index 00000000..d48285a8 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/TypeMatcherGroup.java @@ -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 matchers(); + + /** + * 获取最小距离 + * @return + */ + int getDistanceMin(); + + /** + * 获取最大距离 + * @return + */ + int getDistanceMax(); +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/TypeMatchers.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/TypeMatchers.java index cd895e30..aaf034ad 100644 --- a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/TypeMatchers.java +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/TypeMatchers.java @@ -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 defaultTypeMatcherList = Collections.synchronizedList(new ArrayList<>()); + private static List defaultTypeMatcherList = new ArrayList<>(); /** * 默认内置扩展的匹配器列表 */ - private static List extensionMatcherList = Collections.synchronizedList(new ArrayList<>()); + private static List extensionMatcherList = new ArrayList<>(); + /** + * 内置扩展匹配器组列表 + */ + private static List extensionMatcherGroupList = new ArrayList<>(); /** * 用户自定义的匹配器列表 */ - private List customTypeMatcherList = Collections.synchronizedList(new ArrayList<>()); + private List 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); } } diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/AbstractExtensionMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/AbstractExtensionMatcherGroup.java new file mode 100644 index 00000000..93b09dc4 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/AbstractExtensionMatcherGroup.java @@ -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 matchers; + + public AbstractExtensionMatcherGroup(int distanceMin, int distanceMax) { + this.distanceMin = distanceMin; + this.distanceMax = distanceMax; + this.matchers = new ArrayList<>(); + } + + @Override + public List 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; + } +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/ArrayMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/ArrayMatcherGroup.java new file mode 100644 index 00000000..577c4bcd --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/ArrayMatcherGroup.java @@ -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; + } + }); + } + +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/BooleanMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/BooleanMatcherGroup.java new file mode 100644 index 00000000..1d31b8e7 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/BooleanMatcherGroup.java @@ -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; + } + }); + } + +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/DateMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/DateMatcherGroup.java new file mode 100644 index 00000000..f14087bb --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/DateMatcherGroup.java @@ -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; + } + }); + } + +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/ListMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/ListMatcherGroup.java new file mode 100644 index 00000000..a9cb2b7a --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/ListMatcherGroup.java @@ -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; + } + }); + } + +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/MapMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/MapMatcherGroup.java new file mode 100644 index 00000000..048c0b4c --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/MapMatcherGroup.java @@ -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() { + + } + +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/NumberMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/NumberMatcherGroup.java new file mode 100644 index 00000000..43ce104c --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/NumberMatcherGroup.java @@ -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; + } + }); + } + +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/SetMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/SetMatcherGroup.java new file mode 100644 index 00000000..0b0add58 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/SetMatcherGroup.java @@ -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; + } + }); + } + +} diff --git a/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/StringMatcherGroup.java b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/StringMatcherGroup.java new file mode 100644 index 00000000..404c81c4 --- /dev/null +++ b/neutrino-core/src/main/java/fun/asgc/neutrino/core/type/extension/StringMatcherGroup.java @@ -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; + } + }); + } + +} diff --git a/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/TypeUtilTest.java b/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/TypeUtilTest.java index 76e6de3c..aa998afb 100644 --- a/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/TypeUtilTest.java +++ b/neutrino-core/src/test/java/fun/asgc/neutrino/core/util/TypeUtilTest.java @@ -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));