1 16 package javax.faces.component; 17 18 import javax.faces.FactoryFinder; 19 import javax.faces.context.FacesContext; 20 import javax.faces.el.ValueBinding; 21 import javax.faces.event.AbortProcessingException; 22 import javax.faces.event.FacesEvent; 23 import javax.faces.event.FacesListener; 24 import javax.faces.render.RenderKit; 25 import javax.faces.render.RenderKitFactory; 26 import javax.faces.render.Renderer; 27 import java.io.IOException ; 28 import java.io.Serializable ; 29 import java.lang.reflect.Array ; 30 import java.util.*; 31 32 33 61 public abstract class UIComponentBase 62 extends UIComponent 63 { 64 private _ComponentAttributesMap _attributesMap = null; 65 private Map _valueBindingMap = null; 66 private List _childrenList = null; 67 private Map _facetMap = null; 68 private List _facesListeners = null; 69 private String _clientId = null; 70 private String _id = null; 71 private UIComponent _parent = null; 72 private boolean _transient = false; 73 74 public UIComponentBase() 75 { 76 } 77 78 public Map getAttributes() 79 { 80 if (_attributesMap == null) 81 { 82 _attributesMap = new _ComponentAttributesMap(this); 83 } 84 return _attributesMap; 85 } 86 87 public ValueBinding getValueBinding(String name) 88 { 89 if (name == null) throw new NullPointerException ("name"); 90 if (_valueBindingMap == null) 91 { 92 return null; 93 } 94 else 95 { 96 return (ValueBinding)_valueBindingMap.get(name); 97 } 98 } 99 100 public void setValueBinding(String name, 101 ValueBinding binding) 102 { 103 if (name == null) throw new NullPointerException ("name"); 104 if (_valueBindingMap == null) 105 { 106 _valueBindingMap = new HashMap(); 107 } 108 _valueBindingMap.put(name, binding); 109 } 110 111 115 public String getClientId(FacesContext context) 116 { 117 if (context == null) throw new NullPointerException ("context"); 118 119 if (_clientId != null) return _clientId; 120 121 boolean idWasNull = false; 122 String id = getId(); 123 if (id == null) 124 { 125 UIViewRoot viewRoot = context.getViewRoot(); 128 if (viewRoot != null) 129 { 130 id = viewRoot.createUniqueId(); 131 } 132 else 133 { 134 context.getExternalContext().log("ERROR: Cannot automatically create an id for component of type " + getClass().getName() + " because there is no viewRoot in the current facesContext!"); 135 id = "ERROR"; 136 } 137 idWasNull = true; 139 } 140 141 UIComponent namingContainer = _ComponentUtils.findParentNamingContainer(this, false); 142 if (namingContainer != null) 143 { 144 _clientId = namingContainer.getClientId(context) + NamingContainer.SEPARATOR_CHAR + id; 145 } 146 else 147 { 148 _clientId = id; 149 } 150 151 Renderer renderer = getRenderer(context); 152 if (renderer != null) 153 { 154 _clientId = renderer.convertClientId(context, _clientId); 155 } 156 157 if (idWasNull) 158 { 159 context.getExternalContext().log("WARNING: Component " + _clientId + " just got an automatic id, because there was no id assigned yet. " + 160 "If this component was created dynamically (i.e. not by a JSP tag) you should assign it an " + 161 "explicit static id or assign it the id you get from the createUniqueId from the current UIViewRoot " + 162 "component right after creation!"); 163 } 164 165 return _clientId; 166 } 167 168 public String getId() 169 { 170 return _id; 171 } 172 173 public void setId(String id) 174 { 175 isIdValid(id); 176 _id = id; 177 _clientId = null; 178 } 179 180 public UIComponent getParent() 181 { 182 return _parent; 183 } 184 185 public void setParent(UIComponent parent) 186 { 187 _parent = parent; 188 } 189 190 public boolean getRendersChildren() 191 { 192 Renderer renderer = getRenderer(getFacesContext()); 193 if (renderer != null) 194 { 195 return renderer.getRendersChildren(); 196 } 197 else 198 { 199 return false; 200 } 201 } 202 203 public List getChildren() 204 { 205 if (_childrenList == null) 206 { 207 _childrenList = new _ComponentChildrenList(this); 208 } 209 return _childrenList; 210 } 211 212 public int getChildCount() 213 { 214 return _childrenList == null ? 0 : _childrenList.size(); 215 } 216 217 218 222 public UIComponent findComponent(String expr) 223 { 224 if (expr == null) throw new NullPointerException ("expr"); 225 if (expr.length() == 0) throw new IllegalArgumentException ("empty expr"); 227 UIComponent findBase; 228 if (expr.charAt(0) == NamingContainer.SEPARATOR_CHAR) 229 { 230 findBase = _ComponentUtils.getRootComponent(this); 231 expr = expr.substring(1); 232 } 233 else 234 { 235 if (this instanceof NamingContainer) 236 { 237 findBase = this; 238 } 239 else 240 { 241 findBase = _ComponentUtils.findParentNamingContainer(this, true ); 242 } 243 } 244 245 int separator = expr.indexOf(NamingContainer.SEPARATOR_CHAR); 246 if (separator == -1) 247 { 248 return _ComponentUtils.findComponent(findBase, expr); 249 } 250 else 251 { 252 findBase = _ComponentUtils.findComponent(findBase, expr.substring(0, separator)); 253 if (findBase == null) 254 { 255 return null; 256 } 257 else 258 { 259 return findBase.findComponent(expr.substring(separator + 1)); 260 } 261 } 262 } 263 264 265 public Map getFacets() 266 { 267 if (_facetMap == null) 268 { 269 _facetMap = new _ComponentFacetMap(this); 270 } 271 return _facetMap; 272 } 273 274 public UIComponent getFacet(String name) 275 { 276 return _facetMap == null ? null : (UIComponent)_facetMap.get(name); 277 } 278 279 public Iterator getFacetsAndChildren() 280 { 281 return new _FacetsAndChildrenIterator(_facetMap, _childrenList); 282 } 283 284 public void broadcast(FacesEvent event) 285 throws AbortProcessingException 286 { 287 if (event == null) throw new NullPointerException ("event"); 288 if (_facesListeners == null) return; 289 for (Iterator it = _facesListeners.iterator(); it.hasNext(); ) 290 { 291 FacesListener facesListener = (FacesListener)it.next(); 292 if (event.isAppropriateListener(facesListener)) 293 { 294 event.processListener(facesListener); 295 } 296 } 297 } 298 299 public void decode(FacesContext context) 300 { 301 if (context == null) throw new NullPointerException ("context"); 302 Renderer renderer = getRenderer(context); 303 if (renderer != null) 304 { 305 renderer.decode(context, this); 306 } 307 } 308 309 public void encodeBegin(FacesContext context) 310 throws IOException 311 { 312 if (context == null) throw new NullPointerException ("context"); 313 if (!isRendered()) return; 314 Renderer renderer = getRenderer(context); 315 if (renderer != null) 316 { 317 renderer.encodeBegin(context, this); 318 } 319 } 320 321 public void encodeChildren(FacesContext context) 322 throws IOException 323 { 324 if (context == null) throw new NullPointerException ("context"); 325 if (!isRendered()) return; 326 Renderer renderer = getRenderer(context); 327 if (renderer != null) 328 { 329 renderer.encodeChildren(context, this); 330 } 331 } 332 333 public void encodeEnd(FacesContext context) 334 throws IOException 335 { 336 if (context == null) throw new NullPointerException ("context"); 337 if (!isRendered()) return; 338 Renderer renderer = getRenderer(context); 339 if (renderer != null) 340 { 341 renderer.encodeEnd(context, this); 342 } 343 } 344 345 protected void addFacesListener(FacesListener listener) 346 { 347 if (listener == null) throw new NullPointerException ("listener"); 348 if (_facesListeners == null) 349 { 350 _facesListeners = new ArrayList(); 351 } 352 _facesListeners.add(listener); 353 } 354 355 protected FacesListener[] getFacesListeners(Class clazz) 356 { 357 if (_facesListeners == null) 358 { 359 return (FacesListener[])Array.newInstance(clazz, 0); 360 } 361 List lst = null; 362 for (Iterator it = _facesListeners.iterator(); it.hasNext(); ) 363 { 364 FacesListener facesListener = (FacesListener)it.next(); 365 if (clazz.isAssignableFrom(facesListener.getClass())) 366 { 367 if (lst == null) lst = new ArrayList(); 368 lst.add(facesListener); 369 } 370 } 371 if (lst == null) 372 { 373 return (FacesListener[])Array.newInstance(clazz, 0); 374 } 375 else 376 { 377 return (FacesListener[])lst.toArray((FacesListener[])Array.newInstance(clazz, lst.size())); 378 } 379 } 380 381 protected void removeFacesListener(FacesListener listener) 382 { 383 if (_facesListeners != null) 384 { 385 _facesListeners.remove(listener); 386 } 387 } 388 389 public void queueEvent(FacesEvent event) 390 { 391 if (event == null) throw new NullPointerException ("event"); 392 UIComponent parent = getParent(); 393 if (parent == null) 394 { 395 throw new IllegalStateException ("component is not a descendant of a UIViewRoot"); 396 } 397 parent.queueEvent(event); 398 } 399 400 public void processDecodes(FacesContext context) 401 { 402 if (context == null) throw new NullPointerException ("context"); 403 if (!isRendered()) return; 404 for (Iterator it = getFacetsAndChildren(); it.hasNext(); ) 405 { 406 UIComponent childOrFacet = (UIComponent)it.next(); 407 childOrFacet.processDecodes(context); 408 } 409 try 410 { 411 decode(context); 412 } 413 catch (RuntimeException e) 414 { 415 context.renderResponse(); 416 throw e; 417 } 418 } 419 420 public void processValidators(FacesContext context) 421 { 422 if (context == null) throw new NullPointerException ("context"); 423 if (!isRendered()) return; 424 for (Iterator it = getFacetsAndChildren(); it.hasNext(); ) 425 { 426 UIComponent childOrFacet = (UIComponent)it.next(); 427 childOrFacet.processValidators(context); 428 } 429 } 430 431 public void processUpdates(FacesContext context) 432 { 433 if (context == null) throw new NullPointerException ("context"); 434 if (!isRendered()) return; 435 for (Iterator it = getFacetsAndChildren(); it.hasNext(); ) 436 { 437 UIComponent childOrFacet = (UIComponent)it.next(); 438 childOrFacet.processUpdates(context); 439 } 440 } 441 442 public Object processSaveState(FacesContext context) 443 { 444 if (context == null) throw new NullPointerException ("context"); 445 if (isTransient()) return null; 446 Map facetMap = null; 447 for (Iterator it = getFacets().entrySet().iterator(); it.hasNext(); ) 448 { 449 Map.Entry entry = (Map.Entry)it.next(); 450 if (facetMap == null) facetMap = new HashMap(); 451 UIComponent component = (UIComponent)entry.getValue(); 452 if (!component.isTransient()) 453 { 454 facetMap.put(entry.getKey(), component.processSaveState(context)); 455 } 456 } 457 List childrenList = null; 458 if (getChildCount() > 0) 459 { 460 for (Iterator it = getChildren().iterator(); it.hasNext(); ) 461 { 462 UIComponent child = (UIComponent)it.next(); 463 if (!child.isTransient()) 464 { 465 if (childrenList == null) childrenList = new ArrayList(getChildCount()); 466 childrenList.add(child.processSaveState(context)); 467 } 468 } 469 } 470 return new Object [] {saveState(context), 471 facetMap, 472 childrenList}; 473 } 474 475 public void processRestoreState(FacesContext context, 476 Object state) 477 { 478 if (context == null) throw new NullPointerException ("context"); 479 Object myState = ((Object [])state)[0]; 480 Map facetMap = (Map)((Object [])state)[1]; 481 List childrenList = (List)((Object [])state)[2]; 482 for (Iterator it = getFacets().entrySet().iterator(); it.hasNext(); ) 483 { 484 Map.Entry entry = (Map.Entry)it.next(); 485 Object facetState = facetMap.get(entry.getKey()); 486 if (facetState != null) 487 { 488 ((UIComponent)entry.getValue()).processRestoreState(context, facetState); 489 } 490 else 491 { 492 context.getExternalContext().log("No state found to restore facet " + entry.getKey()); 493 } 494 } 495 if (getChildCount() > 0) 496 { 497 int idx = 0; 498 for (Iterator it = getChildren().iterator(); it.hasNext(); ) 499 { 500 UIComponent child = (UIComponent)it.next(); 501 Object childState = childrenList.get(idx++); 502 if (childState != null) 503 { 504 child.processRestoreState(context, childState); 505 } 506 else 507 { 508 context.getExternalContext().log("No state found to restore child of component " + getId()); 509 } 510 } 511 } 512 restoreState(context, myState); 513 } 514 515 protected FacesContext getFacesContext() 516 { 517 return FacesContext.getCurrentInstance(); 518 } 519 520 protected Renderer getRenderer(FacesContext context) 521 { 522 if (context == null) throw new NullPointerException ("context"); 523 String rendererType = getRendererType(); 524 if (rendererType == null) return null; 525 String renderKitId = context.getViewRoot().getRenderKitId(); 526 RenderKitFactory rkf = (RenderKitFactory)FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY); 527 RenderKit renderKit = rkf.getRenderKit(context, renderKitId); 528 Renderer renderer = renderKit.getRenderer(getFamily(), rendererType); 529 if (renderer == null) 530 { 531 getFacesContext().getExternalContext().log("No Renderer found for component " + getClientId(context) + " (component-family=" + getFamily() + ", renderer-type=" + rendererType + ")"); 532 } 533 return renderer; 534 } 535 536 public boolean isTransient() 537 { 538 return _transient; 539 } 540 541 public void setTransient(boolean transientFlag) 542 { 543 _transient = transientFlag; 544 } 545 546 547 public static Object saveAttachedState(FacesContext context, 548 Object attachedObject) 549 { 550 if (attachedObject == null) return null; 551 if (attachedObject instanceof List) 552 { 553 ArrayList lst = new ArrayList(((List)attachedObject).size()); 554 for (Iterator it = ((List)attachedObject).iterator(); it.hasNext(); ) 555 { 556 lst.add(saveAttachedState(context, it.next())); 557 } 558 return new _AttachedListStateWrapper(lst); 559 } 560 else if (attachedObject instanceof StateHolder) 561 { 562 if (((StateHolder)attachedObject).isTransient()) 563 { 564 return null; 565 } 566 else 567 { 568 return new _AttachedStateWrapper(attachedObject.getClass(), 569 ((StateHolder)attachedObject).saveState(context)); 570 } 571 } 572 else if (attachedObject instanceof Serializable ) 573 { 574 return attachedObject; 575 } 576 else 577 { 578 return new _AttachedStateWrapper(attachedObject.getClass(), null); 579 } 580 } 581 582 public static Object restoreAttachedState(FacesContext context, 583 Object stateObj) 584 throws IllegalStateException 585 { 586 if (context == null) throw new NullPointerException ("context"); 587 if (stateObj == null) return null; 588 if (stateObj instanceof _AttachedListStateWrapper) 589 { 590 List lst = ((_AttachedListStateWrapper)stateObj).getWrappedStateList(); 591 List restoredList = new ArrayList(lst.size()); 592 for (Iterator it = lst.iterator(); it.hasNext(); ) 593 { 594 restoredList.add(restoreAttachedState(context, it.next())); 595 } 596 return restoredList; 597 } 598 else if (stateObj instanceof _AttachedStateWrapper) 599 { 600 Class clazz = ((_AttachedStateWrapper)stateObj).getClazz(); 601 Object restoredObject = null; 602 try 603 { 604 restoredObject = clazz.newInstance(); 605 } 606 catch (InstantiationException e) 607 { 608 throw new RuntimeException ("Could not restore StateHolder of type " + clazz.getName() + " (missing no-args constructor?)", e); 609 } 610 catch (IllegalAccessException e) 611 { 612 throw new RuntimeException (e); 613 } 614 if (restoredObject instanceof StateHolder) 615 { 616 Object wrappedState = ((_AttachedStateWrapper)stateObj).getWrappedStateObject(); 617 ((StateHolder)restoredObject).restoreState(context, wrappedState); 618 } 619 return restoredObject; 620 } 621 else 622 { 623 return stateObj; 624 } 625 } 626 627 628 public Object saveState(FacesContext context) 629 { 630 Object values[] = new Object [7]; 631 values[0] = _id; 632 values[1] = _rendered; 633 values[2] = _rendererType; 634 values[3] = _clientId; 635 values[4] = saveAttributesMap(); 636 values[5] = saveAttachedState(context, _facesListeners); 637 values[6] = saveValueBindingMap(context); 638 return ((Object ) (values)); 639 } 640 641 public void restoreState(FacesContext context, Object state) 642 { 643 Object values[] = (Object [])state; 644 _id = (String )values[0]; 645 _rendered = (Boolean )values[1]; 646 _rendererType = (String )values[2]; 647 _clientId = (String )values[3]; 648 restoreAttributesMap(values[4]); 649 _facesListeners = (List)restoreAttachedState(context, values[5]); 650 restoreValueBindingMap(context, values[6]); 651 } 652 653 654 private Object saveAttributesMap() 655 { 656 if (_attributesMap != null) 657 { 658 return _attributesMap.getUnderlyingMap(); 659 } 660 else 661 { 662 return null; 663 } 664 } 665 666 private void restoreAttributesMap(Object stateObj) 667 { 668 if (stateObj != null) 669 { 670 _attributesMap = new _ComponentAttributesMap(this, (Map)stateObj); 671 } 672 else 673 { 674 _attributesMap = null; 675 } 676 } 677 678 private Object saveValueBindingMap(FacesContext context) 679 { 680 if (_valueBindingMap != null) 681 { 682 int initCapacity = (_valueBindingMap.size() * 4 + 3) / 3; 683 HashMap stateMap = new HashMap(initCapacity); 684 for (Iterator it = _valueBindingMap.entrySet().iterator(); it.hasNext(); ) 685 { 686 Map.Entry entry = (Map.Entry)it.next(); 687 stateMap.put(entry.getKey(), 688 saveAttachedState(context, entry.getValue())); 689 } 690 return stateMap; 691 } 692 else 693 { 694 return null; 695 } 696 } 697 698 private void restoreValueBindingMap(FacesContext context, Object stateObj) 699 { 700 if (stateObj != null) 701 { 702 Map stateMap = (Map)stateObj; 703 int initCapacity = (stateMap.size() * 4 + 3) / 3; 704 _valueBindingMap = new HashMap(initCapacity); 705 for (Iterator it = stateMap.entrySet().iterator(); it.hasNext(); ) 706 { 707 Map.Entry entry = (Map.Entry)it.next(); 708 _valueBindingMap.put(entry.getKey(), 709 restoreAttachedState(context, entry.getValue())); 710 } 711 } 712 else 713 { 714 _valueBindingMap = null; 715 } 716 } 717 718 719 722 private void isIdValid(String string) { 723 724 if(string == null) 726 return; 727 728 if(string.length()==0){ 731 throw new IllegalArgumentException ("component identifier must not be a zero-length String"); 732 } 733 734 char[] chars = string.toCharArray(); 736 for (int i = 0; i < chars.length; i++) { 737 char tmpChar = chars[i]; 738 739 if(i==0){ 741 if(!Character.isLetter(tmpChar) && tmpChar !='_'){ 742 throw new IllegalArgumentException ("component identifier's first character must be a letter or an underscore ('_')! But it is \""+tmpChar+"\""); 743 } 744 }else{ 745 746 if(!Character.isDigit(tmpChar) && !Character.isLetter(tmpChar) && tmpChar !='-' && tmpChar !='_'){ 748 throw new IllegalArgumentException ("Subsequent characters of component identifier must be a letter, a digit, an underscore ('_'), or a dash ('-')! But component identifier contains \""+tmpChar+"\""); 749 } 750 } 751 } 752 753 } 754 755 756 757 759 private static final boolean DEFAULT_RENDERED = true; 760 761 private Boolean _rendered = null; 762 private String _rendererType = null; 763 764 765 766 public void setRendered(boolean rendered) 767 { 768 _rendered = Boolean.valueOf(rendered); 769 } 770 771 public boolean isRendered() 772 { 773 if (_rendered != null) return _rendered.booleanValue(); 774 ValueBinding vb = getValueBinding("rendered"); 775 Boolean v = vb != null ? (Boolean )vb.getValue(getFacesContext()) : null; 776 return v != null ? v.booleanValue() : DEFAULT_RENDERED; 777 } 778 779 public void setRendererType(String rendererType) 780 { 781 _rendererType = rendererType; 782 } 783 784 public String getRendererType() 785 { 786 if (_rendererType != null) return _rendererType; 787 ValueBinding vb = getValueBinding("rendererType"); 788 return vb != null ? (String )vb.getValue(getFacesContext()) : null; 789 } 790 791 792 } 794 | Popular Tags |