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