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: DefaultVariableMapper.java 1470662 2013-04-22 19:04:45Z lu4242 $
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                          _variableResolved = true;
91                      }
92                      return returnValue;
93                  }
94              }
95              
96              if (_templateContext != null)
97              {
98                  if (!_templateContext.isParameterEmpty() &&
99                      _templateContext.containsParameter(name))
100                 {
101                     returnValue = _templateContext.getParameter(name);
102                     if (_trackResolveVariables)
103                     {
104                         _variableResolved = true;
105                     }
106                     return returnValue;
107                 }
108                 else if (!_templateContext.isKnownParametersEmpty() &&
109                     _templateContext.containsKnownParameter(name))
110                 {
111                     // This part is the most important in alwaysRecompile EL cache hack.
112                     // The idea is maintain a list of the parameters used in a template,
113                     // and if the name to be resolved match one of the list, even if the
114                     // param was not set it is necessary to track it as variable resolved.
115                     // This will force create a new EL expression each time the view is
116                     // built, preserving ui:param and VariableMapper behavior, but allow
117                     // cache all expressions that are not related.
118                     if (_trackResolveVariables)
119                     {
120                         _variableResolved = true;
121                     }
122                 }
123             }
124             
125             if (_delegate != null)
126             {
127                 returnValue = _delegate.resolveVariable(name);
128             }
129         }
130         else if (_trackResolveVariables)
131         {
132             // Is this code in a block that wants to cache 
133             // the resulting expression(s) and variable has been resolved?
134             _variableResolved = true;
135         }
136         
137         return returnValue;
138     }
139 
140     /**
141      * @see javax.el.VariableMapper#setVariable(java.lang.String, javax.el.ValueExpression)
142      */
143     public ValueExpression setVariable(String name, ValueExpression expression)
144     {
145         if (_vars == null)
146         {
147             _vars = new HashMap<String, ValueExpression>();
148         }
149         
150         return _vars.put(name, expression);
151     }
152     
153     /**
154      * Set the current page context this variable mapper should resolve against.
155      * 
156      * @param pageContext
157      */
158     public void setPageContext(PageContext pageContext)
159     {
160         this._pageContext = pageContext;
161     }
162     
163     /**
164      * Set the current template context this variable mapper should resolve against.
165      * 
166      * @param templateContext
167      */
168     public void setTemplateContext(TemplateContext templateContext)
169     {
170         this._templateContext = templateContext;
171     }
172 
173     @Override
174     public boolean isAnyFaceletsVariableResolved()
175     {
176         if (_trackResolveVariables)
177         {
178             return _variableResolved;
179         }
180         else
181         {
182             //Force expression creation
183             return true;
184         }
185     }
186 
187     @Override
188     public void beforeConstructELExpression()
189     {
190         _trackResolveVariables = true;
191         _variableResolved = false;
192     }
193 
194     @Override
195     public void afterConstructELExpression()
196     {
197         _trackResolveVariables = false;
198         _variableResolved = false;
199     }
200 }