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.el;
20  
21  import java.util.HashMap;
22  import java.util.Map;
23  
24  import javax.el.ValueExpression;
25  import javax.el.VariableMapper;
26  
27  import org.apache.myfaces.view.facelets.PageContext;
28  import org.apache.myfaces.view.facelets.TemplateContext;
29  
30  /**
31   * Default instance of a VariableMapper backed by a Map
32   * 
33   * @see javax.el.VariableMapper
34   * @see javax.el.ValueExpression
35   * @see java.util.Map
36   * 
37   * @author Jacob Hookom
38   * @version $Id$
39   */
40  public final class DefaultVariableMapper extends VariableMapperBase
41  {
42      private Map<String, ValueExpression> _vars;
43      
44      private PageContext _pageContext;
45      
46      private TemplateContext _templateContext;
47      
48      private VariableMapper _delegate;
49      
50      public boolean _trackResolveVariables;
51      
52      public boolean _variableResolved;
53  
54      public DefaultVariableMapper()
55      {
56          super();
57          _trackResolveVariables = false;
58          _variableResolved = false;
59      }
60  
61      public DefaultVariableMapper(VariableMapper delegate)
62      {
63          super();
64          this._delegate = delegate;
65      }
66      
67      /**
68       * @see javax.el.VariableMapper#resolveVariable(java.lang.String)
69       */
70      public ValueExpression resolveVariable(String name)
71      {
72          ValueExpression returnValue = null;
73          
74          if (_vars != null)
75          {
76              returnValue = _vars.get(name);
77          }
78  
79          //If the variable is not on the VariableMapper
80          if (returnValue == null)
81          {
82              //Check on page and template context
83              if (_pageContext != null && _pageContext.getAttributeCount() > 0)
84              {
85                  if (_pageContext.getAttributes().containsKey(name))
86                  {
87                      returnValue = _pageContext.getAttributes().get(name);
88                      if (_trackResolveVariables)
89                      {
90                          if (returnValue instanceof CacheableValueExpression)
91                          {
92                              if (returnValue instanceof CacheableValueExpressionWrapper)
93                              {
94                                  returnValue = ((CacheableValueExpressionWrapper)returnValue).
95                                      getWrapped();
96                              }
97                          }
98                          else
99                          {
100                             _variableResolved = true;
101                         }
102                     }
103                     return returnValue;
104                 }
105             }
106             
107             if (_templateContext != null)
108             {
109                 if (!_templateContext.isParameterEmpty() &&
110                     _templateContext.containsParameter(name))
111                 {
112                     returnValue = _templateContext.getParameter(name);
113                     if (_trackResolveVariables &&
114                         !(returnValue instanceof CacheableValueExpression))
115                     {
116                         _variableResolved = true;
117                     }
118                     return returnValue;
119                 }
120                 else if (!_templateContext.isKnownParametersEmpty() &&
121                     _templateContext.containsKnownParameter(name))
122                 {
123                     // This part is the most important in alwaysRecompile EL cache hack.
124                     // The idea is maintain a list of the parameters used in a template,
125                     // and if the name to be resolved match one of the list, even if the
126                     // param was not set it is necessary to track it as variable resolved.
127                     // This will force create a new EL expression each time the view is
128                     // built, preserving ui:param and VariableMapper behavior, but allow
129                     // cache all expressions that are not related.
130                     if (_trackResolveVariables)
131                     {
132                         _variableResolved = true;
133                     }
134                 }
135             }
136             
137             if (_delegate != null)
138             {
139                 returnValue = _delegate.resolveVariable(name);
140             }
141         }
142         else if (_trackResolveVariables)
143         {
144             // Is this code in a block that wants to cache 
145             // the resulting expression(s) and variable has been resolved?
146             _variableResolved = true;
147         }
148         
149         return returnValue;
150     }
151 
152     /**
153      * @see javax.el.VariableMapper#setVariable(java.lang.String, javax.el.ValueExpression)
154      */
155     public ValueExpression setVariable(String name, ValueExpression expression)
156     {
157         if (_vars == null)
158         {
159             _vars = new HashMap<String, ValueExpression>();
160         }
161         
162         return _vars.put(name, expression);
163     }
164     
165     /**
166      * Set the current page context this variable mapper should resolve against.
167      * 
168      * @param pageContext
169      */
170     public void setPageContext(PageContext pageContext)
171     {
172         this._pageContext = pageContext;
173     }
174     
175     /**
176      * Set the current template context this variable mapper should resolve against.
177      * 
178      * @param templateContext
179      */
180     public void setTemplateContext(TemplateContext templateContext)
181     {
182         this._templateContext = templateContext;
183     }
184 
185     @Override
186     public boolean isAnyFaceletsVariableResolved()
187     {
188         if (_trackResolveVariables)
189         {
190             return _variableResolved;
191         }
192         else
193         {
194             //Force expression creation
195             return true;
196         }
197     }
198 
199     @Override
200     public void beforeConstructELExpression()
201     {
202         _trackResolveVariables = true;
203         _variableResolved = false;
204     }
205 
206     @Override
207     public void afterConstructELExpression()
208     {
209         _trackResolveVariables = false;
210         _variableResolved = false;
211     }
212 }