Coverage Report - org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport
 
Classes in this File Line Coverage Branch Coverage Complexity
ComponentSupport
0%
0/311
0%
0/228
6.84
 
 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 org.apache.myfaces.view.facelets.tag.jsf;
 20  
 
 21  
 import java.io.IOException;
 22  
 import java.lang.reflect.InvocationTargetException;
 23  
 import java.lang.reflect.Method;
 24  
 import java.util.Collection;
 25  
 import java.util.Iterator;
 26  
 import java.util.Locale;
 27  
 import java.util.Map;
 28  
 
 29  
 import javax.faces.FacesException;
 30  
 import javax.faces.component.NamingContainer;
 31  
 import javax.faces.component.UIComponent;
 32  
 import javax.faces.component.UIPanel;
 33  
 import javax.faces.component.UIViewRoot;
 34  
 import javax.faces.component.UniqueIdVendor;
 35  
 import javax.faces.context.FacesContext;
 36  
 import javax.faces.view.facelets.FaceletContext;
 37  
 import javax.faces.view.facelets.TagAttribute;
 38  
 import javax.faces.view.facelets.TagAttributeException;
 39  
 
 40  
 import org.apache.myfaces.shared.config.MyfacesConfig;
 41  
 import org.apache.myfaces.view.facelets.ComponentState;
 42  
 import org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy;
 43  
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 44  
 import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage;
 45  
 import org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguageBase;
 46  
 
 47  
 /**
 48  
  * 
 49  
  * @author Jacob Hookom
 50  
  * @version $Id$
 51  
  */
 52  0
 public final class ComponentSupport
 53  
 {
 54  
     private static final Method SET_CACHED_FACES_CONTEXT;
 55  
         
 56  
     static
 57  
     {
 58  0
         Method method = null;
 59  
         try
 60  
         {
 61  
             // The trick here is define this method in UIComponent as a class scoped method
 62  
             // and get it from there. Even if the real implementation is in UIComponentBase,
 63  
             // the jvm will always call the right one and in case of a instance not extending
 64  
             // from UIComponentBase it will call a dummy method.
 65  0
             method = UIComponent.class.getDeclaredMethod("setCachedFacesContext", FacesContext.class);
 66  0
             method.setAccessible(true);
 67  
         }
 68  0
         catch (NoSuchMethodException ex)
 69  
         {
 70  0
             method = null;
 71  
         }
 72  0
         catch (SecurityException ex)
 73  
         {
 74  0
             method = null;
 75  0
         }
 76  0
         SET_CACHED_FACES_CONTEXT = method;
 77  0
     }
 78  
 
 79  
     private final static String MARK_DELETED = "oam.vf.MARK_DELETED";
 80  
     public final static String MARK_CREATED = "oam.vf.MARK_ID";
 81  
     
 82  
     /**
 83  
      * The UIPanel components, which are dynamically generated to serve as a container for
 84  
      * facets with multiple non panel children, are marked with this attribute.
 85  
      * This constant is duplicate in javax.faces.webapp.UIComponentClassicTagBase
 86  
      */
 87  
     public final static String FACET_CREATED_UIPANEL_MARKER = "oam.vf.createdUIPanel";
 88  
 
 89  
     /**
 90  
      * Special myfaces core marker to indicate the component is handled by a facelet tag handler,
 91  
      * so its creation is not handled by user programatically and PSS remove listener should
 92  
      * not register it when a remove happens.
 93  
      */
 94  
     public final static String COMPONENT_ADDED_BY_HANDLER_MARKER = "oam.vf.addedByHandler";
 95  
 
 96  
     /**
 97  
      * The key under the facelet state map is stored
 98  
      */
 99  
     public final static String FACELET_STATE_INSTANCE = "oam.FACELET_STATE_INSTANCE";
 100  
 
 101  
     /**
 102  
      * Used in conjunction with markForDeletion where any UIComponent marked will be removed.
 103  
      * 
 104  
      * @deprecated use FaceletCompositionContext.finalizeForDeletion
 105  
      * @param component
 106  
      *            UIComponent to finalize
 107  
      */
 108  
     @Deprecated
 109  
     public static void finalizeForDeletion(UIComponent component)
 110  
     {
 111  
         // remove any existing marks of deletion
 112  0
         component.getAttributes().remove(MARK_DELETED);
 113  
 
 114  
         // finally remove any children marked as deleted
 115  0
         if (component.getChildCount() > 0)
 116  
         {
 117  0
             for (Iterator<UIComponent> iter = component.getChildren().iterator(); iter.hasNext();)
 118  
             {
 119  0
                 UIComponent child = iter.next();
 120  0
                 if (child.getAttributes().containsKey(MARK_DELETED))
 121  
                 {
 122  0
                     iter.remove();
 123  
                 }
 124  0
             }
 125  
         }
 126  
 
 127  
         // remove any facets marked as deleted
 128  0
         if (component.getFacetCount() > 0)
 129  
         {
 130  0
             Map<String, UIComponent> facets = component.getFacets();
 131  0
             Collection<UIComponent> col = facets.values();
 132  0
             for (Iterator<UIComponent> itr = col.iterator(); itr.hasNext();)
 133  
             {
 134  0
                 UIComponent fc = itr.next();
 135  0
                 if (fc.getAttributes().containsKey(MARK_DELETED))
 136  
                 {
 137  0
                     itr.remove();
 138  
                 }
 139  0
             }
 140  
         }
 141  0
     }
 142  
 
 143  
     /**
 144  
      * A lighter-weight version of UIComponent's findChild.
 145  
      * 
 146  
      * @param parent
 147  
      *            parent to start searching from
 148  
      * @param id
 149  
      *            to match to
 150  
      * @return UIComponent found or null
 151  
      */
 152  
     public static UIComponent findChild(UIComponent parent, String id)
 153  
     {
 154  0
         int childCount = parent.getChildCount();
 155  0
         if (childCount > 0)
 156  
         {
 157  0
             for (int i = 0; i < childCount; i++)
 158  
             {
 159  0
                 UIComponent child = parent.getChildren().get(i);
 160  0
                 if (id.equals(child.getId()))
 161  
                 {
 162  0
                     return child;
 163  
                 }
 164  
             }
 165  
         }
 166  0
         return null;
 167  
     }
 168  
     
 169  
     public static String findFacetNameByComponentInstance(
 170  
         UIComponent parent, UIComponent instance)
 171  
     {
 172  0
         if (parent.getFacetCount() > 0)
 173  
         {
 174  0
             for (Map.Entry<String, UIComponent> entry : parent.getFacets().entrySet())
 175  
             {
 176  0
                 UIComponent facet = entry.getValue();
 177  
                 // check if this is a dynamically generated UIPanel
 178  0
                 if (Boolean.TRUE.equals(facet.getAttributes()
 179  
                              .get(FACET_CREATED_UIPANEL_MARKER)))
 180  
                 {
 181  
                     // only check the children and facets of the panel
 182  0
                     if (facet.getChildCount() > 0)
 183  
                     {
 184  0
                         for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
 185  
                         {
 186  0
                             UIComponent child = facet.getChildren().get(i);
 187  0
                             if (instance.equals(child))
 188  
                             {
 189  0
                                 return entry.getKey();
 190  
                             }
 191  
                         }
 192  
                     }
 193  0
                     if (facet.getFacetCount() > 0)
 194  
                     {
 195  0
                         Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
 196  0
                         while (itr2.hasNext())
 197  
                         {
 198  0
                             UIComponent child = itr2.next();
 199  0
                             if (instance.equals(child))
 200  
                             {
 201  0
                                 return entry.getKey();
 202  
                             }
 203  0
                         }
 204  0
                     }
 205  
                 }
 206  0
                 else if (instance.equals(facet))
 207  
                 {
 208  0
                     return entry.getKey();
 209  
                 }
 210  0
             }
 211  0
             return null;
 212  
         }
 213  0
         return null;
 214  
     }
 215  
 
 216  
     public static UIComponent findChildInFacetByTagId(
 217  
         UIComponent parent, String id, String facetName)
 218  
     {
 219  0
         if (parent.getFacetCount() > 0)
 220  
         {
 221  0
             UIComponent facet = parent.getFacet(facetName);
 222  0
             if (facet != null)
 223  
             {
 224  
                 // check if this is a dynamically generated UIPanel
 225  0
                 if (Boolean.TRUE.equals(facet.getAttributes()
 226  
                              .get(FACET_CREATED_UIPANEL_MARKER)))
 227  
                 {
 228  
                     // only check the children and facets of the panel
 229  0
                     if (facet.getChildCount() > 0)
 230  
                     {
 231  0
                         for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
 232  
                         {
 233  0
                             UIComponent child = facet.getChildren().get(i);
 234  0
                             if (id.equals(child.getAttributes().get(MARK_CREATED)))
 235  
                             {
 236  0
                                 return child;
 237  
                             }
 238  
                         }
 239  
                     }
 240  0
                     if (facet.getFacetCount() > 0)
 241  
                     {
 242  0
                         Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
 243  0
                         while (itr2.hasNext())
 244  
                         {
 245  0
                             UIComponent child = itr2.next();
 246  0
                             if (id.equals(child.getAttributes().get(MARK_CREATED)))
 247  
                             {
 248  0
                                 return child;
 249  
                             }
 250  0
                         }
 251  0
                     }
 252  
                 }
 253  0
                 else if (id.equals(facet.getAttributes().get(MARK_CREATED)))
 254  
                 {
 255  0
                     return facet;
 256  
                 }
 257  
             }
 258  
         }
 259  0
         return null;
 260  
     }
 261  
     
 262  
     public static UIComponent findChildInChildrenByTagId(
 263  
         UIComponent parent, String id)
 264  
     {
 265  0
         if (parent.getChildCount() > 0)
 266  
         {
 267  0
             for (int i = 0, childCount = parent.getChildCount(); i < childCount; i ++)
 268  
             {
 269  0
                 UIComponent child = parent.getChildren().get(i);
 270  0
                 if (id.equals(child.getAttributes().get(MARK_CREATED)))
 271  
                 {
 272  0
                     return child;
 273  
                 }
 274  
             }
 275  
         }
 276  0
         return null;
 277  
     }
 278  
     
 279  
     /**
 280  
      * By TagId, find Child
 281  
      * 
 282  
      * @param parent
 283  
      * @param id
 284  
      * @return
 285  
      */
 286  
     public static UIComponent findChildByTagId(UIComponent parent, String id)
 287  
     {
 288  0
         Iterator<UIComponent> itr = null;
 289  0
         if (parent.getChildCount() > 0)
 290  
         {
 291  0
             for (int i = 0, childCount = parent.getChildCount(); i < childCount; i ++)
 292  
             {
 293  0
                 UIComponent child = parent.getChildren().get(i);
 294  0
                 if (id.equals(child.getAttributes().get(MARK_CREATED)))
 295  
                 {
 296  0
                     return child;
 297  
                 }
 298  
             }
 299  
         }
 300  0
         if (parent.getFacetCount() > 0)
 301  
         {
 302  0
             itr = parent.getFacets().values().iterator();
 303  0
             while (itr.hasNext())
 304  
             {
 305  0
                 UIComponent facet = itr.next();
 306  
                 // check if this is a dynamically generated UIPanel
 307  0
                 if (Boolean.TRUE.equals(facet.getAttributes()
 308  
                              .get(FACET_CREATED_UIPANEL_MARKER)))
 309  
                 {
 310  
                     // only check the children and facets of the panel
 311  0
                     if (facet.getChildCount() > 0)
 312  
                     {
 313  0
                         for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
 314  
                         {
 315  0
                             UIComponent child = facet.getChildren().get(i);
 316  0
                             if (id.equals(child.getAttributes().get(MARK_CREATED)))
 317  
                             {
 318  0
                                 return child;
 319  
                             }
 320  
                         }
 321  
                     }
 322  0
                     if (facet.getFacetCount() > 0)
 323  
                     {
 324  0
                         Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
 325  0
                         while (itr2.hasNext())
 326  
                         {
 327  0
                             UIComponent child = itr2.next();
 328  0
                             if (id.equals(child.getAttributes().get(MARK_CREATED)))
 329  
                             {
 330  0
                                 return child;
 331  
                             }
 332  0
                         }
 333  0
                     }
 334  
                 }
 335  0
                 else if (id.equals(facet.getAttributes().get(MARK_CREATED)))
 336  
                 {
 337  0
                     return facet;
 338  
                 }
 339  0
             }
 340  
         }
 341  
 
 342  0
         return null;
 343  
     }
 344  
     
 345  
     public static String findChildInFacetsByTagId(UIComponent parent, String id)
 346  
     {
 347  0
         Iterator<Map.Entry<String, UIComponent>> itr = null;
 348  0
         if (parent.getFacetCount() > 0)
 349  
         {
 350  0
             itr = parent.getFacets().entrySet().iterator();
 351  0
             while (itr.hasNext())
 352  
             {
 353  0
                 Map.Entry<String, UIComponent> entry = itr.next();
 354  0
                 UIComponent facet = entry.getValue();
 355  
                 // check if this is a dynamically generated UIPanel
 356  0
                 if (Boolean.TRUE.equals(facet.getAttributes()
 357  
                              .get(FACET_CREATED_UIPANEL_MARKER)))
 358  
                 {
 359  
                     // only check the children and facets of the panel
 360  0
                     if (facet.getChildCount() > 0)
 361  
                     {
 362  0
                         for (int i = 0, childCount = facet.getChildCount(); i < childCount; i ++)
 363  
                         {
 364  0
                             UIComponent child = facet.getChildren().get(i);
 365  0
                             if (id.equals(child.getAttributes().get(MARK_CREATED)))
 366  
                             {
 367  0
                                 return entry.getKey();
 368  
                             }
 369  
                         }
 370  
                     }
 371  0
                     if (facet.getFacetCount() > 0)
 372  
                     {
 373  0
                         Iterator<UIComponent> itr2 = facet.getFacets().values().iterator();
 374  0
                         while (itr2.hasNext())
 375  
                         {
 376  0
                             UIComponent child = itr2.next();
 377  0
                             if (id.equals(child.getAttributes().get(MARK_CREATED)))
 378  
                             {
 379  0
                                 return entry.getKey();
 380  
                             }
 381  0
                         }
 382  0
                     }
 383  
                 }
 384  0
                 else if (id.equals(facet.getAttributes().get(MARK_CREATED)))
 385  
                 {
 386  0
                     return entry.getKey();
 387  
                 }
 388  0
             }
 389  
         }
 390  0
         return null;
 391  
     }
 392  
 
 393  
     /**
 394  
      * According to JSF 1.2 tag specs, this helper method will use the TagAttribute passed in determining the Locale
 395  
      * intended.
 396  
      * 
 397  
      * @param ctx
 398  
      *            FaceletContext to evaluate from
 399  
      * @param attr
 400  
      *            TagAttribute representing a Locale
 401  
      * @return Locale found
 402  
      * @throws TagAttributeException
 403  
      *             if the Locale cannot be determined
 404  
      */
 405  
     public static Locale getLocale(FaceletContext ctx, TagAttribute attr) throws TagAttributeException
 406  
     {
 407  0
         Object obj = attr.getObject(ctx);
 408  0
         if (obj instanceof Locale)
 409  
         {
 410  0
             return (Locale) obj;
 411  
         }
 412  0
         if (obj instanceof String)
 413  
         {
 414  0
             String s = (String) obj;
 415  0
             if (s.length() == 2)
 416  
             {
 417  0
                 return new Locale(s);
 418  
             }
 419  
 
 420  0
             if (s.length() == 5)
 421  
             {
 422  0
                 return new Locale(s.substring(0, 2), s.substring(3, 5).toUpperCase());
 423  
             }
 424  
 
 425  0
             if (s.length() >= 7)
 426  
             {
 427  0
                 return new Locale(s.substring(0, 2), s.substring(3, 5).toUpperCase(), s.substring(6, s.length()));
 428  
             }
 429  
 
 430  0
             throw new TagAttributeException(attr, "Invalid Locale Specified: " + s);
 431  
         }
 432  
         else
 433  
         {
 434  0
             throw new TagAttributeException(attr, "Attribute did not evaluate to a String or Locale: " + obj);
 435  
         }
 436  
     }
 437  
 
 438  
     /**
 439  
      * Tries to walk up the parent to find the UIViewRoot, if not found, then go to FaceletContext's FacesContext for
 440  
      * the view root.
 441  
      * 
 442  
      * @param ctx
 443  
      *            FaceletContext
 444  
      * @param parent
 445  
      *            UIComponent to search from
 446  
      * @return UIViewRoot instance for this evaluation
 447  
      */
 448  
     public static UIViewRoot getViewRoot(FaceletContext ctx, UIComponent parent)
 449  
     {
 450  0
         UIComponent c = parent;
 451  
         do
 452  
         {
 453  0
             if (c instanceof UIViewRoot)
 454  
             {
 455  0
                 return (UIViewRoot) c;
 456  
             }
 457  
             else
 458  
             {
 459  0
                 c = c.getParent();
 460  
             }
 461  0
         } while (c != null);
 462  
 
 463  0
         UIViewRoot root = ctx.getFacesContext().getViewRoot();
 464  0
         if (root == null)
 465  
         {
 466  0
             root = FaceletCompositionContext.getCurrentInstance(ctx).getViewRoot(ctx.getFacesContext());
 467  
         }
 468  0
         return root;
 469  
     }
 470  
     
 471  
     /**
 472  
      * Marks all direct children and Facets with an attribute for deletion.
 473  
      * 
 474  
      * @deprecated use FaceletCompositionContext.markForDeletion
 475  
      * @see #finalizeForDeletion(UIComponent)
 476  
      * @param component
 477  
      *            UIComponent to mark
 478  
      */
 479  
     @Deprecated
 480  
     public static void markForDeletion(UIComponent component)
 481  
     {
 482  
         // flag this component as deleted
 483  0
         component.getAttributes().put(MARK_DELETED, Boolean.TRUE);
 484  
 
 485  0
         Iterator<UIComponent> iter = component.getFacetsAndChildren();
 486  0
         while (iter.hasNext())
 487  
         {
 488  0
             UIComponent child = iter.next();
 489  0
             if (child.getAttributes().containsKey(MARK_CREATED))
 490  
             {
 491  0
                 child.getAttributes().put(MARK_DELETED, Boolean.TRUE);
 492  
             }
 493  0
         }
 494  0
     }
 495  
 
 496  
     public static void encodeRecursive(FacesContext context, UIComponent toRender) throws IOException, FacesException
 497  
     {
 498  0
         if (toRender.isRendered())
 499  
         {
 500  0
             toRender.encodeBegin(context);
 501  
             
 502  0
             if (toRender.getRendersChildren())
 503  
             {
 504  0
                 toRender.encodeChildren(context);
 505  
             }
 506  0
             else if (toRender.getChildCount() > 0)
 507  
             {
 508  0
                 for (int i = 0, childCount = toRender.getChildCount(); i < childCount; i++)
 509  
                 {
 510  0
                     UIComponent child = toRender.getChildren().get(i);
 511  0
                     encodeRecursive(context, child);
 512  
                 }
 513  
             }
 514  
             
 515  0
             toRender.encodeEnd(context);
 516  
         }
 517  0
     }
 518  
 
 519  
     public static void removeTransient(UIComponent component)
 520  
     {
 521  0
         if (component.getChildCount() > 0)
 522  
         {
 523  0
             for (Iterator<UIComponent> itr = component.getChildren().iterator(); itr.hasNext();)
 524  
             {
 525  0
                 UIComponent child = itr.next();
 526  0
                 if (child.isTransient())
 527  
                 {
 528  0
                     itr.remove();
 529  
                 }
 530  
                 else
 531  
                 {
 532  0
                     removeTransient(child);
 533  
                 }
 534  0
             }
 535  
         }
 536  
         
 537  0
         if (component.getFacetCount() > 0)
 538  
         {
 539  0
             Map<String, UIComponent> facets = component.getFacets();
 540  0
             for (Iterator<UIComponent> itr = facets.values().iterator(); itr.hasNext();)
 541  
             {
 542  0
                 UIComponent facet = itr.next();
 543  0
                 if (facet.isTransient())
 544  
                 {
 545  0
                     itr.remove();
 546  
                 }
 547  
                 else
 548  
                 {
 549  0
                     removeTransient(facet);
 550  
                 }
 551  0
             }
 552  
         }
 553  0
     }
 554  
 
 555  
     /**
 556  
      * Determine if the passed component is not null and if it's new to the tree. This operation can be used for
 557  
      * determining if attributes should be wired to the component.
 558  
      * 
 559  
      * @deprecated use ComponentHandler.isNew
 560  
      * @param component
 561  
      *            the component you wish to modify
 562  
      * @return true if it's new
 563  
      */
 564  
     @Deprecated
 565  
     public static boolean isNew(UIComponent component)
 566  
     {
 567  0
         return component != null && component.getParent() == null;
 568  
     }
 569  
     
 570  
     /**
 571  
      * Create a new UIPanel for the use as a dynamically 
 572  
      * created container for multiple children in a facet.
 573  
      * Duplicate in javax.faces.webapp.UIComponentClassicTagBase.
 574  
      * @param facesContext
 575  
      * @return
 576  
      */
 577  
     private static UIComponent createFacetUIPanel(FaceletContext ctx, UIComponent parent, String facetName)
 578  
     {
 579  0
         FacesContext facesContext = ctx.getFacesContext();
 580  0
         UIComponent panel = facesContext.getApplication().createComponent(facesContext, UIPanel.COMPONENT_TYPE, null);
 581  
         
 582  
         // The panel created by this method is special. To be restored properly and do not
 583  
         // create duplicate ids or any other unwanted conflicts, it requires an unique id.
 584  
         // This code is usually called when more than one component is added to a facet and
 585  
         // it is necessary to create a shared container.
 586  
         // Use FaceletCompositionContext.generateUniqueComponentId() is not possible, because
 587  
         // <c:if> blocks inside a facet will make component ids unstable. Use UniqueIdVendor
 588  
         // is feasible but also will be affected by <c:if> blocks inside a facet.
 589  
         // The only solution that will generate real unique ids is use the parent id and the
 590  
         // facet name and derive an unique id that cannot be generated by SectionUniqueIdCounter,
 591  
         // doing the same trick as with metadata: use a double __ and add a prefix (f).
 592  
         // Note this id will never be printed into the response, because this is just a container.
 593  0
         FaceletCompositionContext mctx = FaceletCompositionContext.getCurrentInstance(ctx);
 594  0
         UniqueIdVendor uniqueIdVendor = mctx.getUniqueIdVendorFromStack();
 595  0
         if (uniqueIdVendor == null)
 596  
         {
 597  0
             uniqueIdVendor = ComponentSupport.getViewRoot(ctx, parent);
 598  
         }
 599  0
         if (uniqueIdVendor != null)
 600  
         {
 601  
             // UIViewRoot implements UniqueIdVendor, so there is no need to cast to UIViewRoot
 602  
             // and call createUniqueId(). See ComponentTagHandlerDelegate
 603  0
             int index = facetName.indexOf('.');
 604  0
             String cleanFacetName = facetName;
 605  0
             if (index >= 0)
 606  
             {
 607  0
                 cleanFacetName = facetName.replace('.', '_');
 608  
             }
 609  0
             panel.setId(uniqueIdVendor.createUniqueId(facesContext, 
 610  
                     mctx.getSharedStringBuilder()
 611  
                       .append(parent.getId())
 612  
                       .append("__f_")
 613  
                       .append(cleanFacetName).toString()));
 614  
         }
 615  0
         panel.getAttributes().put(FACET_CREATED_UIPANEL_MARKER, Boolean.TRUE);
 616  0
         panel.getAttributes().put(ComponentSupport.COMPONENT_ADDED_BY_HANDLER_MARKER, Boolean.TRUE);
 617  0
         return panel;
 618  
     }
 619  
     
 620  
     public static void addFacet(FaceletContext ctx, UIComponent parent, UIComponent c, String facetName)
 621  
     {
 622  
         // facets now can have multiple children and the direct
 623  
         // child of a facet is always an UIPanel (since 2.0)
 624  0
         UIComponent facet = parent.getFacets().get(facetName);
 625  0
         if (facet == null)
 626  
         {
 627  
             //Just set it directly like  before
 628  0
             parent.getFacets().put(facetName, c);
 629  
         }
 630  0
         else if (!(facet instanceof UIPanel))
 631  
         {
 632  
             // there is a facet, but it is not an instance of UIPanel
 633  0
             UIComponent child = facet;
 634  0
             facet = createFacetUIPanel(ctx, parent, facetName);
 635  0
             facet.getChildren().add(child);
 636  0
             facet.getChildren().add(c);
 637  0
             parent.getFacets().put(facetName, facet);
 638  0
         }
 639  
         else
 640  
         {
 641  
             // we have a facet, which is an instance of UIPanel at this point
 642  
             // check if it is a facet marked UIPanel
 643  0
             if (Boolean.TRUE.equals(facet.getAttributes().get(FACET_CREATED_UIPANEL_MARKER)))
 644  
             {
 645  0
                 facet.getChildren().add(c);
 646  
             }
 647  
             else
 648  
             {
 649  
                 // the facet is an instance of UIPanel, but it is not marked,
 650  
                 // so we have to create a new UIPanel and store this one in it
 651  0
                 UIComponent oldPanel = facet;
 652  0
                 facet = createFacetUIPanel(ctx, parent, facetName);
 653  0
                 facet.getChildren().add(oldPanel);
 654  0
                 facet.getChildren().add(c);
 655  0
                 parent.getFacets().put(facetName, facet);
 656  
             }
 657  
         }
 658  0
     }
 659  
     
 660  
     public static void removeFacet(FaceletContext ctx, UIComponent parent, UIComponent c, String facetName)
 661  
     {
 662  0
         UIComponent facet = parent.getFacet(facetName);
 663  0
         if (Boolean.TRUE.equals(facet.getAttributes().get(FACET_CREATED_UIPANEL_MARKER)))
 664  
         {
 665  0
             facet.getChildren().remove(c);
 666  
         }
 667  
         else
 668  
         {
 669  0
             parent.getFacets().remove(facetName);
 670  
         }
 671  0
     }
 672  
 
 673  
     public static void markComponentToRestoreFully(FacesContext context, UIComponent component)
 674  
     {
 675  0
         if (MyfacesConfig.getCurrentInstance(context.getExternalContext()).isRefreshTransientBuildOnPSSPreserveState())
 676  
         {
 677  0
             component.getAttributes().put(DefaultFaceletsStateManagementStrategy.COMPONENT_ADDED_AFTER_BUILD_VIEW,
 678  
                                           ComponentState.REMOVE_ADD);
 679  
         }
 680  
         //component.subscribeToEvent(PostAddToViewEvent.class, new RestoreComponentFullyListener());
 681  0
         if (FaceletViewDeclarationLanguage.isRefreshTransientBuildOnPSSAuto(context))
 682  
         {
 683  0
             FaceletViewDeclarationLanguage.cleanTransientBuildOnRestore(context);
 684  
         }
 685  0
     }
 686  
     
 687  
     public static void markComponentToRefreshDynamically(FacesContext context, UIComponent component)
 688  
     {
 689  0
         FaceletViewDeclarationLanguageBase.dynamicComponentNeedsRefresh(context);
 690  0
     }
 691  
     
 692  
     public static UIComponent findComponentChildOrFacetFrom(FacesContext facesContext, UIComponent parent, String expr)
 693  
     {
 694  0
         final char separatorChar = facesContext.getNamingContainerSeparatorChar();
 695  0
         int separator = expr.indexOf(separatorChar);
 696  0
         if (separator == -1)
 697  
         {
 698  0
             return ComponentSupport.findComponentChildOrFacetFrom(
 699  
                     parent, expr, null);
 700  
         }
 701  
         else
 702  
         {
 703  0
             return ComponentSupport.findComponentChildOrFacetFrom(
 704  
                     parent, expr.substring(0,separator), expr);
 705  
         }
 706  
     }
 707  
     
 708  
     public static UIComponent findComponentChildOrFacetFrom(UIComponent parent, String id, String innerExpr)
 709  
     {
 710  0
         if (parent.getFacetCount() > 0)
 711  
         {
 712  0
             for (UIComponent facet : parent.getFacets().values())
 713  
             {
 714  0
                 if (id.equals(facet.getId()))
 715  
                 {
 716  0
                     if (innerExpr == null)
 717  
                     {
 718  0
                         return facet;
 719  
                     }
 720  0
                     else if (facet instanceof NamingContainer)
 721  
                     {
 722  0
                         UIComponent find = facet.findComponent(innerExpr);
 723  0
                         if (find != null)
 724  
                         {
 725  0
                             return find;
 726  
                         }
 727  0
                     }
 728  
                 }
 729  0
                 else if (!(facet instanceof NamingContainer))
 730  
                 {
 731  0
                     UIComponent find = findComponentChildOrFacetFrom(facet, id, innerExpr);
 732  0
                     if (find != null)
 733  
                     {
 734  0
                         return find;
 735  
                     }
 736  
                 }
 737  0
             }
 738  
         }
 739  0
         if (parent.getChildCount() > 0)
 740  
         {
 741  0
             for (int i = 0, childCount = parent.getChildCount(); i < childCount; i++)
 742  
             {
 743  0
                 UIComponent child = parent.getChildren().get(i);
 744  0
                 if (id.equals(child.getId()))
 745  
                 {
 746  0
                     if (innerExpr == null)
 747  
                     {
 748  0
                         return child;
 749  
                     }
 750  0
                     else if (child instanceof NamingContainer)
 751  
                     {
 752  0
                         UIComponent find = child.findComponent(innerExpr);
 753  0
                         if (find != null)
 754  
                         {
 755  0
                             return find;
 756  
                         }
 757  0
                     }
 758  
                 }
 759  0
                 else if (!(child instanceof NamingContainer))
 760  
                 {
 761  0
                     UIComponent find = findComponentChildOrFacetFrom(child, id, innerExpr);
 762  0
                     if (find != null)
 763  
                     {
 764  0
                         return find;
 765  
                     }
 766  
                 }
 767  
             }
 768  
         }
 769  0
         return null;
 770  
     }
 771  
     
 772  
     public static String getFindComponentExpression(FacesContext facesContext, UIComponent component)
 773  
     {
 774  0
         char separatorChar = facesContext.getNamingContainerSeparatorChar();
 775  0
         UIComponent parent = component.getParent();
 776  0
         StringBuilder sb = new StringBuilder();
 777  0
         sb.append(component.getId());
 778  0
         while (parent != null)
 779  
         {
 780  0
             if (parent instanceof NamingContainer)
 781  
             {
 782  0
                 sb.insert(0, separatorChar);
 783  0
                 sb.insert(0, parent.getId());
 784  
             }
 785  0
             parent = parent.getParent();
 786  
         }
 787  0
         return sb.toString();
 788  
     }
 789  
     
 790  
     public static Object restoreInitialTagState(FaceletContext ctx, FaceletCompositionContext fcc,
 791  
                                                 UIComponent parent, String uniqueId)
 792  
     {
 793  0
         Object value = null;
 794  
         //if (fcc.isUsingPSSOnThisView() &&
 795  
         //    PhaseId.RESTORE_VIEW.equals(ctx.getFacesContext().getCurrentPhaseId()) &&
 796  
         //    !MyfacesConfig.getCurrentInstance(
 797  
         //            ctx.getFacesContext().getExternalContext()).isRefreshTransientBuildOnPSSPreserveState())
 798  0
         if (fcc.isUsingPSSOnThisView() && !fcc.isRefreshTransientBuildOnPSSPreserveState())
 799  
         {
 800  0
             UIViewRoot root = getViewRoot(ctx, parent);
 801  0
             FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
 802  0
             if (map == null)
 803  
             {
 804  0
                 value = null;
 805  
             }
 806  
             else
 807  
             {
 808  0
                 value = map.getState(uniqueId);
 809  
             }
 810  
         }
 811  0
         return value;
 812  
     }
 813  
     
 814  
     public static void saveInitialTagState(FaceletContext ctx, FaceletCompositionContext fcc,
 815  
                                            UIComponent parent, String uniqueId, Object value)
 816  
     {
 817  
         // Only save the value when the view was built the first time, to ensure PSS algorithm 
 818  
         // work correctly. If preserve state is enabled, just ignore it, because this tag will
 819  
         // force full restore over the parent
 820  
         //if (fcc.isUsingPSSOnThisView()) {
 821  
         //    if (!fcc.isRefreshingTransientBuild() && !ctx.getFacesContext().isPostback()
 822  
         //        && !MyfacesConfig.getCurrentInstance(
 823  
         //            ctx.getFacesContext().getExternalContext()).isRefreshTransientBuildOnPSSPreserveState())
 824  
         
 825  
         // If we save the value each time the view is updated, we can use PSS on the dynamic parts,
 826  
         // just calling markInitialState() on the required components, simplifying the algorithm.
 827  0
         if (fcc.isUsingPSSOnThisView() && !fcc.isRefreshTransientBuildOnPSSPreserveState())
 828  
         {
 829  0
             UIViewRoot root = getViewRoot(ctx, parent);
 830  0
             FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
 831  0
             if (map == null)
 832  
             {
 833  0
                 map = new FaceletState();
 834  0
                 root.getAttributes().put(FACELET_STATE_INSTANCE, map);
 835  
             }
 836  0
             map.putState(uniqueId, value);
 837  
         }
 838  0
     }
 839  
     
 840  
     public static FaceletState getFaceletState(FaceletContext ctx, UIComponent parent, boolean create)
 841  
     {
 842  0
         UIViewRoot root = getViewRoot(ctx, parent);
 843  0
         FaceletState map = (FaceletState) root.getAttributes().get(FACELET_STATE_INSTANCE);
 844  0
         if (map == null && create)
 845  
         {
 846  0
             map = new FaceletState();
 847  0
             root.getAttributes().put(FACELET_STATE_INSTANCE, map);
 848  
         }
 849  0
         return map;
 850  
     }
 851  
     
 852  
     public static void setCachedFacesContext(UIComponent component,
 853  
         FacesContext context)
 854  
     {
 855  0
         if (SET_CACHED_FACES_CONTEXT != null)
 856  
         {
 857  
             try
 858  
             {
 859  0
                 SET_CACHED_FACES_CONTEXT.invoke(component, context);
 860  
             }
 861  0
             catch (IllegalAccessException ex)
 862  
             {
 863  
             }
 864  0
             catch (IllegalArgumentException ex)
 865  
             {
 866  
             }
 867  0
             catch (InvocationTargetException ex)
 868  
             {
 869  0
             }
 870  
         }
 871  0
     }
 872  
 }