initial add of validation failure concept to provide errors equivalent in validation context

This commit is contained in:
Keith Donald
2009-02-26 23:05:21 +00:00
parent 16e88dcb6f
commit 55b3dc58a1
9 changed files with 227 additions and 8 deletions

View File

@@ -22,14 +22,18 @@ import org.springframework.context.MessageSourceResolvable;
import org.springframework.core.style.ToStringCreator;
class DefaultMessageResolver implements MessageResolver, MessageSourceResolvable {
private Object source;
private String[] codes;
private Severity severity;
private Object[] args;
private String defaultText;
public DefaultMessageResolver(Object source, String[] codes, Severity severity, Object[] args,
String defaultText) {
public DefaultMessageResolver(Object source, String[] codes, Severity severity, Object[] args, String defaultText) {
this.source = source;
this.codes = codes;
this.severity = severity;
@@ -56,7 +60,7 @@ class DefaultMessageResolver implements MessageResolver, MessageSourceResolvable
}
public String toString() {
return new ToStringCreator(this).append("source", source).append("severity", severity).append("codes",
codes).append("args", args).append("defaultText", defaultText).toString();
return new ToStringCreator(this).append("source", source).append("severity", severity).append("codes", codes)
.append("args", args).append("defaultText", defaultText).toString();
}
}

View File

@@ -181,7 +181,7 @@ public class MessageBuilder {
/**
* Records the fallback text of the message being built. If the message has no codes, this will always be used as
* the text. If the message has codes but none can be resolved, this will alway be used as the text.
* the text. If the message has codes but none can be resolved, this will always be used as the text.
* @param text the default text
* @return this, for fluent API usage
*/

View File

@@ -0,0 +1,37 @@
package org.springframework.binding.validation;
import java.util.Map;
import org.springframework.binding.message.Severity;
/**
* A failure that occurred against a specific property on the object being violated.
*
* @author Keith Donald
*/
public final class PropertyValidationFailure extends ValidationFailure {
private String propertyName;
/**
* Creates a new property validation failure.
* @param propertyName the property name
* @param code the failure code
* @param severity the severity
* @param arguments named failure arguments
* @param defaultMessage default message text
*/
public PropertyValidationFailure(String propertyName, String code, Severity severity, Map arguments,
String defaultMessage) {
super(code, severity, arguments, defaultMessage);
this.propertyName = propertyName;
}
/**
* The name of the property.
*/
public String getPropertyName() {
return propertyName;
}
}

View File

@@ -21,7 +21,7 @@ import java.security.Principal;
import org.springframework.binding.message.MessageContext;
/**
* A validator context. Allows for recording validation error messages, as well as validating data entered by the user.
* A context for a validator to use to access user data and report validation failures.
*
* @author Keith Donald
* @author Scott Andrews
@@ -29,7 +29,9 @@ import org.springframework.binding.message.MessageContext;
public interface ValidationContext {
/**
* The context for recording validation messages
* A context for adding messages to display to the user directly. The {@link #addFailure(ValidationFailure)}
* operation provides a higher level of abstraction for reporting validation failures. This method provides more
* control over the actual message added.
*/
public MessageContext getMessageContext();
@@ -49,4 +51,17 @@ public interface ValidationContext {
* @return the value the user entered in the field bound to the property
*/
public Object getUserValue(String property);
/**
* Add a validation failure to this context. Called by a validator to report failures against the current object
* being validated. Use to report a general failure against the object, or a specific failure against a property on
* the object. The failure code provided is typically mapped to one or message codes that result in a Message being
* added to the {@link MessageContext}.
* @param failure the validation failure
* @see #getMessageContext()
* @see ValidationFailureMessageResolverFactory
* @see PropertyValidationFailure
*/
public void addFailure(ValidationFailure failure);
}

View File

@@ -0,0 +1,68 @@
package org.springframework.binding.validation;
import java.util.Map;
import org.springframework.binding.message.Severity;
/**
* A failure that occurred during validation. Each failure has a code that uniquely identifies the validation constraint
* that was violated; for example "required", or "maxLength". A failure has a severity describing the intensity of the
* violation. A failure may have additional arguments that can be used as named parameters in a UI display message. A
* failure can also have a default message to display if no suitable message can be resolved.
*/
public class ValidationFailure {
private String code;
private Severity severity;
private Map arguments;
private String defaultMessage;
/**
* Creates a new validation failure
* @param code the failure code
* @param severity the severity
* @param arguments named failure arguments
* @param defaultMessage the default message text
*/
public ValidationFailure(String code, Severity severity, Map arguments, String defaultMessage) {
this.code = code;
this.severity = severity;
this.arguments = arguments;
this.defaultMessage = defaultMessage;
}
/**
* The failure code, uniquely identifying the validation constraint that failed.
*/
public String getCode() {
return code;
}
/**
* The severity of the failure, which measures the impact of the constraint violation.
*/
public Severity getSeverity() {
return severity;
}
/**
* An map of arguments that can be used as named parameters in the message associated with this validation failure.
* Each constraint that can fail defines a set of arguments that are specific to it. For example, a range constriant
* might define arguments of "min" and "max" of Integer values. In the message bundle, you then might see
* "range=The ${label} field value must be between ${min} and ${max}".
*/
public Map getArguments() {
return arguments;
}
/**
* The default message to display if no suitable display message can be resolved for this failure.
*/
public String getDefaultMessage() {
return defaultMessage;
}
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright 2004-2008 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.binding.validation;
import java.util.Map;
import java.util.TreeMap;
import org.springframework.binding.message.Severity;
import org.springframework.util.StringUtils;
public class ValidationFailureBuilder {
private String propertyName;
private String constraint;
private Severity severity;
private Map args = new TreeMap();
private String defaultText;
public ValidationFailureBuilder forProperty(String propertyName) {
this.propertyName = propertyName;
return this;
}
public ValidationFailureBuilder constraint(String constraint) {
this.constraint = constraint;
return this;
}
public ValidationFailureBuilder warning() {
severity = Severity.WARNING;
return this;
}
public ValidationFailureBuilder error() {
severity = Severity.ERROR;
return this;
}
public ValidationFailureBuilder arg(String name, Object value) {
args.put(name, value);
return this;
}
public ValidationFailure build() {
if (severity == null) {
severity = Severity.ERROR;
}
if (StringUtils.hasText(propertyName)) {
return new PropertyValidationFailure(propertyName, constraint, severity, args, defaultText);
} else {
return new ValidationFailure(constraint, severity, args, defaultText);
}
}
}

View File

@@ -0,0 +1,18 @@
package org.springframework.binding.validation;
import org.springframework.binding.message.MessageResolver;
/**
* Translates a validation failure into a resolvable message.
*
* @author Keith Donald
*/
public interface ValidationFailureMessageResolverFactory {
/**
* Creates a new message resolver for the validation failure.
* @param failure the validation failure
* @return the message resolver for the failure
*/
MessageResolver createMessageResolver(ValidationFailure failure);
}