1 55 56 package org.apache.commons.el; 57 58 import java.io.Reader ; 59 import java.io.StringReader ; 60 import java.text.MessageFormat ; 61 import java.util.Collections ; 62 import java.util.HashMap ; 63 import java.util.Map ; 64 import javax.servlet.jsp.el.ExpressionEvaluator ; 65 import javax.servlet.jsp.el.ELException ; 66 import javax.servlet.jsp.el.VariableResolver ; 67 import javax.servlet.jsp.el.FunctionMapper ; 68 import org.apache.commons.el.parser.ELParser; 69 import org.apache.commons.el.parser.ParseException; 70 import org.apache.commons.el.parser.Token; 71 import org.apache.commons.el.parser.TokenMgrError; 72 73 123 124 public class ExpressionEvaluatorImpl 125 extends ExpressionEvaluator 126 { 127 131 135 137 static Map sCachedExpressionStrings = 138 Collections.synchronizedMap (new HashMap ()); 139 140 142 static Map sCachedExpectedTypes = new HashMap (); 143 144 145 static Logger sLogger = new Logger (System.out); 146 147 148 boolean mBypassCache; 149 150 155 public ExpressionEvaluatorImpl () { } 156 157 164 public ExpressionEvaluatorImpl (boolean pBypassCache) 165 { 166 mBypassCache = pBypassCache; 167 } 168 169 184 public Object evaluate (String pExpressionString, 185 Class pExpectedType, 186 VariableResolver pResolver, 187 FunctionMapper functions) 188 throws ELException 189 { 190 return evaluate (pExpressionString, 191 pExpectedType, 192 pResolver, 193 functions, 194 sLogger); 195 } 196 197 219 public javax.servlet.jsp.el.Expression parseExpression(String expression, 220 Class expectedType, 221 FunctionMapper fMapper) 222 throws ELException 223 { 224 parseExpressionString(expression); 226 227 return new JSTLExpression(this, expression, expectedType, fMapper); 229 } 230 231 236 Object evaluate (String pExpressionString, 237 Class pExpectedType, 238 VariableResolver pResolver, 239 FunctionMapper functions, 240 Logger pLogger) 241 throws ELException 242 { 243 if (pExpressionString == null) { 245 throw new ELException 246 (Constants.NULL_EXPRESSION_STRING); 247 } 248 249 Object parsedValue = parseExpressionString (pExpressionString); 251 252 if (parsedValue instanceof String ) { 254 String strValue = (String ) parsedValue; 256 return convertStaticValueToExpectedType (strValue, 257 pExpectedType, 258 pLogger); 259 } 260 261 else if (parsedValue instanceof Expression) { 262 Object value = 264 ((Expression) parsedValue).evaluate (pResolver, 265 functions, 266 pLogger); 267 return convertToExpectedType (value, 268 pExpectedType, 269 pLogger); 270 } 271 272 else if (parsedValue instanceof ExpressionString) { 273 String strValue = 275 ((ExpressionString) parsedValue).evaluate (pResolver, 276 functions, 277 pLogger); 278 return convertToExpectedType (strValue, 279 pExpectedType, 280 pLogger); 281 } 282 283 else { 284 return null; 286 } 287 } 288 289 297 public Object parseExpressionString (String pExpressionString) 298 throws ELException 299 { 300 if (pExpressionString.length () == 0) { 302 return ""; 303 } 304 305 Object ret = 307 mBypassCache ? 308 null : 309 sCachedExpressionStrings.get (pExpressionString); 310 311 if (ret == null) { 312 Reader r = new StringReader (pExpressionString); 314 ELParser parser = new ELParser (r); 315 try { 316 ret = parser.ExpressionString (); 317 sCachedExpressionStrings.put (pExpressionString, ret); 318 } 319 catch (ParseException exc) { 320 throw new ELException 321 (formatParseException (pExpressionString, 322 exc)); 323 } 324 catch (TokenMgrError exc) { 325 throw new ELException (exc.getMessage ()); 330 } 331 } 332 return ret; 333 } 334 335 340 Object convertToExpectedType (Object pValue, 341 Class pExpectedType, 342 Logger pLogger) 343 throws ELException 344 { 345 return Coercions.coerce (pValue, 346 pExpectedType, 347 pLogger); 348 } 349 350 356 Object convertStaticValueToExpectedType (String pValue, 357 Class pExpectedType, 358 Logger pLogger) 359 throws ELException 360 { 361 if (pExpectedType == String .class || 363 pExpectedType == Object .class) { 364 return pValue; 365 } 366 367 Map valueByString = getOrCreateExpectedTypeMap (pExpectedType); 369 if (!mBypassCache && 370 valueByString.containsKey (pValue)) { 371 return valueByString.get (pValue); 372 } 373 else { 374 Object ret = Coercions.coerce (pValue, pExpectedType, pLogger); 376 valueByString.put (pValue, ret); 377 return ret; 378 } 379 } 380 381 387 static Map getOrCreateExpectedTypeMap (Class pExpectedType) 388 { 389 synchronized (sCachedExpectedTypes) { 390 Map ret = (Map ) sCachedExpectedTypes.get (pExpectedType); 391 if (ret == null) { 392 ret = Collections.synchronizedMap (new HashMap ()); 393 sCachedExpectedTypes.put (pExpectedType, ret); 394 } 395 return ret; 396 } 397 } 398 399 407 static String formatParseException (String pExpressionString, 408 ParseException pExc) 409 { 410 StringBuffer expectedBuf = new StringBuffer (); 412 int maxSize = 0; 413 boolean printedOne = false; 414 415 if (pExc.expectedTokenSequences == null) 416 return pExc.toString(); 417 418 for (int i = 0; i < pExc.expectedTokenSequences.length; i++) { 419 if (maxSize < pExc.expectedTokenSequences [i].length) { 420 maxSize = pExc.expectedTokenSequences [i].length; 421 } 422 for (int j = 0; j < pExc.expectedTokenSequences [i].length; j++) { 423 if (printedOne) { 424 expectedBuf.append (", "); 425 } 426 expectedBuf.append 427 (pExc.tokenImage [pExc.expectedTokenSequences [i] [j]]); 428 printedOne = true; 429 } 430 } 431 String expected = expectedBuf.toString (); 432 433 StringBuffer encounteredBuf = new StringBuffer (); 435 Token tok = pExc.currentToken.next; 436 for (int i = 0; i < maxSize; i++) { 437 if (i != 0) encounteredBuf.append (" "); 438 if (tok.kind == 0) { 439 encounteredBuf.append (pExc.tokenImage [0]); 440 break; 441 } 442 encounteredBuf.append (addEscapes (tok.image)); 443 tok = tok.next; 444 } 445 String encountered = encounteredBuf.toString (); 446 447 return MessageFormat.format 449 (Constants.PARSE_EXCEPTION, 450 new Object [] { 451 expected, 452 encountered, 453 }); 454 } 455 456 463 static String addEscapes (String str) 464 { 465 StringBuffer retval = new StringBuffer (); 466 char ch; 467 for (int i = 0; i < str.length (); i++) { 468 switch (str.charAt (i)) { 469 case 0 : 470 continue; 471 case '\b': 472 retval.append ("\\b"); 473 continue; 474 case '\t': 475 retval.append ("\\t"); 476 continue; 477 case '\n': 478 retval.append ("\\n"); 479 continue; 480 case '\f': 481 retval.append ("\\f"); 482 continue; 483 case '\r': 484 retval.append ("\\r"); 485 continue; 486 default: 487 if ((ch = str.charAt (i)) < 0x20 || ch > 0x7e) { 488 String s = "0000" + Integer.toString (ch, 16); 489 retval.append ("\\u" + s.substring (s.length () - 4, s.length ())); 490 } 491 else { 492 retval.append (ch); 493 } 494 continue; 495 } 496 } 497 return retval.toString (); 498 } 499 500 508 public String parseAndRender (String pExpressionString) 509 throws ELException 510 { 511 Object val = parseExpressionString (pExpressionString); 512 if (val instanceof String ) { 513 return (String ) val; 514 } 515 else if (val instanceof Expression) { 516 return "${" + ((Expression) val).getExpressionString () + "}"; 517 } 518 else if (val instanceof ExpressionString) { 519 return ((ExpressionString) val).getExpressionString (); 520 } 521 else { 522 return ""; 523 } 524 } 525 526 530 private class JSTLExpression 531 extends javax.servlet.jsp.el.Expression 532 { 533 private ExpressionEvaluatorImpl evaluator; 534 private String expression; 535 private Class expectedType; 536 private FunctionMapper fMapper; 537 538 public JSTLExpression(ExpressionEvaluatorImpl evaluator, String expression, 539 Class expectedType, FunctionMapper fMapper) 540 { 541 this.evaluator = evaluator; 542 this.expression = expression; 543 this.expectedType = expectedType; 544 this.fMapper = fMapper; 545 } 546 547 public Object evaluate( VariableResolver vResolver ) 548 throws ELException 549 { 550 return evaluator.evaluate(this.expression, 551 this.expectedType, 552 vResolver, 553 this.fMapper); 554 } 555 } 556 557 559 } 560 | Popular Tags |