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.ELException;
25  import javax.el.ValueExpression;
26  import javax.el.VariableMapper;
27  import javax.faces.FacesWrapper;
28  
29  /**
30   * Utility class for wrapping another VariableMapper with a new context, represented by a {@link java.util.Map Map}.
31   * Modifications occur to the Map instance, but resolve against the wrapped VariableMapper if the Map doesn't contain
32   * the ValueExpression requested.
33   * 
34   * @author Jacob Hookom
35   * @version $Id$
36   */
37  public final class VariableMapperWrapper extends VariableMapperBase implements FacesWrapper<VariableMapper>
38  {
39  
40      private final VariableMapper _target;
41      
42      private final VariableMapperBase _targetBase;
43  
44      private Map<String, ValueExpression> _vars;
45      
46      //private final boolean _checkTargetBase;
47      
48      public boolean _trackResolveVariables;
49      
50      public boolean _variableResolved;
51  
52      /**
53       * 
54       */
55      public VariableMapperWrapper(VariableMapper orig)
56      {
57          super();
58          _target = orig;
59          _targetBase = (orig instanceof VariableMapperBase) ? (VariableMapperBase) orig : null;
60          //_checkTargetBase = true;
61          _trackResolveVariables = false;
62          _variableResolved = false;
63      }
64  
65      /**
66       * First tries to resolve agains the inner Map, then the wrapped ValueExpression.
67       * 
68       * @see javax.el.VariableMapper#resolveVariable(java.lang.String)
69       */
70      public ValueExpression resolveVariable(String variable)
71      {
72          ValueExpression ve = null;
73          try
74          {
75              if (_vars != null)
76              {
77                  ve = (ValueExpression) _vars.get(variable);
78  
79                  // Is this code in a block that wants to cache 
80                  // the resulting expression(s) and variable has been resolved?
81                  if (_trackResolveVariables && ve != null)
82                  {
83                      _variableResolved = true;
84                  }
85              }
86              
87              if (ve == null)
88              {
89                  return _target.resolveVariable(variable);
90              }
91              
92              return ve;
93          }
94          catch (StackOverflowError e)
95          {
96              throw new ELException("Could not Resolve Variable [Overflow]: " + variable, e);
97          }
98      }
99  
100     /**
101      * Set the ValueExpression on the inner Map instance.
102      * 
103      * @see javax.el.VariableMapper#setVariable(java.lang.String, javax.el.ValueExpression)
104      */
105     public ValueExpression setVariable(String variable, ValueExpression expression)
106     {
107         if (_vars == null)
108         {
109             _vars = new HashMap<String, ValueExpression>();
110         }
111         
112         return _vars.put(variable, expression);
113     }
114 
115     @Override
116     public boolean isAnyFaceletsVariableResolved()
117     {
118         if (_trackResolveVariables)
119         {
120             if (_variableResolved)
121             {
122                 //Force EL creation!
123                 return true;
124             }
125             else
126             {
127                 //Otherwise check parent variable mapper 
128                 //if (_checkTargetBase)
129                 //{
130                     if (_targetBase != null)
131                     {
132                         return _targetBase.isAnyFaceletsVariableResolved();
133                     }
134                     else
135                     {
136                         // Another VariableMapper not extending from the base one was used. 
137                         // (that's the reason why _targetBase is null).
138                         // It is not possible to be sure the EL expression could use that mapper, 
139                         // so return true to force EL expression creation.
140                         return true;
141                     }
142                 //}
143                 //else
144                 //{
145                     // If no check for targetBase is required, we are in a context that suppose there will not
146                     // be variables resolved that could affect the expressions. So return false, indicating
147                     // the resulting expression can be cached.
148                     //return false;
149                 //}
150             }
151         }
152         else
153         {
154             // Force expression creation, because the call is outside caching block.
155             return true;
156         }
157     }
158 
159     public VariableMapper getWrapped()
160     {
161         return _target;
162     }
163 
164     @Override
165     public void beforeConstructELExpression()
166     {
167         _trackResolveVariables = true;
168         _variableResolved = false;
169         //if (_checkTargetBase && _targetBase != null)
170         if (_targetBase != null)
171         {
172             _targetBase.beforeConstructELExpression();
173         }
174     }
175 
176     @Override
177     public void afterConstructELExpression()
178     {
179         //if (_checkTargetBase && _targetBase != null)
180         if (_targetBase != null)
181         {
182             _targetBase.afterConstructELExpression();
183         }
184         _trackResolveVariables = false;
185         _variableResolved = false;
186     }
187 }