1
1
/*
2
- * Copyright 2002-2008 the original author or authors.
2
+ * Copyright 2002-2012 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
18
18
19
19
import java .io .Serializable ;
20
20
import java .util .ArrayList ;
21
+ import java .util .Collection ;
22
+ import java .util .LinkedHashSet ;
21
23
import java .util .List ;
24
+ import java .util .Set ;
22
25
23
26
import org .springframework .util .StringUtils ;
24
27
25
28
/**
26
29
* Default implementation of the {@link MessageCodesResolver} interface.
27
30
*
28
- * <p>Will create two message codes for an object error, in the following order:
31
+ * <p>Will create two message codes for an object error, in the following order (when
32
+ * using the {@link Style#PREFIX_ERROR_CODE prefixed} {@link #setStyle(Style) style}):
29
33
* <ul>
30
34
* <li>1.: code + "." + object name
31
35
* <li>2.: code
68
72
* <li>7. try "typeMismatch"
69
73
* </ul>
70
74
*
75
+ * <p>By default the {@code errorCode}s will be placed at the beginning of constructed
76
+ * message strings. The {@link #setStyle(Style) style} property can be used to specify
77
+ * alternative {@link Style styles} of concatination.
78
+ *
71
79
* <p>In order to group all codes into a specific category within your resource bundles,
72
80
* e.g. "validation.typeMismatch.name" instead of the default "typeMismatch.name",
73
81
* consider specifying a {@link #setPrefix prefix} to be applied.
74
82
*
75
83
* @author Juergen Hoeller
84
+ * @author Phillip Webb
76
85
* @since 1.0.1
77
86
*/
78
87
@ SuppressWarnings ("serial" )
@@ -83,9 +92,13 @@ public class DefaultMessageCodesResolver implements MessageCodesResolver, Serial
83
92
*/
84
93
public static final String CODE_SEPARATOR = "." ;
85
94
95
+ private static final Style DEFAULT_STYLE = Style .PREFIX_ERROR_CODE ;
96
+
86
97
87
98
private String prefix = "" ;
88
99
100
+ private Style style = DEFAULT_STYLE ;
101
+
89
102
90
103
/**
91
104
* Specify a prefix to be applied to any code built by this resolver.
@@ -96,6 +109,14 @@ public void setPrefix(String prefix) {
96
109
this .prefix = (prefix != null ? prefix : "" );
97
110
}
98
111
112
+ /**
113
+ * Specify the style of message code that will be built by this resolver.
114
+ * <p>Default is {@link Style#PREFIX_ERROR_CODE}.
115
+ */
116
+ public void setStyle (Style style ) {
117
+ this .style = (style == null ? DEFAULT_STYLE : style );
118
+ }
119
+
99
120
/**
100
121
* Return the prefix to be applied to any code built by this resolver.
101
122
* <p>Returns an empty String in case of no prefix.
@@ -106,9 +127,7 @@ protected String getPrefix() {
106
127
107
128
108
129
public String [] resolveMessageCodes (String errorCode , String objectName ) {
109
- return new String [] {
110
- postProcessMessageCode (errorCode + CODE_SEPARATOR + objectName ),
111
- postProcessMessageCode (errorCode )};
130
+ return resolveMessageCodes (errorCode , objectName , "" , null );
112
131
}
113
132
114
133
/**
@@ -121,26 +140,54 @@ public String[] resolveMessageCodes(String errorCode, String objectName) {
121
140
* @return the list of codes
122
141
*/
123
142
public String [] resolveMessageCodes (String errorCode , String objectName , String field , Class <?> fieldType ) {
124
- List <String > codeList = new ArrayList <String >();
143
+ Set <String > codeList = new LinkedHashSet <String >();
125
144
List <String > fieldList = new ArrayList <String >();
126
145
buildFieldList (field , fieldList );
127
- for (String fieldInList : fieldList ) {
128
- codeList .add (postProcessMessageCode (errorCode + CODE_SEPARATOR + objectName + CODE_SEPARATOR + fieldInList ));
129
- }
146
+ addCodes (codeList , errorCode , objectName , fieldList );
130
147
int dotIndex = field .lastIndexOf ('.' );
131
148
if (dotIndex != -1 ) {
132
149
buildFieldList (field .substring (dotIndex + 1 ), fieldList );
133
150
}
134
- for (String fieldInList : fieldList ) {
135
- codeList .add (postProcessMessageCode (errorCode + CODE_SEPARATOR + fieldInList ));
136
- }
151
+ addCodes (codeList , errorCode , null , fieldList );
137
152
if (fieldType != null ) {
138
- codeList . add ( postProcessMessageCode ( errorCode + CODE_SEPARATOR + fieldType .getName () ));
153
+ addCode ( codeList , errorCode , null , fieldType .getName ());
139
154
}
140
- codeList . add ( postProcessMessageCode ( errorCode ) );
155
+ addCode ( codeList , errorCode , null , null );
141
156
return StringUtils .toStringArray (codeList );
142
157
}
143
158
159
+ private void addCodes (Collection <String > codeList , String errorCode , String objectName , Iterable <String > fields ) {
160
+ for (String field : fields ) {
161
+ addCode (codeList , errorCode , objectName , field );
162
+ }
163
+ }
164
+
165
+ private void addCode (Collection <String > codeList , String errorCode , String objectName , String field ) {
166
+ String code = getCode (errorCode , objectName , field );
167
+ codeList .add (postProcessMessageCode (code ));
168
+ }
169
+
170
+ private String getCode (String errorCode , String objectName , String field ) {
171
+ switch (this .style ) {
172
+ case PREFIX_ERROR_CODE :
173
+ return toDelimitedString (errorCode , objectName , field );
174
+ case POSTFIX_ERROR_CODE :
175
+ return toDelimitedString (objectName , field , errorCode );
176
+ }
177
+ throw new IllegalStateException ("Unknown style " + this .style );
178
+ }
179
+
180
+ private String toDelimitedString (String ... elements ) {
181
+ StringBuilder rtn = new StringBuilder ();
182
+ for (String element : elements ) {
183
+ if (StringUtils .hasLength (element )) {
184
+ rtn .append (rtn .length () == 0 ? "" : CODE_SEPARATOR );
185
+ rtn .append (element );
186
+ }
187
+ }
188
+ return rtn .toString ();
189
+ }
190
+
144
191
/**
145
192
* Add both keyed and non-keyed entries for the supplied <code>field</code>
146
193
* to the supplied field list.
@@ -173,4 +220,23 @@ protected String postProcessMessageCode(String code) {
173
220
return getPrefix () + code ;
174
221
}
175
222
223
+
224
+ /**
225
+ * The various styles that can be used to construct message codes.
226
+ */
227
+ public static enum Style {
228
+
229
+ /**
230
+ * Prefix the error code at the beginning of the generated message code. eg:
231
+ * {@code errorCode + "." + object name + "." + field}
232
+ */
233
+ PREFIX_ERROR_CODE ,
234
+
235
+ /**
236
+ * Postfix the error code at the end of the generated message code. eg:
237
+ * {@code object name + "." + field + "." + errorCode}
238
+ */
239
+ POSTFIX_ERROR_CODE
240
+ }
241
+
176
242
}
0 commit comments