From 7304c090213a38108f9f06cf1d2db3f9f754c621 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 21 Jul 2010 14:24:10 +0000 Subject: [PATCH] Spring field error arguments include actually declared annotation attributes in alphabetical order (SPR-6730) --- .../DefaultBindingErrorProcessor.java | 6 ++-- .../SpringValidatorAdapter.java | 29 +++++++++++++++++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/org.springframework.context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java b/org.springframework.context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java index eaab86b9ab..6f61c910b8 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/DefaultBindingErrorProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -79,8 +79,8 @@ public class DefaultBindingErrorProcessor implements BindingErrorProcessor { /** * Return FieldError arguments for a binding error on the given field. * Invoked for each missing required field and each type mismatch. - *

The default implementation returns a single argument of type - * DefaultMessageSourceResolvable, with "objectName.field" and "field" as codes. + *

The default implementation returns a single argument indicating the field name + * (of type DefaultMessageSourceResolvable, with "objectName.field" and "field" as codes). * @param objectName the name of the target object * @param field the field that caused the binding error * @return the Object array that represents the FieldError arguments diff --git a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java index 79822ddb42..083bb40c84 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/beanvalidation/SpringValidatorAdapter.java @@ -16,9 +16,12 @@ package org.springframework.validation.beanvalidation; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.TreeMap; import javax.validation.ConstraintViolation; import javax.validation.metadata.BeanDescriptor; import javax.validation.metadata.ConstraintDescriptor; @@ -43,6 +46,14 @@ import org.springframework.validation.Validator; */ public class SpringValidatorAdapter implements Validator, javax.validation.Validator { + private static final Set internalAnnotationAttributes = new HashSet(3); + + static { + internalAnnotationAttributes.add("message"); + internalAnnotationAttributes.add("groups"); + internalAnnotationAttributes.add("payload"); + } + private javax.validation.Validator targetValidator; @@ -95,8 +106,11 @@ public class SpringValidatorAdapter implements Validator, javax.validation.Valid /** * Return FieldError arguments for a validation error on the given field. * Invoked for each violated constraint. - *

The default implementation returns a single argument of type - * DefaultMessageSourceResolvable, with "objectName.field" and "field" as codes. + *

The default implementation returns a first argument indicating the field name + * (of type DefaultMessageSourceResolvable, with "objectName.field" and "field" as codes). + * Afterwards, it adds all actual constraint annotation attributes (i.e. excluding + * "message", "groups" and "payload") in alphabetical order of their attribute names. + *

Can be overridden to e.g. add further attributes from the constraint descriptor. * @param objectName the name of the target object * @param field the field that caused the binding error * @param descriptor the JSR-303 constraint descriptor @@ -109,7 +123,16 @@ public class SpringValidatorAdapter implements Validator, javax.validation.Valid List arguments = new LinkedList(); String[] codes = new String[] {objectName + Errors.NESTED_PATH_SEPARATOR + field, field}; arguments.add(new DefaultMessageSourceResolvable(codes, field)); - arguments.addAll(descriptor.getAttributes().values()); + // Using a TreeMap for alphabetical ordering of attribute names + Map attributesToExpose = new TreeMap(); + for (Map.Entry entry : descriptor.getAttributes().entrySet()) { + String attributeName = entry.getKey(); + Object attributeValue = entry.getValue(); + if (!internalAnnotationAttributes.contains(attributeName)) { + attributesToExpose.put(attributeName, attributeValue); + } + } + arguments.addAll(attributesToExpose.values()); return arguments.toArray(new Object[arguments.size()]); }