Skip to content

Commit abeb15b

Browse files
committed
HV-710 Adding CrossParameterNode to paths for cross-parameter constraint violations
1 parent 35a6b6c commit abeb15b

File tree

7 files changed

+51
-10
lines changed

7 files changed

+51
-10
lines changed

engine/src/main/java/org/hibernate/validator/internal/engine/ValidatorImpl.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,7 +486,7 @@ private <T, U, V> boolean validateConstraint(ValidationContext<T, ?> validationC
486486
);
487487
}
488488
else {
489-
valueContext.appendNode( beanMetaDataManager.getBeanMetaData( valueContext.getCurrentBeanType() ) );
489+
valueContext.appendBeanNode();
490490
}
491491

492492
if ( isValidationRequired( validationContext, valueContext, metaConstraint ) ) {
@@ -971,6 +971,7 @@ private <T> int validateParametersForGroup(MethodValidationContext<T> validation
971971
ValueContext<T, Object> valueContext = getExecutableValueContext(
972972
object, validationContext.getRootBeanClass(), executableMetaData, currentValidatedGroup
973973
);
974+
valueContext.appendCrossParameterNode();
974975
valueContext.setCurrentValidatedValue( parameterValues );
975976

976977
// 1. validate cross-parameter constraints
@@ -981,6 +982,11 @@ private <T> int validateParametersForGroup(MethodValidationContext<T> validation
981982
return validationContext.getFailingConstraints().size() - numberOfViolationsBefore;
982983
}
983984

985+
valueContext = getExecutableValueContext(
986+
object, validationContext.getRootBeanClass(), executableMetaData, currentValidatedGroup
987+
);
988+
valueContext.setCurrentValidatedValue( parameterValues );
989+
984990
// 2. validate parameter constraints
985991
for ( int i = 0; i < parameterValues.length; i++ ) {
986992
PathImpl originalPath = valueContext.getPropertyPath();

engine/src/main/java/org/hibernate/validator/internal/engine/ValueContext.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import javax.validation.groups.Default;
2323

2424
import org.hibernate.validator.internal.engine.path.PathImpl;
25-
import org.hibernate.validator.internal.metadata.aggregated.BeanMetaData;
2625
import org.hibernate.validator.internal.metadata.aggregated.ParameterMetaData;
2726
import org.hibernate.validator.internal.metadata.facets.Cascadable;
2827
import org.hibernate.validator.internal.metadata.facets.Validatable;
@@ -131,11 +130,16 @@ else if ( node.getKind() == ElementKind.RETURN_VALUE ) {
131130
}
132131
}
133132

134-
public final void appendNode(BeanMetaData<?> node) {
133+
public final void appendBeanNode() {
135134
propertyPath = PathImpl.createCopy( propertyPath );
136135
propertyPath.addBeanNode();
137136
}
138137

138+
public final void appendCrossParameterNode() {
139+
propertyPath = PathImpl.createCopy( propertyPath );
140+
propertyPath.addCrossParameterNode();
141+
}
142+
139143
public final void markCurrentPropertyAsIterable() {
140144
propertyPath.makeLeafNodeIterable();
141145
}

engine/src/main/java/org/hibernate/validator/internal/engine/path/NodeImpl.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,15 @@
3434
* @author Gunnar Morling
3535
*/
3636
public class NodeImpl
37-
implements Path.PropertyNode, Path.MethodNode, Path.ConstructorNode, Path.BeanNode, Path.ParameterNode, Path.ReturnValueNode, Serializable {
37+
implements Path.PropertyNode, Path.MethodNode, Path.ConstructorNode, Path.BeanNode, Path.ParameterNode, Path.ReturnValueNode, Path.CrossParameterNode, Serializable {
3838
private static final long serialVersionUID = 2075466571633860499L;
3939

4040
private static final Log log = LoggerFactory.make();
4141

4242
public static final String INDEX_OPEN = "[";
4343
public static final String INDEX_CLOSE = "]";
4444
private static final String RETURN_VALUE_NODE_NAME = "<return value>";
45+
private static final String CROSS_PARAMETER_NODE_NAME = "<cross-parameter>";
4546

4647
private final String name;
4748
private final NodeImpl parent;
@@ -96,6 +97,19 @@ public static NodeImpl createParameterNode(String name, NodeImpl parent, int par
9697
);
9798
}
9899

100+
public static NodeImpl createCrossParameterNode(NodeImpl parent) {
101+
return new NodeImpl(
102+
CROSS_PARAMETER_NODE_NAME,
103+
parent,
104+
false,
105+
null,
106+
null,
107+
ElementKind.CROSS_PARAMETER,
108+
Collections.<Class<?>>emptyList(),
109+
null
110+
);
111+
}
112+
99113
public static NodeImpl createMethodNode(String name, NodeImpl parent, List<Class<?>> parameterTypes) {
100114
return new NodeImpl( name, parent, false, null, null, ElementKind.METHOD, parameterTypes, null );
101115
}

engine/src/main/java/org/hibernate/validator/internal/engine/path/PathImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,14 @@ public NodeImpl addParameterNode(String nodeName, int index) {
143143
return currentLeafNode;
144144
}
145145

146+
public NodeImpl addCrossParameterNode() {
147+
NodeImpl parent = nodeList.isEmpty() ? null : (NodeImpl) nodeList.get( nodeList.size() - 1 );
148+
currentLeafNode = NodeImpl.createCrossParameterNode( parent );
149+
nodeList.add( currentLeafNode );
150+
hashCode = -1;
151+
return currentLeafNode;
152+
}
153+
146154
public NodeImpl addBeanNode() {
147155
NodeImpl parent = nodeList.isEmpty() ? null : (NodeImpl) nodeList.get( nodeList.size() - 1 );
148156
currentLeafNode = NodeImpl.createBeanNode( parent );

engine/src/test/java/org/hibernate/validator/test/internal/engine/methodvalidation/ConstructorValidationTest.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import org.hibernate.validator.test.internal.engine.methodvalidation.service.CustomerRepositoryImpl.ValidB2BRepository;
3030

3131
import static org.fest.assertions.Assertions.assertThat;
32-
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertDescriptorKinds;
32+
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNodeKinds;
3333
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNodeNames;
3434
import static org.hibernate.validator.testutil.ValidatorUtil.getValidator;
3535

@@ -56,7 +56,7 @@ public void constructorParameterValidationYieldsConstraintViolation() throws Exc
5656
assertThat( constraintViolation.getRootBeanClass() ).isEqualTo( CustomerRepositoryImpl.class );
5757
assertThat( constraintViolation.getInvalidValue() ).isNull();
5858

59-
assertDescriptorKinds(
59+
assertNodeKinds(
6060
constraintViolation.getPropertyPath(),
6161
ElementKind.CONSTRUCTOR,
6262
ElementKind.PARAMETER
@@ -82,7 +82,7 @@ public void cascadedConstructorParameterValidationYieldsConstraintViolation() th
8282
assertThat( constraintViolation.getInvalidValue() ).isNull();
8383

8484
Path path = constraintViolation.getPropertyPath();
85-
assertDescriptorKinds( path, ElementKind.CONSTRUCTOR, ElementKind.PARAMETER, ElementKind.PROPERTY );
85+
assertNodeKinds( path, ElementKind.CONSTRUCTOR, ElementKind.PARAMETER, ElementKind.PROPERTY );
8686
assertNodeNames( path, "CustomerRepositoryImpl", "arg0", "name" );
8787
}
8888

@@ -108,7 +108,7 @@ public void constructorReturnValueValidationYieldsConstraintViolation() throws E
108108
ValidB2BRepository.class
109109
);
110110

111-
assertDescriptorKinds(
111+
assertNodeKinds(
112112
constraintViolation.getPropertyPath(),
113113
ElementKind.CONSTRUCTOR,
114114
ElementKind.RETURN_VALUE
@@ -136,7 +136,7 @@ public void cascadedConstructorReturnValueValidationYieldsConstraintViolation()
136136
assertThat( constraintViolation.getInvalidValue() ).isNull();
137137

138138
Path path = constraintViolation.getPropertyPath();
139-
assertDescriptorKinds( path, ElementKind.CONSTRUCTOR, ElementKind.RETURN_VALUE, ElementKind.PROPERTY );
139+
assertNodeKinds( path, ElementKind.CONSTRUCTOR, ElementKind.RETURN_VALUE, ElementKind.PROPERTY );
140140
assertNodeNames( path, "CustomerRepositoryImpl", "<return value>", "customer" );
141141
}
142142

engine/src/test/java/org/hibernate/validator/test/internal/engine/methodvalidation/MethodLevelValidationTest.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap;
4848
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertConstraintViolation;
4949
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintViolationMessages;
50+
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNodeKinds;
51+
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNodeNames;
5052
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations;
5153
import static org.hibernate.validator.testutil.ValidatorUtil.getValidatingProxy;
5254
import static org.testng.Assert.assertEquals;
@@ -585,6 +587,13 @@ public void validationOfCrossParameterConstraint() {
585587
DateMidnight.class,
586588
DateMidnight.class
587589
);
590+
591+
assertNodeNames(
592+
constraintViolation.getPropertyPath(),
593+
"methodWithCrossParameterConstraint",
594+
"<cross-parameter>"
595+
);
596+
assertNodeKinds( constraintViolation.getPropertyPath(), ElementKind.METHOD, ElementKind.CROSS_PARAMETER );
588597
}
589598
}
590599

engine/src/test/java/org/hibernate/validator/testutil/ConstraintViolationAssert.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ public static void assertConstraintTypes(Set<ConstraintDescriptor<?>> descriptor
198198
* @param path The path under test
199199
* @param kinds The node kinds
200200
*/
201-
public static void assertDescriptorKinds(Path path, ElementKind... kinds) {
201+
public static void assertNodeKinds(Path path, ElementKind... kinds) {
202202
Iterator<Path.Node> pathIterator = path.iterator();
203203

204204
for ( ElementKind kind : kinds ) {

0 commit comments

Comments
 (0)