diff --git a/spring-binding/src/main/java/org/springframework/binding/validation/DefaultSpringMvcValidationFailureMessageCodesFactory.java b/spring-binding/src/main/java/org/springframework/binding/validation/DefaultSpringMvcValidationFailureMessageCodesFactory.java new file mode 100644 index 00000000..59b86cb4 --- /dev/null +++ b/spring-binding/src/main/java/org/springframework/binding/validation/DefaultSpringMvcValidationFailureMessageCodesFactory.java @@ -0,0 +1,44 @@ +package org.springframework.binding.validation; + +/** + * Failure message codes factory specialization that applies default Spring MVC errorCode-to-messageCodes mapping rules. + * The difference between this subclass and the default {@link ValidationFailureMessageCodesFactory} is where the + * constraint code falls in the message code. Specifically, for a property validation failure the default algorithm + * results in these codes: + * + *
+ * ${failureMessageCodePrefix}.${model}.${property}.${constraint}
+ * ${failureMessageCodePrefix}.${propertyType}.${constraint}
+ * ${failureMessageCodePrefix}.${constraint}
+ *
+ *
+ * while this original Spring MVC algorithm results in these codes:
+ *
+ *
+ * ${failureMessageCodePrefix}.${constraint}.${model}.${property}
+ * ${failureMessageCodePrefix}.${constraint}.${propertyType}
+ * ${failureMessageCodePrefix}.${constraint}
+ *
+ *
+ * @author Keith Donald
+ */
+public class DefaultSpringMvcValidationFailureMessageCodesFactory extends ValidationFailureMessageCodesFactory {
+
+ public String[] createMessageCodes(ValidationFailure failure, ValidationFailureModelContext modelContext) {
+ String constraintMessageCode = appendFailureMessageCodePrefix().append(failure.getConstraint()).append(
+ codeSeparator()).toString();
+ if (failure.getProperty() != null) {
+ String propertyConstraintMessageCode = appendFailureMessageCodePrefix().append(codeSeparator()).append(
+ failure.getConstraint()).append(modelContext.getModel()).append(codeSeparator()).append(
+ failure.getProperty()).append(codeSeparator()).toString();
+ String typeConstraintMessageCode = appendFailureMessageCodePrefix().append(codeSeparator()).append(
+ failure.getConstraint()).append(modelContext.getPropertyType().getName()).toString();
+ return new String[] { propertyConstraintMessageCode, typeConstraintMessageCode, constraintMessageCode };
+ } else {
+ String objectConstraintMessageCode = appendFailureMessageCodePrefix().append(codeSeparator()).append(
+ failure.getConstraint()).append(modelContext.getModel()).append(codeSeparator()).toString();
+ return new String[] { objectConstraintMessageCode, constraintMessageCode };
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/validation/DefaultValidationFailureMessageResolverFactory.java b/spring-binding/src/main/java/org/springframework/binding/validation/DefaultValidationFailureMessageResolverFactory.java
index a8e46cdf..ae740576 100644
--- a/spring-binding/src/main/java/org/springframework/binding/validation/DefaultValidationFailureMessageResolverFactory.java
+++ b/spring-binding/src/main/java/org/springframework/binding/validation/DefaultValidationFailureMessageResolverFactory.java
@@ -39,8 +39,8 @@ import org.springframework.util.Assert;
*
* Employs the following algorithm to map property validation failure to a message:
*
+ * ${failureMessageCodePrefix}.${model}.${property}.${constraint}
+ * ${failureMessageCodePrefix}.${propertyType}.${constraint}
+ * ${failureMessageCodePrefix}.${constraint}
+ *
+ *
+ * @author Keith Donald
+ */
+public class ValidationFailureMessageCodesFactory {
+
+ private String failureMessageCodePrefix = "validation";
+
+ /**
+ * The prefix to prepend to all validation failure message codes.
+ */
+ public String getFailureMessageCodePrefix() {
+ return failureMessageCodePrefix;
+ }
+
+ /**
+ * A prefix to prepend to all validation failure message codes; default if not set explicitly is "validation".
+ * @param failureMessageCodePrefix the failure message code prefix
+ */
+ public void setFailureMessageCodePrefix(String failureMessageCodePrefix) {
+ this.failureMessageCodePrefix = failureMessageCodePrefix;
+ }
+
+ public String[] createMessageCodes(ValidationFailure failure, ValidationFailureModelContext modelContext) {
+ String constraintMessageCode = appendFailureMessageCodePrefix().append(codeSeparator()).append(
+ failure.getConstraint()).toString();
+ if (failure.getProperty() != null) {
+ String propertyConstraintMessageCode = appendFailureMessageCodePrefix().append(codeSeparator()).append(
+ modelContext.getModel()).append(codeSeparator()).append(failure.getProperty()).append(
+ codeSeparator()).append(failure.getConstraint()).toString();
+ String typeConstraintMessageCode = appendFailureMessageCodePrefix().append(codeSeparator()).append(
+ modelContext.getPropertyType().getName()).append(codeSeparator()).append(failure.getConstraint())
+ .toString();
+ return new String[] { propertyConstraintMessageCode, typeConstraintMessageCode, constraintMessageCode };
+ } else {
+ String objectConstraintMessageCode = appendFailureMessageCodePrefix().append(codeSeparator()).append(
+ modelContext.getModel()).append(codeSeparator()).append(failure.getConstraint()).toString();
+ return new String[] { objectConstraintMessageCode, constraintMessageCode };
+ }
+ }
+
+ protected StringBuilder appendFailureMessageCodePrefix() {
+ return new StringBuilder().append(failureMessageCodePrefix);
+ }
+
+ protected char codeSeparator() {
+ return DefaultValidationFailureMessageResolverFactory.CODE_SEPARATOR;
+ }
+}
\ No newline at end of file
diff --git a/spring-binding/src/main/java/org/springframework/binding/validation/ValidationFailureMessageResolverFactory.java b/spring-binding/src/main/java/org/springframework/binding/validation/ValidationFailureMessageResolverFactory.java
index 0c577fce..e3b9c9f1 100644
--- a/spring-binding/src/main/java/org/springframework/binding/validation/ValidationFailureMessageResolverFactory.java
+++ b/spring-binding/src/main/java/org/springframework/binding/validation/ValidationFailureMessageResolverFactory.java
@@ -27,6 +27,8 @@ import org.springframework.binding.message.MessageResolver;
*/
public interface ValidationFailureMessageResolverFactory {
+ public static final char CODE_SEPARATOR = '.';
+
/**
* Creates a new MessageResolver that can resolve the failure {@link Message} for the reported ValidationFailure.
* @param failure a validation failure reported by a validator