1 16 17 package org.apache.taglibs.standard.lang.jstl; 18 19 import java.io.Reader ; 20 import java.io.StringReader ; 21 import java.text.MessageFormat ; 22 import java.util.Collections ; 23 import java.util.HashMap ; 24 import java.util.Map ; 25 26 import org.apache.taglibs.standard.lang.jstl.parser.ELParser; 27 import org.apache.taglibs.standard.lang.jstl.parser.ParseException; 28 import org.apache.taglibs.standard.lang.jstl.parser.Token; 29 import org.apache.taglibs.standard.lang.jstl.parser.TokenMgrError; 30 31 81 82 public class ELEvaluator 83 { 84 88 92 94 static Map sCachedExpressionStrings = 95 Collections.synchronizedMap (new HashMap ()); 96 97 99 static Map sCachedExpectedTypes = new HashMap (); 100 101 102 static Logger sLogger = new Logger (System.out); 103 104 105 VariableResolver mResolver; 106 107 108 boolean mBypassCache; 109 110 119 public ELEvaluator (VariableResolver pResolver) 120 { 121 mResolver = pResolver; 122 } 123 124 136 public ELEvaluator (VariableResolver pResolver, 137 boolean pBypassCache) 138 { 139 mResolver = pResolver; 140 mBypassCache = pBypassCache; 141 } 142 143 156 public Object evaluate (String pExpressionString, 157 Object pContext, 158 Class pExpectedType, 159 Map functions, 160 String defaultPrefix) 161 throws ELException 162 { 163 return evaluate (pExpressionString, 164 pContext, 165 pExpectedType, 166 functions, 167 defaultPrefix, 168 sLogger); 169 } 170 171 176 Object evaluate (String pExpressionString, 177 Object pContext, 178 Class pExpectedType, 179 Map functions, 180 String defaultPrefix, 181 Logger pLogger) 182 throws ELException 183 { 184 if (pExpressionString == null) { 186 throw new ELException 187 (Constants.NULL_EXPRESSION_STRING); 188 } 189 190 Object parsedValue = parseExpressionString (pExpressionString); 192 193 if (parsedValue instanceof String ) { 195 String strValue = (String ) parsedValue; 197 return convertStaticValueToExpectedType (strValue, 198 pExpectedType, 199 pLogger); 200 } 201 202 else if (parsedValue instanceof Expression) { 203 Object value = 205 ((Expression) parsedValue).evaluate (pContext, 206 mResolver, 207 functions, 208 defaultPrefix, 209 pLogger); 210 return convertToExpectedType (value, 211 pExpectedType, 212 pLogger); 213 } 214 215 else if (parsedValue instanceof ExpressionString) { 216 String strValue = 218 ((ExpressionString) parsedValue).evaluate (pContext, 219 mResolver, 220 functions, 221 defaultPrefix, 222 pLogger); 223 return convertToExpectedType (strValue, 224 pExpectedType, 225 pLogger); 226 } 227 228 else { 229 return null; 231 } 232 } 233 234 242 public Object parseExpressionString (String pExpressionString) 243 throws ELException 244 { 245 if (pExpressionString.length () == 0) { 247 return ""; 248 } 249 250 Object ret = 252 mBypassCache ? 253 null : 254 sCachedExpressionStrings.get (pExpressionString); 255 256 if (ret == null) { 257 Reader r = new StringReader (pExpressionString); 259 ELParser parser = new ELParser (r); 260 try { 261 ret = parser.ExpressionString (); 262 sCachedExpressionStrings.put (pExpressionString, ret); 263 } 264 catch (ParseException exc) { 265 throw new ELException 266 (formatParseException (pExpressionString, 267 exc)); 268 } 269 catch (TokenMgrError exc) { 270 throw new ELException (exc.getMessage ()); 275 } 276 } 277 return ret; 278 } 279 280 285 Object convertToExpectedType (Object pValue, 286 Class pExpectedType, 287 Logger pLogger) 288 throws ELException 289 { 290 return Coercions.coerce (pValue, 291 pExpectedType, 292 pLogger); 293 } 294 295 301 Object convertStaticValueToExpectedType (String pValue, 302 Class pExpectedType, 303 Logger pLogger) 304 throws ELException 305 { 306 if (pExpectedType == String .class || 308 pExpectedType == Object .class) { 309 return pValue; 310 } 311 312 Map valueByString = getOrCreateExpectedTypeMap (pExpectedType); 314 if (!mBypassCache && 315 valueByString.containsKey (pValue)) { 316 return valueByString.get (pValue); 317 } 318 else { 319 Object ret = Coercions.coerce (pValue, pExpectedType, pLogger); 321 valueByString.put (pValue, ret); 322 return ret; 323 } 324 } 325 326 332 static Map getOrCreateExpectedTypeMap (Class pExpectedType) 333 { 334 synchronized (sCachedExpectedTypes) { 335 Map ret = (Map ) sCachedExpectedTypes.get (pExpectedType); 336 if (ret == null) { 337 ret = Collections.synchronizedMap (new HashMap ()); 338 sCachedExpectedTypes.put (pExpectedType, ret); 339 } 340 return ret; 341 } 342 } 343 344 352 static String formatParseException (String pExpressionString, 353 ParseException pExc) 354 { 355 StringBuffer expectedBuf = new StringBuffer (); 357 int maxSize = 0; 358 boolean printedOne = false; 359 360 if (pExc.expectedTokenSequences == null) 361 return pExc.toString(); 362 363 for (int i = 0; i < pExc.expectedTokenSequences.length; i++) { 364 if (maxSize < pExc.expectedTokenSequences [i].length) { 365 maxSize = pExc.expectedTokenSequences [i].length; 366 } 367 for (int j = 0; j < pExc.expectedTokenSequences [i].length; j++) { 368 if (printedOne) { 369 expectedBuf.append (", "); 370 } 371 expectedBuf.append 372 (pExc.tokenImage [pExc.expectedTokenSequences [i] [j]]); 373 printedOne = true; 374 } 375 } 376 String expected = expectedBuf.toString (); 377 378 StringBuffer encounteredBuf = new StringBuffer (); 380 Token tok = pExc.currentToken.next; 381 for (int i = 0; i < maxSize; i++) { 382 if (i != 0) encounteredBuf.append (" "); 383 if (tok.kind == 0) { 384 encounteredBuf.append (pExc.tokenImage [0]); 385 break; 386 } 387 encounteredBuf.append (addEscapes (tok.image)); 388 tok = tok.next; 389 } 390 String encountered = encounteredBuf.toString (); 391 392 return MessageFormat.format 394 (Constants.PARSE_EXCEPTION, 395 new Object [] { 396 expected, 397 encountered, 398 }); 399 } 400 401 408 static String addEscapes (String str) 409 { 410 StringBuffer retval = new StringBuffer (); 411 char ch; 412 for (int i = 0; i < str.length (); i++) { 413 switch (str.charAt (i)) { 414 case 0 : 415 continue; 416 case '\b': 417 retval.append ("\\b"); 418 continue; 419 case '\t': 420 retval.append ("\\t"); 421 continue; 422 case '\n': 423 retval.append ("\\n"); 424 continue; 425 case '\f': 426 retval.append ("\\f"); 427 continue; 428 case '\r': 429 retval.append ("\\r"); 430 continue; 431 default: 432 if ((ch = str.charAt (i)) < 0x20 || ch > 0x7e) { 433 String s = "0000" + Integer.toString (ch, 16); 434 retval.append ("\\u" + s.substring (s.length () - 4, s.length ())); 435 } 436 else { 437 retval.append (ch); 438 } 439 continue; 440 } 441 } 442 return retval.toString (); 443 } 444 445 453 public String parseAndRender (String pExpressionString) 454 throws ELException 455 { 456 Object val = parseExpressionString (pExpressionString); 457 if (val instanceof String ) { 458 return (String ) val; 459 } 460 else if (val instanceof Expression) { 461 return "${" + ((Expression) val).getExpressionString () + "}"; 462 } 463 else if (val instanceof ExpressionString) { 464 return ((ExpressionString) val).getExpressionString (); 465 } 466 else { 467 return ""; 468 } 469 } 470 471 473 } 474 | Popular Tags |