View Javadoc

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.IOException;
22  import java.net.URL;
23  import java.util.ArrayList;
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.LinkedList;
27  import java.util.List;
28  import java.util.Set;
29  
30  import javax.el.ELContext;
31  import javax.el.ELException;
32  import javax.el.ELResolver;
33  import javax.el.ExpressionFactory;
34  import javax.el.FunctionMapper;
35  import javax.el.ValueExpression;
36  import javax.el.VariableMapper;
37  import javax.faces.FacesException;
38  import javax.faces.application.Resource;
39  import javax.faces.component.UIComponent;
40  import javax.faces.context.FacesContext;
41  import javax.faces.view.facelets.FaceletContext;
42  import javax.faces.view.facelets.FaceletException;
43  
44  import org.apache.myfaces.view.facelets.AbstractFacelet;
45  import org.apache.myfaces.view.facelets.AbstractFaceletContext;
46  import org.apache.myfaces.view.facelets.ELExpressionCacheMode;
47  import org.apache.myfaces.view.facelets.FaceletCompositionContext;
48  import org.apache.myfaces.view.facelets.PageContext;
49  import org.apache.myfaces.view.facelets.TemplateClient;
50  import org.apache.myfaces.view.facelets.TemplateContext;
51  import org.apache.myfaces.view.facelets.TemplateManager;
52  import org.apache.myfaces.view.facelets.el.DefaultVariableMapper;
53  import org.apache.myfaces.view.facelets.el.VariableMapperBase;
54  import org.apache.myfaces.view.facelets.tag.jsf.core.AjaxHandler;
55  
56  /**
57   * Default FaceletContext implementation.
58   * 
59   * A single FaceletContext is used for all Facelets involved in an invocation of
60   * {@link org.apache.myfaces.view.facelets.Facelet#apply(FacesContext, UIComponent)
61   * Facelet#apply(FacesContext, UIComponent)}. This
62   * means that included Facelets are treated the same as the JSP include directive.
63   * 
64   * @author Jacob Hookom
65   * @version $Id: DefaultFaceletContext.java 1341415 2012-05-22 11:33:08Z lu4242 $
66   */
67  final class DefaultFaceletContext extends AbstractFaceletContext
68  {
69      private final FacesContext _faces;
70  
71      private final ELContext _ctx;
72  
73      private final AbstractFacelet _facelet;
74      private final List<AbstractFacelet> _faceletHierarchy;
75  
76      private VariableMapper _varMapper;
77      private final DefaultVariableMapper _defaultVarMapper;
78      private VariableMapperBase _varMapperBase;
79  
80      private FunctionMapper _fnMapper;
81  
82      //private final Map<String, Integer> _ids;
83      //private final Map<Integer, Integer> _prefixes;
84      private String _prefix;
85  
86      private StringBuilder _uniqueIdBuilder;
87  
88      //private final LinkedList<TemplateManager> _clients;
89      
90      private final FaceletCompositionContext _mctx;
91      
92      private LinkedList<AjaxHandler> _ajaxHandlerStack;
93      
94      private final List<TemplateContext> _isolatedTemplateContext;
95      
96      private int _currentTemplateContext;
97      
98      private ELExpressionCacheMode _elExpressionCacheMode;
99      
100     private boolean _isCacheELExpressions;
101 
102     private final List<PageContext> _isolatedPageContext;
103     
104     public DefaultFaceletContext(DefaultFaceletContext ctx,
105             AbstractFacelet facelet, boolean ccWrap)
106     {
107         _ctx = ctx._ctx;
108         //_ids = ctx._ids;
109         //_prefixes = ctx._prefixes;
110         //_clients = ctx._clients;
111         _faces = ctx._faces;
112         _fnMapper = ctx._fnMapper;
113         _varMapper = ctx._varMapper;
114         _defaultVarMapper = ctx._defaultVarMapper;
115         _varMapperBase = ctx._varMapperBase;
116         _faceletHierarchy = new ArrayList<AbstractFacelet>(ctx._faceletHierarchy
117                 .size() + 1);
118         _faceletHierarchy.addAll(ctx._faceletHierarchy);
119         _faceletHierarchy.add(facelet);
120         _facelet = facelet;
121         _mctx = ctx._mctx;
122         
123         if (ccWrap)
124         {
125             // Each time a composite component is being applied, a new
126             // ajax stack should be created, and f:ajax tags outside the
127             // composite component should be ignored.
128             _ajaxHandlerStack = null;
129         }
130         else
131         {
132             // It is a template include, the current ajax stack should be
133             // preserved.
134             _ajaxHandlerStack = ctx._ajaxHandlerStack;
135         }
136         
137         // It is not necessary to create a copy of this array, because we always use
138         // pushTemplateContext(TemplateContext) / popTemplateContext() and
139         // pushCompositeComponentClient(final TemplateClient client) / popCompositeComponentClient()
140         // in pairs.
141         //_isolatedTemplateContext = new ArrayList<TemplateContext>(ctx._isolatedTemplateContext.size()+1);
142         //for (int i = 0; i <= ctx._currentTemplateContext; i++)
143         //{
144         //    _isolatedTemplateContext.add(ctx._isolatedTemplateContext.get(i));
145         //}
146         _isolatedTemplateContext = ctx._isolatedTemplateContext;
147         _currentTemplateContext = ctx._currentTemplateContext;
148         
149         _isolatedPageContext = ctx._isolatedPageContext;
150         
151         _elExpressionCacheMode = ctx._elExpressionCacheMode;
152         _isCacheELExpressions = ctx._isCacheELExpressions;
153 
154         //Update FACELET_CONTEXT_KEY on FacesContext attribute map, to 
155         //reflect the current facelet context instance
156         ctx.getFacesContext().getAttributes().put(
157                 FaceletContext.FACELET_CONTEXT_KEY, this);
158     }
159 
160     public DefaultFaceletContext(FacesContext faces, AbstractFacelet facelet, FaceletCompositionContext mctx)
161     {
162         _ctx = faces.getELContext();
163         //_ids = new HashMap<String, Integer>();
164         //_prefixes = new HashMap<Integer, Integer>();
165         //_clients = new LinkedList<TemplateManager>();
166         _faces = faces;
167         _fnMapper = _ctx.getFunctionMapper();
168         _varMapper = _ctx.getVariableMapper();
169         if (_varMapper == null)
170         {
171             _defaultVarMapper = new DefaultVariableMapper();
172             _varMapper = _defaultVarMapper;
173             _varMapperBase = _defaultVarMapper;
174         }
175         else
176         {
177             _defaultVarMapper = new DefaultVariableMapper(_varMapper);
178             _varMapper = _defaultVarMapper;
179             _varMapperBase = _defaultVarMapper;
180         }
181         
182         _faceletHierarchy = new ArrayList<AbstractFacelet>(1);
183         _faceletHierarchy.add(facelet);
184         _facelet = facelet;
185         _mctx = mctx;
186         
187         _isolatedTemplateContext = new ArrayList<TemplateContext>(1);
188         _isolatedTemplateContext.add(new TemplateContextImpl());
189         _currentTemplateContext = 0;
190         _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
191         
192         _isolatedPageContext = new ArrayList<PageContext>(8);
193         
194         _elExpressionCacheMode = mctx.getELExpressionCacheMode();
195         _isCacheELExpressions = !ELExpressionCacheMode.noCache.equals(_elExpressionCacheMode);
196     }
197 
198     /**
199      * {@inheritDoc}
200      */
201     @Override
202     public FacesContext getFacesContext()
203     {
204         return _faces;
205     }
206 
207     /**
208      * {@inheritDoc}
209      */
210     @Override
211     public ExpressionFactory getExpressionFactory()
212     {
213         return _facelet.getExpressionFactory();
214     }
215 
216     /**
217      * {@inheritDoc}
218      */
219     @Override
220     public void setVariableMapper(VariableMapper varMapper)
221     {
222         // Assert.param("varMapper", varMapper);
223         _varMapper = varMapper;
224         _varMapperBase = (_varMapper instanceof VariableMapperBase) ? (VariableMapperBase) varMapper : null;
225     }
226 
227     /**
228      * {@inheritDoc}
229      */
230     @Override
231     public void setFunctionMapper(FunctionMapper fnMapper)
232     {
233         // Assert.param("fnMapper", fnMapper);
234         _fnMapper = fnMapper;
235     }
236 
237     /**
238      * {@inheritDoc}
239      */
240     @Override
241     public void includeFacelet(UIComponent parent, String relativePath)
242             throws IOException
243     {
244         _facelet.include(this, parent, relativePath);
245     }
246 
247     /**
248      * {@inheritDoc}
249      */
250     @Override
251     public FunctionMapper getFunctionMapper()
252     {
253         return _fnMapper;
254     }
255 
256     /**
257      * {@inheritDoc}
258      */
259     @Override
260     public VariableMapper getVariableMapper()
261     {
262         return _varMapper;
263     }
264 
265     /**
266      * {@inheritDoc}
267      */
268     @Override
269     @SuppressWarnings("unchecked")
270     public Object getContext(Class key)
271     {
272         return _ctx.getContext(key);
273     }
274 
275     /**
276      * {@inheritDoc}
277      */
278     @Override
279     @SuppressWarnings("unchecked")
280     public void putContext(Class key, Object contextObject)
281     {
282         _ctx.putContext(key, contextObject);
283     }
284 
285     /**
286      * {@inheritDoc}
287      */
288     @Override
289     public String generateUniqueId(String base)
290     {
291         if (_prefix == null)
292         {
293             _uniqueIdBuilder = new StringBuilder(
294                     _faceletHierarchy.size() * 30);
295             for (int i = 0; i < _faceletHierarchy.size(); i++)
296             {
297                 AbstractFacelet facelet = _faceletHierarchy.get(i);
298                 _uniqueIdBuilder.append(facelet.getFaceletId());
299             }
300 
301             // Integer prefixInt = new Integer(builder.toString().hashCode());
302             // -= Leonardo Uribe =- if the previous formula is used, it is possible that
303             // negative values are introduced. The presence of '-' char causes problems
304             // with htmlunit 2.4 or lower, so in order to prevent it it is better to use
305             // only positive values instead.
306             // Take into account CompilationManager.nextTagId() uses Math.abs too.
307             Integer prefixInt = new Integer(Math.abs(_uniqueIdBuilder.toString().hashCode()));
308             _prefix = prefixInt.toString();
309         }
310 
311         _uniqueIdBuilder.setLength(0);
312         // getFaceletCompositionContext().generateUniqueId() is the one who ensures
313         // the final id will be unique, but prefix and base ensure it will be unique
314         // per facelet because prefix is calculated from faceletHierarchy and base is
315         // related to the tagId, which depends on the location.
316         //_uniqueIdBuilder.append(getFaceletCompositionContext().generateUniqueId());
317         
318         String uniqueIdFromIterator = getFaceletCompositionContext().getUniqueIdFromIterator();
319         if (uniqueIdFromIterator == null)
320         {
321             getFaceletCompositionContext().generateUniqueId(_uniqueIdBuilder);
322             _uniqueIdBuilder.append("_");
323             _uniqueIdBuilder.append(_prefix);
324             // Since two different facelets are used to build the metadata, it is necessary
325             // to trim the "base" part from the returned unique id, to ensure the components will be
326             // refreshed properly. Note the "base" part is the one that allows to ensure
327             // uniqueness between two different facelets with the same <f:metadata>, but since by 
328             // spec view metadata sections cannot live on template client facelets, this case is
329             // just not possible. 
330             if (!getFaceletCompositionContext().isInMetadataSection())
331             {
332                 _uniqueIdBuilder.append("_");
333                 _uniqueIdBuilder.append(base);
334             }
335             uniqueIdFromIterator = _uniqueIdBuilder.toString();
336             getFaceletCompositionContext().addUniqueId(uniqueIdFromIterator);
337             return uniqueIdFromIterator;
338         }
339         else
340         {
341             getFaceletCompositionContext().incrementUniqueId();
342             return uniqueIdFromIterator;
343         }
344     }
345 
346     /**
347      * {@inheritDoc}
348      */
349     @Override
350     public Object getAttribute(String name)
351     {
352         if (_varMapper != null)
353         {
354             ValueExpression ve = _varMapper.resolveVariable(name);
355             if (ve != null)
356             {
357                 return ve.getValue(this);
358             }
359         }
360         return null;
361     }
362 
363     /**
364      * {@inheritDoc}
365      */
366     @Override
367     public void setAttribute(String name, Object value)
368     {
369         if (_varMapper != null)
370         {
371             if (value == null)
372             {
373                 _varMapper.setVariable(name, null);
374             }
375             else
376             {
377                 _varMapper.setVariable(name, _facelet.getExpressionFactory()
378                         .createValueExpression(value, Object.class));
379             }
380         }
381     }
382 
383     /**
384      * {@inheritDoc}
385      */
386     @Override
387     public void includeFacelet(UIComponent parent, URL absolutePath)
388             throws IOException, FacesException, ELException
389     {
390         _facelet.include(this, parent, absolutePath);
391     }
392 
393     /**
394      * {@inheritDoc}
395      */
396     @Override
397     public ELResolver getELResolver()
398     {
399         return _ctx.getELResolver();
400     }
401 
402     //Begin methods from AbstractFaceletContext
403 
404     @Override
405     public TemplateManager popClient(TemplateClient client)
406     {
407         //if (!this._clients.isEmpty())
408         //{
409         //    Iterator<TemplateManager> itr = this._clients.iterator();
410         //    while (itr.hasNext())
411         //    {
412         //        if (itr.next().equals(client))
413         //        {
414         //            itr.remove();
415         //            return;
416         //        }
417         //    }
418         //}
419         //throw new IllegalStateException(client + " not found");
420         //return _clients.removeFirst();
421         return _isolatedTemplateContext.get(_currentTemplateContext).popClient(this);
422     }
423 
424     @Override
425     public void pushClient(final TemplateClient client)
426     {
427         //this._clients.add(0, new TemplateManager(this._facelet, client, true));
428         //_clients.addFirst(new TemplateManagerImpl(this._facelet, client, true));
429         _isolatedTemplateContext.get(_currentTemplateContext).pushClient(this, this._facelet, client);
430     }
431 
432     public TemplateManager popExtendedClient(TemplateClient client)
433     {
434         //return _clients.removeLast();
435         return _isolatedTemplateContext.get(_currentTemplateContext).popExtendedClient(this);
436     }
437     
438     @Override
439     public void extendClient(final TemplateClient client)
440     {
441         //this._clients.add(new TemplateManager(this._facelet, client, false));
442         //_clients.addLast(new TemplateManagerImpl(this._facelet, client, false));
443         _isolatedTemplateContext.get(_currentTemplateContext).extendClient(this, this._facelet, client);
444     }
445 
446     @Override
447     public boolean includeDefinition(UIComponent parent, String name)
448             throws IOException, FaceletException, FacesException, ELException
449     {
450         //boolean found = false;
451         //TemplateManager client;
452         //for (int i = 0, size = this._clients.size(); i < size && !found; i++)
453         //{
454         //    client = ((TemplateManager) this._clients.get(i));
455         //    if (client.equals(this._facelet))
456         //        continue;
457         //    found = client.apply(this, parent, name);
458         //}
459         //return found;
460         return _isolatedTemplateContext.get(_currentTemplateContext).includeDefinition(
461                 this, this._facelet, parent, name);
462     }
463 
464     /*
465     private final static class TemplateManagerImpl extends TemplateManager implements TemplateClient
466     {
467         private final DefaultFacelet _owner;
468 
469         private final TemplateClient _target;
470 
471         private final boolean _root;
472 
473         private final Set<String> _names = new HashSet<String>();
474 
475         public TemplateManagerImpl(DefaultFacelet owner, TemplateClient target,
476                 boolean root)
477         {
478             this._owner = owner;
479             this._target = target;
480             this._root = root;
481         }
482 
483         public boolean apply(FaceletContext ctx, UIComponent parent, String name)
484                 throws IOException, FacesException, FaceletException,
485                 ELException
486         {
487             String testName = (name != null) ? name : "facelets._NULL_DEF_";
488             if (this._names.contains(testName))
489             {
490                 return false;
491             }
492             else
493             {
494                 this._names.add(testName);
495                 boolean found = false;
496                 found = this._target
497                         .apply(new DefaultFaceletContext(
498                                 (DefaultFaceletContext) ctx, this._owner, false),
499                                 parent, name);
500                 this._names.remove(testName);
501                 return found;
502             }
503         }
504 
505         public boolean equals(Object o)
506         {
507             // System.out.println(this.owner.getAlias() + " == " +
508             // ((DefaultFacelet) o).getAlias());
509             return this._owner == o || this._target == o;
510         }
511 
512         public boolean isRoot()
513         {
514             return this._root;
515         }
516     }*/
517 
518     /*
519     @Override
520     public TemplateManager popCompositeComponentClient(boolean cleanClientStack)
521     {
522         //if (!this._compositeComponentClients.isEmpty())
523         //{
524             //if (cleanClientStack)
525             //{
526             //    _clientsStack.get(_currentClientStack).clear();
527             //}
528             //_currentClientStack--;
529             //return this._compositeComponentClients.remove(0);
530         //}
531         if (_currentTemplateContext > 0)
532         {
533             TemplateManager tm = _isolatedTemplateContext.get(_currentTemplateContext).getCompositeComponentClient();
534             if (cleanClientStack)
535             {
536                 _isolatedTemplateContext.get(_currentTemplateContext).clear();
537             }
538             _currentTemplateContext--;
539             return tm;
540         }
541         return null;
542     }
543     
544 
545     @Override
546     public void pushCompositeComponentClient(final TemplateClient client)
547     {
548         //this._compositeComponentClients.add(0, new CompositeComponentTemplateManager(this._facelet, client));
549         //if (_currentClientStack + 1 <= _clientsStack.size())
550         //{
551         //    _clientsStack.add(new LinkedList<TemplateManager>());
552         //}
553         //_currentClientStack++;
554         if (_currentTemplateContext + 1 <= _isolatedTemplateContext.size())
555         {
556             _isolatedTemplateContext.add(new IsolatedTemplateContextImpl());
557         }
558         _currentTemplateContext++;
559         _isolatedTemplateContext.get(_currentTemplateContext).setCompositeComponentClient(
560             new CompositeComponentTemplateManager(this._facelet, client));
561     }
562     
563     @Override
564     public void pushCompositeComponentClient(final TemplateManager client)
565     {
566         //this._compositeComponentClients.add(0, client);
567         //if (_currentClientStack + 1 < _clientsStack.size())
568         //{
569         //    _clientsStack.add(new LinkedList<TemplateManager>());
570         //}
571         //_currentClientStack++;
572         if (_currentTemplateContext + 1 < _isolatedTemplateContext.size())
573         {
574             _isolatedTemplateContext.add(new IsolatedTemplateContextImpl());
575         }
576         _currentTemplateContext++;
577         _isolatedTemplateContext.get(_currentTemplateContext).setCompositeComponentClient(client);
578     }*/
579     
580     @Override
581     public void pushCompositeComponentClient(final TemplateClient client)
582     {
583         TemplateContext itc = new TemplateContextImpl();
584         itc.setCompositeComponentClient(
585                 new CompositeComponentTemplateManager(this._facelet, client, getPageContext()));
586         _isolatedTemplateContext.add(itc);
587         _currentTemplateContext++;
588         _defaultVarMapper.setTemplateContext(itc);
589     }
590     
591     @Override
592     public void popCompositeComponentClient()
593     {
594         if (_currentTemplateContext > 0)
595         {
596             _isolatedTemplateContext.remove(_currentTemplateContext);
597             _currentTemplateContext--;
598             _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
599         }
600     }
601     
602     @Override
603     public void pushTemplateContext(TemplateContext client)
604     {
605         _isolatedTemplateContext.add(client);
606         _currentTemplateContext++;
607         _defaultVarMapper.setTemplateContext(client);
608     }    
609 
610     
611     @Override
612     public TemplateContext popTemplateContext()
613     {
614         if (_currentTemplateContext > 0)
615         {
616             TemplateContext itc = _isolatedTemplateContext.get(_currentTemplateContext);
617             _isolatedTemplateContext.remove(_currentTemplateContext);
618             _currentTemplateContext--;
619             _defaultVarMapper.setTemplateContext(_isolatedTemplateContext.get(_currentTemplateContext));
620             return itc;
621         }
622         return null;
623     }
624     
625     @Override
626     public TemplateContext getTemplateContext()
627     {
628         return _isolatedTemplateContext.get(_currentTemplateContext);
629     }
630 
631     @Override
632     public boolean includeCompositeComponentDefinition(UIComponent parent, String name)
633             throws IOException, FaceletException, FacesException, ELException
634     {
635         //boolean found = false;
636         //TemplateManager client;
637 
638         //for (int i = 0, size = this._compositeComponentClients.size(); i < size && !found; i++)
639         //{
640         //    client = ((TemplateManager) this._compositeComponentClients.get(i));
641         //    if (client.equals(this._facelet))
642         //        continue;
643         //    found = client.apply(this, parent, name);
644         //}
645 
646         //return found;
647         TemplateClient ccClient = _isolatedTemplateContext.get(_currentTemplateContext).getCompositeComponentClient();
648         if (ccClient != null)
649         {
650             return ccClient.apply(this, parent, name);
651         }
652         return false;
653     }
654     
655     private final static class CompositeComponentTemplateManager extends TemplateManager implements TemplateClient
656     {
657         private final AbstractFacelet _owner;
658 
659         protected final TemplateClient _target;
660 
661         private final Set<String> _names = new HashSet<String>();
662         
663         private final PageContext _pageContext;
664 
665         public CompositeComponentTemplateManager(AbstractFacelet owner, TemplateClient target, PageContext pageContext)
666         {
667             this._owner = owner;
668             this._target = target;
669             this._pageContext = pageContext;
670         }
671 
672         public boolean apply(FaceletContext ctx, UIComponent parent, String name)
673                 throws IOException, FacesException, FaceletException,
674                 ELException
675         {
676             String testName = (name != null) ? name : "facelets._NULL_DEF_";
677             if (this._names.contains(testName))
678             {
679                 return false;
680             }
681             else
682             {
683                 this._names.add(testName);
684                 boolean found = false;
685                 AbstractFaceletContext actx = new DefaultFaceletContext(
686                         (DefaultFaceletContext) ctx, this._owner, false);
687                 ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, actx);
688                 try
689                 {
690                     actx.pushPageContext(this._pageContext);
691                     found = this._target
692                             .apply(actx,
693                                     parent, name);
694                 }
695                 finally
696                 {
697                     actx.popPageContext();
698                 }
699                 ctx.getFacesContext().getAttributes().put(FaceletContext.FACELET_CONTEXT_KEY, ctx);
700                 this._names.remove(testName);
701                 return found;
702             }
703         }
704 
705         public boolean equals(Object o)
706         {
707             // System.out.println(this.owner.getAlias() + " == " +
708             // ((DefaultFacelet) o).getAlias());
709             return this._owner == o || this._target == o;
710         }
711 
712         @Override
713         public int hashCode()
714         {
715             int result = _owner != null ? _owner.hashCode() : 0;
716             result = 31 * result + (_target != null ? _target.hashCode() : 0);
717             return result;
718         }
719     }
720     
721     @Override
722     public void pushPageContext(PageContext client)
723     {
724         _isolatedPageContext.add(client);
725         _defaultVarMapper.setPageContext(client);
726     }    
727 
728     @Override
729     public PageContext popPageContext()
730     {
731         if (!_isolatedPageContext.isEmpty())
732         {
733             int currentPageContext = _isolatedPageContext.size()-1;
734             PageContext itc = _isolatedPageContext.get(currentPageContext);
735             _isolatedPageContext.remove(currentPageContext);
736             if (!_isolatedPageContext.isEmpty())
737             {
738                 _defaultVarMapper.setPageContext(getPageContext());
739             }
740             else
741             {
742                 _defaultVarMapper.setPageContext(null);
743             }
744             return itc;
745         }
746         return null;
747     }
748     
749     @Override
750     public PageContext getPageContext()
751     {
752         return _isolatedPageContext.get(_isolatedPageContext.size()-1);
753     }
754     
755     //End methods from AbstractFaceletContext
756     
757     /**
758      * {@inheritDoc}
759      */
760     @Override
761     public boolean isPropertyResolved()
762     {
763         return _ctx.isPropertyResolved();
764     }
765 
766     /**
767      * {@inheritDoc}
768      */
769     @Override
770     public void setPropertyResolved(boolean resolved)
771     {
772         _ctx.setPropertyResolved(resolved);
773     }
774 
775     @Override
776     public void applyCompositeComponent(UIComponent parent, Resource resource)
777             throws IOException, FaceletException, FacesException, ELException
778     {
779         _facelet.applyCompositeComponent(this, parent, resource);
780     }
781 
782     @Override
783     public Iterator<AjaxHandler> getAjaxHandlers()
784     {
785         if (_ajaxHandlerStack != null && !_ajaxHandlerStack.isEmpty())
786         {
787             return _ajaxHandlerStack.iterator();
788         }
789         return null;
790     }
791 
792     @Override
793     public void popAjaxHandlerToStack()
794     {
795         if (_ajaxHandlerStack != null && !_ajaxHandlerStack.isEmpty())
796         {
797             _ajaxHandlerStack.removeFirst();
798         }
799     }
800 
801     @Override
802     public void pushAjaxHandlerToStack(
803             AjaxHandler parent)
804     {
805         if (_ajaxHandlerStack == null)
806         {
807             _ajaxHandlerStack = new LinkedList<AjaxHandler>();
808         }
809 
810         _ajaxHandlerStack.addFirst(parent);
811     }
812 
813     @Override
814     public boolean isBuildingCompositeComponentMetadata()
815     {
816         return _facelet.isBuildingCompositeComponentMetadata();
817     }
818     
819     public FaceletCompositionContext getFaceletCompositionContext()
820     {
821         return _mctx;
822     }
823     
824     public boolean isAnyFaceletsVariableResolved()
825     {
826         //if (isAllowCacheELExpressions() && _varMapperBase != null)
827         if (_varMapperBase != null)
828         {
829             return _varMapperBase.isAnyFaceletsVariableResolved();
830         }
831         return true;
832     }
833     
834     public boolean isAllowCacheELExpressions()
835     {
836         return _isCacheELExpressions && getTemplateContext().isAllowCacheELExpressions() 
837                 && getPageContext().isAllowCacheELExpressions();
838     }
839     
840     public void beforeConstructELExpression()
841     {
842         //if (isAllowCacheELExpressions() && _varMapperBase != null)
843         if (_varMapperBase != null)
844         {
845             _varMapperBase.beforeConstructELExpression();
846         }
847     }
848     
849     public void afterConstructELExpression()
850     {
851         //if (isAllowCacheELExpressions() && _varMapperBase != null)
852         if (_varMapperBase != null)
853         {
854             _varMapperBase.afterConstructELExpression();
855         }
856     }
857     
858     public ELExpressionCacheMode getELExpressionCacheMode()
859     {
860         return _elExpressionCacheMode;
861     }
862     
863 }