diff --git a/plusone-validator/pom.xml b/plusone-validator/pom.xml index 0f999a6..41a865f 100644 --- a/plusone-validator/pom.xml +++ b/plusone-validator/pom.xml @@ -44,6 +44,11 @@ xyz.zhouxy.plusone plusone-commons + + org.jspecify + jspecify + 1.0.0 + org.junit.jupiter junit-jupiter diff --git a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/BasePropertyValidator.java b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/BasePropertyValidator.java index 15ad45c..e6860e8 100644 --- a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/BasePropertyValidator.java +++ b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/BasePropertyValidator.java @@ -24,6 +24,8 @@ import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; +import org.jspecify.annotations.Nullable; + /** * 属性校验器。包含针对属性的校验规则。 * @@ -135,9 +137,9 @@ public abstract class BasePropertyValidator< /** * 校验属性 * - * @param obj 属性所在的对象 + * @param obj 属性所在的对象,允许为 {@code null} */ - public final void validate(T obj) { + public final void validate(@Nullable T obj) { for (Consumer consumer : consumers) { consumer.accept(getter.apply(obj)); } diff --git a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java index 13887ee..9917a5c 100644 --- a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java +++ b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/BaseValidator.java @@ -28,6 +28,8 @@ import java.util.function.Supplier; import xyz.zhouxy.plusone.validator.function.*; +import org.jspecify.annotations.Nullable; + /** * 校验器基类 *

@@ -311,7 +313,7 @@ public abstract class BaseValidator implements IValidator { /** {@inheritDoc} */ @Override - public void validate(T obj) { + public void validate(@Nullable T obj) { this.rules.forEach(rule -> rule.accept(obj)); } } diff --git a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/IValidator.java b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/IValidator.java index 5de6d64..7f22c3a 100644 --- a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/IValidator.java +++ b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/IValidator.java @@ -15,6 +15,8 @@ */ package xyz.zhouxy.plusone.validator; +import org.jspecify.annotations.Nullable; + /** * 校验器 * @@ -30,7 +32,7 @@ public interface IValidator { /** * 校验指定对象是否符合预定义规则 * - * @param obj 待校验的对象实例 + * @param obj 待校验的对象实例,允许为 {@code null} */ - void validate(T obj); + void validate(@Nullable T obj); } diff --git a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/MapValidator.java b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/MapValidator.java index 50a22d6..ebd5d8c 100644 --- a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/MapValidator.java +++ b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/MapValidator.java @@ -23,6 +23,8 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; +import org.jspecify.annotations.Nullable; + /** * 对 Map 进行校验的校验器 * @@ -59,10 +61,10 @@ public abstract class MapValidator extends BaseValidator> { /** * 校验并拷贝,仅保留指定 key 的属性。 * - * @param obj 待校验的 map + * @param obj 待校验的 map,允许为 {@code null} * @return 拷贝后的 map */ - public final Map validateAndCopy(Map obj) { + public final Map validateAndCopy(@Nullable Map obj) { return validateAndCopyInternal(obj, this.keys); } @@ -89,7 +91,7 @@ public abstract class MapValidator extends BaseValidator> { return validateAndCopyInternal(obj, Arrays.asList(keys)); } - private final Map validateAndCopyInternal(Map obj, Collection keys) { + private final Map validateAndCopyInternal(@Nullable Map obj, Collection keys) { validate(obj); return obj.entrySet().stream() .filter(kv -> keys.contains(kv.getKey())) diff --git a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/StringPropertyValidator.java b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/StringPropertyValidator.java index e974d61..7cede95 100644 --- a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/StringPropertyValidator.java +++ b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/StringPropertyValidator.java @@ -547,7 +547,7 @@ public class StringPropertyValidator private static Predicate length(int length) { AssertTools.checkArgument(length >= 0, - "The expected length must be non-negative."); + "The expected length must be non-negative."); return input -> input == null || input.length() == length; } diff --git a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/ValidationException.java b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/ValidationException.java index 29bb1ae..d6ba219 100644 --- a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/ValidationException.java +++ b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/ValidationException.java @@ -15,6 +15,8 @@ */ package xyz.zhouxy.plusone.validator; +import org.jspecify.annotations.Nullable; + /** * 校验失败异常 * @@ -30,11 +32,11 @@ public class ValidationException extends RuntimeException { super(message); } - private ValidationException(Throwable cause) { + private ValidationException(@Nullable Throwable cause) { super(cause); } - private ValidationException(String message, Throwable cause) { + private ValidationException(String message, @Nullable Throwable cause) { super(message, cause); } @@ -71,10 +73,10 @@ public class ValidationException extends RuntimeException { /** * 创建 {@code ValidationException} 实例 * - * @param cause 导致校验失败的根本异常 + * @param cause 导致校验失败的根本异常,允许为 {@code null} * @return {@code ValidationException} 实例 */ - public static ValidationException withCause(Throwable cause) { + public static ValidationException withCause(@Nullable Throwable cause) { return new ValidationException(cause); } @@ -82,10 +84,10 @@ public class ValidationException extends RuntimeException { * 创建 {@code ValidationException} 实例 * * @param message 异常信息 - * @param cause 导致校验失败的根本异常 + * @param cause 导致校验失败的根本异常,允许为 {@code null} * @return {@code ValidationException} 实例 */ - public static ValidationException withMessageAndCause(String message, Throwable cause) { + public static ValidationException withMessageAndCause(String message, @Nullable Throwable cause) { return new ValidationException(message, cause); } } diff --git a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/function/package-info.java b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/function/package-info.java new file mode 100644 index 0000000..dff0381 --- /dev/null +++ b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/function/package-info.java @@ -0,0 +1,37 @@ +/* + * Copyright 2025-present ZhouXY + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/** + * 函数式接口包,提供带序列化能力的特殊 {@code Function} 子类型。 + * + *

+ * 本包中的接口均继承自 {@link java.util.function.Function},同时实现 + * {@link java.io.Serializable},使 lambda 表达式或方法引用可以被序列化。 + * 主要用作 {@link xyz.zhouxy.plusone.validator.BaseValidator} 中 + * {@code ruleFor} 方法族的参数类型,以支持特定类型的属性取值。 + * + *

+ */ +@NullMarked +package xyz.zhouxy.plusone.validator.function; + +import org.jspecify.annotations.NullMarked; diff --git a/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/package-info.java b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/package-info.java new file mode 100644 index 0000000..92c0404 --- /dev/null +++ b/plusone-validator/src/main/java/xyz/zhouxy/plusone/validator/package-info.java @@ -0,0 +1,52 @@ +/* + * Copyright 2025-present ZhouXY + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + */ + +/** + * Plusone Validator 核心包,提供流式校验 API。 + * + *

+ * 使用 lambda 表达式(包括方法引用)和流式 API 构建校验规则,对对象进行校验。 + * 支持校验普通对象(POJO)和 {@code Map} 对象。 + * + *

快速开始

+ *
{@code
+ * public class PersonValidator extends BaseValidator {
+ *     public PersonValidator() {
+ *         ruleFor(Person::getName)
+ *             .notNull()
+ *             .notBlank();
+ *         ruleForInt(Person::getAge)
+ *             .gt(0);
+ *     }
+ * }
+ * }
+ * + *

核心概念

+ * + * + * @see xyz.zhouxy.plusone.validator.BaseValidator + * @see xyz.zhouxy.plusone.validator.MapValidator + */ +@NullMarked +package xyz.zhouxy.plusone.validator; + +import org.jspecify.annotations.NullMarked;