001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.expression.spel; 018 019import java.text.MessageFormat; 020 021/** 022 * Contains all the messages that can be produced by the Spring Expression Language. 023 * Each message has a kind (info, warn, error) and a code number. Tests can be written to 024 * expect particular code numbers rather than particular text, enabling the message text 025 * to more easily be modified and the tests to run successfully in different locales. 026 * 027 * <p>When a message is formatted, it will have this kind of form, capturing the prefix 028 * and the error kind: 029 * 030 * <pre class="code">EL1004E: Type cannot be found 'String'</pre> 031 * 032 * @author Andy Clement 033 * @author Juergen Hoeller 034 * @since 3.0 035 */ 036public enum SpelMessage { 037 038 TYPE_CONVERSION_ERROR(Kind.ERROR, 1001, 039 "Type conversion problem, cannot convert from {0} to {1}"), 040 041 CONSTRUCTOR_NOT_FOUND(Kind.ERROR, 1002, 042 "Constructor call: No suitable constructor found on type {0} for arguments {1}"), 043 044 CONSTRUCTOR_INVOCATION_PROBLEM(Kind.ERROR, 1003, 045 "A problem occurred whilst attempting to construct an object of type ''{0}'' using arguments ''{1}''"), 046 047 METHOD_NOT_FOUND(Kind.ERROR, 1004, 048 "Method call: Method {0} cannot be found on type {1}"), 049 050 TYPE_NOT_FOUND(Kind.ERROR, 1005, 051 "Type cannot be found ''{0}''"), 052 053 FUNCTION_NOT_DEFINED(Kind.ERROR, 1006, 054 "Function ''{0}'' could not be found"), 055 056 PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL(Kind.ERROR, 1007, 057 "Property or field ''{0}'' cannot be found on null"), 058 059 PROPERTY_OR_FIELD_NOT_READABLE(Kind.ERROR, 1008, 060 "Property or field ''{0}'' cannot be found on object of type ''{1}'' - maybe not public or not valid?"), 061 062 PROPERTY_OR_FIELD_NOT_WRITABLE_ON_NULL(Kind.ERROR, 1009, 063 "Property or field ''{0}'' cannot be set on null"), 064 065 PROPERTY_OR_FIELD_NOT_WRITABLE(Kind.ERROR, 1010, 066 "Property or field ''{0}'' cannot be set on object of type ''{1}'' - maybe not public or not writable?"), 067 068 METHOD_CALL_ON_NULL_OBJECT_NOT_ALLOWED(Kind.ERROR, 1011, 069 "Method call: Attempted to call method {0} on null context object"), 070 071 CANNOT_INDEX_INTO_NULL_VALUE(Kind.ERROR, 1012, 072 "Cannot index into a null value"), 073 074 NOT_COMPARABLE(Kind.ERROR, 1013, 075 "Cannot compare instances of {0} and {1}"), 076 077 INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION(Kind.ERROR, 1014, 078 "Incorrect number of arguments for function, {0} supplied but function takes {1}"), 079 080 INVALID_TYPE_FOR_SELECTION(Kind.ERROR, 1015, 081 "Cannot perform selection on input data of type ''{0}''"), 082 083 RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN(Kind.ERROR, 1016, 084 "Result of selection criteria is not boolean"), 085 086 BETWEEN_RIGHT_OPERAND_MUST_BE_TWO_ELEMENT_LIST(Kind.ERROR, 1017, 087 "Right operand for the 'between' operator has to be a two-element list"), 088 089 INVALID_PATTERN(Kind.ERROR, 1018, 090 "Pattern is not valid ''{0}''"), 091 092 PROJECTION_NOT_SUPPORTED_ON_TYPE(Kind.ERROR, 1019, 093 "Projection is not supported on the type ''{0}''"), 094 095 ARGLIST_SHOULD_NOT_BE_EVALUATED(Kind.ERROR, 1020, 096 "The argument list of a lambda expression should never have getValue() called upon it"), 097 098 EXCEPTION_DURING_PROPERTY_READ(Kind.ERROR, 1021, 099 "A problem occurred whilst attempting to access the property ''{0}'': ''{1}''"), 100 101 FUNCTION_REFERENCE_CANNOT_BE_INVOKED(Kind.ERROR, 1022, 102 "The function ''{0}'' mapped to an object of type ''{1}'' which cannot be invoked"), 103 104 EXCEPTION_DURING_FUNCTION_CALL(Kind.ERROR, 1023, 105 "A problem occurred whilst attempting to invoke the function ''{0}'': ''{1}''"), 106 107 ARRAY_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1024, 108 "The array has ''{0}'' elements, index ''{1}'' is invalid"), 109 110 COLLECTION_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1025, 111 "The collection has ''{0}'' elements, index ''{1}'' is invalid"), 112 113 STRING_INDEX_OUT_OF_BOUNDS(Kind.ERROR, 1026, 114 "The string has ''{0}'' characters, index ''{1}'' is invalid"), 115 116 INDEXING_NOT_SUPPORTED_FOR_TYPE(Kind.ERROR, 1027, 117 "Indexing into type ''{0}'' is not supported"), 118 119 INSTANCEOF_OPERATOR_NEEDS_CLASS_OPERAND(Kind.ERROR, 1028, 120 "The operator 'instanceof' needs the right operand to be a class, not a ''{0}''"), 121 122 EXCEPTION_DURING_METHOD_INVOCATION(Kind.ERROR, 1029, 123 "A problem occurred when trying to execute method ''{0}'' on object of type ''{1}'': ''{2}''"), 124 125 OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES(Kind.ERROR, 1030, 126 "The operator ''{0}'' is not supported between objects of type ''{1}'' and ''{2}''"), 127 128 PROBLEM_LOCATING_METHOD(Kind.ERROR, 1031, 129 "Problem locating method {0} on type {1}"), 130 131 SETVALUE_NOT_SUPPORTED( Kind.ERROR, 1032, 132 "setValue(ExpressionState, Object) not supported for ''{0}''"), 133 134 MULTIPLE_POSSIBLE_METHODS(Kind.ERROR, 1033, 135 "Method call of ''{0}'' is ambiguous, supported type conversions allow multiple variants to match"), 136 137 EXCEPTION_DURING_PROPERTY_WRITE(Kind.ERROR, 1034, 138 "A problem occurred whilst attempting to set the property ''{0}'': {1}"), 139 140 NOT_AN_INTEGER(Kind.ERROR, 1035, 141 "The value ''{0}'' cannot be parsed as an int"), 142 143 NOT_A_LONG(Kind.ERROR, 1036, 144 "The value ''{0}'' cannot be parsed as a long"), 145 146 INVALID_FIRST_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1037, 147 "First operand to matches operator must be a string. ''{0}'' is not"), 148 149 INVALID_SECOND_OPERAND_FOR_MATCHES_OPERATOR(Kind.ERROR, 1038, 150 "Second operand to matches operator must be a string. ''{0}'' is not"), 151 152 FUNCTION_MUST_BE_STATIC(Kind.ERROR, 1039, 153 "Only static methods can be called via function references. " + 154 "The method ''{0}'' referred to by name ''{1}'' is not static."), 155 156 NOT_A_REAL(Kind.ERROR, 1040, 157 "The value ''{0}'' cannot be parsed as a double"), 158 159 MORE_INPUT(Kind.ERROR, 1041, 160 "After parsing a valid expression, there is still more data in the expression: ''{0}''"), 161 162 RIGHT_OPERAND_PROBLEM(Kind.ERROR, 1042, 163 "Problem parsing right operand"), 164 165 NOT_EXPECTED_TOKEN(Kind.ERROR, 1043, 166 "Unexpected token. Expected ''{0}'' but was ''{1}''"), 167 168 OOD(Kind.ERROR, 1044, 169 "Unexpectedly ran out of input"), 170 171 NON_TERMINATING_DOUBLE_QUOTED_STRING(Kind.ERROR, 1045, 172 "Cannot find terminating \" for string"), 173 174 NON_TERMINATING_QUOTED_STRING(Kind.ERROR, 1046, 175 "Cannot find terminating '' for string"), 176 177 MISSING_LEADING_ZERO_FOR_NUMBER(Kind.ERROR, 1047, 178 "A real number must be prefixed by zero, it cannot start with just ''.''"), 179 180 REAL_CANNOT_BE_LONG(Kind.ERROR, 1048, 181 "Real number cannot be suffixed with a long (L or l) suffix"), 182 183 UNEXPECTED_DATA_AFTER_DOT(Kind.ERROR, 1049, 184 "Unexpected data after ''.'': ''{0}''"), 185 186 MISSING_CONSTRUCTOR_ARGS(Kind.ERROR, 1050, 187 "The arguments '(...)' for the constructor call are missing"), 188 189 RUN_OUT_OF_ARGUMENTS(Kind.ERROR, 1051, 190 "Unexpectedly ran out of arguments"), 191 192 UNABLE_TO_GROW_COLLECTION(Kind.ERROR, 1052, 193 "Unable to grow collection"), 194 195 UNABLE_TO_GROW_COLLECTION_UNKNOWN_ELEMENT_TYPE(Kind.ERROR, 1053, 196 "Unable to grow collection: unable to determine list element type"), 197 198 UNABLE_TO_CREATE_LIST_FOR_INDEXING(Kind.ERROR, 1054, 199 "Unable to dynamically create a List to replace a null value"), 200 201 UNABLE_TO_CREATE_MAP_FOR_INDEXING(Kind.ERROR, 1055, 202 "Unable to dynamically create a Map to replace a null value"), 203 204 UNABLE_TO_DYNAMICALLY_CREATE_OBJECT(Kind.ERROR, 1056, 205 "Unable to dynamically create instance of ''{0}'' to replace a null value"), 206 207 NO_BEAN_RESOLVER_REGISTERED(Kind.ERROR, 1057, 208 "No bean resolver registered in the context to resolve access to bean ''{0}''"), 209 210 EXCEPTION_DURING_BEAN_RESOLUTION(Kind.ERROR, 1058, 211 "A problem occurred when trying to resolve bean ''{0}'':''{1}''"), 212 213 INVALID_BEAN_REFERENCE(Kind.ERROR, 1059, 214 "@ or & can only be followed by an identifier or a quoted name"), 215 216 TYPE_NAME_EXPECTED_FOR_ARRAY_CONSTRUCTION(Kind.ERROR, 1060, 217 "Expected the type of the new array to be specified as a String but found ''{0}''"), 218 219 INCORRECT_ELEMENT_TYPE_FOR_ARRAY(Kind.ERROR, 1061, 220 "The array of type ''{0}'' cannot have an element of type ''{1}'' inserted"), 221 222 MULTIDIM_ARRAY_INITIALIZER_NOT_SUPPORTED(Kind.ERROR, 1062, 223 "Using an initializer to build a multi-dimensional array is not currently supported"), 224 225 MISSING_ARRAY_DIMENSION(Kind.ERROR, 1063, 226 "A required array dimension has not been specified"), 227 228 INITIALIZER_LENGTH_INCORRECT(Kind.ERROR, 1064, 229 "Array initializer size does not match array dimensions"), 230 231 UNEXPECTED_ESCAPE_CHAR(Kind.ERROR, 1065, 232 "Unexpected escape character"), 233 234 OPERAND_NOT_INCREMENTABLE(Kind.ERROR, 1066, 235 "The expression component ''{0}'' does not support increment"), 236 237 OPERAND_NOT_DECREMENTABLE(Kind.ERROR, 1067, 238 "The expression component ''{0}'' does not support decrement"), 239 240 NOT_ASSIGNABLE(Kind.ERROR, 1068, 241 "The expression component ''{0}'' is not assignable"), 242 243 MISSING_CHARACTER(Kind.ERROR, 1069, 244 "Missing expected character ''{0}''"), 245 246 LEFT_OPERAND_PROBLEM(Kind.ERROR, 1070, 247 "Problem parsing left operand"), 248 249 MISSING_SELECTION_EXPRESSION(Kind.ERROR, 1071, 250 "A required selection expression has not been specified"), 251 252 /** @since 4.1 */ 253 EXCEPTION_RUNNING_COMPILED_EXPRESSION(Kind.ERROR, 1072, 254 "An exception occurred whilst evaluating a compiled expression"), 255 256 /** @since 4.3.17 */ 257 FLAWED_PATTERN(Kind.ERROR, 1073, 258 "Failed to efficiently evaluate pattern ''{0}'': consider redesigning it"); 259 260 261 private final Kind kind; 262 263 private final int code; 264 265 private final String message; 266 267 268 SpelMessage(Kind kind, int code, String message) { 269 this.kind = kind; 270 this.code = code; 271 this.message = message; 272 } 273 274 275 /** 276 * Produce a complete message including the prefix and with the inserts 277 * applied to the message. 278 * @param inserts the inserts to put into the formatted message 279 * @return a formatted message 280 * @since 4.3.5 281 */ 282 public String formatMessage(Object... inserts) { 283 StringBuilder formattedMessage = new StringBuilder(); 284 formattedMessage.append("EL").append(this.code); 285 switch (this.kind) { 286 case ERROR: 287 formattedMessage.append("E"); 288 break; 289 } 290 formattedMessage.append(": "); 291 formattedMessage.append(MessageFormat.format(this.message, inserts)); 292 return formattedMessage.toString(); 293 } 294 295 296 /** 297 * Message kinds. 298 */ 299 public enum Kind { INFO, WARNING, ERROR } 300 301}