Skip to content

Commit

Permalink
HV-776 Throwing an exception in case @ValidateOnExecution is used on …
Browse files Browse the repository at this point in the history
…overridden method
  • Loading branch information
hferentschik committed Mar 19, 2013
1 parent 2b831c9 commit aa77c4a
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 10 deletions.
Expand Up @@ -380,13 +380,16 @@ private EnumSet<ExecutableType> commonExecutableTypeChecks(ValidateOnExecution v
return executableTypes;
}

public Method replaceWithOverriddenOrInterfaceMethod(Method method, List<Method> interfaceMethods) {
LinkedList<Method> list = new LinkedList<Method>( interfaceMethods );
public Method replaceWithOverriddenOrInterfaceMethod(Method method, List<Method> allMethodsOfType) {
LinkedList<Method> list = new LinkedList<Method>( allMethodsOfType );
Iterator<Method> iterator = list.descendingIterator();
while ( iterator.hasNext() ) {
Method interfaceMethod = iterator.next();
if ( ReflectionHelper.overrides( method, interfaceMethod ) ) {
return interfaceMethod;
Method overriddenOrInterfaceMethod = iterator.next();
if ( ReflectionHelper.overrides( method, overriddenOrInterfaceMethod ) ) {
if ( method.getAnnotation( ValidateOnExecution.class ) != null ) {
throw log.getValidateOnExecutionOnOverriddenOrInterfaceMethodException( method );
}
return overriddenOrInterfaceMethod;
}
}

Expand Down
Expand Up @@ -822,6 +822,10 @@ public static boolean overrides(Method subTypeMethod, Method superTypeMethod) {
Contracts.assertValueNotNull( subTypeMethod, "subTypeMethod" );
Contracts.assertValueNotNull( superTypeMethod, "superTypeMethod" );

if ( subTypeMethod.equals( superTypeMethod) ) {
return false;
}

if ( !subTypeMethod.getName().equals( superTypeMethod.getName() ) ) {
return false;
}
Expand Down
Expand Up @@ -20,6 +20,7 @@
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.IllegalFormatException;
Expand Down Expand Up @@ -595,4 +596,8 @@ public interface Log extends BasicLogger {

@Message(id = 165, value = "Mixing IMPLICIT and other executable types is not allowed.")
IllegalArgumentException getMixingImplicitWithOtherExecutableTypesException();

@Message(id = 166,
value = "@ValidateOnExecution is not allowed on methods overriding a superclass method or implementing an interface. Check configuration for %1$s")
ValidationException getValidateOnExecutionOnOverriddenOrInterfaceMethodException(Method m);
}
Expand Up @@ -23,7 +23,7 @@
/**
* @author Hardy Ferentschik
*/
public class SecretService extends SecretServiceBase {
public class CIA extends SecretServiceBase {

// The @ValidateOnExecution annotations here are expected to be ignored
// since the methods override super-type methods
Expand Down
@@ -0,0 +1,88 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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
* http://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.hibernate.validator.integration.cdi.methodvalidation.inheritance;

import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.inject.Inject;
import javax.validation.ValidationException;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.hibernate.validator.internal.cdi.ValidationExtension;

import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

/**
* @author Hardy Ferentschik
*/
@RunWith(Arquillian.class)
public class InvalidConfiguredClassInheritanceMethodValidationTest {

@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create( JavaArchive.class )
.addClass( CIA.class )
.addClass( SecretServiceBase.class );
}

@Inject
BeanManager beanManager;

@Test
public void testInvalidConfigurationThrowsException() {
ValidationExtension extension = beanManager.getExtension( ValidationExtension.class );
AnnotatedType<CIA> annotatedType = beanManager.createAnnotatedType( CIA.class );
try {
extension.processAnnotatedType( new ProcessAnnotatedTypeImpl<CIA>( annotatedType ) );
fail( "ValidationExtension should throw an exception, because the validated method overrides another " +
"method and adds @ValidateOnExecution " );
}
catch ( ValidationException e ) {
assertTrue( e.getMessage().startsWith( "HV000166" ) );
}
}

public static class ProcessAnnotatedTypeImpl<T> implements ProcessAnnotatedType<T> {
private AnnotatedType<T> annotatedType;

public ProcessAnnotatedTypeImpl(AnnotatedType<T> annotatedType) {
this.annotatedType = annotatedType;
}

@Override
public AnnotatedType<T> getAnnotatedType() {
return annotatedType;
}

@Override
public void setAnnotatedType(AnnotatedType<T> type) {
this.annotatedType = type;
}

@Override
public void veto() {
}
}
}
@@ -0,0 +1,28 @@
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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
* http://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.hibernate.validator.integration.cdi.methodvalidation.inheritance;

import javax.validation.constraints.NotNull;

/**
* @author Hardy Ferentschik
*/
public class MI6 extends SecretServiceBase {
@Override
public void whisper(@NotNull String secret) {
}
}
Expand Up @@ -35,23 +35,23 @@
* @author Hardy Ferentschik
*/
@RunWith(Arquillian.class)
public class ClassInheritanceMethodValidationTest {
public class SuccessfulClassInheritanceMethodValidationTest {

@Deployment
public static JavaArchive createDeployment() {
return ShrinkWrap.create( JavaArchive.class )
.addClass( SecretService.class )
.addClass( MI6.class )
.addClass( SecretServiceBase.class )
.addAsManifestResource( EmptyAsset.INSTANCE, "beans.xml" );
}

@Inject
SecretService secretService;
MI6 mi6;

@Test
public void testOverriddenExecutionTypeIsConsidered() {
try {
secretService.whisper( null );
mi6.whisper( null );
fail( "Method invocation should have caused a ConstraintViolationException" );
}
catch ( ConstraintViolationException e ) {
Expand Down

0 comments on commit aa77c4a

Please sign in to comment.