1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.el.unified.resolver;
20
21 import org.apache.myfaces.config.ManagedBeanBuilder;
22 import org.apache.myfaces.config.RuntimeConfig;
23 import org.apache.myfaces.config.element.ManagedBean;
24 import org.apache.myfaces.context.servlet.StartupServletExternalContextImpl;
25
26 import javax.el.ELContext;
27 import javax.el.ELException;
28 import javax.el.ELResolver;
29 import javax.el.PropertyNotFoundException;
30 import javax.el.PropertyNotWritableException;
31 import javax.faces.FacesException;
32 import javax.faces.context.ExternalContext;
33 import javax.faces.context.FacesContext;
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import java.beans.FeatureDescriptor;
37 import java.util.ArrayList;
38 import java.util.HashMap;
39 import java.util.Iterator;
40 import java.util.List;
41 import java.util.Map;
42
43
44
45
46
47
48 public class ManagedBeanResolver extends ELResolver
49 {
50 private static final Log log = LogFactory.getLog(ManagedBeanResolver.class);
51 private static final String BEANS_UNDER_CONSTRUCTION =
52 "org.apache.myfaces.el.unified.resolver.managedbean.beansUnderConstruction";
53
54
55 protected static final Map<String, Scope> s_standardScopes = new HashMap<String, Scope>(16);
56
57 static
58 {
59 s_standardScopes.put("request", new Scope()
60 {
61 public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
62 {
63 extContext.getRequestMap().put(name, obj);
64 }
65 });
66
67 s_standardScopes.put("session", new Scope()
68 {
69 public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
70 {
71 extContext.getSessionMap().put(name, obj);
72 }
73 });
74
75 s_standardScopes.put("application", new Scope()
76 {
77 public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
78 {
79 extContext.getApplicationMap().put(name, obj);
80 }
81 });
82
83 s_standardScopes.put("none", new Scope()
84 {
85 public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj)
86 {
87
88 }
89 });
90 }
91
92
93
94
95
96
97
98
99
100
101
102
103
104 protected final Map<String, Scope> _scopes = new HashMap<String, Scope>(16);
105 {
106 _scopes.putAll(s_standardScopes);
107 }
108
109
110
111
112 private RuntimeConfig runtimeConfig;
113
114 private ManagedBeanBuilder beanBuilder = new ManagedBeanBuilder();
115
116
117 public ManagedBeanResolver()
118 {
119 }
120
121 @Override
122 public void setValue(final ELContext context, final Object base, final Object property, final Object value)
123 throws NullPointerException, PropertyNotFoundException, PropertyNotWritableException, ELException
124 {
125
126 if ((base == null) && (property == null))
127 {
128 throw new PropertyNotFoundException();
129 }
130
131 }
132
133 @Override
134 public boolean isReadOnly(final ELContext context, final Object base, final Object property)
135 throws NullPointerException, PropertyNotFoundException, ELException
136 {
137
138 if ((base == null) && (property == null))
139 {
140 throw new PropertyNotFoundException();
141 }
142
143 return false;
144 }
145
146 @Override
147 @SuppressWarnings("unchecked")
148 public Object getValue(final ELContext context, final Object base, final Object property)
149 throws NullPointerException, PropertyNotFoundException, ELException
150 {
151
152 if (base != null)
153 {
154 return null;
155 }
156
157 if (property == null)
158 {
159 throw new PropertyNotFoundException();
160 }
161
162 final FacesContext facesContext = facesContext(context);
163 if (facesContext == null)
164 {
165 return null;
166 }
167 final ExternalContext extContext = facesContext.getExternalContext();
168 if (extContext == null)
169 {
170 return null;
171 }
172
173 final boolean startup = (extContext instanceof StartupServletExternalContextImpl);
174
175
176 if (!startup)
177 {
178 if (extContext.getRequestMap().containsKey(property))
179 {
180 return null;
181 }
182 }
183
184
185 if (!startup)
186 {
187 if (extContext.getSessionMap().containsKey(property))
188 {
189 return null;
190 }
191 }
192
193
194 if (extContext.getApplicationMap().containsKey(property))
195 {
196 return null;
197 }
198
199
200
201 if (!(property instanceof String))
202 {
203 return null;
204 }
205 final String strProperty = (String) property;
206
207 final ManagedBean managedBean = runtimeConfig(context).getManagedBean(strProperty);
208 Object beanInstance = null;
209 if (managedBean != null)
210 {
211 context.setPropertyResolved(true);
212
213 beanInstance = createManagedBean(managedBean, facesContext);
214 }
215
216 return beanInstance;
217 }
218
219
220
221
222
223
224 @SuppressWarnings("unchecked")
225 private Object createManagedBean(final ManagedBean managedBean, final FacesContext facesContext) throws ELException
226 {
227
228 final ExternalContext extContext = facesContext.getExternalContext();
229 final Map requestMap = extContext.getRequestMap();
230
231
232 List beansUnderConstruction = (List<String>) requestMap.get(BEANS_UNDER_CONSTRUCTION);
233 if (beansUnderConstruction == null)
234 {
235 beansUnderConstruction = new ArrayList<String>();
236 requestMap.put(BEANS_UNDER_CONSTRUCTION, beansUnderConstruction);
237 }
238
239 final String managedBeanName = managedBean.getManagedBeanName();
240 if (beansUnderConstruction.contains(managedBeanName))
241 {
242 throw new ELException("Detected cyclic reference to managedBean " + managedBeanName);
243 }
244
245 beansUnderConstruction.add(managedBeanName);
246
247 Object obj = null;
248 try
249 {
250 obj = beanBuilder.buildManagedBean(facesContext, managedBean);
251 }
252 finally
253 {
254 beansUnderConstruction.remove(managedBeanName);
255 }
256
257 putInScope(managedBean, facesContext, extContext, obj);
258
259 return obj;
260 }
261
262 @SuppressWarnings("unchecked")
263 private void putInScope(final ManagedBean managedBean, final FacesContext facesContext,
264 final ExternalContext extContext, final Object obj)
265 {
266
267 final String managedBeanName = managedBean.getManagedBeanName();
268
269 if (obj == null)
270 {
271 if (log.isDebugEnabled())
272 log.debug("Variable '" + managedBeanName + "' could not be resolved.");
273 }
274 else
275 {
276 final String scopeKey = managedBean.getManagedBeanScope();
277
278
279 final Scope scope = _scopes.get(scopeKey);
280 if (scope != null)
281 {
282 scope.put(facesContext, extContext, managedBeanName, obj);
283 }
284 else
285
286 {
287 log.error("Managed bean '" + managedBeanName + "' has illegal scope: " + scopeKey);
288 }
289 }
290
291 }
292
293
294 private static FacesContext facesContext(final ELContext context)
295 {
296 return (FacesContext)context.getContext(FacesContext.class);
297 }
298
299 @Override
300 public Class<?> getType(final ELContext context, final Object base, final Object property)
301 throws NullPointerException, PropertyNotFoundException, ELException
302 {
303
304 if ((base == null) && (property == null))
305 {
306 throw new PropertyNotFoundException();
307 }
308
309 return null;
310 }
311
312 @Override
313 public Iterator<FeatureDescriptor> getFeatureDescriptors(final ELContext context, final Object base)
314 {
315
316 if (base != null)
317 return null;
318
319 final ArrayList<FeatureDescriptor> descriptors = new ArrayList<FeatureDescriptor>();
320
321 final Map<String, ManagedBean> managedBeans = runtimeConfig(context).getManagedBeans();
322 for (Map.Entry<String, ManagedBean> managedBean : managedBeans.entrySet())
323 {
324 descriptors.add(makeDescriptor(managedBean.getKey(), managedBean.getValue()));
325 }
326
327 return descriptors.iterator();
328 }
329
330 private static FeatureDescriptor makeDescriptor(final String beanName, final ManagedBean managedBean)
331 {
332 final FeatureDescriptor fd = new FeatureDescriptor();
333 fd.setValue(ELResolver.RESOLVABLE_AT_DESIGN_TIME, Boolean.TRUE);
334 fd.setValue(ELResolver.TYPE, managedBean.getManagedBeanClass());
335 fd.setName(beanName);
336 fd.setDisplayName(beanName);
337 fd.setShortDescription(managedBean.getDescription());
338 fd.setExpert(false);
339 fd.setHidden(false);
340 fd.setPreferred(true);
341 return fd;
342 }
343
344 protected RuntimeConfig runtimeConfig(final ELContext context)
345 {
346 final FacesContext facesContext = facesContext(context);
347
348
349 if (this.runtimeConfig == null)
350 {
351 this.runtimeConfig = RuntimeConfig.getCurrentInstance(facesContext.getExternalContext());
352 }
353
354 return runtimeConfig;
355 }
356
357 @Override
358 public Class<?> getCommonPropertyType(final ELContext context, final Object base)
359 {
360 if (base == null)
361 {
362 return Object.class;
363 }
364
365 return null;
366 }
367
368 interface Scope
369 {
370 public void put(FacesContext facesContext, ExternalContext extContext, String name, Object obj);
371 }
372 }