1 16 package org.apache.myfaces.el; 17 18 import java.io.StringReader ; 19 import java.util.List ; 20 21 import javax.faces.application.Application; 22 import javax.faces.component.UIComponent; 23 import javax.faces.context.FacesContext; 24 import javax.faces.el.EvaluationException; 25 import javax.faces.el.ReferenceSyntaxException; 26 import javax.servlet.jsp.el.ELException ; 27 import javax.servlet.jsp.el.FunctionMapper ; 28 import javax.servlet.jsp.el.VariableResolver ; 29 30 import org.apache.myfaces.util.StringUtils; 31 32 import org.apache.commons.el.ArraySuffix; 33 import org.apache.commons.el.BinaryOperatorExpression; 34 import org.apache.commons.el.Coercions; 35 import org.apache.commons.el.ComplexValue; 36 import org.apache.commons.el.ConditionalExpression; 37 import org.apache.commons.el.Expression; 38 import org.apache.commons.el.ExpressionString; 39 import org.apache.commons.el.FunctionInvocation; 40 import org.apache.commons.el.Literal; 41 import org.apache.commons.el.Logger; 42 import org.apache.commons.el.NamedValue; 43 import org.apache.commons.el.PropertySuffix; 44 import org.apache.commons.el.UnaryOperatorExpression; 45 import org.apache.commons.el.ValueSuffix; 46 import org.apache.commons.el.parser.ELParser; 47 import org.apache.commons.el.parser.ParseException; 48 import org.apache.commons.logging.Log; 49 import org.apache.commons.logging.LogFactory; 50 51 52 81 public class ELParserHelper 82 { 83 static final Log log = LogFactory.getLog(ELParserHelper.class); 84 public static final Logger LOGGER = new Logger(System.out); 85 86 private ELParserHelper() 87 { 88 } 90 91 95 public static Object parseExpression(String expressionString) 96 { 97 expressionString = toJspElExpression(expressionString); 98 99 ELParser parser = new ELParser(new StringReader (expressionString)); 100 try 101 { 102 Object expression = parser.ExpressionString(); 103 if (!(expression instanceof Expression) 104 && !(expression instanceof ExpressionString)) 105 { 106 throw new ReferenceSyntaxException("Invalid expression: '" 107 + expressionString 108 + "'. Parsed Expression of unexpected type " 109 + expression.getClass().getName()); 110 } 111 112 replaceSuffixes(expression); 113 114 return expression; 115 } 116 catch (ParseException e) 117 { 118 String msg = "Invalid expression: '" + expressionString + "'"; 119 log.debug(msg, e); 120 throw new ReferenceSyntaxException(msg, e); 121 } 122 } 123 124 131 static String toJspElExpression(String expressionString) 132 { 133 StringBuffer sb = new StringBuffer (expressionString.length()); 134 int remainsPos = 0; 135 136 for (int posOpenBrace = expressionString.indexOf('{'); posOpenBrace >= 0; 137 posOpenBrace = expressionString.indexOf('{', remainsPos)) 138 { 139 if (posOpenBrace > 0) 140 { 141 if( posOpenBrace-1 > remainsPos ) 142 sb.append(expressionString.substring(remainsPos, posOpenBrace - 1)); 143 144 if (expressionString.charAt(posOpenBrace - 1) == '$') 145 { 146 sb.append("${'${'}"); 147 remainsPos = posOpenBrace+1; 148 continue; 149 } 150 else if (expressionString.charAt(posOpenBrace - 1) == '#') 151 { 152 sb.append("${"); 173 int posCloseBrace = indexOfMatchingClosingBrace(expressionString, posOpenBrace); 174 sb.append(expressionString.substring(posOpenBrace + 1, posCloseBrace + 1)); 175 remainsPos = posCloseBrace + 1; 176 continue; 177 }else{ 179 if( posOpenBrace > remainsPos ) 180 sb.append( expressionString.charAt(posOpenBrace - 1) ); 181 } 182 } 183 184 sb.append('{'); 186 remainsPos = posOpenBrace + 1; 187 } 188 189 sb.append(expressionString.substring(remainsPos)); 190 191 return new String (sb.toString()); 193 } 194 195 private static int findQuote(String expressionString, int start) 196 { 197 int indexofSingleQuote = expressionString.indexOf('\'', start); 198 int indexofDoubleQuote = expressionString.indexOf('"', start); 199 return StringUtils.minIndex(indexofSingleQuote, indexofDoubleQuote); 200 } 201 202 212 private static int indexOfMatchingClosingBrace(String expressionString, 213 int indexofOpeningBrace) 214 { 215 int len = expressionString.length(); 216 int i = indexofOpeningBrace + 1; 217 218 for (;;) 220 { 221 if (i >= len) 222 { 223 throw new ReferenceSyntaxException( 224 "Missing closing brace. Expression: '" + expressionString 225 + "'"); 226 } 227 228 int indexofClosingBrace = expressionString.indexOf('}', i); 229 i = StringUtils.minIndex(indexofClosingBrace, findQuote( 230 expressionString, i)); 231 232 if (i < 0) 233 { 234 throw new ReferenceSyntaxException( 236 "Missing closing brace. Expression: '" + expressionString 237 + "'"); 238 } 239 240 if (i != indexofClosingBrace) 242 { 243 i = indexOfMatchingClosingQuote(expressionString, i) + 1; 244 if (i == 0) 245 { 246 throw new ReferenceSyntaxException( 248 "Missing closing quote. Expression: '" 249 + expressionString + "'"); 250 } 251 } 252 else 253 { 254 return i; 256 } 257 } 258 } 259 260 268 private static int indexOfMatchingClosingQuote(String expressionString, 269 int indexOfOpeningQuote) 270 { 271 char quote = expressionString.charAt(indexOfOpeningQuote); 272 for (int i = expressionString.indexOf(quote, indexOfOpeningQuote + 1); 273 i >= 0; i = expressionString.indexOf(quote, i + 1)) 274 { 275 if (!isEscaped(expressionString, i)) 276 { 277 return i; 278 } 279 } 280 281 return -1; 283 } 284 285 private static boolean isEscaped(String expressionString, int i) 286 { 287 int escapeCharCount = 0; 288 while ((--i >= 0) && (expressionString.charAt(i) == '\\')) 289 { 290 escapeCharCount++; 291 } 292 293 return (escapeCharCount % 2) != 0; 294 } 295 296 306 private static void replaceSuffixes(Object expression) 307 { 308 if (expression instanceof Expression) 309 { 310 replaceSuffixes((Expression) expression); 311 } 312 else if (expression instanceof ExpressionString) 313 { 314 replaceSuffixes((ExpressionString) expression); 315 } 316 else 317 { 318 throw new IllegalStateException ( 319 "Expression element of unknown class: " 320 + expression.getClass().getName()); 321 } 322 } 323 324 private static void replaceSuffixes(ExpressionString expressionString) 325 { 326 Object [] expressions = expressionString.getElements(); 327 for (int i = 0, len = expressions.length; i < len; i++) 328 { 329 Object expression = expressions[i]; 330 if (expression instanceof Expression) 331 { 332 replaceSuffixes((Expression) expression); 333 } 334 else if (expression instanceof ExpressionString) 335 { 336 replaceSuffixes((ExpressionString) expression); 337 } 338 else if (!(expression instanceof String )) 339 { 340 throw new IllegalStateException ( 341 "Expression element of unknown class: " 342 + expression.getClass().getName()); 343 } 344 } 346 } 347 348 static void replaceSuffixes(Expression expression) 349 { 350 if (expression instanceof BinaryOperatorExpression) 351 { 352 replaceSuffixes(((BinaryOperatorExpression) expression) 353 .getExpression()); 354 } 355 else if (expression instanceof ComplexValue) 356 { 357 replaceSuffixes((ComplexValue) expression); 358 } 359 else if (expression instanceof ConditionalExpression) 360 { 361 ConditionalExpression conditionalExpression = 362 (ConditionalExpression) expression; 363 replaceSuffixes(conditionalExpression.getTrueBranch()); 364 replaceSuffixes(conditionalExpression.getFalseBranch()); 365 } 366 else if (expression instanceof UnaryOperatorExpression) 367 { 368 replaceSuffixes(((UnaryOperatorExpression) expression) 369 .getExpression()); 370 } 371 372 else if (!(expression instanceof FunctionInvocation 374 || expression instanceof Literal || expression instanceof NamedValue)) 375 { 376 throw new IllegalStateException ( 377 "Expression element of unknown class: " 378 + expression.getClass().getName()); 379 } 380 } 381 382 private static void replaceSuffixes(ComplexValue complexValue) 383 { 384 Application application = FacesContext.getCurrentInstance() 385 .getApplication(); 386 387 List suffixes = complexValue.getSuffixes(); 388 for (int i = 0, len = suffixes.size(); i < len; i++) 389 { 390 ValueSuffix suffix = (ValueSuffix) suffixes.get(i); 391 if (suffix instanceof PropertySuffix) 392 { 393 if (suffix instanceof MyPropertySuffix) 394 { 395 throw new IllegalStateException ( 396 "Suffix is MyPropertySuffix and must not be"); 397 } 398 399 suffixes.set(i, new MyPropertySuffix((PropertySuffix) suffix, 400 application)); 401 } 402 else if (suffix instanceof ArraySuffix) 403 { 404 if (suffix instanceof MyArraySuffix) 405 { 406 throw new IllegalStateException ( 407 "Suffix is MyArraySuffix and must not be"); 408 } 409 410 suffixes.set(i, new MyArraySuffix((ArraySuffix) suffix, 411 application)); 412 } 413 else 414 { 415 throw new IllegalStateException ("Unknown suffix class: " 416 + suffix.getClass().getName()); 417 } 418 } 419 } 420 421 private static Integer coerceToIntegerWrapper(Object base, Object index) 422 throws EvaluationException, ELException 423 { 424 Integer integer = Coercions.coerceToInteger(index, LOGGER); 425 if (integer != null) 426 { 427 return integer; 428 } 429 throw new ReferenceSyntaxException( 430 "Cannot convert index to int for base " + base.getClass().getName() 431 + " and index " + index); 432 } 433 434 446 public static Integer toIndex(Object base, Object index) 447 throws ELException , EvaluationException 448 { 449 if ((base instanceof List ) || (base.getClass().isArray())) 450 { 451 return coerceToIntegerWrapper(base, index); 452 } 453 if (base instanceof UIComponent) 454 { 455 try 456 { 457 return coerceToIntegerWrapper(base, index); 458 } 459 catch (Throwable t) 460 { 461 return null; 463 } 464 } 465 466 return null; 468 } 469 470 473 public static class MyArraySuffix extends ArraySuffix 474 { 475 private Application _application; 476 477 public MyArraySuffix(ArraySuffix arraySuffix, Application application) 478 { 479 super(arraySuffix.getIndex()); 480 replaceSuffixes(getIndex()); 481 _application = application; 482 } 483 484 488 public Object evaluate(Object base, VariableResolver variableResolver, 489 FunctionMapper functions, Logger logger) 490 throws ELException 491 { 492 if (base == null) 494 { 495 return null; 496 } 497 498 Object indexVal = getIndex().evaluate(variableResolver, functions, 500 logger); 501 if (indexVal == null) 502 { 503 return null; 504 } 505 506 Integer index = toIndex(base, indexVal); 507 if (index == null) 508 { 509 return _application.getPropertyResolver().getValue(base, 510 indexVal); 511 } 512 else 513 { 514 return _application.getPropertyResolver().getValue(base, 515 index.intValue()); 516 } 517 } 518 } 519 520 public static class MyPropertySuffix extends PropertySuffix 521 { 522 private Application _application; 523 524 public MyPropertySuffix(PropertySuffix propertySuffix, 525 Application application) 526 { 527 super(propertySuffix.getName()); 528 _application = application; 529 } 530 531 535 public Object evaluate(Object base, VariableResolver variableResolver, 536 FunctionMapper functions, Logger logger) 537 throws ELException 538 { 539 if (base == null) 541 { 542 return null; 543 } 544 545 String indexVal = getName(); 547 if (indexVal == null) 548 { 549 return null; 550 } 551 552 Integer index = toIndex(base, indexVal); 553 if (index == null) 554 { 555 return _application.getPropertyResolver().getValue(base, 556 indexVal); 557 } 558 else 559 { 560 return _application.getPropertyResolver().getValue(base, 561 index.intValue()); 562 } 563 } 564 } 565 } | Popular Tags |