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.el;
20  
21  import java.util.HashMap;
22  import java.util.Map;
23  import java.util.List;
24  import java.util.ArrayList;
25  
26  import javax.faces.context.ExternalContext;
27  import javax.faces.context.FacesContext;
28  import javax.faces.el.ReferenceSyntaxException;
29  import javax.faces.el.VariableResolver;
30  import javax.faces.FacesException;
31  
32  import org.apache.myfaces.config.ManagedBeanBuilder;
33  import org.apache.myfaces.config.RuntimeConfig;
34  import org.apache.myfaces.config.element.ManagedBean;
35  
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  
39  
40  /**
41   * @author Manfred Geiler (latest modification by $Author: grantsmith $)
42   * @author Anton Koinov
43   * @version $Revision: 472618 $ $Date: 2006-11-08 15:06:54 -0500 (Wed, 08 Nov 2006) $
44   */
45  public class VariableResolverImpl
46      extends VariableResolver
47  {
48      //~ Static fields/initializers -----------------------------------------------------------------
49  
50      private static final Log log              = LogFactory.getLog(VariableResolverImpl.class);
51      private static final String BEANS_UNDER_CONSTRUCTION = "org.apache.myfaces.config.beansUnderConstruction";
52  
53      //~ Instance fields ----------------------------------------------------------------------------
54  
55      public static final Map s_standardImplicitObjects = new HashMap(32);
56      static {
57          s_standardImplicitObjects.put(
58              "applicationScope",
59              new ImplicitObject()
60              {
61                  public Object get(FacesContext facesContext)
62                  {
63                      return facesContext.getExternalContext().getApplicationMap();
64                  }
65              });
66          s_standardImplicitObjects.put(
67              "cookie",
68              new ImplicitObject()
69              {
70                  public Object get(FacesContext facesContext)
71                  {
72                      return facesContext.getExternalContext().getRequestCookieMap();
73                  }
74              });
75          s_standardImplicitObjects.put(
76              "facesContext",
77              new ImplicitObject()
78              {
79                  public Object get(FacesContext facesContext)
80                  {
81                      return facesContext;
82                  }
83              });
84          s_standardImplicitObjects.put(
85              "header",
86              new ImplicitObject()
87              {
88                  public Object get(FacesContext facesContext)
89                  {
90                      return facesContext.getExternalContext().getRequestHeaderMap();
91                  }
92              });
93          s_standardImplicitObjects.put(
94              "headerValues",
95              new ImplicitObject()
96              {
97                  public Object get(FacesContext facesContext)
98                  {
99                      return facesContext.getExternalContext().getRequestHeaderValuesMap();
100                 }
101             });
102         s_standardImplicitObjects.put(
103             "initParam",
104             new ImplicitObject()
105             {
106                 public Object get(FacesContext facesContext)
107                 {
108                     return facesContext.getExternalContext().getInitParameterMap();
109                 }
110             });
111         s_standardImplicitObjects.put(
112             "param",
113             new ImplicitObject()
114             {
115                 public Object get(FacesContext facesContext)
116                 {
117                     return facesContext.getExternalContext().getRequestParameterMap();
118                 }
119             });
120         s_standardImplicitObjects.put(
121             "paramValues",
122             new ImplicitObject()
123             {
124                 public Object get(FacesContext facesContext)
125                 {
126                     return facesContext.getExternalContext().getRequestParameterValuesMap();
127                 }
128             });
129         s_standardImplicitObjects.put(
130             "requestScope",
131             new ImplicitObject()
132             {
133                 public Object get(FacesContext facesContext)
134                 {
135                     return facesContext.getExternalContext().getRequestMap();
136                 }
137             });
138         s_standardImplicitObjects.put(
139             "sessionScope",
140             new ImplicitObject()
141             {
142                 public Object get(FacesContext facesContext)
143                 {
144                     return facesContext.getExternalContext().getSessionMap();
145                 }
146             });
147         s_standardImplicitObjects.put(
148             "view",
149             new ImplicitObject()
150             {
151                 public Object get(FacesContext facesContext)
152                 {
153                     return facesContext.getViewRoot();
154                 }
155             });
156     }
157 
158     /**
159      * Stores all implicit objects defined for this instance of <code>VariableResolver</code>
160      * <p>
161      * Can store instances of <code>ImplicitObject</code> which have the ability to
162      * dynamically resolve against FacesContext. Can also store any other object
163      * which itself is the value for the implicit object (this in effect will be
164      * a static object).
165      * </p>
166      * <p>
167      * WARNING: this implementation is not serialized as it is thread safe because
168      *          it does not update/add to _implicitObjects after object initialization.
169      *          If you need to add your own implicit objects, either extend and add more
170      *          in an initialization block, or add proper sychronization
171      * </p>
172      */
173     protected final Map _implicitObjects = new HashMap(32);
174     {
175         _implicitObjects.putAll(s_standardImplicitObjects);
176     }
177 
178     protected static final Map s_standardScopes = new HashMap(16);
179     static {
180         s_standardScopes.put(
181             "request",
182             new Scope()
183             {
184                 public void put(ExternalContext extContext, String name, Object obj)
185                 {
186                     extContext.getRequestMap().put(name, obj);
187                 }
188             });
189         s_standardScopes.put(
190             "session",
191             new Scope()
192             {
193                 public void put(ExternalContext extContext, String name, Object obj)
194                 {
195                     extContext.getSessionMap().put(name, obj);
196                 }
197             });
198         s_standardScopes.put(
199             "application",
200             new Scope()
201             {
202                 public void put(ExternalContext extContext, String name, Object obj)
203                 {
204                     extContext.getApplicationMap().put(name, obj);
205                 }
206             });
207         s_standardScopes.put(
208             "none",
209             new Scope()
210             {
211                 public void put(ExternalContext extContext, String name, Object obj)
212                 {
213                     // do nothing
214                 }
215             });
216     }
217 
218     /**
219      * Stores all scopes defined for this instance of <code>VariableResolver</code>
220      * <p>
221      * Can store instances of <code>Scope</code> which have the ability to
222      * dynamically resolve against ExternalContext for put operations.
223      * </p>
224      * <p>
225      * WARNING: this implementation is not serialized as it is thread safe because
226      *          it does not update/add to _scopes after object initialization.
227      *          If you need to add your own scopes, either extend and add more
228      *          in an initialization block, or add proper sychronization
229      * </p>
230      */
231     protected final Map _scopes = new HashMap(16);
232     {
233         _scopes.putAll(s_standardScopes);
234     }
235 
236     /**
237      * RuntimeConfig is instantiated once per servlet and never changes--we can
238      * safely cache it
239      */
240     private RuntimeConfig _runtimeConfig;
241 
242     private ManagedBeanBuilder beanBuilder = new ManagedBeanBuilder();
243 
244 
245     //~ Methods ---------------------------------------------------------------
246 
247     public Object resolveVariable(FacesContext facesContext, String name)
248     {
249         if ((name == null) || (name.length() == 0))
250         {
251             throw new ReferenceSyntaxException("Varible name is null or empty");
252         }
253 
254         // Implicit objects
255         Object implicitObject = _implicitObjects.get(name);
256         if (implicitObject != null)
257         {
258             if (implicitObject instanceof ImplicitObject)
259             {
260                 // a complex runtime object
261                 return ((ImplicitObject) implicitObject).get(facesContext);
262             }
263             else
264             {
265                 // a simple object
266                 return implicitObject;
267             }
268         }
269 
270         ExternalContext externalContext = facesContext.getExternalContext();
271 
272         // Request context
273         Map    requestMap = externalContext.getRequestMap();
274         Object obj = requestMap.get(name);
275         if (obj != null)
276         {
277             return obj;
278         }
279 
280         // Session context
281         obj = externalContext.getSessionMap().get(name);
282         if (obj != null)
283         {
284             return obj;
285         }
286 
287         // Application context
288         obj = externalContext.getApplicationMap().get(name);
289         if (obj != null)
290         {
291             return obj;
292         }
293 
294         // ManagedBean
295         ManagedBean mbc = getRuntimeConfig(facesContext).getManagedBean(name);
296 
297         if (mbc != null)
298         {
299 
300             // check for cyclic references
301             List beansUnderConstruction = (List)requestMap.get(BEANS_UNDER_CONSTRUCTION);
302             if (beansUnderConstruction == null) {
303                 beansUnderConstruction = new ArrayList();
304                 requestMap.put(BEANS_UNDER_CONSTRUCTION, beansUnderConstruction);
305             }
306 
307             String managedBeanName = mbc.getManagedBeanName();
308             if (beansUnderConstruction.contains(managedBeanName)) {
309                 throw new FacesException( "Detected cyclic reference to managedBean " + mbc.getManagedBeanName());
310             }
311 
312             beansUnderConstruction.add(managedBeanName);
313             try {
314                 obj = beanBuilder.buildManagedBean(facesContext, mbc);
315             } finally {
316                 beansUnderConstruction.remove(managedBeanName);
317             }
318 
319             // put in scope
320             String scopeKey = mbc.getManagedBeanScope();
321 
322             // find the scope handler object
323             Scope scope = (Scope) _scopes.get(scopeKey);
324             if (scope == null)
325             {
326                 log.error("Managed bean '" + name + "' has illegal scope: "
327                     + scopeKey);
328             }
329             else
330             {
331                 scope.put(externalContext, name, obj);
332             }
333 
334             if(obj==null && log.isDebugEnabled())
335             {
336                 log.debug("Variable '" + name + "' could not be resolved.");
337             }
338 
339             return obj;
340         }
341 
342         if(log.isDebugEnabled())
343         {
344             log.debug("Variable '" + name + "' could not be resolved.");
345         }
346         
347         return null;
348     }
349 
350     protected RuntimeConfig getRuntimeConfig(FacesContext facesContext)
351     {
352         if (_runtimeConfig == null)
353         {
354             _runtimeConfig = RuntimeConfig.getCurrentInstance(facesContext.getExternalContext());
355         }
356         return _runtimeConfig;
357     }
358 }
359 
360 
361 interface ImplicitObject
362 {
363     //~ Methods ---------------------------------------------------------------
364 
365     public Object get(FacesContext facesContext);
366 }
367 
368 
369 interface Scope
370 {
371     //~ Methods ---------------------------------------------------------------
372 
373     public void put(ExternalContext extContext, String name, Object obj);
374 }