org.springframework.validation.DefaultMessageCodesResolver Maven / Gradle / Ivy
/*
* Copyright 2002-2005 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.validation;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Default implementation of the MessageCodesResolver interface.
*
* Will create 2 message codes for an object error, in the following order:
*
* - 1.: code + "." + object name
*
- 2.: code
*
*
* Will create 4 message codes for a field specification, in the following order:
*
* - 1.: code + "." + object name + "." + field
*
- 2.: code + "." + field
*
- 3.: code + "." + field type
*
- 4.: code
*
*
* E.g. in case of code "typeMismatch", object name "user", field "age":
*
* - 1. try "typeMismatch.user.age"
*
- 2. try "typeMismatch.age"
*
- 3. try "typeMismatch.int"
*
- 4. try "typeMismatch"
*
*
* Thus, this resolution algorithm can be leveraged for example to show
* specific messages for binding errors like "required" and "typeMismatch":
*
* - at the object + field level ("age" field, but only on "user");
*
- at the field level (all "age" fields, no matter which object name);
*
- or at the general level (all fields, on any object).
*
*
* In case of array, List or Map properties, both codes for specific
* elements and for the whole collection are generated. Assuming a field
* "name" of an array "groups" in object "user":
*
* - 1. try "typeMismatch.user.groups[0].name"
*
- 2. try "typeMismatch.user.groups.name"
*
- 3. try "typeMismatch.groups[0].name"
*
- 4. try "typeMismatch.groups.name"
*
- 5. try "typeMismatch.name"
*
- 6. try "typeMismatch.java.lang.String"
*
- 7. try "typeMismatch"
*
*
* @author Juergen Hoeller
* @since 1.0.1
*/
public class DefaultMessageCodesResolver implements MessageCodesResolver, Serializable {
public static final String CODE_SEPARATOR = ".";
public String[] resolveMessageCodes(String errorCode, String objectName) {
return new String[] {errorCode + CODE_SEPARATOR + objectName, errorCode};
}
/**
* Build the code list for the given code and field: an object/field-specific code,
* a field-specific code, a plain error code. Arrays, Lists and Maps are resolved
* both for specific elements and the whole collection.
* See class javadoc for details on the generated codes.
* @return the list of codes
*/
public String[] resolveMessageCodes(String errorCode, String objectName, String field, Class fieldType) {
List codeList = new ArrayList();
List fieldList = new ArrayList();
buildFieldList(field, fieldList);
for (Iterator it = fieldList.iterator(); it.hasNext();) {
String fieldInList = (String) it.next();
codeList.add(errorCode + CODE_SEPARATOR + objectName + CODE_SEPARATOR + fieldInList);
}
int dotIndex = field.lastIndexOf('.');
if (dotIndex != -1) {
buildFieldList(field.substring(dotIndex + 1), fieldList);
}
for (Iterator it = fieldList.iterator(); it.hasNext();) {
String fieldInList = (String) it.next();
codeList.add(errorCode + CODE_SEPARATOR + fieldInList);
}
if (fieldType != null) {
codeList.add(errorCode + CODE_SEPARATOR + fieldType.getName());
}
codeList.add(errorCode);
return (String[]) codeList.toArray(new String[codeList.size()]);
}
/**
* Add both keyed and non-keyed entries for the given field to the field list.
*/
protected void buildFieldList(String field, List fieldList) {
fieldList.add(field);
String plainField = field;
int keyIndex = plainField.lastIndexOf('[');
while (keyIndex != -1) {
int endKeyIndex = plainField.indexOf(']', keyIndex);
if (endKeyIndex != -1) {
plainField = plainField.substring(0, keyIndex) + plainField.substring(endKeyIndex + 1);
fieldList.add(plainField);
keyIndex = plainField.lastIndexOf('[');
}
else {
keyIndex = -1;
}
}
}
}