/* * Hibernate Validator, declare and validate application constraints * * License: Apache License, Version 2.0 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>. */ package org.hibernate.validator.testutils; import static org.hibernate.validator.internal.util.Contracts.assertNotNull; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.Locale; import javax.validation.Configuration; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.metadata.BeanDescriptor; import javax.validation.metadata.ConstructorDescriptor; import javax.validation.metadata.MethodDescriptor; import javax.validation.metadata.ParameterDescriptor; import javax.validation.metadata.PropertyDescriptor; import javax.validation.metadata.ReturnValueDescriptor; import javax.validation.spi.ValidationProvider; import org.hibernate.validator.HibernateValidator; import org.hibernate.validator.HibernateValidatorConfiguration; import org.hibernate.validator.constraintvalidation.HibernateConstraintValidatorContext; import org.hibernate.validator.internal.engine.DefaultClockProvider; import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl; import org.hibernate.validator.testutil.DummyTraversableResolver; import org.hibernate.validator.testutil.ValidationInvocationHandler; /** * A helper providing useful functions for setting up validators. * * @author Hardy Ferentschik * @author Gunnar Morling * @author Kevin Pollet <kevin.pollet@serli.com> (C) 2011 SERLI */ public final class ValidatorUtil { /** * Private constructor in order to avoid instantiation. */ private ValidatorUtil() { } /** * Returns a configured instance of {@code Validator}. This validator is configured to use a * {@link DummyTraversableResolver}. This method also sets the default locale to english. * * @return an instance of {@code Validator}. */ public static Validator getValidator() { final Configuration<HibernateValidatorConfiguration> configuration = getConfiguration(); configuration.traversableResolver( new DummyTraversableResolver() ); return configuration.buildValidatorFactory().getValidator(); } /** * Returns the {@code Configuration} object for Hibernate Validator. This method also sets the default locale to * english. * * @return an instance of {@code Configuration} for Hibernate Validator. */ public static HibernateValidatorConfiguration getConfiguration() { return getConfiguration( HibernateValidator.class, Locale.ENGLISH ); } /** * Returns the {@code Configuration} object for Hibernate Validator. This method also sets the default locale to * the given locale. * * @param locale The default locale to set. * * @return an instance of {@code Configuration} for Hibernate Validator. */ public static HibernateValidatorConfiguration getConfiguration(Locale locale) { return getConfiguration( HibernateValidator.class, locale ); } /** * Returns the {@code Configuration} object for the given validation provider type. This method also sets the * default locale to english. * * @param type The validation provider type. * * @return an instance of {@code Configuration}. */ public static <T extends Configuration<T>, U extends ValidationProvider<T>> T getConfiguration(Class<U> type) { return getConfiguration( type, Locale.ENGLISH ); } /** * Returns the {@code Configuration} object for the given validation provider type. This method also sets the * default locale to the given locale. * * @param type The validation provider type. * @param locale The default locale to set. * * @return an instance of {@code Configuration}. */ public static <T extends Configuration<T>, U extends ValidationProvider<T>> T getConfiguration(Class<U> type, Locale locale) { Locale.setDefault( locale ); return Validation.byProvider( type ).configure(); } /** * Returns the {@code PropertyDescriptor} corresponding to the property contained in the given class. * * @param clazz The class containing the given property. * @param property The property name. * * @return an instance of {@code PropertyDescriptor} or {@code null} if does not exists or has no constraint. * * @see javax.validation.metadata.BeanDescriptor#getConstraintsForProperty(String) */ public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String property) { return getValidator().getConstraintsForClass( clazz ).getConstraintsForProperty( property ); } /** * Returns the {@code BeanDescriptor} corresponding to the given type. * * @param clazz The type. * * @return an instance of {@code BeanDescriptor} for the given type, never {@code null} */ public static BeanDescriptor getBeanDescriptor(Class<?> clazz) { return getValidator().getConstraintsForClass( clazz ); } /** * Returns the {@code MethodDescriptor} for the given method signature in the given class. * * @param clazz The class. * @param methodName The method name. * @param parameterTypes The method parameter types. * * @return an instance of {@code MethodDescriptor} for the given method signature or {@code null} if no such method exists. */ public static MethodDescriptor getMethodDescriptor(Class<?> clazz, String methodName, Class<?>... parameterTypes) { return getBeanDescriptor( clazz ).getConstraintsForMethod( methodName, parameterTypes ); } /** * Returns the {@code ConstructorDescriptor} for the given constructor signature in the given class. * * @param clazz The class. * @param parameterTypes The constructor parameter types. * * @return an instance of {@code ConstructorDescriptor} for the given constructor signature or {@code null} if no such constructor exists. */ public static ConstructorDescriptor getConstructorDescriptor(Class<?> clazz, Class<?>... parameterTypes) { return getBeanDescriptor( clazz ).getConstraintsForConstructor( parameterTypes ); } /** * Returns the {@code ParameterDescriptor} for the parameter at the given index within the method, corresponding to * the given signature, within the given class. * * @param clazz The class. * @param methodName The method name. * @param parameterTypes The method parameter types. * @param parameterIndex The parameter index. * * @return an instance of {@code ParameterDescriptor}. */ public static ParameterDescriptor getParameterDescriptor(Class<?> clazz, String methodName, Class<?>[] parameterTypes, int parameterIndex) { final MethodDescriptor methodDescriptor = getMethodDescriptor( clazz, methodName, parameterTypes ); assertNotNull( methodDescriptor, "No method with the given signature is declared in " + clazz + " or its super class" ); return methodDescriptor.getParameterDescriptors().get( parameterIndex ); } /** * Returns the {@code ReturnValueDescriptor} for the given method signature in the given class. * * @param clazz The class. * @param methodName The method name. * @param parameterTypes The method parameter types. * * @return an instance of {@code ReturnValueDescriptor} for the given method signature or {@code null} if no such method exists. */ public static ReturnValueDescriptor getMethodReturnValueDescriptor(Class<?> clazz, String methodName, Class<?>... parameterTypes) { MethodDescriptor methodDescriptor = getBeanDescriptor( clazz ).getConstraintsForMethod( methodName, parameterTypes ); return methodDescriptor != null ? methodDescriptor.getReturnValueDescriptor() : null; } @SuppressWarnings("unchecked") public static <T, I extends T> T getValidatingProxy(I implementor, Class<?>[] interfaces, Validator executableValidator, Class<?>... validationGroups) { InvocationHandler handler = new ValidationInvocationHandler( implementor, executableValidator, validationGroups ); return (T) Proxy.newProxyInstance( implementor.getClass().getClassLoader(), interfaces, handler ); } /** * Creates a proxy for the given object which performs a validation of the given object's method constraints upon method invocation. * * @param <T> The type to which the proxy shall be casted. Must be an interface. * @param <I> The type of the object to be proxied. * @param implementor The object to be proxied. * @param executableValidator The validator to use for method validation. * @param validationGroups Optionally the groups which shall be evaluated. * * @return A proxy performing an automatic method validation. */ public static <T, I extends T> T getValidatingProxy(I implementor, Validator executableValidator, Class<?>... validationGroups) { return getValidatingProxy( implementor, implementor.getClass().getInterfaces(), executableValidator, validationGroups ); } public static HibernateConstraintValidatorContext getConstraintValidatorContext() { return new ConstraintValidatorContextImpl( null, DefaultClockProvider.INSTANCE, null, null ); } }