01: /*
02: * Copyright 2002-2005 the original author or authors.
03: *
04: * Licensed under the Apache License, Version 2.0 (the "License");
05: * you may not use this file except in compliance with the License.
06: * You may obtain a copy of the License at
07: *
08: * http://www.apache.org/licenses/LICENSE-2.0
09: *
10: * Unless required by applicable law or agreed to in writing, software
11: * distributed under the License is distributed on an "AS IS" BASIS,
12: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13: * See the License for the specific language governing permissions and
14: * limitations under the License.
15: */
16:
17: package org.springframework.validation;
18:
19: import org.springframework.beans.PropertyAccessException;
20: import org.springframework.context.support.DefaultMessageSourceResolvable;
21:
22: /**
23: * Default <code>BindingErrorProcessor</code> implementation.
24: *
25: * <p>Uses the "required" error code and the field name to resolve message codes
26: * for a missing field error.
27: *
28: * <p>Creates a <code>FieldError</code> for each <code>PropertyAccessException</code>
29: * given, using the <code>PropertyAccessException</code>'s error code ("typeMismatch",
30: * "methodInvocation") for resolving message codes.
31: *
32: * @author Alef Arendsen
33: * @author Juergen Hoeller
34: * @since 1.2
35: * @see #MISSING_FIELD_ERROR_CODE
36: * @see DataBinder#setBindingErrorProcessor
37: * @see BeanPropertyBindingResult#addError
38: * @see BeanPropertyBindingResult#resolveMessageCodes
39: * @see org.springframework.beans.PropertyAccessException#getErrorCode
40: * @see org.springframework.beans.TypeMismatchException#ERROR_CODE
41: * @see org.springframework.beans.MethodInvocationException#ERROR_CODE
42: */
43: public class DefaultBindingErrorProcessor implements
44: BindingErrorProcessor {
45:
46: /**
47: * Error code that a missing field error (i.e. a required field not
48: * found in the list of property values) will be registered with:
49: * "required".
50: */
51: public static final String MISSING_FIELD_ERROR_CODE = "required";
52:
53: public void processMissingFieldError(String missingField,
54: BindingResult bindingResult) {
55: // Create field error with code "required".
56: String[] codes = bindingResult.resolveMessageCodes(
57: MISSING_FIELD_ERROR_CODE, missingField);
58: Object[] arguments = getArgumentsForBindError(bindingResult
59: .getObjectName(), missingField);
60: bindingResult.addError(new FieldError(bindingResult
61: .getObjectName(), missingField, "", true, codes,
62: arguments, "Field '" + missingField + "' is required"));
63: }
64:
65: public void processPropertyAccessException(
66: PropertyAccessException ex, BindingResult bindingResult) {
67: // Create field error with the exceptions's code, e.g. "typeMismatch".
68: String field = ex.getPropertyChangeEvent().getPropertyName();
69: Object value = ex.getPropertyChangeEvent().getNewValue();
70: String[] codes = bindingResult.resolveMessageCodes(ex
71: .getErrorCode(), field);
72: Object[] arguments = getArgumentsForBindError(bindingResult
73: .getObjectName(), field);
74: bindingResult.addError(new FieldError(bindingResult
75: .getObjectName(), field, value, true, codes, arguments,
76: ex.getLocalizedMessage()));
77: }
78:
79: /**
80: * Return FieldError arguments for a binding error on the given field.
81: * Invoked for each missing required fields and each type mismatch.
82: * <p>Default implementation returns a DefaultMessageSourceResolvable
83: * with "objectName.field" and "field" as codes.
84: * @param field the field that caused the binding error
85: * @return the Object array that represents the FieldError arguments
86: * @see org.springframework.validation.FieldError#getArguments
87: * @see org.springframework.context.support.DefaultMessageSourceResolvable
88: */
89: protected Object[] getArgumentsForBindError(String objectName,
90: String field) {
91: String[] codes = new String[] {
92: objectName + Errors.NESTED_PATH_SEPARATOR + field,
93: field };
94: String defaultMessage = field;
95: return new Object[] { new DefaultMessageSourceResolvable(codes,
96: defaultMessage) };
97: }
98:
99: }
|