Skip to content

Commit

Permalink
HV-1031 Creating copy of PathImpl during marking processed paths
Browse files Browse the repository at this point in the history
  • Loading branch information
gunnarmorling committed Sep 1, 2016
1 parent 4a98f73 commit 40cbdde
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 5 deletions.
Expand Up @@ -6,6 +6,9 @@
*/
package org.hibernate.validator.internal.engine;

import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap;
import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet;

import java.lang.annotation.ElementType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
Expand All @@ -17,6 +20,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.validation.ConstraintValidatorFactory;
import javax.validation.ConstraintViolation;
import javax.validation.MessageInterpolator;
Expand All @@ -26,9 +30,6 @@
import javax.validation.ValidationException;
import javax.validation.metadata.ConstraintDescriptor;

import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.TypeResolver;

import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorContextImpl;
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager;
import org.hibernate.validator.internal.engine.constraintvalidation.ConstraintViolationCreationContext;
Expand All @@ -43,8 +44,8 @@
import org.hibernate.validator.spi.time.TimeProvider;
import org.hibernate.validator.spi.valuehandling.ValidatedValueUnwrapper;

import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap;
import static org.hibernate.validator.internal.util.CollectionHelper.newHashSet;
import com.fasterxml.classmate.ResolvedType;
import com.fasterxml.classmate.TypeResolver;

/**
* Context object keeping track of all required data for a validation call.
Expand Down Expand Up @@ -472,6 +473,9 @@ private boolean isAlreadyValidatedForCurrentGroup(Object value, Class<?> group)
}

private void markCurrentBeanAsProcessedForCurrentPath(Object value, PathImpl path) {
// HV-1031 The path object is mutated as we traverse the object tree, hence copy it before saving it
path = PathImpl.createCopy( path );

if ( processedPathsPerBean.containsKey( value ) ) {
processedPathsPerBean.get( value ).add( path );
}
Expand Down
@@ -0,0 +1,120 @@
/*
* 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.test.internal.engine.typeannotationconstraint;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectPropertyPaths;
import static org.hibernate.validator.testutils.ValidatorUtil.getValidator;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.validation.Constraint;
import javax.validation.ConstraintViolation;
import javax.validation.OverridesAttribute;
import javax.validation.Payload;
import javax.validation.Valid;
import javax.validation.Validator;
import javax.validation.constraints.Size;

import org.hibernate.validator.testutil.TestForIssue;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

/**
* @author Gunnar Morling
*/
@TestForIssue(jiraKey = "HV-1031")
public class SameElementContainedSeveralTimesInCollectionTest {

private Validator validator;

@BeforeClass
public void setup() {
validator = getValidator();
}

@Test
public void sameInvalidInstanceInListShouldBeReportedWithAllPaths() {
ListContainer listContainer = new ListContainer( Arrays.asList( "", "A", "" ) );

Set<ConstraintViolation<ListContainer>> constraintViolations = validator.validate( listContainer );

assertCorrectPropertyPaths( constraintViolations, "values[0]", "values[2]" );
}

@Test
public void sameInvalidInstanceInMapShouldBeReportedWithAllPaths() {
List<String> emptyList = Collections.emptyList();
List<String> nonEmptyList = Arrays.asList( "A" );

HashMap<String, List<String>> values = new HashMap<>();
values.put( "NON_EMPTY", nonEmptyList );
values.put( "EMPTY_1", emptyList );
values.put( "EMPTY_2", emptyList );
MapContainer withMap = new MapContainer( values );

Set<ConstraintViolation<MapContainer>> constraintViolations = validator.validate( withMap );

assertCorrectPropertyPaths( constraintViolations, "values[EMPTY_1]", "values[EMPTY_2]" );
}

private static class ListContainer {

@Valid
public List<@SizeWithTypeUse(min = 1) String> values;

public ListContainer(List<String> values) {
this.values = values;
}
}

private static class MapContainer {

@Valid
public Map<String, @SizeWithTypeUse(min = 1) List<String>> values;

public MapContainer(Map<String, List<String>> values) {
this.values = values;
}
}

// TODO Remove once the original one supports TYPE_USE
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {})
@Size
public @interface SizeWithTypeUse {

String message() default "{javax.validation.constraints.Size.message}";

Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

@OverridesAttribute(constraint = Size.class, name = "min")
int min() default 0;

@OverridesAttribute(constraint = Size.class, name = "max")
int max() default Integer.MAX_VALUE;
}
}

0 comments on commit 40cbdde

Please sign in to comment.