Skip to content

Commit

Permalink
Hibernate Validator - Fix container element constraints detection
Browse files Browse the repository at this point in the history
Fixes #17452
  • Loading branch information
gsmet committed May 25, 2021
1 parent c803ff4 commit 1a22331
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,28 @@ public void build(HibernateValidatorRecorder recorder, RecorderContext recorderC
} else if (annotation.target().kind() == AnnotationTarget.Kind.CLASS) {
contributeClass(classNamesToBeValidated, indexView, annotation.target().asClass().name());
// no need for reflection in the case of a class level constraint
} else if (annotation.target().kind() == AnnotationTarget.Kind.TYPE) {
// container element constraints
AnnotationTarget enclosingTarget = annotation.target().asType().enclosingTarget();
if (enclosingTarget.kind() == AnnotationTarget.Kind.FIELD) {
contributeClass(classNamesToBeValidated, indexView, enclosingTarget.asField().declaringClass().name());
reflectiveFields.produce(new ReflectiveFieldBuildItem(enclosingTarget.asField()));
if (annotation.target().asType().target() != null) {
contributeClassMarkedForCascadingValidation(classNamesToBeValidated, indexView,
consideredAnnotation,
annotation.target().asType().target());
}
} else if (enclosingTarget.kind() == AnnotationTarget.Kind.METHOD) {
contributeClass(classNamesToBeValidated, indexView, enclosingTarget.asMethod().declaringClass().name());
reflectiveMethods.produce(new ReflectiveMethodBuildItem(enclosingTarget.asMethod()));
if (annotation.target().asType().target() != null) {
contributeClassMarkedForCascadingValidation(classNamesToBeValidated, indexView,
consideredAnnotation,
annotation.target().asType().target());
}
contributeMethodsWithInheritedValidation(methodsWithInheritedValidation, indexView,
enclosingTarget.asMethod());
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package io.quarkus.hibernate.validator.test;

import static org.assertj.core.api.Assertions.assertThat;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotBlank;

import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;

public class ContainerElementConstraintsTest {

@Inject
ValidatorFactory validatorFactory;

@RegisterExtension
static final QuarkusUnitTest test = new QuarkusUnitTest().setArchiveProducer(() -> ShrinkWrap
.create(JavaArchive.class).addClasses(TestBean.class));

@Test
public void testContainerElementConstraint() {
assertThat(validatorFactory.getValidator().validate(new TestBean())).hasSize(1);
}

@Test
public void testNestedContainerElementConstraint() {
assertThat(validatorFactory.getValidator().validate(new NestedTestBean())).hasSize(1);
}

@Test
public void testMethodParameterContainerElementConstraint() throws NoSuchMethodException, SecurityException {
Map<String, List<String>> invalidMap = new HashMap<>();
invalidMap.put("key", Collections.singletonList(""));

assertThat(validatorFactory.getValidator().forExecutables().validateParameters(new MethodParameterTestBean(),
MethodParameterTestBean.class.getMethod("test", Map.class), new Object[] { invalidMap })).hasSize(1);
}

@Test
public void testMethodReturnValueContainerElementConstraint() throws NoSuchMethodException, SecurityException {
Map<String, List<String>> invalidMap = new HashMap<>();
invalidMap.put("key", Collections.singletonList(""));

assertThat(validatorFactory.getValidator().forExecutables().validateReturnValue(new MethodReturnValueTestBean(),
MethodReturnValueTestBean.class.getMethod("test"), invalidMap)).hasSize(1);
}

static class TestBean {

public Map<String, @NotBlank String> constrainedMap;

public TestBean() {
Map<String, String> invalidMap = new HashMap<>();
invalidMap.put("key", "");

this.constrainedMap = invalidMap;
}
}

static class NestedTestBean {

public Map<String, List<@NotBlank String>> constrainedMap;

public NestedTestBean() {
Map<String, List<String>> invalidMap = new HashMap<>();
invalidMap.put("key", Collections.singletonList(""));

this.constrainedMap = invalidMap;
}
}

static class MethodParameterTestBean {

public void test(Map<String, List<@NotBlank String>> constrainedMap) {
// do nothing
}
}

static class MethodReturnValueTestBean {

public Map<String, List<@NotBlank String>> test() {
return null;
}
}
}

0 comments on commit 1a22331

Please sign in to comment.