Coverage Report - javax.faces.webapp.UIComponentClassicTagBase
 
Classes in this File Line Coverage Branch Coverage Complexity
UIComponentClassicTagBase
0%
0/419
0%
0/252
0
 
 1  
 /*
 2  
  * Licensed to the Apache Software Foundation (ASF) under one
 3  
  * or more contributor license agreements.  See the NOTICE file
 4  
  * distributed with this work for additional information
 5  
  * regarding copyright ownership.  The ASF licenses this file
 6  
  * to you under the Apache License, Version 2.0 (the
 7  
  * "License"); you may not use this file except in compliance
 8  
  * with the License.  You may obtain a copy of the License at
 9  
  *
 10  
  *   http://www.apache.org/licenses/LICENSE-2.0
 11  
  *
 12  
  * Unless required by applicable law or agreed to in writing,
 13  
  * software distributed under the License is distributed on an
 14  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15  
  * KIND, either express or implied.  See the License for the
 16  
  * specific language governing permissions and limitations
 17  
  * under the License.
 18  
  */
 19  
 package javax.faces.webapp;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.util.ArrayList;
 23  
 import java.util.HashMap;
 24  
 import java.util.HashSet;
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 import java.util.Set;
 28  
 import java.util.Stack;
 29  
 import java.util.concurrent.atomic.AtomicInteger;
 30  
 import java.util.logging.Level;
 31  
 
 32  
 import javax.faces.component.NamingContainer;
 33  
 import javax.faces.component.UIComponent;
 34  
 import javax.faces.component.UIOutput;
 35  
 import javax.faces.component.UIViewRoot;
 36  
 import javax.faces.context.FacesContext;
 37  
 import javax.faces.render.ResponseStateManager;
 38  
 import javax.servlet.jsp.JspException;
 39  
 import javax.servlet.jsp.JspWriter;
 40  
 import javax.servlet.jsp.PageContext;
 41  
 import javax.servlet.jsp.jstl.core.LoopTag;
 42  
 import javax.servlet.jsp.tagext.BodyContent;
 43  
 import javax.servlet.jsp.tagext.BodyTag;
 44  
 import javax.servlet.jsp.tagext.JspIdConsumer;
 45  
 import javax.servlet.jsp.tagext.Tag;
 46  
 
 47  
 /**
 48  
  * @author Bruno Aranda (latest modification by $Author: baranda $)
 49  
  * @author Manfred Geiler
 50  
  * @author Dennis Byrne
 51  
  * @version $Revision$ $Date$
 52  
  *
 53  
  * @since 1.2
 54  
  */
 55  
 
 56  0
 public abstract class UIComponentClassicTagBase extends UIComponentTagBase
 57  
         implements BodyTag, JspIdConsumer
 58  
 {
 59  
     
 60  
     //  do not change this w/out doing likewise in UIComponentTag
 61  
     private static final String COMPONENT_STACK_ATTR = "org.apache.myfaces.COMPONENT_STACK";
 62  
 
 63  
     private static final String REQUEST_FACES_CONTEXT = "org.apache.myfaces.REQUEST_FACES_CONTEXT";
 64  
 
 65  
     private static final String VIEW_IDS = "org.apache.myfaces.VIEW_IDS";
 66  
 
 67  
     private static final String FORMER_CHILD_IDS_SET_ATTR = "org.apache.myfaces.FORMER_CHILD_IDS";
 68  
     private static final String FORMER_FACET_NAMES_SET_ATTR = "org.apache.myfaces.FORMER_FACET_NAMES";
 69  
 
 70  
     private static final String PREVIOUS_JSP_IDS_SET = "org.apache.myfaces.PREVIOUS_JSP_IDS_SET";
 71  
 
 72  
     private static final String BOUND_VIEW_ROOT = "org.apache.myfaces.BOUND_VIEW_ROOT";
 73  
     
 74  
     private static final String LOGICAL_PAGE_ID = "org.apache.myfaces.LOGICAL_PAGE_ID";
 75  
     
 76  
     private static final String LOGICAL_PAGE_COUNTER = "org.apache.myfaces.LOGICAL_PAGE_COUNTER";
 77  
 
 78  
     protected static final String UNIQUE_ID_PREFIX = UIViewRoot.UNIQUE_ID_PREFIX + "_";
 79  
 
 80  0
     protected PageContext pageContext = null;
 81  0
     protected BodyContent bodyContent = null;
 82  
 
 83  0
     private boolean _created = false;
 84  
 
 85  0
     private String _jspId = null;
 86  0
     private String _facesJspId = null;
 87  
 
 88  0
     private List<String> _childrenAdded = null;
 89  0
     private List<String> _facetsAdded = null;
 90  
 
 91  0
     private UIComponent _componentInstance = null;
 92  0
     private String _id = null;
 93  
 
 94  
     private boolean isInAnIterator;
 95  
 
 96  
     // the parent tag
 97  0
     private Tag _parent = null;
 98  
 
 99  
     // the enclosing "classic" parent tag
 100  0
     private UIComponentClassicTagBase _parentClassicTag = null;
 101  
 
 102  0
     private FacesContext _facesContext = null;
 103  
 
 104  
     protected abstract void setProperties(UIComponent component);
 105  
 
 106  
     protected abstract UIComponent createComponent(FacesContext context,
 107  
                                                    String newId) throws JspException;
 108  
 
 109  
     public void release()
 110  
     {
 111  0
         internalRelease();
 112  
 
 113  
         //members, that must/need only be reset when there is no more risk, that the container
 114  
         //wants to reuse this tag
 115  0
         pageContext = null;
 116  0
         _parent = null;
 117  0
         _jspId = null;
 118  0
         _id = null;
 119  0
         _facesJspId = null;
 120  0
         bodyContent = null;
 121  0
     }
 122  
 
 123  
 
 124  
     /**
 125  
      * Reset any members that apply to the according component instance and
 126  
      * must not be reused if the container wants to reuse this tag instance.
 127  
      * This method is called when rendering for this tag is finished
 128  
      * ( doEndTag() ) or when released by the container.
 129  
      */
 130  
     private void internalRelease()
 131  
     {
 132  0
         _facesContext = null;
 133  0
         _componentInstance = null;
 134  0
         _created = false;
 135  
 
 136  0
          _childrenAdded = null;
 137  0
         _facetsAdded = null;
 138  0
     }
 139  
 
 140  
     /**
 141  
      * @see http://java.sun.com/javaee/5/docs/api/javax/faces/webapp/UIComponentClassicTagBase.html#getCreated()
 142  
      */
 143  
     public boolean getCreated()
 144  
     {
 145  0
         return _created;
 146  
     }
 147  
 
 148  
      protected List<String> getCreatedComponents() {
 149  0
          return _childrenAdded;
 150  
     }
 151  
 
 152  
     /**
 153  
      * @see http://java.sun.com/javaee/5/docs/api/javax/faces/webapp/UIComponentClassicTagBase.html#getParentUIComponentClassicTagBase(javax.servlet.jsp.PageContext)
 154  
      * @param pageContext
 155  
      * @return
 156  
      */
 157  
     public static UIComponentClassicTagBase getParentUIComponentClassicTagBase(
 158  
             PageContext pageContext)
 159  
     {
 160  0
         Stack<UIComponentClassicTagBase> stack = getStack(pageContext);
 161  
 
 162  0
         int size = stack.size();
 163  
 
 164  0
         return size > 0 ? stack.get(size - 1) : null;
 165  
     }
 166  
 
 167  
     /**
 168  
      * @see http://java.sun.com/javaee/5/docs/api/javax/faces/webapp/UIComponentClassicTagBase.html#getFacesJspId()
 169  
      * @return
 170  
      */
 171  
     public String getJspId()
 172  
     {
 173  0
         return _jspId;
 174  
     }
 175  
 
 176  
     public void setJspId(String jspId)
 177  
     {
 178  
         // -= Leonardo Uribe =- The javadoc says the following about this method:
 179  
         //
 180  
         // 1. This method is called by the container before doStartTag(). 
 181  
         // 2. The argument is guaranteed to be unique within the page.
 182  
         //
 183  
         // Doing some tests it was found that the jspId generated in a
 184  
         // jsp:include are "reset", so if before call it it was id10
 185  
         // the tags inside jsp:include starts from id1 (really I suppose a
 186  
         // different counter is used), so if we assign this one
 187  
         // directly it is possible to cause duplicate id exceptions later.
 188  
         //
 189  
         // One problem is caused by f:view tag. This one is not included when
 190  
         // we check for duplicate id, so it is possible to assign to a component
 191  
         // in a jsp:include the id of the UIViewRoot instance and cause a 
 192  
         // duplicate id exception when the view is saved.
 193  
         //
 194  
         // Checking the javadoc it was found the following note:
 195  
         //
 196  
         // "... IMPLEMENTATION NOTE: This method will detect where we are in an 
 197  
         // include and assign a unique ID for each include in a particular 'logical page'. 
 198  
         // This allows us to avoid possible duplicate ID situations for included pages 
 199  
         // that have components without explicit IDs..."
 200  
         //
 201  
         // So we need to keep a counter per logical page or page context found. 
 202  
         // It is assumed the first one should not be suffixed. The others needs to be
 203  
         // suffixed, so all generated ids of those pages are different. The final result
 204  
         // is that jsp:include works correctly.
 205  
         //
 206  
         // Note this implementation detail takes precedence over c:forEach tag. If a
 207  
         // jsp:include is inside a c:forEach, jsp:include takes precedence and the 
 208  
         // iteration prefix is ignored. If a custom id is provided for a component, 
 209  
         // it will throw duplicate id exception, because this code is "override" 
 210  
         // by the custom id, and the iteration suffix only applies on generated ids.
 211  0
         Integer logicalPageId = (Integer) pageContext.getAttribute(LOGICAL_PAGE_ID);
 212  
         
 213  0
         if (logicalPageId != null)
 214  
         {
 215  0
             if (logicalPageId.intValue() == 1)
 216  
             {
 217  
                 //Base case, just pass it unchanged
 218  0
                 _jspId = jspId;
 219  
             }
 220  
             else
 221  
             {
 222  
                 // We are on a different page context, suffix it with the logicalPageId
 223  0
                 _jspId = jspId + "pc" + logicalPageId;
 224  
             }
 225  
         }
 226  
         else
 227  
         {
 228  0
             Map<String,Object> requestMap = getFacesContext().getExternalContext().getRequestMap();
 229  0
             AtomicInteger logicalPageCounter = (AtomicInteger) requestMap.get(LOGICAL_PAGE_COUNTER);
 230  
             
 231  0
             if (logicalPageCounter == null)
 232  
             {
 233  
                 //We are processing the first component tag. 
 234  0
                 logicalPageCounter = new AtomicInteger(1);
 235  0
                 logicalPageId = 1;
 236  0
                 requestMap.put(LOGICAL_PAGE_COUNTER, logicalPageCounter);
 237  0
                 pageContext.setAttribute(LOGICAL_PAGE_ID, logicalPageId);
 238  
             }
 239  
             else
 240  
             {
 241  
                 //We are on a different page context, so we need to assign and set.
 242  0
                 logicalPageId = logicalPageCounter.incrementAndGet();
 243  0
                 pageContext.setAttribute(LOGICAL_PAGE_ID, logicalPageId);
 244  0
                 _jspId = jspId + "pc" + logicalPageId;
 245  
             }
 246  
         }
 247  0
         _facesJspId = null;
 248  0
         checkIfItIsInAnIterator(_jspId);
 249  0
     }
 250  
 
 251  
 
 252  
     /**
 253  
      * @param child
 254  
      * @see http://java.sun.com/javaee/5/docs/api/javax/faces/webapp/UIComponentTagBase.html#addChild(javax.faces._componentInstance.UIComponent)
 255  
      */
 256  
 
 257  
     protected void addChild(UIComponent child)
 258  
     {
 259  0
         if (_childrenAdded == null)
 260  
         {
 261  0
             _childrenAdded = new ArrayList<String>();
 262  
         }
 263  
 
 264  0
         _childrenAdded.add(child.getId());
 265  0
     }
 266  
 
 267  
     /**
 268  
      * @param name
 269  
      * @see http://java.sun.com/javaee/5/docs/api/javax/faces/webapp/UIComponentTagBase.html#addFacet(java.lang.String)
 270  
      */
 271  
     protected void addFacet(String name)
 272  
     {
 273  0
         if (_facetsAdded == null)
 274  
         {
 275  0
             _facetsAdded = new ArrayList<String>();
 276  
         }
 277  
 
 278  0
         _facetsAdded.add(name);
 279  0
     }
 280  
 
 281  
     /**
 282  
      * Return the UIComponent instance associated with this tag.
 283  
      * @return a UIComponent, never null.
 284  
      */
 285  
     public UIComponent getComponentInstance()
 286  
     {
 287  0
         return _componentInstance;
 288  
     }
 289  
 
 290  
     /**
 291  
      * @return
 292  
      * @see http://java.sun.com/javaee/5/docs/api/javax/faces/webapp/UIComponentTagBase.html#getFacesContext()
 293  
      */
 294  
 
 295  
     protected FacesContext getFacesContext()
 296  
     {
 297  0
         if (_facesContext != null)
 298  
         {
 299  0
             return _facesContext;
 300  
         }
 301  
 
 302  0
         _facesContext = pageContext == null ? null : (FacesContext) pageContext.getAttribute(REQUEST_FACES_CONTEXT);
 303  
 
 304  0
         if (_facesContext != null)
 305  
         {
 306  0
             return _facesContext;
 307  
         }
 308  
 
 309  0
         _facesContext = FacesContext.getCurrentInstance();
 310  
 
 311  0
         if (_facesContext != null)
 312  
         {
 313  0
             if(pageContext != null)
 314  
             {
 315  0
                 pageContext.setAttribute(REQUEST_FACES_CONTEXT, _facesContext);
 316  
             }
 317  0
             return _facesContext;
 318  
         }
 319  
 
 320  
         // should never be reached
 321  0
         throw new RuntimeException("FacesContext not found");
 322  
     }
 323  
 
 324  
     /**
 325  
      * @return
 326  
      * @see http://java.sun.com/javaee/5/docs/api/javax/faces/webapp/UIComponentTagBase.html#getIndexOfNextChildTag()
 327  
      */
 328  
 
 329  
     protected int getIndexOfNextChildTag()
 330  
     {
 331  0
         if (_childrenAdded == null)
 332  
         {
 333  0
             return 0;
 334  
         }
 335  
 
 336  0
         return _childrenAdded.size();
 337  
     }
 338  
 
 339  
     /**
 340  
      * @param id
 341  
      * @see http://java.sun.com/javaee/5/docs/api/javax/faces/webapp/UIComponentTagBase.html#setId(java.lang.String)
 342  
      */
 343  
     public void setId(String id)
 344  
     {
 345  0
         if (id != null && id.startsWith(UIViewRoot.UNIQUE_ID_PREFIX))
 346  
         {
 347  0
             throw new IllegalArgumentException("Id is non-null and starts with UIViewRoot.UNIQUE_ID_PREFIX: "+id);
 348  
         }
 349  
 
 350  0
         _id = id;
 351  0
     }
 352  
 
 353  
     /**
 354  
      * Return the id (if any) specified as an xml attribute on this tag.
 355  
      */
 356  
     protected String getId()
 357  
     {
 358  0
         return _id;
 359  
     }
 360  
 
 361  
     protected String getFacesJspId() {
 362  0
         if (_facesJspId == null)
 363  
         {
 364  0
             if (_jspId != null)
 365  
             {
 366  0
                 _facesJspId = UNIQUE_ID_PREFIX + _jspId;
 367  
 
 368  0
                 if (isIdDuplicated(_facesJspId)) {
 369  0
                     _facesJspId = createNextId(_facesJspId);
 370  
                 }
 371  
             }
 372  
             else
 373  
             {
 374  0
                 _facesJspId = _facesContext.getViewRoot().createUniqueId();
 375  
             }
 376  
         }
 377  
 
 378  0
         return _facesJspId;
 379  
     }
 380  
 
 381  
     public void setBodyContent(BodyContent bodyContent)
 382  
     {
 383  0
         this.bodyContent = bodyContent;
 384  0
     }
 385  
 
 386  
     public void doInitBody() throws JspException
 387  
     {
 388  
         // nothing by default
 389  0
     }
 390  
 
 391  
     public int doAfterBody() throws JspException
 392  
     {
 393  0
         UIComponentClassicTagBase parentTag = getParentUIComponentClassicTagBase(pageContext);
 394  
 
 395  0
         if (isRootTag(parentTag) || isInRenderedChildrenComponent(parentTag))
 396  
         {
 397  0
             UIComponent verbatimComp = createVerbatimComponentFromBodyContent();
 398  
 
 399  0
             if (verbatimComp != null)
 400  
             {
 401  0
                 List<String> childrenAddedIds = (List<String>)
 402  
                   _componentInstance.getAttributes().get(FORMER_CHILD_IDS_SET_ATTR);
 403  
 
 404  0
                 if (childrenAddedIds == null)
 405  
                 {
 406  0
                     _componentInstance.getChildren().add(verbatimComp);
 407  
                 }
 408  
                 else
 409  
                 {
 410  0
                     int index = _componentInstance.getChildCount();
 411  0
                     if (childrenAddedIds.size() == index)
 412  
                     {
 413  
                         // verbatim already present, replace it
 414  0
                         _componentInstance.getChildren().add(index-1, verbatimComp);
 415  
                     }
 416  
                     else
 417  
                     {
 418  0
                         _componentInstance.getChildren().add(verbatimComp);
 419  
                     }
 420  
                 }
 421  
 
 422  
                 // also tell the parent-tag about the new component instance
 423  0
                 if(parentTag!=null) {
 424  0
                     parentTag.addChild(verbatimComp);
 425  
                 }
 426  
             }
 427  
         }
 428  
 
 429  0
         return getDoAfterBodyValue();
 430  
     }
 431  
 
 432  
     /**
 433  
      * Standard method invoked by the JSP framework to inform this tag
 434  
      * of the PageContext associated with the jsp page currently being
 435  
      * processed.
 436  
      */
 437  
     public void setPageContext(PageContext pageContext)
 438  
     {
 439  0
         this.pageContext = pageContext;
 440  0
     }
 441  
 
 442  
     /**
 443  
      * Returns the enclosing JSP tag object. Note that this is not
 444  
      * necessarily a JSF tag.
 445  
      */
 446  
     public Tag getParent()
 447  
     {
 448  0
         return _parent;
 449  
     }
 450  
 
 451  
     /**
 452  
      * Standard method invoked by the JSP framework to inform this tag
 453  
      * of the enclosing JSP tag object.
 454  
      */
 455  
     public void setParent(Tag tag)
 456  
     {
 457  0
         this._parent = tag;
 458  0
     }
 459  
 
 460  
     public BodyContent getBodyContent()
 461  
     {
 462  0
         return bodyContent;
 463  
     }
 464  
 
 465  
     public int doStartTag() throws JspException
 466  
     {
 467  0
         this._facesContext = getFacesContext();
 468  
 
 469  0
         if (_facesContext == null)
 470  
         {
 471  0
             throw new JspException("FacesContext not found");
 472  
         }
 473  
 
 474  0
         _childrenAdded = null;
 475  0
         _facetsAdded = null;
 476  
 
 477  0
         _parentClassicTag = getParentUIComponentClassicTagBase(pageContext);
 478  
 
 479  0
         UIComponent verbatimComp = null;
 480  
 
 481  
         // create the verbatim component if not inside a facet (facets are rendered
 482  
         // by their parents) and in a component that renders children
 483  0
         if (!isFacet())
 484  
         {
 485  0
             Tag parent = getParent();
 486  
 
 487  
             // flush if in a loop tag and not in a jsp tag
 488  0
             if (parent != null && parent instanceof LoopTag)
 489  
             {
 490  0
                 JspWriter outWriter = pageContext.getOut();
 491  0
                 boolean insideJspTag = (outWriter instanceof BodyContent);
 492  
 
 493  0
                 if (!insideJspTag)
 494  
                 {
 495  
                     try
 496  
                     {
 497  0
                         outWriter.flush();
 498  
                     }
 499  0
                     catch (IOException e)
 500  
                     {
 501  0
                         throw new JspException("Exception flushing when creating verbatim _componentInstance", e);
 502  0
                     }
 503  
                 }
 504  
             }
 505  
 
 506  
             // create the transient _componentInstance
 507  0
             if (_parentClassicTag != null)
 508  
             {
 509  0
                 verbatimComp = _parentClassicTag.createVerbatimComponentFromBodyContent();
 510  
             }
 511  
         }
 512  
 
 513  
         // find the _componentInstance for this tag
 514  0
         _componentInstance = findComponent(_facesContext);
 515  
 
 516  
         // add the verbatim component
 517  0
         if (verbatimComp != null && _parentClassicTag != null)
 518  
         {
 519  0
             addVerbatimBeforeComponent(_parentClassicTag, verbatimComp, _componentInstance);
 520  
         }
 521  
 
 522  0
         Map<String,Object> viewComponentIds = getViewComponentIds();
 523  
 
 524  
         // check that the instance returned by the client ID for the viewComponentIds
 525  
         // is the same like this one, so we do not perform again the check for duplicated ids
 526  0
         Object tagInstance = null;
 527  0
         String clientId = null;
 528  0
         if (_id != null) {
 529  0
             clientId = _componentInstance.getClientId(_facesContext);
 530  0
             tagInstance = (viewComponentIds.get(clientId) == this) ? this : null;
 531  
         }
 532  
 
 533  0
         if (tagInstance == null)
 534  
         {
 535  
             // check for duplicated IDs
 536  0
             if (_id != null)
 537  
             {
 538  0
                 if (clientId != null)
 539  
                 {
 540  0
                     if (viewComponentIds.containsKey(clientId))
 541  
                     {
 542  0
                         throw new JspException("Duplicated component Id: '"+clientId+"' " +
 543  
                                 "for component: '"+getPathToComponent(_componentInstance)+"'.");
 544  
                     }
 545  
 
 546  0
                     viewComponentIds.put(clientId, this);
 547  
                 }
 548  
             }
 549  
 
 550  
             // add to the component or facet to parent
 551  0
             if (_parentClassicTag != null)
 552  
             {
 553  0
                 if (isFacet())
 554  
                 {
 555  0
                     _parentClassicTag.addFacet(getFacetName());
 556  
                 }
 557  
                 else
 558  
                 {
 559  0
                      _parentClassicTag.addChild(_componentInstance);
 560  
                 }
 561  
             }
 562  
         }
 563  
 
 564  
         // push this tag on the stack
 565  0
         pushTag();
 566  
 
 567  0
         return getDoStartValue();
 568  
     }
 569  
 
 570  
     public int doEndTag() throws JspException
 571  
     {
 572  0
         popTag();
 573  0
         UIComponent component = getComponentInstance();
 574  
 
 575  0
         removeFormerChildren(component);
 576  0
         removeFormerFacets(component);
 577  
 
 578  
         try
 579  
         {
 580  0
             UIComponentClassicTagBase parentTag =
 581  
                     getParentUIComponentClassicTagBase(pageContext);
 582  
 
 583  0
             UIComponent verbatimComp = createVerbatimComponentFromBodyContent();
 584  
 
 585  0
              if (verbatimComp != null)
 586  
             {
 587  0
                 component.getChildren().add(verbatimComp);
 588  
 
 589  0
                 if (parentTag != null)
 590  
                 {
 591  0
                     parentTag.addChild(verbatimComp);
 592  
                 }
 593  
             }
 594  
         }
 595  0
         catch (Throwable e)
 596  
         {
 597  0
             throw new JspException(e);
 598  
         }
 599  
         finally
 600  
         {
 601  0
             component = null;
 602  0
         }
 603  
 
 604  0
         int retValue = getDoEndValue();
 605  
 
 606  0
         internalRelease();
 607  
 
 608  0
         return retValue;
 609  
     }
 610  
 
 611  
     protected int getDoAfterBodyValue() throws javax.servlet.jsp.JspException
 612  
     {
 613  0
         return SKIP_BODY;
 614  
     }
 615  
 
 616  
     /**
 617  
      * Get the value to be returned by the doStartTag method to the
 618  
      * JSP framework. Subclasses which wish to use the inherited
 619  
      * doStartTag but control whether the tag is permitted to contain
 620  
      * nested tags or not can just override this method to return
 621  
      * Tag.SOME_CONSTANT.
 622  
      *
 623  
      * @return BodyTag.EVAL_BODY_BUFFERED
 624  
      */
 625  
     protected int getDoStartValue()
 626  
             throws JspException
 627  
     {
 628  0
         return BodyTag.EVAL_BODY_BUFFERED;
 629  
     }
 630  
 
 631  
     /**
 632  
      * Get the value to be returned by the doEndTag method to the
 633  
      * JSP framework. Subclasses which wish to use the inherited
 634  
      * doEndTag but control whether the tag is permitted to contain
 635  
      * nested tags or not can just override this method to return
 636  
      * Tag.SOME_CONSTANT.
 637  
      *
 638  
      * @return Tag.EVAL_PAGE
 639  
      */
 640  
     protected int getDoEndValue()
 641  
             throws JspException
 642  
     {
 643  0
         return Tag.EVAL_PAGE;
 644  
     }
 645  
 
 646  
     protected String getFacetName()
 647  
     {
 648  0
         return isFacet() ? ((FacetTag)_parent).getName() : null;
 649  
     }
 650  
 
 651  
 
 652  
     /**
 653  
      * Creates a UIComponent from the BodyContent
 654  
      */
 655  
     protected UIComponent createVerbatimComponentFromBodyContent()
 656  
     {
 657  0
         UIOutput verbatimComp = null;
 658  
 
 659  0
         if (bodyContent != null)
 660  
         {
 661  0
             String strContent = bodyContent.getString();
 662  
 
 663  0
             if (strContent != null)
 664  
             {
 665  0
                 String trimmedContent = strContent.trim();
 666  0
                 if (trimmedContent.length() > 0 && !isComment(strContent))
 667  
                 {
 668  0
                     verbatimComp = createVerbatimComponent();
 669  0
                     verbatimComp.setValue(strContent);
 670  
                 }
 671  
             }
 672  
 
 673  0
             bodyContent.clearBody();
 674  
         }
 675  
 
 676  0
         return verbatimComp;
 677  
     }
 678  
 
 679  
     private static boolean isComment(String bodyContent)
 680  
     {
 681  0
         return (bodyContent.startsWith("<!--") && bodyContent.endsWith("-->"));
 682  
     }
 683  
 
 684  
     /**
 685  
      * <p>Creates a transient UIOutput using the Application, with the following characteristics:</p>
 686  
      * <p/>
 687  
      * <p><code>componentType</code> is
 688  
      * <code>javax.faces.HtmlOutputText</code>.</p>
 689  
      * <p/>
 690  
      * <p><code>transient</code> is <code>true</code>.</p>
 691  
      * <p/>
 692  
      * <p><code>escape</code> is <code>false</code>.</p>
 693  
      * <p/>
 694  
      * <p><code>id</code> is
 695  
      * <code>FacesContext.getViewRoot().createUniqueId()</code></p>
 696  
      */
 697  
     protected UIOutput createVerbatimComponent()
 698  
     {
 699  0
         UIOutput verbatimComp = (UIOutput) getFacesContext().getApplication()
 700  
                 .createComponent("javax.faces.HtmlOutputText");
 701  0
         verbatimComp.setTransient(true);
 702  0
         verbatimComp.getAttributes().put("escape", Boolean.FALSE);
 703  0
         verbatimComp.setId(getFacesContext().getViewRoot().createUniqueId());
 704  
 
 705  0
         return verbatimComp;
 706  
     }
 707  
 
 708  
     protected void addVerbatimBeforeComponent(
 709  
             UIComponentClassicTagBase parentTag,
 710  
             UIComponent verbatimComp,
 711  
             UIComponent component)
 712  
     {
 713  0
         UIComponent parent = component.getParent();
 714  
 
 715  0
         if (parent == null)
 716  
         {
 717  0
             return;
 718  
         }
 719  
 
 720  0
         List<UIComponent> children = parent.getChildren();
 721  
         // EDGE CASE:
 722  
         // Consider CASE 1 or 2 where the _componentInstance is provided via a
 723  
         // _componentInstance binding in session or application scope.
 724  
         // The automatically created UIOuput instances for the template text
 725  
         // will already be present.  Check the JSP_CREATED_COMPONENT_IDS attribute,
 726  
         // if present and the number of created components is the same
 727  
         // as the number of children replace at a -1 offset from the current
 728  
         // value of indexOfComponentInParent, otherwise, call add()
 729  
 
 730  0
         List<String> childrenAddedIds = (List<String>)
 731  
                 parent.getAttributes().get(FORMER_CHILD_IDS_SET_ATTR);
 732  
 
 733  
 
 734  0
         int parentIndex = children.indexOf(component);
 735  
 
 736  0
          if (childrenAddedIds != null)
 737  
          {
 738  0
              if (parentIndex > 0 && childrenAddedIds.size() == parentIndex)
 739  
              {
 740  0
                  UIComponent formerVerbatim = children.get(parentIndex - 1);
 741  
 
 742  0
                  if (formerVerbatim instanceof UIOutput && formerVerbatim.isTransient())
 743  
                  {
 744  0
                      children.set(parentIndex - 1, verbatimComp);
 745  
                  }
 746  
              }
 747  
          }
 748  
 
 749  0
         children.add(parentIndex, verbatimComp);
 750  
 
 751  0
         parentTag.addChild(verbatimComp);
 752  0
     }
 753  
 
 754  
     /**
 755  
      * <p>Add <i>verbatim</i> as a sibling of <i>_componentInstance</i> in
 756  
      * <i>_componentInstance</i> in the parent's child list.  <i>verbatim</i> is
 757  
      * added to the list at the position immediatly following
 758  
      * <i>_componentInstance</i>.</p>
 759  
      */
 760  
 
 761  
     protected void addVerbatimAfterComponent(UIComponentClassicTagBase parentTag,
 762  
                                              UIComponent verbatim,
 763  
                                              UIComponent component)
 764  
     {
 765  0
         int indexOfComponentInParent = 0;
 766  0
         UIComponent parent = component.getParent();
 767  
 
 768  
         // invert the order of this if and the assignment below.  Since this line is
 769  
         // here, it appears an early return is acceptable/desired if parent is null,
 770  
         // and, if it is null, we should probably check for that before we try to
 771  
         // access it.  2006-03-15 jdl
 772  0
         if (null == parent)
 773  
         {
 774  0
             return;
 775  
         }
 776  0
         List<UIComponent> children = parent.getChildren();
 777  0
         indexOfComponentInParent = children.indexOf(component);
 778  0
         if (children.size() - 1 == indexOfComponentInParent)
 779  
         {
 780  0
             children.add(verbatim);
 781  
         }
 782  
         else
 783  
         {
 784  0
             children.add(indexOfComponentInParent + 1, verbatim);
 785  
         }
 786  0
         parentTag.addChild(verbatim);
 787  0
     }
 788  
 
 789  
     /**
 790  
      * @deprecated the ResponseWriter is now set by {@link
 791  
      * javax.faces.application.ViewHandler#renderView}
 792  
      */
 793  
     protected void setupResponseWriter() {
 794  0
     }
 795  
 
 796  
     /**
 797  
      * Invoke encodeBegin on the associated UIComponent. Subclasses can
 798  
      * override this method to perform custom processing before or after
 799  
      * the UIComponent method invocation.
 800  
      */
 801  
     protected void encodeBegin()
 802  
             throws IOException
 803  
     {
 804  0
         if (log.isLoggable(Level.FINE))
 805  0
             log.fine("Entered encodeBegin for client-Id: " + _componentInstance.getClientId(getFacesContext()));
 806  0
         _componentInstance.encodeBegin(getFacesContext());
 807  0
         if (log.isLoggable(Level.FINE))
 808  0
             log.fine("Exited encodeBegin");
 809  0
     }
 810  
 
 811  
     /**
 812  
      * Invoke encodeChildren on the associated UIComponent. Subclasses can
 813  
      * override this method to perform custom processing before or after
 814  
      * the UIComponent method invocation. This is only invoked for components
 815  
      * whose getRendersChildren method returns true.
 816  
      */
 817  
     protected void encodeChildren()
 818  
             throws IOException
 819  
     {
 820  0
         if (log.isLoggable(Level.FINE))
 821  0
             log.fine("Entered encodeChildren for client-Id: " + _componentInstance.getClientId(getFacesContext()));
 822  0
         _componentInstance.encodeChildren(getFacesContext());
 823  0
         if (log.isLoggable(Level.FINE))
 824  0
             log.fine("Exited encodeChildren for client-Id: " + _componentInstance.getClientId(getFacesContext()));
 825  0
     }
 826  
 
 827  
     /**
 828  
      * Invoke encodeEnd on the associated UIComponent. Subclasses can override this
 829  
      * method to perform custom processing before or after the UIComponent method
 830  
      * invocation.
 831  
      */
 832  
     protected void encodeEnd()
 833  
             throws IOException
 834  
     {
 835  0
         if (log.isLoggable(Level.FINE))
 836  0
             log.fine("Entered encodeEnd for client-Id: " + _componentInstance.getClientId(getFacesContext()));
 837  0
         _componentInstance.encodeEnd(getFacesContext());
 838  0
         if (log.isLoggable(Level.FINE))
 839  0
             log.fine("Exited encodeEnd for client-Id: " + _componentInstance.getClientId(getFacesContext()));
 840  
 
 841  0
     }
 842  
 
 843  
 
 844  
 
 845  
     private boolean isRootTag(UIComponentClassicTagBase parentTag)
 846  
     {
 847  0
         return (parentTag == this);
 848  
     }
 849  
 
 850  
     private boolean isInRenderedChildrenComponent (UIComponentClassicTagBase tag)
 851  
     {
 852  0
         return (_parentClassicTag != null && tag.getComponentInstance().getRendersChildren());
 853  
     }
 854  
 
 855  
     private boolean isFacet()
 856  
     {
 857  0
         return _parent != null && _parent instanceof FacetTag;
 858  
     }
 859  
 
 860  
     /** Map of <ID,Tag> in the view */
 861  
     @SuppressWarnings("unchecked")
 862  
     private Map<String, Object> getViewComponentIds()
 863  
     {
 864  0
         Map<String, Object> requestMap = _facesContext.getExternalContext().getRequestMap();
 865  
         Map<String, Object> viewComponentIds;
 866  
 
 867  0
         if (_parent == null)
 868  
         {
 869  
             // top level _componentInstance
 870  0
             viewComponentIds = new HashMap<String, Object>();
 871  0
             requestMap.put(VIEW_IDS, viewComponentIds);
 872  
         }
 873  
         else
 874  
         {
 875  0
             viewComponentIds = (Map<String, Object>)requestMap.get(VIEW_IDS);
 876  
             
 877  
             // Check if null, this can happen if someone programatically tries to do an include of a 
 878  
             // JSP fragment. This code will prevent NullPointerException from happening in such cases.
 879  0
             if (viewComponentIds == null)
 880  
             {
 881  0
                 viewComponentIds = new HashMap<String, Object>();
 882  0
                 requestMap.put(VIEW_IDS, viewComponentIds);
 883  
             }
 884  
         }
 885  
 
 886  0
         return viewComponentIds;
 887  
     }
 888  
 
 889  
 
 890  
     private static final Stack<UIComponentClassicTagBase> getStack(PageContext pageContext)
 891  
     {
 892  0
         Stack<UIComponentClassicTagBase> stack = (Stack<UIComponentClassicTagBase>) pageContext.getAttribute(COMPONENT_STACK_ATTR,
 893  
                 PageContext.REQUEST_SCOPE);
 894  
 
 895  0
         if (stack == null)
 896  
         {
 897  0
             stack = new Stack<UIComponentClassicTagBase>();
 898  0
             pageContext.setAttribute(COMPONENT_STACK_ATTR,
 899  
                     stack, PageContext.REQUEST_SCOPE);
 900  
         }
 901  
 
 902  0
         return stack;
 903  
     }
 904  
 
 905  
     /**
 906  
      * The pageContext's request scope map is used to hold a stack of
 907  
      * JSP tag objects seen so far, so that a new tag can find the
 908  
      * parent tag that encloses it. Access to the parent tag is used
 909  
      * to find the parent UIComponent for the component associated
 910  
      * with this tag plus some other uses.
 911  
      */
 912  
     private void popTag()
 913  
     {
 914  0
         Stack<UIComponentClassicTagBase> stack = getStack(pageContext);
 915  
 
 916  0
         int size = stack.size();
 917  0
         stack.remove(size -1);
 918  0
         if (size <= 1)
 919  0
             pageContext.removeAttribute(COMPONENT_STACK_ATTR,
 920  
                                          PageContext.REQUEST_SCOPE);
 921  
 
 922  0
     }
 923  
 
 924  
     private void pushTag()
 925  
     {
 926  0
         getStack(pageContext).add(this);
 927  0
     }
 928  
 
 929  
     //private boolean isIncludedOrForwarded() {
 930  
     //    return getFacesContext().getExternalContext().getRequestMap().
 931  
     //            containsKey("javax.servlet.include.request_uri");
 932  
     //}
 933  
 
 934  
      /** Generate diagnostic output. */
 935  
     private String getPathToComponent(UIComponent component)
 936  
     {
 937  0
         StringBuffer buf = new StringBuffer();
 938  
 
 939  0
         if(component == null)
 940  
         {
 941  0
             buf.append("{Component-Path : ");
 942  0
             buf.append("[null]}");
 943  0
             return buf.toString();
 944  
         }
 945  
 
 946  0
         getPathToComponent(component,buf);
 947  
 
 948  0
         buf.insert(0,"{Component-Path : ");
 949  0
         buf.append("}");
 950  
 
 951  0
         return buf.toString();
 952  
     }
 953  
 
 954  
     /** Generate diagnostic output. */
 955  
     private static void getPathToComponent(UIComponent component, StringBuffer buf)
 956  
     {
 957  0
         if(component == null)
 958  0
             return;
 959  
 
 960  0
         StringBuffer intBuf = new StringBuffer();
 961  
 
 962  0
         intBuf.append("[Class: ");
 963  0
         intBuf.append(component.getClass().getName());
 964  0
         if(component instanceof UIViewRoot)
 965  
         {
 966  0
             intBuf.append(",ViewId: ");
 967  0
             intBuf.append(((UIViewRoot) component).getViewId());
 968  
         }
 969  
         else
 970  
         {
 971  0
             intBuf.append(",Id: ");
 972  0
             intBuf.append(component.getId());
 973  
         }
 974  0
         intBuf.append("]");
 975  
 
 976  0
         buf.insert(0,intBuf);
 977  
 
 978  0
         getPathToComponent(component.getParent(),buf);
 979  0
     }
 980  
 
 981  
     /**
 982  
      * Remove any child components of the associated components which do not
 983  
      * have corresponding tags as children of this tag. This only happens
 984  
      * when a view is being re-rendered and there are components in the view
 985  
      * tree which don't have corresponding JSP tags. Wrapping JSF tags in
 986  
      * JSTL "c:if" statements is one way this can happen.
 987  
      * <br />
 988  
      * Attention: programmatically added components are are not affected by this:
 989  
      * they will not be on the old list of created components nor on the new list
 990  
      * of created components, so nothing will happen to them.
 991  
      */
 992  
     private void removeFormerChildren(UIComponent component)
 993  
     {
 994  0
         List<String> formerChildIds = (List<String>)component.getAttributes().get(FORMER_CHILD_IDS_SET_ATTR);
 995  0
         if (formerChildIds != null)
 996  
         {
 997  0
             for (String childId : formerChildIds)
 998  
             {
 999  0
                 if (_childrenAdded == null || !_childrenAdded.contains(childId))
 1000  
                 {
 1001  0
                     UIComponent childToRemove = component.findComponent(childId);
 1002  0
                     if (childToRemove != null)
 1003  
                     {
 1004  0
                         component.getChildren().remove(childToRemove);
 1005  
                     }
 1006  0
                 }
 1007  
             }
 1008  0
             if (_childrenAdded == null)
 1009  
             {
 1010  0
                 component.getAttributes().remove(FORMER_CHILD_IDS_SET_ATTR);
 1011  
             }
 1012  
             else
 1013  
             {
 1014  0
                 component.getAttributes().put(FORMER_CHILD_IDS_SET_ATTR, _childrenAdded);
 1015  
             }
 1016  
         }
 1017  
         else
 1018  
         {
 1019  0
             if (_childrenAdded != null)
 1020  
             {
 1021  0
                 component.getAttributes().put(FORMER_CHILD_IDS_SET_ATTR, _childrenAdded);
 1022  
             }
 1023  
         }
 1024  0
     }
 1025  
 
 1026  
     /** See removeFormerChildren. */
 1027  
     private void removeFormerFacets(UIComponent component)
 1028  
     {
 1029  0
         List<String> formerFacetNames = (List<String>)component.getAttributes().get(FORMER_FACET_NAMES_SET_ATTR);
 1030  0
         if (formerFacetNames != null)
 1031  
         {
 1032  0
             for (String facetName : formerFacetNames)
 1033  
             {
 1034  0
                 if (_facetsAdded == null || !_facetsAdded.contains(facetName)) {
 1035  0
                     component.getFacets().remove(facetName);
 1036  
                 }
 1037  
             }
 1038  0
             if (_facetsAdded == null)
 1039  
             {
 1040  0
                 component.getAttributes().remove(FORMER_FACET_NAMES_SET_ATTR);
 1041  
             }
 1042  
             else
 1043  
             {
 1044  0
                 component.getAttributes().put(FORMER_FACET_NAMES_SET_ATTR, _facetsAdded);
 1045  
             }
 1046  
         }
 1047  
         else
 1048  
         {
 1049  0
             if (_facetsAdded != null)
 1050  
             {
 1051  0
                 component.getAttributes().put(FORMER_FACET_NAMES_SET_ATTR, _facetsAdded);
 1052  
             }
 1053  
         }
 1054  0
     }
 1055  
 
 1056  
     /**
 1057  
      * Return the corresponding UIComponent for this tag, creating it
 1058  
      * if necessary.
 1059  
      * <p>
 1060  
      * If this is not the first time this method has been called, then
 1061  
      * return the cached _componentInstance instance found last time.
 1062  
      * <p>
 1063  
      * If this is not the first time this view has been seen, then
 1064  
      * locate the existing _componentInstance using the id attribute assigned
 1065  
      * to this tag and return it. Note that this is simple for
 1066  
      * components with user-assigned ids. For components with
 1067  
      * generated ids, the "reattachment" relies on the fact that
 1068  
      * UIViewRoot will generate the same id values for tags in
 1069  
      * this page as it did when first generating the view. For this
 1070  
      * reason all JSF tags within a JSTL "c:if" are required to have
 1071  
      * explicitly-assigned ids.
 1072  
      * <p>
 1073  
      * Otherwise create the _componentInstance, populate its properties from
 1074  
      * the xml attributes on this JSP tag and attach it to its parent.
 1075  
      * <p>
 1076  
      * When a _componentInstance is found or created the parent JSP tag is also
 1077  
      * told that the _componentInstance has been "seen". When the parent tag
 1078  
      * ends it will delete any components which were in the view
 1079  
      * previously but have not been seen this time; see doEndTag for
 1080  
      * more details.
 1081  
      */
 1082  
     protected UIComponent findComponent(FacesContext context)
 1083  
             throws JspException
 1084  
     {
 1085  
         // 1. If we have previously located this component, return it.
 1086  0
         if (_componentInstance != null)
 1087  
         {
 1088  0
             return _componentInstance;
 1089  
         }
 1090  
 
 1091  
         // 2. Locate the parent component by looking for a parent UIComponentTag instance,
 1092  
         // and ask it for its component. If there is no parent UIComponentTag instance,
 1093  
         // this tag represents the root component, so get it from the current Tree and return it.
 1094  0
         UIComponentClassicTagBase parentTag = getParentUIComponentClassicTagBase(pageContext);
 1095  
 
 1096  0
         if (parentTag == null)
 1097  
         {
 1098  
             // This is the root
 1099  0
             _componentInstance = context.getViewRoot();
 1100  
 
 1101  
             // check if the view root is already bound to the tag
 1102  0
             Object alreadyBoundViewRootFlag = _componentInstance.getAttributes().get(BOUND_VIEW_ROOT);
 1103  
 
 1104  0
             if (alreadyBoundViewRootFlag == null)
 1105  
             {
 1106  
                 try
 1107  
                 {
 1108  0
                     setProperties(_componentInstance);
 1109  
                 }
 1110  0
                 catch (Throwable e)
 1111  
                 {
 1112  0
                     throw new JspException(e);
 1113  0
                 }
 1114  
 
 1115  0
                 if (_id != null)
 1116  
                 {
 1117  0
                     _componentInstance.setId(_id);
 1118  
                 }
 1119  
                 else
 1120  
                 {
 1121  0
                     _componentInstance.setId(getFacesJspId());
 1122  
                 }
 1123  0
                 _componentInstance.getAttributes().put(BOUND_VIEW_ROOT, true);
 1124  0
                 _created = true;
 1125  
 
 1126  
             }
 1127  0
             else if (hasBinding())
 1128  
             {
 1129  0
                 setProperties(_componentInstance);
 1130  
             }
 1131  
 
 1132  0
             return _componentInstance;
 1133  
         }
 1134  
 
 1135  0
         UIComponent parent = parentTag.getComponentInstance();
 1136  
 
 1137  0
         if (parent == null)
 1138  
         {
 1139  0
             throw new IllegalStateException("parent is null?");
 1140  
         }
 1141  
 
 1142  0
         String facetName = getFacetName();
 1143  0
         if (facetName != null)
 1144  
         {
 1145  
             //Facet
 1146  0
             String id = createUniqueId(context, parent);
 1147  0
             _componentInstance = parent.getFacet(facetName);
 1148  0
             if (_componentInstance == null)
 1149  
             {
 1150  0
                 _componentInstance = createComponent(context, id);
 1151  0
                 _created = true;
 1152  0
                 parent.getFacets().put(facetName, _componentInstance);
 1153  
             }
 1154  
             else
 1155  
             {
 1156  0
                 if (checkFacetNameOnParentExists(parentTag, facetName))
 1157  
                 {
 1158  0
                     throw new IllegalStateException("facet '" + facetName + "' already has a child associated. current associated _componentInstance id: "
 1159  
                             + _componentInstance.getClientId(context) + " class: " + _componentInstance.getClass().getName());
 1160  
                 }
 1161  
             }
 1162  
 
 1163  0
             addFacetNameToParentTag(parentTag, facetName);
 1164  0
             return _componentInstance;
 1165  
         }
 1166  
 
 1167  
         //Child
 1168  
         //
 1169  
         // Note that setProperties is called only when we create the
 1170  
         // _componentInstance; on later passes, the attributes defined on the
 1171  
         // JSP tag are set on this Tag object, but then completely
 1172  
         // ignored.
 1173  
 
 1174  0
         String id = createUniqueId(context, parent);
 1175  
 
 1176  
         // Warn users that this tag is about to find/steal the UIComponent
 1177  
         // that has already been created for a sibling tag with the same id value .
 1178  
         // _childrenAdded is a Set, and we will stomp over a past id when calling
 1179  
         // addChildIdToParentTag.
 1180  
         //
 1181  
         // It would also be reasonable to throw an exception here rather than
 1182  
         // just issue a warning as this is a pretty serious problem. However the
 1183  
         // Sun RI just issues a warning...
 1184  0
         if(parentTag._childrenAdded != null && parentTag._childrenAdded.contains(id))
 1185  
         {
 1186  0
             if(log.isLoggable(Level.WARNING))
 1187  0
                 log.warning("There is more than one JSF tag with an id : " + id);
 1188  
         }
 1189  
 
 1190  0
         _componentInstance = findComponent(parent,id);
 1191  0
         if (_componentInstance == null)
 1192  
         {
 1193  0
             _componentInstance = createComponent(context, id);
 1194  0
             if (id.equals(_componentInstance.getId()) )
 1195  
             {
 1196  0
                 _created = true;
 1197  0
                 int index = parentTag.getIndexOfNextChildTag();
 1198  0
                 if (index > parent.getChildCount())
 1199  
                 {
 1200  0
                     index = parent.getChildCount();
 1201  
                 }
 1202  
 
 1203  0
                 List<UIComponent> children = parent.getChildren();
 1204  0
                 children.add(index, _componentInstance);
 1205  0
             }
 1206  
             // On weblogic portal using faces-adapter, the id set and the retrieved 
 1207  
             // one for <netuix:namingContainer> is different. The reason is 
 1208  
             // this custom solution for integrate jsf changes the id of the parent
 1209  
             // component to allow the same native portlet to be allocated multiple
 1210  
             // times in the same page
 1211  0
             else if (null == findComponent(parent,_componentInstance.getId()))
 1212  
             {
 1213  0
                 _created = true;
 1214  0
                 int index = parentTag.getIndexOfNextChildTag();
 1215  0
                 if (index > parent.getChildCount())
 1216  
                 {
 1217  0
                     index = parent.getChildCount();
 1218  
                 }
 1219  
 
 1220  0
                 List<UIComponent> children = parent.getChildren();
 1221  0
                 children.add(index, _componentInstance);
 1222  
             }
 1223  
         }
 1224  
 
 1225  0
         return _componentInstance;
 1226  
 
 1227  
     }
 1228  
 
 1229  
     private UIComponent findComponent(UIComponent parent, String id)
 1230  
     {
 1231  0
         List li = parent.getChildren();
 1232  
 
 1233  0
         for (int i = 0; i < li.size(); i++)
 1234  
         {
 1235  0
             UIComponent uiComponent = (UIComponent) li.get(i);
 1236  0
             if(uiComponent.getId()!=null && uiComponent.getId().equals(id))
 1237  
             {
 1238  0
                 return uiComponent;
 1239  
             }
 1240  
         }
 1241  
 
 1242  0
         return null;
 1243  
     }
 1244  
 
 1245  
 
 1246  
     private String createUniqueId(FacesContext context, UIComponent parent)
 1247  
             throws JspException
 1248  
     {
 1249  0
         String id = getId();
 1250  0
         if (id == null)
 1251  
         {
 1252  0
             id = getFacesJspId();
 1253  
         }
 1254  0
         else if (isIdDuplicated(id))
 1255  
         {
 1256  0
             if (isInAnIterator)
 1257  
             {
 1258  0
                 setId(createNextId(id));              
 1259  0
                 id = getId();
 1260  
             }
 1261  
             else
 1262  
             {
 1263  0
                 if (parent != null)
 1264  
                 {
 1265  
 
 1266  
                     UIComponent namingContainer;
 1267  
 
 1268  0
                     if (parent instanceof NamingContainer)
 1269  
                     {
 1270  0
                         namingContainer = parent;
 1271  
                     }
 1272  
                     else
 1273  
                     {
 1274  0
                         namingContainer = parent.getParent();
 1275  
                     }
 1276  
 
 1277  0
                     if (namingContainer != null)
 1278  
                     {
 1279  0
                         UIComponent component = namingContainer.findComponent(id);
 1280  
 
 1281  0
                         if (component == null || isPostBack(context))
 1282  
                         {
 1283  0
                             return id;
 1284  
                         }
 1285  
                     }
 1286  
                 }
 1287  
 
 1288  0
                 throw new JspException("Duplicated Id found in the view: " + id);
 1289  
             }
 1290  
         }
 1291  
 
 1292  0
         return id;
 1293  
     }
 1294  
 
 1295  
     private String createNextId(String componentId)
 1296  
     {
 1297  0
         Integer currentCounter = (Integer) getFacesContext().getExternalContext().getRequestMap().get(componentId);
 1298  
 
 1299  0
         int iCurrentCounter = 1;
 1300  
 
 1301  0
         if (currentCounter != null)
 1302  
         {
 1303  0
             iCurrentCounter = currentCounter.intValue();
 1304  0
             iCurrentCounter++;
 1305  
         }
 1306  
 
 1307  0
         getFacesContext().getExternalContext().getRequestMap().put(componentId, new Integer(iCurrentCounter));
 1308  
 
 1309  
         //if (isIncludedOrForwarded())
 1310  
         //{
 1311  
         //    componentId = componentId + "pc" + iCurrentCounter;
 1312  
         //}
 1313  
         //else
 1314  
         //{
 1315  0
         componentId = componentId + UNIQUE_ID_PREFIX + iCurrentCounter;            
 1316  
         //}
 1317  
 
 1318  0
         return componentId;
 1319  
     }
 1320  
         
 1321  
     private void checkIfItIsInAnIterator(String jspId)
 1322  
     {
 1323  0
         Set<String> previousJspIdsSet = getPreviousJspIdsSet();
 1324  
 
 1325  0
         if (previousJspIdsSet.contains(jspId))
 1326  
         {
 1327  0
             isInAnIterator = true;
 1328  
         }
 1329  
         else
 1330  
         {
 1331  0
             previousJspIdsSet.add(jspId);
 1332  0
             isInAnIterator = false;
 1333  
         }
 1334  0
     }
 1335  
 
 1336  
     private Set<String> getPreviousJspIdsSet()
 1337  
     {
 1338  0
         Set<String> previousJspIdsSet = (Set<String>) getFacesContext().getExternalContext()
 1339  
                 .getRequestMap().get(PREVIOUS_JSP_IDS_SET);
 1340  
 
 1341  0
         if (previousJspIdsSet == null)
 1342  
         {
 1343  0
             previousJspIdsSet = new HashSet<String>();
 1344  
             //Add it to the context! The next time is called
 1345  
             //this method it takes the ref from the RequestContext
 1346  0
             getFacesContext().getExternalContext().getRequestMap()
 1347  
                 .put(PREVIOUS_JSP_IDS_SET, previousJspIdsSet);
 1348  
         }
 1349  
 
 1350  0
         return previousJspIdsSet;
 1351  
     }
 1352  
 
 1353  
     private boolean isIdDuplicated(String componentId)
 1354  
     {
 1355  0
         boolean result = false;
 1356  0
         if (_parentClassicTag != null)
 1357  
         {
 1358  0
             if (_parentClassicTag.isInAnIterator)
 1359  
             {
 1360  0
                 return true;
 1361  
             }
 1362  0
             List childComponents = _parentClassicTag.getCreatedComponents();
 1363  
 
 1364  0
             if (childComponents != null)
 1365  
             {
 1366  0
                 result = childComponents.contains(componentId);
 1367  0
                 if (result && (!isInAnIterator))
 1368  
                 {
 1369  0
                     return true;
 1370  
                 }
 1371  
             }
 1372  
         }
 1373  
 
 1374  0
         return result;
 1375  
     }
 1376  
 
 1377  
     private boolean isPostBack(FacesContext facesContext)
 1378  
     {
 1379  0
         return facesContext.getExternalContext().getRequestParameterMap().
 1380  
               containsKey(ResponseStateManager.VIEW_STATE_PARAM);
 1381  
     }
 1382  
 
 1383  
 
 1384  
     /**
 1385  
      * check if the facet is already added to the parent
 1386  
      */
 1387  
     private boolean checkFacetNameOnParentExists(UIComponentClassicTagBase parentTag, String facetName)
 1388  
     {
 1389  0
         return parentTag._facetsAdded != null && parentTag._facetsAdded.contains(facetName);
 1390  
     }
 1391  
 
 1392  
     /**
 1393  
      * Notify the enclosing JSP tag of the id of this facet's id. The parent
 1394  
      * tag will later delete any existing view facets that were not seen
 1395  
      * during this rendering phase; see doEndTag for details.
 1396  
      */
 1397  
     private void addFacetNameToParentTag(UIComponentClassicTagBase parentTag, String facetName)
 1398  
     {
 1399  0
         if (parentTag._facetsAdded == null)
 1400  
         {
 1401  0
             parentTag._facetsAdded = new ArrayList<String>();
 1402  
         }
 1403  0
         parentTag._facetsAdded.add(facetName);
 1404  0
     }
 1405  
 
 1406  
     protected abstract boolean hasBinding();
 1407  
 
 1408  
     public JspWriter getPreviousOut() {
 1409  0
         return bodyContent.getEnclosingWriter();
 1410  
     }
 1411  
 }