1 16 package org.apache.myfaces.el; 17 18 import java.lang.reflect.Method ; 19 import java.util.List ; 20 import java.util.Map ; 21 22 import javax.faces.application.Application; 23 import javax.faces.component.StateHolder; 24 import javax.faces.context.ExternalContext; 25 import javax.faces.context.FacesContext; 26 import javax.faces.el.EvaluationException; 27 import javax.faces.el.PropertyNotFoundException; 28 import javax.faces.el.PropertyResolver; 29 import javax.faces.el.ReferenceSyntaxException; 30 import javax.faces.el.ValueBinding; 31 import javax.servlet.jsp.el.ELException ; 32 import javax.servlet.jsp.el.FunctionMapper ; 33 import javax.servlet.jsp.el.VariableResolver ; 34 35 import org.apache.myfaces.config.RuntimeConfig; 36 import org.apache.myfaces.config.element.ManagedBean; 37 import org.apache.myfaces.util.BiLevelCacheMap; 38 39 import org.apache.commons.el.ArraySuffix; 40 import org.apache.commons.el.Coercions; 41 import org.apache.commons.el.ComplexValue; 42 import org.apache.commons.el.ConditionalExpression; 43 import org.apache.commons.el.Expression; 44 import org.apache.commons.el.ExpressionString; 45 import org.apache.commons.el.NamedValue; 46 import org.apache.commons.el.PropertySuffix; 47 import org.apache.commons.el.ValueSuffix; 48 import org.apache.commons.logging.Log; 49 import org.apache.commons.logging.LogFactory; 50 51 52 136 public class ValueBindingImpl extends ValueBinding implements StateHolder 137 { 138 140 static final Log log = LogFactory.getLog(ValueBindingImpl.class); 141 142 146 protected static FunctionMapper s_functionMapper = new FunctionMapper () 147 { 148 public Method resolveFunction(String prefix, String localName) 149 { 150 throw new ReferenceSyntaxException( 151 "Functions not supported in expressions. Function: " 152 + prefix + ":" + localName); 153 } 154 }; 155 156 private static final BiLevelCacheMap s_expressionCache = 157 new BiLevelCacheMap(90) 158 { 159 protected Object newInstance(Object key) 160 { 161 return ELParserHelper.parseExpression((String ) key); 162 } 163 }; 164 165 167 protected Application _application; 168 protected String _expressionString; 169 protected Object _expression; 170 171 175 private RuntimeConfig _runtimeConfig; 176 177 179 public ValueBindingImpl(Application application, String expression) 180 { 181 if (application == null) 182 { 183 throw new NullPointerException ("application"); 184 } 185 186 if ((expression == null) || (expression.length() == 0)) 188 { 189 throw new ReferenceSyntaxException("Expression: empty or null"); 190 } 191 _application = application; 192 _expressionString = expression; 193 194 _expression = s_expressionCache.get(expression); 195 } 196 197 199 public String getExpressionString() 200 { 201 return _expressionString; 202 } 203 204 public boolean isReadOnly(FacesContext facesContext) 205 { 206 try 207 { 208 Object base_ = resolveToBaseAndProperty(facesContext); 209 if (base_ instanceof String ) 210 { 211 return VariableResolverImpl.s_standardImplicitObjects 212 .containsKey(base_); 213 } 214 215 Object [] baseAndProperty = (Object []) base_; 216 Object base = baseAndProperty[0]; 217 Object property = baseAndProperty[1]; 218 219 Integer index = ELParserHelper.toIndex(base, property); 220 return (index == null) 221 ? _application.getPropertyResolver().isReadOnly(base, property) 222 : _application.getPropertyResolver() 223 .isReadOnly(base, index.intValue()); 224 } 225 catch (NotVariableReferenceException e) 226 { 227 return true; 230 } 231 catch (Exception e) 232 { 233 return false; 235 } 236 } 237 238 public Class getType(FacesContext facesContext) 239 { 240 try 241 { 242 Object base_ = resolveToBaseAndProperty(facesContext); 243 if (base_ instanceof String ) 244 { 245 String name = (String ) base_; 246 247 ManagedBean mbConfig = 251 getRuntimeConfig(facesContext).getManagedBean(name); 252 if (mbConfig != null) 253 { 254 return mbConfig.getManagedBeanClass(); 257 } 258 259 Object val = _application.getVariableResolver() 260 .resolveVariable(facesContext, name); 261 262 return (val != null) ? val.getClass() : Object .class; 266 } 267 else 268 { 269 Object [] baseAndProperty = (Object []) base_; 270 Object base = baseAndProperty[0]; 271 Object property = baseAndProperty[1]; 272 273 Integer index = ELParserHelper.toIndex(base, property); 274 return (index == null) 275 ? _application.getPropertyResolver().getType(base, property) 276 : _application.getPropertyResolver() 277 .getType(base, index.intValue()); 278 } 279 } 280 catch (NotVariableReferenceException e) 281 { 282 try 288 { 289 return getValue(facesContext).getClass(); 290 } 291 catch (Exception e1) 292 { 293 return null; 295 } 296 } 297 catch (Exception e) 298 { 299 return null; 301 } 302 } 303 304 public void setValue(FacesContext facesContext, Object newValue) 305 throws PropertyNotFoundException 306 { 307 try 308 { 309 Object base_ = resolveToBaseAndProperty(facesContext); 310 if (base_ instanceof String ) 311 { 312 String name = (String ) base_; 313 if (VariableResolverImpl.s_standardImplicitObjects 314 .containsKey(name)) 315 { 316 String errorMessage = 317 "Cannot set value of implicit object '" 318 + name + "' for expression '" + _expressionString + "'"; 319 log.error(errorMessage); 320 throw new ReferenceSyntaxException(errorMessage); 321 } 322 323 setValueInScope(facesContext, name, newValue); 325 } 326 else 327 { 328 Object [] baseAndProperty = (Object []) base_; 329 Object base = baseAndProperty[0]; 330 Object property = baseAndProperty[1]; 331 PropertyResolver propertyResolver = 332 _application.getPropertyResolver(); 333 334 Integer index = ELParserHelper.toIndex(base, property); 335 if (index == null) 336 { 337 Class clazz = propertyResolver.getType(base, property); 338 propertyResolver.setValue( 339 base, property, coerce(newValue, clazz)); 340 } 341 else 342 { 343 int indexVal = index.intValue(); 344 Class clazz = propertyResolver.getType(base, indexVal); 345 propertyResolver.setValue( 346 base, indexVal, coerce(newValue, clazz)); 347 } 348 } 349 } 350 catch (IndexOutOfBoundsException e) 351 { 352 throw new PropertyNotFoundException( 354 "Expression: '" + _expressionString + "'", e); 355 } 356 catch (Exception e) 357 { 358 if (newValue == null) 359 { 360 log.error("Cannot set value for expression '" 361 + _expressionString + "' to null.", e); 362 } 363 else 364 { 365 log.error("Cannot set value for expression '" 366 + _expressionString + "' to a new value of type " 367 + newValue.getClass().getName(), e); 368 } 369 throw new EvaluationException( 370 "Expression: '" + _expressionString + "'", e); 371 } 372 } 373 374 private void setValueInScope( 375 FacesContext facesContext, String name, Object newValue) 376 throws ELException 377 { 378 ExternalContext externalContext = facesContext.getExternalContext(); 379 380 Map scopeMap = externalContext.getRequestMap(); 382 Object obj = scopeMap.get(name); 383 if (obj != null) 384 { 385 scopeMap.put(name, coerce(newValue, obj.getClass())); 386 return; 387 } 388 389 scopeMap = externalContext.getSessionMap(); 391 obj = scopeMap.get(name); 392 if (obj != null) 393 { 394 scopeMap.put(name, coerce(newValue, obj.getClass())); 395 return; 396 } 397 398 scopeMap = externalContext.getApplicationMap(); 400 obj = scopeMap.get(name); 401 if (obj != null) 402 { 403 scopeMap.put(name, coerce(newValue, obj.getClass())); 404 return; 405 } 406 407 ManagedBean mbConfig = 409 getRuntimeConfig(facesContext).getManagedBean(name); 410 if (mbConfig != null) 411 { 412 String scopeName = mbConfig.getManagedBeanScope(); 413 414 Scope scope = 417 (Scope) VariableResolverImpl.s_standardScopes.get(scopeName); 418 if (scope != null) 419 { 420 scope.put(externalContext, name, 421 coerce(newValue, mbConfig.getManagedBeanClass())); 422 return; 423 } 424 425 log.error("Managed bean '" + name + "' has illegal scope: " 426 + scopeName); 427 externalContext.getRequestMap().put(name, 428 coerce(newValue, mbConfig.getManagedBeanClass())); 429 return; 430 } 431 432 externalContext.getRequestMap().put(name, newValue); 434 } 435 436 public Object getValue(FacesContext facesContext) 437 throws PropertyNotFoundException 438 { 439 try 440 { 441 return _expression instanceof Expression 442 ? ((Expression) _expression).evaluate( 443 new ELVariableResolver(facesContext), 444 s_functionMapper, ELParserHelper.LOGGER) 445 : ((ExpressionString) _expression).evaluate( 446 new ELVariableResolver(facesContext), 447 s_functionMapper, ELParserHelper.LOGGER); 448 } 449 catch (IndexOutOfBoundsException e) 450 { 451 throw new PropertyNotFoundException( 453 "Expression: '" + _expressionString + "'", e); 454 } 455 catch (Exception e) 456 { 457 log.error("Cannot get value for expression '" + _expressionString 458 + "'", e); 459 460 if (e instanceof ELException ) 461 { 462 log.error("Root cause for exception : ", 463 ((ELException ) e).getRootCause()); 464 } 465 466 throw new EvaluationException( 467 "Expression: '" + _expressionString + "'", e); 468 } 469 } 470 471 protected Object resolveToBaseAndProperty(FacesContext facesContext) 472 throws ELException , NotVariableReferenceException 473 { 474 if (facesContext == null) 475 { 476 throw new NullPointerException ("facesContext"); 477 } 478 479 VariableResolver variableResolver = 480 new ELVariableResolver(facesContext); 481 Object expression = _expression; 482 483 while (expression instanceof ConditionalExpression) 484 { 485 ConditionalExpression conditionalExpression = 486 ((ConditionalExpression) expression); 487 boolean condition = 490 Coercions.coerceToBoolean( 491 conditionalExpression.getCondition().evaluate( 492 variableResolver, s_functionMapper, 493 ELParserHelper.LOGGER), 494 ELParserHelper.LOGGER) 495 .booleanValue(); 496 497 expression = condition ? conditionalExpression.getTrueBranch() 499 : conditionalExpression.getFalseBranch(); 500 } 501 502 if (expression instanceof NamedValue) 503 { 504 return ((NamedValue) expression).getName(); 505 } 506 507 if (!(expression instanceof ComplexValue)) { 508 throw new NotVariableReferenceException( 510 "Parsed Expression of unsupported type for this operation. Expression class: " 511 + _expression.getClass().getName() + ". Expression: '" 512 + _expressionString + "'"); 513 } 514 515 ComplexValue complexValue = (ComplexValue) expression; 516 517 Object base = complexValue.getPrefix() 519 .evaluate(variableResolver, s_functionMapper, 520 ELParserHelper.LOGGER); 521 if (base == null) 522 { 523 throw new PropertyNotFoundException("Base is null: " 524 + complexValue.getPrefix().getExpressionString()); 525 } 526 527 List suffixes = complexValue.getSuffixes(); 529 int max = suffixes.size() - 1; 530 for (int i = 0; i < max; i++) 531 { 532 ValueSuffix suffix = (ValueSuffix) suffixes.get(i); 533 base = suffix.evaluate(base, variableResolver, s_functionMapper, 534 ELParserHelper.LOGGER); 535 if (base == null) 536 { 537 throw new PropertyNotFoundException("Base is null: " 538 + suffix.getExpressionString()); 539 } 540 } 541 542 ArraySuffix arraySuffix = (ArraySuffix) suffixes.get(max); 544 Expression arraySuffixIndex = arraySuffix.getIndex(); 545 546 Object index; 547 if (arraySuffixIndex != null) 548 { 549 index = arraySuffixIndex.evaluate( 550 variableResolver, s_functionMapper, 551 ELParserHelper.LOGGER); 552 if (index == null) 553 { 554 throw new PropertyNotFoundException("Index is null: " 555 + arraySuffixIndex.getExpressionString()); 556 } 557 } 558 else 559 { 560 index = ((PropertySuffix) arraySuffix).getName(); 561 } 562 563 return new Object [] {base, index}; 564 } 565 566 private Object coerce(Object value, Class clazz) throws ELException 567 { 568 return (value == null) ? null 569 : (clazz == null) ? value : 570 Coercions.coerce(value, clazz, ELParserHelper.LOGGER); 571 } 572 573 protected RuntimeConfig getRuntimeConfig(FacesContext facesContext) 574 { 575 if (_runtimeConfig == null) 576 { 577 _runtimeConfig = RuntimeConfig.getCurrentInstance(facesContext.getExternalContext()); 578 } 579 return _runtimeConfig; 580 } 581 582 public String toString() 583 { 584 return _expressionString; 585 } 586 587 589 private boolean _transient = false; 590 591 595 public ValueBindingImpl() 596 { 597 _application = null; 598 _expressionString = null; 599 _expression = null; 600 } 601 602 public Object saveState(FacesContext facesContext) 603 { 604 return _expressionString; 605 } 606 607 public void restoreState(FacesContext facesContext, Object obj) 608 { 609 _application = facesContext.getApplication(); 610 _expressionString = (String ) obj; 611 _expression = s_expressionCache.get(_expressionString); 612 } 613 614 public boolean isTransient() 615 { 616 return _transient; 617 } 618 619 public void setTransient(boolean flag) 620 { 621 _transient = flag; 622 } 623 624 626 public static class ELVariableResolver implements VariableResolver { 627 private final FacesContext _facesContext; 628 629 public ELVariableResolver(FacesContext facesContext) 630 { 631 _facesContext = facesContext; 632 } 633 634 public Object resolveVariable(String pName) 635 throws ELException 636 { 637 return _facesContext.getApplication().getVariableResolver() 638 .resolveVariable(_facesContext, pName); 639 } 640 } 641 642 public static final class NotVariableReferenceException 643 extends ReferenceSyntaxException 644 { 645 public NotVariableReferenceException(String message) 646 { 647 super(message); 648 } 649 } 650 } 651 | Popular Tags |