Skip to content

Commit

Permalink
HV-1363 Updated ValidationExtension to use new property filtering
Browse files Browse the repository at this point in the history
- introduced new helper in cdi module to deal with new PropertyFilter
spi.
  • Loading branch information
marko-bekhta committed May 4, 2018
1 parent 9a70c78 commit d5fe970
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
import org.hibernate.validator.cdi.internal.ValidatorFactoryBean;
import org.hibernate.validator.cdi.internal.interceptor.ValidationEnabledAnnotatedType;
import org.hibernate.validator.cdi.internal.interceptor.ValidationInterceptor;
import org.hibernate.validator.cdi.internal.util.GetterPropertyMatcherHelper;
import org.hibernate.validator.internal.util.Contracts;
import org.hibernate.validator.internal.util.ExecutableHelper;
import org.hibernate.validator.internal.util.ReflectionHelper;
import org.hibernate.validator.internal.util.TypeResolutionHelper;
import org.hibernate.validator.internal.util.logging.Log;
import org.hibernate.validator.internal.util.logging.LoggerFactory;
Expand Down Expand Up @@ -99,6 +99,7 @@ public class ValidationExtension implements Extension {
*/
private final Validator validator;
private final ValidatorFactory validatorFactory;
private final GetterPropertyMatcherHelper getterPropertyMatcherHelper;
private final Set<ExecutableType> globalExecutableTypes;
private final boolean isExecutableValidationEnabled;

Expand All @@ -119,6 +120,7 @@ public ValidationExtension() {
isExecutableValidationEnabled = bootstrap.isExecutableValidationEnabled();
validatorFactory = config.buildValidatorFactory();
validator = validatorFactory.getValidator();
getterPropertyMatcherHelper = GetterPropertyMatcherHelper.forValidationFactory( validatorFactory );

executableHelper = new ExecutableHelper( new TypeResolutionHelper() );
}
Expand Down Expand Up @@ -263,8 +265,7 @@ private <T> void determineConstrainedMethods(AnnotatedType<T> type, BeanDescript
for ( AnnotatedMethod<? super T> annotatedMethod : type.getMethods() ) {
Method method = annotatedMethod.getJavaMember();

//TODO: need to update the getter logic here:
boolean isGetter = false/*ReflectionHelper.isGetterMethod( method )*/;
boolean isGetter = getterPropertyMatcherHelper.isProperty( method );

// obtain @ValidateOnExecution from the top-most method in the hierarchy
Method methodForExecutableTypeRetrieval = replaceWithOverriddenOrInterfaceMethod( method, overriddenAndImplementedMethods );
Expand Down Expand Up @@ -317,7 +318,7 @@ private boolean isNonGetterConstrained(Method method, BeanDescriptor beanDescrip
}

private boolean isGetterConstrained(Method method, BeanDescriptor beanDescriptor) {
String propertyName = ReflectionHelper.getPropertyName( method );
String propertyName = getterPropertyMatcherHelper.getPropertyName( method );
PropertyDescriptor propertyDescriptor = beanDescriptor.getConstraintsForProperty( propertyName );
return propertyDescriptor != null && propertyDescriptor.findConstraints()
.declaredOn( ElementType.METHOD )
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* 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.cdi.internal.util;

import java.lang.reflect.Method;
import java.lang.reflect.Type;

import javax.validation.ValidatorFactory;

import org.hibernate.validator.HibernateValidatorFactory;
import org.hibernate.validator.internal.properties.DefaultGetterPropertyMatcher;
import org.hibernate.validator.spi.properties.ConstrainableExecutable;
import org.hibernate.validator.spi.properties.GetterPropertyMatcher;

/**
* A wrapper around {@link GetterPropertyMatcher}.
*
* @author Marko Bekhta
*/
public class GetterPropertyMatcherHelper {

private final GetterPropertyMatcher getterPropertyMatcher;

private GetterPropertyMatcherHelper(GetterPropertyMatcher getterPropertyMatcher) {
this.getterPropertyMatcher = getterPropertyMatcher;
}

public boolean isProperty(Method method) {
return getterPropertyMatcher.isProperty( new ConstrainableMethod( method ) );
}

public String getPropertyName(Method method) {
return getterPropertyMatcher.getPropertyName( new ConstrainableMethod( method ) );
}

public static GetterPropertyMatcherHelper forValidationFactory(ValidatorFactory factory) {
GetterPropertyMatcher getterPropertyMatcher;
if ( factory instanceof HibernateValidatorFactory ) {
getterPropertyMatcher = factory.unwrap( HibernateValidatorFactory.class ).getGetterPropertyMatcher();
}
else {
getterPropertyMatcher = new DefaultGetterPropertyMatcher();
}
return new GetterPropertyMatcherHelper( getterPropertyMatcher );
}

private static class ConstrainableMethod implements ConstrainableExecutable {

private final Method method;

private ConstrainableMethod(Method method) {
this.method = method;
}

@Override public Class<?> getReturnType() {
return method.getReturnType();
}

@Override public String getName() {
return method.getName();
}

@Override public Type[] getParameterTypes() {
return method.getParameterTypes();
}

public Method getMethod() {
return method;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class DefaultGetterPropertyMatcher implements GetterPropertyMatcher {
private static final String PROPERTY_ACCESSOR_PREFIX_GET = "get";
private static final String PROPERTY_ACCESSOR_PREFIX_IS = "is";
private static final String PROPERTY_ACCESSOR_PREFIX_HAS = "has";
public static final String[] PROPERTY_ACCESSOR_PREFIXES = {
private static final String[] PROPERTY_ACCESSOR_PREFIXES = {
PROPERTY_ACCESSOR_PREFIX_GET,
PROPERTY_ACCESSOR_PREFIX_IS,
PROPERTY_ACCESSOR_PREFIX_HAS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/
package org.hibernate.validator.internal.util;

import static org.hibernate.validator.internal.properties.DefaultGetterPropertyMatcher.PROPERTY_ACCESSOR_PREFIXES;
import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap;

import java.lang.invoke.MethodHandles;
Expand Down Expand Up @@ -83,47 +82,6 @@ public final class ReflectionHelper {
private ReflectionHelper() {
}

/**
* Returns the JavaBeans property name of the given member.
* <p>
* For fields, the field name will be returned. For getter methods, the
* decapitalized property name will be returned, with the "get", "is" or "has"
* prefix stripped off. Getter methods are methods
* </p>
* <ul>
* <li>whose name start with "get" and who have a return type but no parameter
* or</li>
* <li>whose name starts with "is" and who have no parameter and return
* {@code boolean} or</li>
* <li>whose name starts with "has" and who have no parameter and return
* {@code boolean} (HV-specific, not mandated by JavaBeans spec).</li>
* </ul>
*
* @param member The member for which to get the property name.
*
* @return The property name for the given member or {@code null} if the
* member is neither a field nor a getter method according to the
* JavaBeans standard.
*/
@Deprecated
public static String getPropertyName(Member member) {
String name = null;

if ( member instanceof Field ) {
name = member.getName();
}

if ( member instanceof Method ) {
String methodName = member.getName();
for ( String prefix : PROPERTY_ACCESSOR_PREFIXES ) {
if ( methodName.startsWith( prefix ) ) {
name = StringHelper.decapitalize( methodName.substring( prefix.length() ) );
}
}
}
return name;
}

/**
* @param member The {@code Member} instance for which to retrieve the type.
*
Expand Down

0 comments on commit d5fe970

Please sign in to comment.