From c7bee0033ef794784b9c9fd39f61a245abff0c62 Mon Sep 17 00:00:00 2001 From: Charles7c Date: Fri, 15 Nov 2024 21:53:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(data/mp):=20=E6=96=B0=E5=A2=9E=E6=9E=9A?= =?UTF-8?q?=E4=B8=BE=E6=A0=A1=E9=AA=8C=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../starter/core/validation/CheckUtils.java | 204 +++++++++++++++++ .../core/validation/ValidationUtils.java | 176 ++++++++++++++ .../starter/core/validation/Validator.java | 214 ++++++++++++++++++ .../validation/constraints/EnumValue.java | 88 +++++++ .../constraints/EnumValueValidator.java | 96 ++++++++ .../data/mf/util/QueryWrapperHelper.java | 2 +- .../data/mp/service/impl/ServiceImpl.java | 2 +- .../data/mp/util/QueryWrapperHelper.java | 2 +- 8 files changed, 781 insertions(+), 3 deletions(-) create mode 100644 continew-starter-core/src/main/java/top/continew/starter/core/validation/CheckUtils.java create mode 100644 continew-starter-core/src/main/java/top/continew/starter/core/validation/ValidationUtils.java create mode 100644 continew-starter-core/src/main/java/top/continew/starter/core/validation/Validator.java create mode 100644 continew-starter-core/src/main/java/top/continew/starter/core/validation/constraints/EnumValue.java create mode 100644 continew-starter-core/src/main/java/top/continew/starter/core/validation/constraints/EnumValueValidator.java diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/validation/CheckUtils.java b/continew-starter-core/src/main/java/top/continew/starter/core/validation/CheckUtils.java new file mode 100644 index 00000000..5225cbf2 --- /dev/null +++ b/continew-starter-core/src/main/java/top/continew/starter/core/validation/CheckUtils.java @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.starter.core.validation; + +import cn.hutool.core.text.CharSequenceUtil; +import top.continew.starter.core.constant.StringConstants; +import top.continew.starter.core.exception.BusinessException; + +import java.util.function.BooleanSupplier; + +/** + * 业务参数校验工具类(抛出 500 ServiceException) + * + * @author Charles7c + * @see BusinessException + * @since 1.0.0 + */ +public class CheckUtils extends Validator { + + private static final Class EXCEPTION_TYPE = BusinessException.class; + + private CheckUtils() { + } + + /** + * 如果不存在,抛出异常 + * + * @param obj 被检测的对象 + * @param entityName 实体名 + * @param fieldName 字段名 + * @param fieldValue 字段值 + */ + public static void throwIfNotExists(Object obj, String entityName, String fieldName, Object fieldValue) { + String message = "%s 为 [%s] 的 %s 记录已不存在".formatted(fieldName, fieldValue, CharSequenceUtil + .replace(entityName, "DO", StringConstants.EMPTY)); + throwIfNull(obj, message, EXCEPTION_TYPE); + } + + /** + * 如果为空,抛出异常 + * + * @param obj 被检测的对象 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNull(Object obj, String template, Object... params) { + throwIfNull(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不为空,抛出异常 + * + * @param obj 被检测的对象 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotNull(Object obj, String template, Object... params) { + throwIfNotNull(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果存在,抛出异常 + * + * @param obj 被检测的对象 + * @param entityName 实体名 + * @param fieldName 字段名 + * @param fieldValue 字段值 + */ + public static void throwIfExists(Object obj, String entityName, String fieldName, Object fieldValue) { + String message = "%s 为 [%s] 的 %s 记录已存在".formatted(fieldName, fieldValue, entityName); + throwIfNotNull(obj, message, EXCEPTION_TYPE); + } + + /** + * 如果为空,抛出异常 + * + * @param obj 被检测的对象 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfEmpty(Object obj, String template, Object... params) { + throwIfEmpty(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不为空,抛出异常 + * + * @param obj 被检测的对象 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotEmpty(Object obj, String template, Object... params) { + throwIfNotEmpty(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果为空,抛出异常 + * + * @param str 被检测的字符串 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfBlank(CharSequence str, String template, Object... params) { + throwIfBlank(str, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不为空,抛出异常 + * + * @param str 被检测的字符串 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotBlank(CharSequence str, String template, Object... params) { + throwIfNotBlank(str, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果相同,抛出异常 + * + * @param obj1 要比较的对象1 + * @param obj2 要比较的对象2 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfEqual(Object obj1, Object obj2, String template, Object... params) { + throwIfEqual(obj1, obj2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不相同,抛出异常 + * + * @param obj1 要比较的对象1 + * @param obj2 要比较的对象2 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotEqual(Object obj1, Object obj2, String template, Object... params) { + throwIfNotEqual(obj1, obj2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果相同,抛出异常(不区分大小写) + * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfEqualIgnoreCase(CharSequence str1, CharSequence str2, String template, Object... params) { + throwIfEqualIgnoreCase(str1, str2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不相同,抛出异常(不区分大小写) + * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotEqualIgnoreCase(CharSequence str1, + CharSequence str2, + String template, + Object... params) { + throwIfNotEqualIgnoreCase(str1, str2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果条件成立,抛出异常 + * + * @param condition 条件 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIf(boolean condition, String template, Object... params) { + throwIf(condition, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果条件成立,抛出异常 + * + * @param conditionSupplier 条件 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIf(BooleanSupplier conditionSupplier, String template, Object... params) { + throwIf(conditionSupplier, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } +} diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/validation/ValidationUtils.java b/continew-starter-core/src/main/java/top/continew/starter/core/validation/ValidationUtils.java new file mode 100644 index 00000000..22c1f0d8 --- /dev/null +++ b/continew-starter-core/src/main/java/top/continew/starter/core/validation/ValidationUtils.java @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.starter.core.validation; + +import cn.hutool.core.text.CharSequenceUtil; +import top.continew.starter.core.exception.BadRequestException; + +import java.util.function.BooleanSupplier; + +/** + * 基本参数校验工具类(抛出 400 BadRequestException) + * + * @author Charles7c + * @see BadRequestException + * @since 1.0.0 + */ +public class ValidationUtils extends Validator { + + private static final Class EXCEPTION_TYPE = BadRequestException.class; + + private ValidationUtils() { + } + + /** + * 如果为空,抛出异常 + * + * @param obj 被检测的对象 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNull(Object obj, String template, Object... params) { + throwIfNull(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不为空,抛出异常 + * + * @param obj 被检测的对象 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotNull(Object obj, String template, Object... params) { + throwIfNotNull(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果为空,抛出异常 + * + * @param obj 被检测的对象 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfEmpty(Object obj, String template, Object... params) { + throwIfEmpty(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不为空,抛出异常 + * + * @param obj 被检测的对象 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotEmpty(Object obj, String template, Object... params) { + throwIfNotEmpty(obj, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果为空,抛出异常 + * + * @param str 被检测的字符串 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfBlank(CharSequence str, String template, Object... params) { + throwIfBlank(str, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不为空,抛出异常 + * + * @param str 被检测的字符串 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotBlank(CharSequence str, String template, Object... params) { + throwIfNotBlank(str, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果相同,抛出异常 + * + * @param obj1 要比较的对象1 + * @param obj2 要比较的对象2 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfEqual(Object obj1, Object obj2, String template, Object... params) { + throwIfEqual(obj1, obj2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不相同,抛出异常 + * + * @param obj1 要比较的对象1 + * @param obj2 要比较的对象2 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotEqual(Object obj1, Object obj2, String template, Object... params) { + throwIfNotEqual(obj1, obj2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果相同,抛出异常(不区分大小写) + * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfEqualIgnoreCase(CharSequence str1, CharSequence str2, String template, Object... params) { + throwIfEqualIgnoreCase(str1, str2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果不相同,抛出异常(不区分大小写) + * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIfNotEqualIgnoreCase(CharSequence str1, + CharSequence str2, + String template, + Object... params) { + throwIfNotEqualIgnoreCase(str1, str2, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果条件成立,抛出异常 + * + * @param condition 条件 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIf(boolean condition, String template, Object... params) { + throwIf(condition, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } + + /** + * 如果条件成立,抛出异常 + * + * @param conditionSupplier 条件 + * @param template 异常信息模板,被替换的部分用 {} 表示,如果模板为 null,返回 "null" + * @param params 参数值 + */ + public static void throwIf(BooleanSupplier conditionSupplier, String template, Object... params) { + throwIf(conditionSupplier, CharSequenceUtil.format(template, params), EXCEPTION_TYPE); + } +} diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/validation/Validator.java b/continew-starter-core/src/main/java/top/continew/starter/core/validation/Validator.java new file mode 100644 index 00000000..dba74a48 --- /dev/null +++ b/continew-starter-core/src/main/java/top/continew/starter/core/validation/Validator.java @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.starter.core.validation; + +import cn.hutool.core.text.CharSequenceUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.extra.spring.SpringUtil; +import jakarta.validation.ConstraintViolation; +import jakarta.validation.ConstraintViolationException; + +import java.util.Set; +import java.util.function.BooleanSupplier; + +/** + * 校验器 + * + * @author Charles7c + * @since 1.0.0 + */ +public class Validator { + + private static final jakarta.validation.Validator VALIDATOR = SpringUtil + .getBean(jakarta.validation.Validator.class); + + protected Validator() { + } + + /** + * 如果为空,抛出异常 + * + * @param obj 被检测的对象 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfNull(Object obj, String message, Class exceptionType) { + throwIf(null == obj, message, exceptionType); + } + + /** + * 如果不为空,抛出异常 + * + * @param obj 被检测的对象 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfNotNull(Object obj, String message, Class exceptionType) { + throwIf(null != obj, message, exceptionType); + } + + /** + * 如果为空,抛出异常 + * + * @param obj 被检测的对象 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfEmpty(Object obj, String message, Class exceptionType) { + throwIf(ObjectUtil.isEmpty(obj), message, exceptionType); + } + + /** + * 如果不为空,抛出异常 + * + * @param obj 被检测的对象 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfNotEmpty(Object obj, String message, Class exceptionType) { + throwIf(ObjectUtil.isNotEmpty(obj), message, exceptionType); + } + + /** + * 如果为空,抛出异常 + * + * @param str 被检测的字符串 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfBlank(CharSequence str, + String message, + Class exceptionType) { + throwIf(CharSequenceUtil.isBlank(str), message, exceptionType); + } + + /** + * 如果不为空,抛出异常 + * + * @param str 被检测的字符串 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfNotBlank(CharSequence str, + String message, + Class exceptionType) { + throwIf(CharSequenceUtil.isNotBlank(str), message, exceptionType); + } + + /** + * 如果相同,抛出异常 + * + * @param obj1 要比较的对象1 + * @param obj2 要比较的对象2 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfEqual(Object obj1, + Object obj2, + String message, + Class exceptionType) { + throwIf(ObjectUtil.equal(obj1, obj2), message, exceptionType); + } + + /** + * 如果不相同,抛出异常 + * + * @param obj1 要比较的对象1 + * @param obj2 要比较的对象2 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfNotEqual(Object obj1, + Object obj2, + String message, + Class exceptionType) { + throwIf(ObjectUtil.notEqual(obj1, obj2), message, exceptionType); + } + + /** + * 如果相同,抛出异常(不区分大小写) + * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfEqualIgnoreCase(CharSequence str1, + CharSequence str2, + String message, + Class exceptionType) { + throwIf(CharSequenceUtil.equalsIgnoreCase(str1, str2), message, exceptionType); + } + + /** + * 如果不相同,抛出异常(不区分大小写) + * + * @param str1 要比较的字符串1 + * @param str2 要比较的字符串2 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIfNotEqualIgnoreCase(CharSequence str1, + CharSequence str2, + String message, + Class exceptionType) { + throwIf(!CharSequenceUtil.equalsIgnoreCase(str1, str2), message, exceptionType); + } + + /** + * 如果条件成立,抛出异常 + * + * @param condition 条件 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIf(boolean condition, String message, Class exceptionType) { + if (condition) { + throw ReflectUtil.newInstance(exceptionType, message); + } + } + + /** + * 如果条件成立,抛出异常 + * + * @param conditionSupplier 条件 + * @param message 错误信息 + * @param exceptionType 异常类型 + */ + protected static void throwIf(BooleanSupplier conditionSupplier, + String message, + Class exceptionType) { + if (null != conditionSupplier && conditionSupplier.getAsBoolean()) { + throw ReflectUtil.newInstance(exceptionType, message); + } + } + + /** + * JSR 303 校验 + * + * @param obj 被校验对象 + * @param groups 分组 + * @since 2.3.0 + */ + public static void validate(Object obj, Class... groups) { + Set> violations = VALIDATOR.validate(obj, groups); + if (!violations.isEmpty()) { + throw new ConstraintViolationException(violations); + } + } +} diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/validation/constraints/EnumValue.java b/continew-starter-core/src/main/java/top/continew/starter/core/validation/constraints/EnumValue.java new file mode 100644 index 00000000..0fa2ae57 --- /dev/null +++ b/continew-starter-core/src/main/java/top/continew/starter/core/validation/constraints/EnumValue.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.starter.core.validation.constraints; + +import jakarta.validation.Constraint; +import jakarta.validation.Payload; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import static java.lang.annotation.ElementType.*; + +/** + * 枚举校验注解 + * + *

+ * {@code @EnumValue(value = XxxEnum.class, message = "参数值非法")}
+ * {@code @EnumValue(enumValues = {"F", "M"} ,message = "性别只允许为F或M")} + *

+ * + * @author Jasmine + * @author Charles7c + * @since 2.7.3 + */ +@Documented +@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE}) +@Retention(RetentionPolicy.RUNTIME) +@Constraint(validatedBy = EnumValueValidator.class) +public @interface EnumValue { + + /** + * 枚举类 + * + * @return 枚举类 + */ + Class value() default Enum.class; + + /** + * 枚举值 + * + * @return 枚举值 + */ + String[] enumValues() default {}; + + /** + * 获取枚举值的方法名 + * + * @return 获取枚举值的方法名 + */ + String method() default ""; + + /** + * 提示消息 + * + * @return 提示消息 + */ + String message() default "参数值非法"; + + /** + * 分组 + * + * @return 分组 + */ + Class[] groups() default {}; + + /** + * 负载 + * + * @return 负载 + */ + Class[] payload() default {}; +} diff --git a/continew-starter-core/src/main/java/top/continew/starter/core/validation/constraints/EnumValueValidator.java b/continew-starter-core/src/main/java/top/continew/starter/core/validation/constraints/EnumValueValidator.java new file mode 100644 index 00000000..86ba9896 --- /dev/null +++ b/continew-starter-core/src/main/java/top/continew/starter/core/validation/constraints/EnumValueValidator.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + *

+ * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.gnu.org/licenses/lgpl.html + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.continew.starter.core.validation.constraints; + +import cn.hutool.core.text.CharSequenceUtil; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.function.Function; + +/** + * 枚举校验注解校验器 + * + * @author Charles7c + * @author Jasmine + * @since 2.7.3 + */ +public class EnumValueValidator implements ConstraintValidator { + + private static final Logger log = LoggerFactory.getLogger(EnumValueValidator.class); + private Class enumClass; + private String[] enumValues; + private String enumMethod; + + @Override + public void initialize(EnumValue enumValue) { + this.enumClass = enumValue.value(); + this.enumValues = enumValue.enumValues(); + this.enumMethod = enumValue.method(); + } + + @Override + public boolean isValid(Object value, ConstraintValidatorContext context) { + if (value == null) { + return true; + } + // 优先校验 enumValues + if (enumValues.length > 0) { + return Arrays.asList(enumValues).contains(value.toString()); + } + Enum[] enumConstants = enumClass.getEnumConstants(); + if (enumConstants.length == 0) { + return false; + } + if (CharSequenceUtil.isBlank(enumMethod)) { + return findEnumValue(enumConstants, Enum::toString, value.toString()); + } + try { + // 枚举类指定了方法名,则调用指定方法获取枚举值 + Method method = enumClass.getMethod(enumMethod); + for (Enum enumConstant : enumConstants) { + if (method.invoke(enumConstant).equals(value)) { + return true; + } + } + } catch (Exception e) { + log.error("An error occurred while validating the enum value, please check the @EnumValue parameter configuration.", e); + } + return false; + } + + /** + * 遍历枚举类,判断是否包含指定值 + * + * @param enumConstants 枚举类数组 + * @param function 获取枚举值的函数 + * @param value 待校验的值 + * @return 是否包含指定值 + */ + private boolean findEnumValue(Enum[] enumConstants, Function function, Object value) { + for (Enum enumConstant : enumConstants) { + if (function.apply(enumConstant).equals(value)) { + return true; + } + } + return false; + } +} diff --git a/continew-starter-data/continew-starter-data-mf/src/main/java/top/continew/starter/data/mf/util/QueryWrapperHelper.java b/continew-starter-data/continew-starter-data-mf/src/main/java/top/continew/starter/data/mf/util/QueryWrapperHelper.java index 9232b2b2..8247171e 100644 --- a/continew-starter-data/continew-starter-data-mf/src/main/java/top/continew/starter/data/mf/util/QueryWrapperHelper.java +++ b/continew-starter-data/continew-starter-data-mf/src/main/java/top/continew/starter/data/mf/util/QueryWrapperHelper.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; import org.springframework.data.domain.Sort; import top.continew.starter.core.exception.BadRequestException; import top.continew.starter.core.util.ReflectUtils; -import top.continew.starter.core.util.validate.ValidationUtils; +import top.continew.starter.core.validation.ValidationUtils; import top.continew.starter.data.core.annotation.Query; import top.continew.starter.data.core.annotation.QueryIgnore; import top.continew.starter.data.core.enums.QueryType; diff --git a/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/service/impl/ServiceImpl.java b/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/service/impl/ServiceImpl.java index 8b93dfc9..5f30b138 100644 --- a/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/service/impl/ServiceImpl.java +++ b/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/service/impl/ServiceImpl.java @@ -18,7 +18,7 @@ package top.continew.starter.data.mp.service.impl; import cn.hutool.core.util.ClassUtil; import top.continew.starter.core.util.ReflectUtils; -import top.continew.starter.core.util.validate.CheckUtils; +import top.continew.starter.core.validation.CheckUtils; import top.continew.starter.data.mp.base.BaseMapper; import top.continew.starter.data.mp.service.IService; diff --git a/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/util/QueryWrapperHelper.java b/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/util/QueryWrapperHelper.java index 81734f96..75c6986a 100644 --- a/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/util/QueryWrapperHelper.java +++ b/continew-starter-data/continew-starter-data-mp/src/main/java/top/continew/starter/data/mp/util/QueryWrapperHelper.java @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; import org.springframework.data.domain.Sort; import top.continew.starter.core.exception.BadRequestException; import top.continew.starter.core.util.ReflectUtils; -import top.continew.starter.core.util.validate.ValidationUtils; +import top.continew.starter.core.validation.ValidationUtils; import top.continew.starter.data.core.annotation.Query; import top.continew.starter.data.core.annotation.QueryIgnore; import top.continew.starter.data.core.enums.QueryType;