View Javadoc
1   /*
2    * Copyright 2002-2014 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
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.expression.spel;
18  
19  import java.text.MessageFormat;
20  
21  /**
22   * Contains all the messages that can be produced by the Spring Expression Language.
23   * Each message has a kind (info, warn, error) and a code number. Tests can be written to
24   * expect particular code numbers rather than particular text, enabling the message text
25   * to more easily be modified and the tests to run successfully in different locales.
26   *
27   * <p>When a message is formatted, it will have this kind of form
28   *
29   * <pre class="code">
30   * EL1004E: (pos 34): Type cannot be found 'String'
31   * </pre>
32   *
33   * The prefix captures the code and the error kind, whilst the position is included
34   * if it is known.
35   *
36   * @author Andy Clement
37   * @since 3.0
38   */
39  public enum SpelMessage {
40  
41  	TYPE_CONVERSION_ERROR(Kind.ERROR, 1001,
42  			"Type conversion problem, cannot convert from {0} to {1}"),
43  
44  	CONSTRUCTOR_NOT_FOUND(Kind.ERROR, 1002,
45  			"Constructor call: No suitable constructor found on type {0} for arguments {1}"),
46  
47  	CONSTRUCTOR_INVOCATION_PROBLEM(Kind.ERROR, 1003,
48  			"A problem occurred whilst attempting to construct an object of type ''{0}'' using arguments ''{1}''"),
49  
50  	METHOD_NOT_FOUND(Kind.ERROR, 1004,
51  			"Method call: Method {0} cannot be found on {1} type"),
52  
53  	TYPE_NOT_FOUND(Kind.ERROR, 1005,
54  			"Type cannot be found ''{0}''"),
55  
56  	FUNCTION_NOT_DEFINED(Kind.ERROR, 1006,
57  			"The function ''{0}'' could not be found"),
58  
59  	PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL(Kind.ERROR, 1007,
60  			"Property or field ''{0}'' cannot be found on null"),
61  
62  	PROPERTY_OR_FIELD_NOT_READABLE(Kind.ERROR, 1008,
63  			"Property or field ''{0}'' cannot be found on object of type ''{1}'' - maybe not public?"),
64  
65  	PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL(Kind.ERROR, 1009,
66  			"Property or field ''{0}'' cannot be set on null"),
67  
68  	PROPERTY_OR_FIELD_NOT_WRITABLE(Kind.ERROR, 1010,
69  			"Property or field ''{0}'' cannot be set on object of type ''{1}'' - maybe not public?"),
70  
71  	METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED(Kind.ERROR, 1011,
72  			"Method call: Attempted to call method {0} on null context object"),
73  
74  	CANNOT_INDEX_INTO_NULL_VALUE(Kind.ERROR, 1012,
75  			"Cannot index into a null value"),
76  
77  	NOT_COMPARABLE(Kind.ERROR, 1013,
78  			"Cannot compare instances of {0} and {1}"),
79  
80  	INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION(Kind.ERROR, 1014,
81  			"Incorrect number of arguments for function, {0} supplied but function takes {1}"),
82  
83  	INVALID_TYPE_FOR_SELECTION(Kind.ERROR, 1015,
84  			"Cannot perform selection on input data of type ''{0}''"),
85  
86  	RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN(Kind.ERROR, 1016,
87  			"Result of selection criteria is not boolean"),
88  
89  	BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST(Kind.ERROR, 1017,
90  			"Right operand for the 'between' operator has to be a two-element list"),
91  
92  	INVALID_PATTERN(Kind.ERROR, 1018,
93  			"Pattern is not valid ''{0}''"),
94  
95  	PROJECTION_NOT_SUPPORTED_ON_TYPE(Kind.ERROR, 1019,
96  			"Projection is not supported on the type ''{0}''"),
97  
98  	ARGLIST_SHOULD_NOT_BE_EVALUATED(Kind.ERROR, 1020,
99  			"The argument list of a lambda expression should never have getValue() called upon it"),
100 
101 	EXCEPTION_DURING_PROPERTY_READ(Kind.ERROR, 1021,
102 			"A problem occurred whilst attempting to access the property ''{0}'': ''{1}''"),
103 
104 	FUNCTION_REFERENCE_CANNOT_BE_INVOKED(Kind.ERROR, 1022,
105 			"The function ''{0}'' mapped to an object of type ''{1}'' which cannot be invoked"),
106 
107 	EXCEPTION_DURING_FUNCTION_CALL(Kind.ERROR, 1023,
108 			"A problem occurred whilst attempting to invoke the function ''{0}'': ''{1}''"),
109 
110 	ARRAY_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1024,
111 			"The array has ''{0}'' elements, index ''{1}'' is invalid"),
112 
113 	COLLECTION_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1025,
114 			"The collection has ''{0}'' elements, index ''{1}'' is invalid"),
115 
116 	STRING_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1026,
117 			"The string has ''{0}'' characters, index ''{1}'' is invalid"),
118 
119 	INDEXING_NOT_SUPPORTED_FOR_TYPE(Kind.ERROR, 1027,
120 			"Indexing into type ''{0}'' is not supported"),
121 
122 	INSTANCEOF_OPERATOR_NEEDS_CLASS_OPERAND(Kind.ERROR, 1028,
123 			"The operator 'instanceof' needs the right operand to be a class, not a ''{0}''"),
124 
125 	EXCEPTION_DURING_METHOD_INVOCATION(Kind.ERROR, 1029,
126 			"A problem occurred when trying to execute method ''{0}'' on object of type ''{1}'': ''{2}''"),
127 
128 	OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES(Kind.ERROR, 1030,
129 			"The operator ''{0}'' is not supported between objects of type ''{1}'' and ''{2}''"),
130 
131 	PROBLEM_LOCATING_METHOD(Kind.ERROR, 1031,
132 			"Problem locating method {0} on type {1}"),
133 
134 	SETVALUE_NOT_SUPPORTED(	Kind.ERROR, 1032,
135 			"setValue(ExpressionState, Object) not supported for ''{0}''"),
136 
137 	MULTIPLE_POSSIBLE_METHODS(Kind.ERROR, 1033,
138 			"Method call of ''{0}'' is ambiguous, supported type conversions allow multiple variants to match"),
139 
140 	EXCEPTION_DURING_PROPERTY_WRITE(Kind.ERROR, 1034,
141 			"A problem occurred whilst attempting to set the property ''{0}'': {1}"),
142 
143 	NOT_AN_INTEGER(Kind.ERROR, 1035,
144 			"The value ''{0}'' cannot be parsed as an int"),
145 
146 	NOT_A_LONG(Kind.ERROR, 1036,
147 			"The value ''{0}'' cannot be parsed as a long"),
148 
149 	INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1037,
150 			"First operand to matches operator must be a string. ''{0}'' is not"),
151 
152 	INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1038,
153 			"Second operand to matches operator must be a string. ''{0}'' is not"),
154 
155 	FUNCTION_MUST_BE_STATIC(Kind.ERROR, 1039,
156 			"Only static methods can be called via function references. " +
157 			"The method ''{0}'' referred to by name ''{1}'' is not static."),
158 
159 	NOT_A_REAL(Kind.ERROR, 1040,
160 			"The value ''{0}'' cannot be parsed as a double"),
161 
162 	MORE_INPUT(Kind.ERROR,1041,
163 			"After parsing a valid expression, there is still more data in the expression: ''{0}''"),
164 
165 	RIGHT_OPERAND_PROBLEM(Kind.ERROR, 1042,
166 			"Problem parsing right operand"),
167 
168 	NOT_EXPECTED_TOKEN(Kind.ERROR, 1043,
169 			"Unexpected token. Expected ''{0}'' but was ''{1}''"),
170 
171 	OOD(Kind.ERROR, 1044,
172 			"Unexpectedly ran out of input"),
173 
174 	NON_TERMINATING_DOUBLE_QUOTED_STRING(Kind.ERROR, 1045,
175 			"Cannot find terminating \" for string"),
176 
177 	NON_TERMINATING_QUOTED_STRING(Kind.ERROR, 1046,
178 			"Cannot find terminating ' for string"),
179 
180 	MISSING_LEADING_ZERO_FOR_NUMBER(Kind.ERROR, 1047,
181 			"A real number must be prefixed by zero, it cannot start with just ''.''"),
182 
183 	REAL_CANNOT_BE_LONG(Kind.ERROR, 1048,
184 			"Real number cannot be suffixed with a long (L or l) suffix"),
185 
186 	UNEXPECTED_DATA_AFTER_DOT(Kind.ERROR, 1049,
187 			"Unexpected data after ''.'': ''{0}''"),
188 
189 	MISSING_CONSTRUCTOR_ARGS(Kind.ERROR, 1050,
190 			"The arguments '(...)' for the constructor call are missing"),
191 
192 	RUN_OUT_OF_ARGUMENTS(Kind.ERROR, 1051,
193 			"Unexpected ran out of arguments"),
194 
195 	UNABLE_TO_GROW_COLLECTION(Kind.ERROR, 1052,
196 			"Unable to grow collection"),
197 
198 	UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE(Kind.ERROR, 1053,
199 			"Unable to grow collection: unable to determine list element type"),
200 
201 	UNABLE_TO_CREATE_LIST_FOR_INDEXING(Kind.ERROR, 1054,
202 			"Unable to dynamically create a List to replace a null value"),
203 
204 	UNABLE_TO_CREATE_MAP_FOR_INDEXING(Kind.ERROR, 1055,
205 			"Unable to dynamically create a Map to replace a null value"),
206 
207 	UNABLE_TO_DYNAMICALLY_CREATE_OBJECT(Kind.ERROR, 1056,
208 			"Unable to dynamically create instance of ''{0}'' to replace a null value"),
209 
210 	NO_BEAN_RESOLVER_REGISTERED(Kind.ERROR, 1057,
211 			"No bean resolver registered in the context to resolve access to bean ''{0}''"),
212 
213 	EXCEPTION_DURING_BEAN_RESOLUTION(Kind.ERROR, 1058,
214 			"A problem occurred when trying to resolve bean ''{0}'':''{1}''"),
215 
216 	INVALID_BEAN_REFERENCE(Kind.ERROR, 1059,
217 			"@ can only be followed by an identifier or a quoted name"),
218 
219 	TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION(Kind.ERROR, 1060,
220 			"Expected the type of the new array to be specified as a String but found ''{0}''"),
221 
222 	INCORRECT_ELEMENT_TYPE_FOR_ARRAY(Kind.ERROR, 1061,
223 			"The array of type ''{0}'' cannot have an element of type ''{1}'' inserted"),
224 
225 	MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED(Kind.ERROR, 1062,
226 			"Using an initializer to build a multi-dimensional array is not currently supported"),
227 
228 	MISSING_ARRAY_DIMENSION(Kind.ERROR, 1063,
229 			"A required array dimension has not been specified"),
230 
231 	INITIALIZER_LENGTH_INCORRECT(Kind.ERROR, 1064,
232 			"array initializer size does not match array dimensions"),
233 
234 	UNEXPECTED_ESCAPE_CHAR(Kind.ERROR, 1065, "unexpected escape character."),
235 
236 	OPERAND_NOT_INCREMENTABLE(Kind.ERROR, 1066,
237 			"the expression component ''{0}'' does not support increment"),
238 
239 	OPERAND_NOT_DECREMENTABLE(Kind.ERROR, 1067,
240 			"the expression component ''{0}'' does not support decrement"),
241 
242 	NOT_ASSIGNABLE(Kind.ERROR, 1068,
243 			"the expression component ''{0}'' is not assignable"),
244 
245 	MISSING_CHARACTER(Kind.ERROR, 1069,
246 			"missing expected character ''{0}''"),
247 
248 	LEFT_OPERAND_PROBLEM(Kind.ERROR, 1070,
249 			"Problem parsing left operand"),
250 
251 	MISSING_SELECTION_EXPRESSION(Kind.ERROR, 1071,
252 			"A required selection expression has not been specified"),
253 	
254 	EXCEPTION_RUNNING_COMPILED_EXPRESSION(Kind.ERROR,1072,
255 			"An exception occurred whilst evaluating a compiled expression");
256 
257 
258 	private final Kind kind;
259 
260 	private final int code;
261 
262 	private final String message;
263 
264 
265 	private SpelMessage(Kind kind, int code, String message) {
266 		this.kind = kind;
267 		this.code = code;
268 		this.message = message;
269 	}
270 
271 
272 	/**
273 	 * Produce a complete message including the prefix, the position (if known)
274 	 * and with the inserts applied to the message.
275 	 * @param pos the position (ignored and not included in the message if less than 0)
276 	 * @param inserts the inserts to put into the formatted message
277 	 * @return a formatted message
278 	 */
279 	public String formatMessage(int pos, Object... inserts) {
280 		StringBuilder formattedMessage = new StringBuilder();
281 		formattedMessage.append("EL").append(this.code);
282 		switch (this.kind) {
283 			case ERROR:
284 				formattedMessage.append("E");
285 				break;
286 		}
287 		formattedMessage.append(":");
288 		if (pos != -1) {
289 			formattedMessage.append("(pos ").append(pos).append("): ");
290 		}
291 		formattedMessage.append(MessageFormat.format(this.message, inserts));
292 		return formattedMessage.toString();
293 	}
294 
295 
296 	public static enum Kind { INFO, WARNING, ERROR }
297 
298 }