Coverage Report - org.apache.myfaces.view.facelets.impl.DefaultFacelet
 
Classes in this File Line Coverage Branch Coverage Complexity
DefaultFacelet
0%
0/201
0%
0/110
3.391
DefaultFacelet$ApplyToken
0%
0/12
N/A
3.391
 
 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.impl;
 20  
 
 21  
 import java.io.Externalizable;
 22  
 import java.io.IOException;
 23  
 import java.io.ObjectInput;
 24  
 import java.io.ObjectOutput;
 25  
 import java.net.URL;
 26  
 import java.text.DateFormat;
 27  
 import java.text.SimpleDateFormat;
 28  
 import java.util.Collections;
 29  
 import java.util.Collection;
 30  
 import java.util.Date;
 31  
 import java.util.Iterator;
 32  
 import java.util.List;
 33  
 import java.util.Map;
 34  
 import java.util.WeakHashMap;
 35  
 import java.util.logging.Level;
 36  
 import java.util.logging.Logger;
 37  
 
 38  
 import javax.el.ELException;
 39  
 import javax.el.ExpressionFactory;
 40  
 import javax.faces.FacesException;
 41  
 import javax.faces.application.Resource;
 42  
 import javax.faces.application.ViewResource;
 43  
 import javax.faces.component.UIComponent;
 44  
 import javax.faces.component.UIViewRoot;
 45  
 import javax.faces.component.UniqueIdVendor;
 46  
 import javax.faces.context.FacesContext;
 47  
 import javax.faces.view.facelets.FaceletContext;
 48  
 import javax.faces.view.facelets.FaceletException;
 49  
 import javax.faces.view.facelets.FaceletHandler;
 50  
 import org.apache.myfaces.shared.config.MyfacesConfig;
 51  
 
 52  
 import org.apache.myfaces.view.facelets.AbstractFacelet;
 53  
 import org.apache.myfaces.view.facelets.AbstractFaceletContext;
 54  
 import org.apache.myfaces.view.facelets.FaceletCompositionContext;
 55  
 import org.apache.myfaces.view.facelets.FaceletFactory;
 56  
 import org.apache.myfaces.view.facelets.compiler.EncodingHandler;
 57  
 import org.apache.myfaces.view.facelets.tag.jsf.ComponentSupport;
 58  
 
 59  
 
 60  
 /**
 61  
  * Default Facelet implementation.
 62  
  * 
 63  
  * @author Jacob Hookom
 64  
  * @version $Id$
 65  
  */
 66  
 final class DefaultFacelet extends AbstractFacelet
 67  
 {
 68  
 
 69  
     //private static final Logger log = Logger.getLogger("facelets.facelet");
 70  0
     private static final Logger log = Logger.getLogger(DefaultFacelet.class.getName());
 71  
 
 72  
     private final static String APPLIED_KEY = "org.apache.myfaces.view.facelets.APPLIED";
 73  
 
 74  
     private final String _alias;
 75  
     
 76  
     private final String _faceletId;
 77  
 
 78  
     private final ExpressionFactory _elFactory;
 79  
 
 80  
     private final DefaultFaceletFactory _factory;
 81  
 
 82  
     private final long _createTime;
 83  
 
 84  
     private final long _refreshPeriod;
 85  
 
 86  
     private final Map<String, URL> _relativePaths;
 87  
 
 88  
     private final FaceletHandler _root;
 89  
 
 90  
     private final URL _src;
 91  
 
 92  
     private final boolean _isBuildingCompositeComponentMetadata; 
 93  
     
 94  
     private final boolean _encodingHandler;
 95  
 
 96  
     public DefaultFacelet(DefaultFaceletFactory factory, ExpressionFactory el, URL src, String alias,
 97  
                           String faceletId, FaceletHandler root)
 98  0
     {
 99  0
         _factory = factory;
 100  0
         _elFactory = el;
 101  0
         _src = src;
 102  0
         _root = root;
 103  0
         _alias = alias;
 104  0
         _faceletId = faceletId;
 105  0
         _createTime = System.currentTimeMillis();
 106  0
         _refreshPeriod = _factory.getRefreshPeriod();
 107  0
         _relativePaths = Collections.synchronizedMap(new WeakHashMap());
 108  0
         _isBuildingCompositeComponentMetadata = false;
 109  0
         _encodingHandler = (root instanceof EncodingHandler);
 110  0
     }
 111  
 
 112  
     public DefaultFacelet(DefaultFaceletFactory factory, ExpressionFactory el, URL src, String alias,
 113  
             String faceletId, FaceletHandler root, boolean isBuildingCompositeComponentMetadata)
 114  0
     {
 115  0
         _factory = factory;
 116  0
         _elFactory = el;
 117  0
         _src = src;
 118  0
         _root = root;
 119  0
         _alias = alias;
 120  0
         _faceletId = faceletId;
 121  0
         _createTime = System.currentTimeMillis();
 122  0
         _refreshPeriod = _factory.getRefreshPeriod();
 123  0
         _relativePaths = Collections.synchronizedMap(new WeakHashMap());
 124  0
         _isBuildingCompositeComponentMetadata = isBuildingCompositeComponentMetadata;
 125  0
         _encodingHandler = (root instanceof EncodingHandler);
 126  0
     }    
 127  
 
 128  
     /**
 129  
      * @see org.apache.myfaces.view.facelets.Facelet#apply(javax.faces.context.FacesContext,
 130  
      *      javax.faces.component.UIComponent)
 131  
      */
 132  
     public void apply(FacesContext facesContext, UIComponent parent) throws IOException, FacesException,
 133  
             FaceletException, ELException
 134  
     {
 135  0
         FaceletCompositionContext myFaceletContext = null;
 136  0
         boolean faceletCompositionContextInitialized = false;
 137  0
         boolean recordUniqueIds = false;
 138  0
         myFaceletContext = FaceletCompositionContext.getCurrentInstance(facesContext);
 139  0
         if (myFaceletContext == null)
 140  
         {
 141  0
             myFaceletContext = new FaceletCompositionContextImpl(_factory, facesContext);
 142  0
             myFaceletContext.init(facesContext);
 143  0
             faceletCompositionContextInitialized = true;
 144  0
             if (_encodingHandler && !myFaceletContext.isBuildingViewMetadata()
 145  
                     && MyfacesConfig.getCurrentInstance(
 146  
                     facesContext.getExternalContext()).isViewUniqueIdsCacheEnabled() && 
 147  
                     _refreshPeriod <= 0)
 148  
             {
 149  0
                 List<String> uniqueIdList = ((EncodingHandler)_root).getUniqueIdList();
 150  0
                 if (uniqueIdList == null)
 151  
                 {
 152  0
                     myFaceletContext.initUniqueIdRecording();
 153  0
                     recordUniqueIds = true;
 154  
                 }
 155  
                 else
 156  
                 {
 157  0
                     myFaceletContext.setUniqueIdsIterator(uniqueIdList.iterator());
 158  
                 }
 159  
             }
 160  0
             if (parent instanceof UIViewRoot)
 161  
             {
 162  0
                 myFaceletContext.setViewRoot((UIViewRoot)parent);
 163  0
                 ComponentSupport.setCachedFacesContext((UIViewRoot)parent, facesContext);
 164  
             }
 165  
         }
 166  0
         DefaultFaceletContext ctx = new DefaultFaceletContext(facesContext, this, myFaceletContext);
 167  
         
 168  
         //Set FACELET_CONTEXT_KEY on FacesContext attribute map, to 
 169  
         //reflect the current facelet context instance
 170  0
         FaceletContext oldCtx = (FaceletContext) 
 171  
                 facesContext.getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctx);
 172  
         
 173  0
         ctx.pushPageContext(new PageContextImpl());
 174  
         
 175  
         try
 176  
         {
 177  
             // push the parent as a UniqueIdVendor to the stack here,
 178  
             // if there is no UniqueIdVendor on the stack yet
 179  0
             boolean pushedUniqueIdVendor = false;
 180  0
             if (parent instanceof UniqueIdVendor
 181  
                 && ctx.getFaceletCompositionContext().getUniqueIdVendorFromStack() == null)
 182  
             {
 183  0
                 ctx.getFaceletCompositionContext().pushUniqueIdVendorToStack((UniqueIdVendor) parent);
 184  0
                 pushedUniqueIdVendor = true;
 185  
             }
 186  
             
 187  0
             this.refresh(parent);
 188  0
             myFaceletContext.markForDeletion(parent);
 189  0
             _root.apply(ctx, parent);
 190  0
             if (faceletCompositionContextInitialized &&
 191  
                 parent instanceof UIViewRoot)
 192  
             {
 193  0
                 UIComponent metadataFacet = parent.getFacet(UIViewRoot.METADATA_FACET_NAME);
 194  0
                 if (metadataFacet != null)
 195  
                 {
 196  
                     // Ensure metadata facet is removed from deletion, so if by some reason
 197  
                     // is not refreshed, its content will not be removed from the component tree.
 198  
                     // This behavior is preferred, even if the spec suggest to include it using
 199  
                     // a trick with the template client.
 200  0
                     myFaceletContext.removeComponentForDeletion(metadataFacet);
 201  
                 }
 202  0
                 if (myFaceletContext.isRefreshingTransientBuild())
 203  
                 {
 204  0
                     myFaceletContext.finalizeRelocatableResourcesForDeletion((UIViewRoot) parent);
 205  
                 }
 206  
             }
 207  0
             myFaceletContext.finalizeForDeletion(parent);
 208  0
             this.markApplied(parent);
 209  
             
 210  
             // remove the UniqueIdVendor from the stack again
 211  0
             if (pushedUniqueIdVendor)
 212  
             {
 213  0
                 ctx.getFaceletCompositionContext().popUniqueIdVendorToStack();
 214  
             }
 215  
         }
 216  
         finally
 217  
         {
 218  0
             ctx.popPageContext();
 219  
             
 220  0
             if (faceletCompositionContextInitialized)
 221  
             {
 222  0
                 if (parent instanceof UIViewRoot)
 223  
                 {
 224  0
                     ComponentSupport.setCachedFacesContext((UIViewRoot)parent, null);
 225  
                 }
 226  0
                 myFaceletContext.release(facesContext);
 227  0
                 List<String> uniqueIdList = ((EncodingHandler)_root).getUniqueIdList();
 228  0
                 if (recordUniqueIds &&  uniqueIdList == null)
 229  
                 {
 230  0
                     uniqueIdList = Collections.unmodifiableList(
 231  
                             myFaceletContext.getUniqueIdList());
 232  0
                     ((EncodingHandler)_root).setUniqueIdList(uniqueIdList);
 233  
                 }
 234  
             }
 235  
             
 236  0
             if (oldCtx != null)
 237  
             {
 238  0
                 facesContext.getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, oldCtx);
 239  
             }
 240  
         }
 241  0
     }
 242  
     
 243  
     public void applyDynamicComponentHandler(FacesContext facesContext, 
 244  
             UIComponent parent, String baseKey)
 245  
          throws IOException, FacesException, FaceletException, ELException
 246  
     {
 247  0
         FaceletCompositionContext fcctx = null;
 248  0
         boolean faceletCompositionContextInitialized = false;
 249  0
         fcctx = FaceletCompositionContext.getCurrentInstance(facesContext);
 250  0
         boolean pushDynCompSection = false;
 251  0
         if (fcctx == null)
 252  
         {
 253  0
             fcctx = new FaceletCompositionContextImpl(_factory, facesContext, 
 254  
                 baseKey);
 255  0
             fcctx.init(facesContext);
 256  0
             faceletCompositionContextInitialized = true;
 257  
         }
 258  
         else
 259  
         {
 260  0
             pushDynCompSection = true;
 261  0
             fcctx.pushDynamicComponentSection(baseKey);
 262  
         }
 263  
         // Disable dynamic component top level if the parent is a
 264  
         // dynamic wrapper, to allow the content to be reorganized properly under
 265  
         // a refresh.
 266  0
         if (parent.getAttributes().containsKey("oam.vf.DYN_WRAPPER"))
 267  
         {
 268  0
             fcctx.setDynamicComponentTopLevel(false);
 269  
         }
 270  
         
 271  0
         FaceletContext oldCtx = (FaceletContext) facesContext.getAttributes().get(
 272  
             FaceletContext.FACELET_CONTEXT_KEY);
 273  0
         DefaultFaceletContext ctx = new DefaultFaceletContext(facesContext, this, fcctx);
 274  
         
 275  
         //Set FACELET_CONTEXT_KEY on FacesContext attribute map, to 
 276  
         //reflect the current facelet context instance
 277  0
         facesContext.getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctx);
 278  
         
 279  0
         ctx.pushPageContext(new PageContextImpl());
 280  
         
 281  
         try
 282  
         {
 283  
             // push the parent as a UniqueIdVendor to the stack here,
 284  
             // if there is no UniqueIdVendor on the stack yet
 285  0
             boolean pushedUniqueIdVendor = false;
 286  0
             if (parent instanceof UniqueIdVendor
 287  
                 && ctx.getFaceletCompositionContext().getUniqueIdVendorFromStack() == null)
 288  
             {
 289  0
                 ctx.getFaceletCompositionContext().pushUniqueIdVendorToStack((UniqueIdVendor) parent);
 290  0
                 pushedUniqueIdVendor = true;
 291  
             }
 292  
             
 293  
             //this.refresh(parent);
 294  
             //myFaceletContext.markForDeletion(parent);
 295  0
             _root.apply(ctx, parent);
 296  
             //myFaceletContext.finalizeForDeletion(parent);
 297  
             //this.markApplied(parent);
 298  
             
 299  
             // remove the UniqueIdVendor from the stack again
 300  0
             if (pushedUniqueIdVendor)
 301  
             {
 302  0
                 ctx.getFaceletCompositionContext().popUniqueIdVendorToStack();
 303  
             }
 304  
         }
 305  
         finally
 306  
         {
 307  0
             ctx.popPageContext();
 308  0
             facesContext.getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, oldCtx);
 309  
             
 310  0
             if (pushDynCompSection)
 311  
             {
 312  0
                 fcctx.popDynamicComponentSection();
 313  
             }
 314  0
             if (faceletCompositionContextInitialized)
 315  
             {
 316  0
                 fcctx.release(facesContext);
 317  
             }
 318  
         }
 319  0
     }    
 320  
 
 321  
     private void refresh(UIComponent c)
 322  
     {
 323  0
         if (_refreshPeriod > 0)
 324  
         {
 325  
 
 326  
             // finally remove any children marked as deleted
 327  0
             int sz = c.getChildCount();
 328  0
             if (sz > 0)
 329  
             {
 330  0
                 UIComponent cc = null;
 331  0
                 List<UIComponent> cl = c.getChildren();
 332  
                 ApplyToken token;
 333  0
                 while (--sz >= 0)
 334  
                 {
 335  0
                     cc = cl.get(sz);
 336  0
                     if (!cc.isTransient())
 337  
                     {
 338  0
                         token = (ApplyToken) cc.getAttributes().get(APPLIED_KEY);
 339  0
                         if (token != null && token._time < _createTime && token._alias.equals(_alias))
 340  
                         {
 341  0
                             if (log.isLoggable(Level.INFO))
 342  
                             {
 343  0
                                 DateFormat df = SimpleDateFormat.getTimeInstance();
 344  0
                                 log.info("Facelet[" + _alias + "] was modified @ "
 345  
                                         + df.format(new Date(_createTime)) + ", flushing component applied @ "
 346  
                                         + df.format(new Date(token._time)));
 347  
                             }
 348  0
                             cl.remove(sz);
 349  
                         }
 350  
                     }
 351  
                 }
 352  
             }
 353  
 
 354  
             // remove any facets marked as deleted
 355  0
             if (c.getFacetCount() > 0)
 356  
             {
 357  0
                 Collection<UIComponent> col = c.getFacets().values();
 358  
                 UIComponent fc;
 359  
                 ApplyToken token;
 360  0
                 for (Iterator<UIComponent> itr = col.iterator(); itr.hasNext();)
 361  
                 {
 362  0
                     fc = itr.next();
 363  0
                     if (!fc.isTransient())
 364  
                     {
 365  0
                         token = (ApplyToken) fc.getAttributes().get(APPLIED_KEY);
 366  0
                         if (token != null && token._time < _createTime && token._alias.equals(_alias))
 367  
                         {
 368  0
                             if (log.isLoggable(Level.INFO))
 369  
                             {
 370  0
                                 DateFormat df = SimpleDateFormat.getTimeInstance();
 371  0
                                 log.info("Facelet[" + _alias + "] was modified @ "
 372  
                                         + df.format(new Date(_createTime)) + ", flushing component applied @ "
 373  
                                         + df.format(new Date(token._time)));
 374  
                             }
 375  0
                             itr.remove();
 376  
                         }
 377  
                     }
 378  
                 }
 379  
             }
 380  
         }
 381  0
     }
 382  
 
 383  
     private void markApplied(UIComponent parent)
 384  
     {
 385  0
         if (this._refreshPeriod > 0)
 386  
         {
 387  0
             int facetCount = parent.getFacetCount();
 388  0
             int childCount = parent.getChildCount();
 389  0
             if (childCount > 0 || facetCount > 0)
 390  
             {
 391  0
                 ApplyToken token = new ApplyToken(_alias, System.currentTimeMillis() + _refreshPeriod);
 392  
 
 393  0
                 if (facetCount > 0)
 394  
                 {
 395  0
                     for (UIComponent facet : parent.getFacets().values())
 396  
                     {
 397  0
                         markApplied(token, facet);
 398  0
                     }
 399  
                 }
 400  0
                 for (int i = 0; i < childCount; i++)
 401  
                 {
 402  0
                     UIComponent child = parent.getChildren().get(i);
 403  0
                     markApplied(token, child);
 404  
                 }
 405  
             }
 406  
         }
 407  0
     }
 408  
 
 409  
     private void markApplied(ApplyToken token, UIComponent c)
 410  
     {
 411  0
         if (!c.isTransient())
 412  
         {
 413  0
             Map<String, Object> attr = c.getAttributes();
 414  0
             if (!attr.containsKey(APPLIED_KEY))
 415  
             {
 416  0
                 attr.put(APPLIED_KEY, token);
 417  
             }
 418  
         }
 419  0
     }
 420  
 
 421  
     /**
 422  
      * Return the alias name for error messages and logging
 423  
      * 
 424  
      * @return alias name
 425  
      */
 426  
     public String getAlias()
 427  
     {
 428  0
         return _alias;
 429  
     }
 430  
     
 431  
     public String getFaceletId()
 432  
     {
 433  0
         return _faceletId;
 434  
     }
 435  
 
 436  
     /**
 437  
      * Return this Facelet's ExpressionFactory instance
 438  
      * 
 439  
      * @return internal ExpressionFactory instance
 440  
      */
 441  
     public ExpressionFactory getExpressionFactory()
 442  
     {
 443  0
         return _elFactory;
 444  
     }
 445  
 
 446  
     /**
 447  
      * The time when this Facelet was created, NOT the URL source code
 448  
      * 
 449  
      * @return final timestamp of when this Facelet was created
 450  
      */
 451  
     public long getCreateTime()
 452  
     {
 453  0
         return _createTime;
 454  
     }
 455  
 
 456  
     /**
 457  
      * Delegates resolution to DefaultFaceletFactory reference. Also, caches URLs for relative paths.
 458  
      * 
 459  
      * @param path
 460  
      *            a relative url path
 461  
      * @return URL pointing to destination
 462  
      * @throws IOException
 463  
      *             if there is a problem creating the URL for the path specified
 464  
      */
 465  
     private URL getRelativePath(FacesContext facesContext, String path) throws IOException
 466  
     {
 467  0
         URL url = (URL) _relativePaths.get(path);
 468  0
         if (url == null)
 469  
         {
 470  0
             url = _factory.resolveURL(facesContext, _src, path);
 471  0
             if (url != null)
 472  
             {
 473  0
                 ViewResource viewResource = (ViewResource) facesContext.getAttributes().get(
 474  
                     FaceletFactory.LAST_RESOURCE_RESOLVED);
 475  0
                 if (viewResource != null)
 476  
                 {
 477  
                     // If a view resource has been used to resolve a resource, the cache is in
 478  
                     // the ResourceHandler implementation. No need to cache in _relativeLocations.
 479  
                 }
 480  
                 else
 481  
                 {
 482  0
                     _relativePaths.put(path, url);
 483  
                 }
 484  
             }
 485  
         }
 486  0
         return url;
 487  
     }
 488  
 
 489  
     /**
 490  
      * The URL this Facelet was created from.
 491  
      * 
 492  
      * @return the URL this Facelet was created from
 493  
      */
 494  
     public URL getSource()
 495  
     {
 496  0
         return _src;
 497  
     }
 498  
 
 499  
     /**
 500  
      * Given the passed FaceletContext, apply our child FaceletHandlers to the passed parent
 501  
      * 
 502  
      * @see FaceletHandler#apply(FaceletContext, UIComponent)
 503  
      * @param ctx
 504  
      *            the FaceletContext to use for applying our FaceletHandlers
 505  
      * @param parent
 506  
      *            the parent component to apply changes to
 507  
      * @throws IOException
 508  
      * @throws FacesException
 509  
      * @throws FaceletException
 510  
      * @throws ELException
 511  
      */
 512  
     private void include(AbstractFaceletContext ctx, UIComponent parent) throws IOException, FacesException,
 513  
             FaceletException, ELException
 514  
     {
 515  0
         ctx.pushPageContext(new PageContextImpl());
 516  
         try
 517  
         {
 518  0
             this.refresh(parent);
 519  0
             DefaultFaceletContext ctxWrapper = new DefaultFaceletContext((DefaultFaceletContext)ctx, this, false);
 520  0
             ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctxWrapper);
 521  0
             _root.apply(ctxWrapper, parent);
 522  0
             ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctx);
 523  0
             this.markApplied(parent);
 524  
         }
 525  
         finally
 526  
         {
 527  0
             ctx.popPageContext();
 528  0
         }
 529  0
     }
 530  
 
 531  
     /**
 532  
      * Used for delegation by the DefaultFaceletContext. First pulls the URL from {@link #getRelativePath(String)
 533  
      * getRelativePath(String)}, then calls
 534  
      * {@link #include(org.apache.myfaces.view.facelets.AbstractFaceletContext,
 535  
      * javax.faces.component.UIComponent, java.net.URL)}.
 536  
      * 
 537  
      * @see FaceletContext#includeFacelet(UIComponent, String)
 538  
      * @param ctx
 539  
      *            FaceletContext to pass to the included Facelet
 540  
      * @param parent
 541  
      *            UIComponent to apply changes to
 542  
      * @param path
 543  
      *            relative path to the desired Facelet from the FaceletContext
 544  
      * @throws IOException
 545  
      * @throws FacesException
 546  
      * @throws FaceletException
 547  
      * @throws ELException
 548  
      */
 549  
     public void include(AbstractFaceletContext ctx, UIComponent parent, String path)
 550  
             throws IOException, FacesException, FaceletException, ELException
 551  
     {
 552  0
         URL url = this.getRelativePath(ctx.getFacesContext(), path);
 553  0
         this.include(ctx, parent, url);
 554  0
     }
 555  
 
 556  
     /**
 557  
      * Grabs a DefaultFacelet from referenced DefaultFaceletFacotry
 558  
      * 
 559  
      * @see DefaultFaceletFactory#getFacelet(URL)
 560  
      * @param ctx
 561  
      *            FaceletContext to pass to the included Facelet
 562  
      * @param parent
 563  
      *            UIComponent to apply changes to
 564  
      * @param url
 565  
      *            URL source to include Facelet from
 566  
      * @throws IOException
 567  
      * @throws FacesException
 568  
      * @throws FaceletException
 569  
      * @throws ELException
 570  
      */
 571  
     public void include(AbstractFaceletContext ctx, UIComponent parent, URL url) throws IOException, FacesException,
 572  
             FaceletException, ELException
 573  
     {
 574  0
         DefaultFacelet f = (DefaultFacelet) _factory.getFacelet(ctx, url);
 575  0
         f.include(ctx, parent);
 576  0
     }
 577  
     
 578  
     public void applyCompositeComponent(AbstractFaceletContext ctx, UIComponent parent, Resource resource)
 579  
             throws IOException, FacesException, FaceletException, ELException
 580  
     {
 581  
         // Here we are creating a facelet using the url provided by the resource.
 582  
         // It works, but the Resource API provides getInputStream() for that. But the default
 583  
         // implementation wraps everything that could contain ValueExpression and decode so
 584  
         // we can't use it here.
 585  
         //DefaultFacelet f = (DefaultFacelet) _factory.getFacelet(resource.getURL());
 586  
         //f.apply(ctx.getFacesContext(), parent);
 587  0
         DefaultFacelet f = (DefaultFacelet) _factory.getFacelet(resource.getURL());
 588  
         
 589  0
         ctx.pushPageContext(new PageContextImpl());
 590  
         try
 591  
         {
 592  
             // push the parent as a UniqueIdVendor to the stack here,
 593  
             // if there is no UniqueIdVendor on the stack yet
 594  0
             boolean pushedUniqueIdVendor = false;
 595  0
             FaceletCompositionContext mctx = ctx.getFaceletCompositionContext();
 596  0
             if (parent instanceof UniqueIdVendor
 597  
                 && ctx.getFaceletCompositionContext().getUniqueIdVendorFromStack() == null)
 598  
             {
 599  0
                 mctx.pushUniqueIdVendorToStack((UniqueIdVendor) parent);
 600  0
                 pushedUniqueIdVendor = true;
 601  
             }
 602  
             
 603  0
             f.refresh(parent);
 604  0
             mctx.markForDeletion(parent);
 605  0
             DefaultFaceletContext ctxWrapper = new DefaultFaceletContext( (DefaultFaceletContext)ctx, f, true);
 606  
             //Update FACELET_CONTEXT_KEY on FacesContext attribute map, to 
 607  
             //reflect the current facelet context instance
 608  0
             ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctxWrapper);
 609  0
             f._root.apply(ctxWrapper, parent);
 610  0
             ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctx);
 611  0
             mctx.finalizeForDeletion(parent);
 612  0
             f.markApplied(parent);
 613  
             
 614  
             // remove the UniqueIdVendor from the stack again
 615  0
             if (pushedUniqueIdVendor)
 616  
             {
 617  0
                 ctx.getFaceletCompositionContext().popUniqueIdVendorToStack();
 618  
             }
 619  
         }
 620  
         finally
 621  
         {
 622  0
             ctx.popPageContext();
 623  0
         }
 624  0
     }
 625  
 
 626  
     private static class ApplyToken implements Externalizable
 627  
     {
 628  
         public String _alias;
 629  
 
 630  
         public long _time;
 631  
 
 632  
         public ApplyToken()
 633  0
         {
 634  0
         }
 635  
 
 636  
         public ApplyToken(String alias, long time)
 637  0
         {
 638  0
             _alias = alias;
 639  0
             _time = time;
 640  0
         }
 641  
 
 642  
         public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException
 643  
         {
 644  0
             _alias = in.readUTF();
 645  0
             _time = in.readLong();
 646  0
         }
 647  
 
 648  
         public void writeExternal(ObjectOutput out) throws IOException
 649  
         {
 650  0
             out.writeUTF(_alias);
 651  0
             out.writeLong(_time);
 652  0
         }
 653  
     }
 654  
 
 655  
     public String toString()
 656  
     {
 657  0
         return _alias;
 658  
     }
 659  
 
 660  
     @Override
 661  
     public boolean isBuildingCompositeComponentMetadata()
 662  
     {
 663  0
         return _isBuildingCompositeComponentMetadata;
 664  
     }
 665  
 }