From 0fef3802024d158e47ddc8db45d061a86e2f51ad Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Wed, 7 Jun 2023 14:09:17 +0100 Subject: [PATCH] Add MethodValidator See gh-29825 --- .../DefaultMethodValidator.java | 77 +++++++++++++++++++ .../beanvalidation/MethodValidator.java | 71 +++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 spring-context/src/main/java/org/springframework/validation/beanvalidation/DefaultMethodValidator.java create mode 100644 spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidator.java diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/DefaultMethodValidator.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/DefaultMethodValidator.java new file mode 100644 index 00000000000..6b69851b8a9 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/DefaultMethodValidator.java @@ -0,0 +1,77 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * 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. + */ + +package org.springframework.validation.beanvalidation; + +import java.lang.reflect.Method; + +import org.springframework.lang.Nullable; + +/** + * Default implementation of {@link MethodValidator} that delegates to a + * {@link MethodValidationAdapter}. Also, convenient as a base class that allows + * handling of the validation result. + * + * @author Rossen Stoyanchev + * @since 6.1 + */ +public class DefaultMethodValidator implements MethodValidator { + + private final MethodValidationAdapter adapter; + + + public DefaultMethodValidator(MethodValidationAdapter adapter) { + this.adapter = adapter; + } + + + @Override + public Class[] determineValidationGroups(Object bean, Method method) { + return MethodValidationAdapter.determineValidationGroups(bean, method); + } + + @Override + public void validateArguments(Object target, Method method, Object[] arguments, Class[] groups) { + MethodValidationResult result = this.adapter.validateMethodArguments(target, method, arguments, groups); + handleArgumentsResult(target, method, arguments, groups, result); + } + + /** + * Subclasses can override this to handle the result of argument validation. + * By default, {@link MethodValidationResult#throwIfViolationsPresent()} is called. + */ + protected void handleArgumentsResult( + Object bean, Method method, Object[] arguments, Class[] groups, MethodValidationResult result) { + + result.throwIfViolationsPresent(); + } + + public void validateReturnValue(Object target, Method method, @Nullable Object returnValue, Class[] groups) { + MethodValidationResult result = this.adapter.validateMethodReturnValue(target, method, returnValue, groups); + handleReturnValueResult(target, method, returnValue, groups, result); + } + + /** + * Subclasses can override this to handle the result of return value validation. + * By default, {@link MethodValidationResult#throwIfViolationsPresent()} is called. + */ + protected void handleReturnValueResult( + Object bean, Method method, @Nullable Object returnValue, Class[] groups, MethodValidationResult result) { + + result.throwIfViolationsPresent(); + } + +} diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidator.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidator.java new file mode 100644 index 00000000000..3109aad4944 --- /dev/null +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidator.java @@ -0,0 +1,71 @@ +/* + * Copyright 2002-2023 the original author or authors. + * + * 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. + */ + +package org.springframework.validation.beanvalidation; + +import java.lang.reflect.Method; + +import org.springframework.lang.Nullable; + +/** + * Contract to apply method validation without directly using + * {@link MethodValidationAdapter}. For use in components where Jakarta Bean + * Validation is an optional dependency and may or may not be present on the + * classpath. If that's not a concern, use {@code MethodValidationAdapter} + * directly. + * + * @author Rossen Stoyanchev + * @since 6.1 + * @see DefaultMethodValidator + */ +public interface MethodValidator { + + /** + * Use this method determine the validation groups to pass into + * {@link #validateArguments(Object, Method, Object[], Class[])} and + * {@link #validateReturnValue(Object, Method, Object, Class[])}. + * @param target the target Object + * @param method the target method + * @return the applicable validation groups as a {@code Class} array + * @see MethodValidationAdapter#determineValidationGroups(Object, Method) + */ + Class[] determineValidationGroups(Object target, Method method); + + /** + * Validate the given method arguments and return the result of validation. + * @param target the target Object + * @param method the target method + * @param arguments candidate arguments for a method invocation + * @param groups groups for validation determined via + * {@link #determineValidationGroups(Object, Method)} + * @throws MethodValidationException should be raised in case of validation + * errors unless the implementation handles those errors otherwise (e.g. + * by injecting {@code BindingResult} into the method). + */ + void validateArguments(Object target, Method method, Object[] arguments, Class[] groups); + + /** + * Validate the given return value and return the result of validation. + * @param target the target Object + * @param method the target method + * @param returnValue value returned from invoking the target method + * @param groups groups for validation determined via + * {@link #determineValidationGroups(Object, Method)} + * @throws MethodValidationException in case of validation errors + */ + void validateReturnValue(Object target, Method method, @Nullable Object returnValue, Class[] groups); + +}