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 java.beans.BeanInfo;
22 import java.beans.FeatureDescriptor;
23 import java.beans.PropertyDescriptor;
24 import java.lang.ref.WeakReference;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.Map;
28 import java.util.Set;
29 import java.util.WeakHashMap;
30
31 import javax.el.ELContext;
32 import javax.el.ELResolver;
33 import javax.el.ValueExpression;
34 import javax.faces.component.UIComponent;
35 import javax.faces.context.FacesContext;
36 import javax.faces.el.CompositeComponentExpressionHolder;
37
38 import org.apache.myfaces.shared.config.MyfacesConfig;
39 import org.apache.myfaces.shared.util.ClassUtils;
40 import org.apache.myfaces.view.facelets.tag.composite.CompositeComponentBeanInfo;
41
42
43
44
45
46 public final class CompositeComponentELResolver extends ELResolver
47 {
48 private static final String ATTRIBUTES_MAP = "attrs";
49
50 private static final String PARENT_COMPOSITE_COMPONENT = "parent";
51
52 private static final String COMPOSITE_COMPONENT_ATTRIBUTES_MAPS =
53 "org.apache.myfaces.COMPOSITE_COMPONENT_ATTRIBUTES_MAPS";
54
55 @Override
56 public Class<?> getCommonPropertyType(ELContext context, Object base)
57 {
58
59
60 return String.class;
61 }
62
63 @Override
64 public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context,
65 Object base)
66 {
67
68
69 return null;
70 }
71
72 @Override
73 public Class<?> getType(ELContext context, Object base, Object property)
74 {
75 if (base != null && property != null &&
76 base instanceof CompositeComponentAttributesMapWrapper &&
77 property instanceof String)
78 {
79 FacesContext facesContext = facesContext(context);
80 if (facesContext == null)
81 {
82 facesContext = FacesContext.getCurrentInstance();
83 }
84 if (facesContext == null)
85 {
86 return null;
87 }
88 if (!MyfacesConfig.getCurrentInstance(facesContext.getExternalContext()).isStrictJsf2CCELResolver())
89 {
90
91
92
93 Class<?> exprType = null;
94 Class<?> metaType = null;
95
96 CompositeComponentAttributesMapWrapper evalMap = (CompositeComponentAttributesMapWrapper) base;
97 ValueExpression ve = evalMap.getExpression((String) property);
98 if (ve != null)
99 {
100 exprType = ve.getType(context);
101 }
102
103 if (!"".equals(property))
104 {
105 if (evalMap._propertyDescriptors != null)
106 {
107 for (PropertyDescriptor pd : evalMap._propertyDescriptors)
108 {
109 if (property.equals(pd.getName()))
110 {
111 metaType = resolveType(context, pd);
112 break;
113 }
114 }
115 }
116 }
117 if (metaType != null)
118 {
119
120 if (exprType == null || exprType.isAssignableFrom(metaType))
121 {
122 context.setPropertyResolved(true);
123 return metaType;
124 }
125 }
126 return exprType;
127 }
128 }
129
130
131 return null;
132 }
133
134
135 private static Class<?> resolveType(ELContext context, PropertyDescriptor pd)
136 {
137 if (pd != null)
138 {
139 Object type = pd.getValue("type");
140 if (type != null)
141 {
142 type = ((ValueExpression)type).getValue(context);
143 if (type instanceof String)
144 {
145 try
146 {
147 type = ClassUtils.javaDefaultTypeToClass((String)type);
148 }
149 catch (ClassNotFoundException e)
150 {
151 type = null;
152 }
153 }
154 return (Class<?>) type;
155 }
156 return pd.getPropertyType();
157 }
158
159 return null;
160 }
161
162 @Override
163 public Object getValue(ELContext context, Object base, Object property)
164 {
165
166
167
168 if ((base != null) && (base instanceof UIComponent)
169 && UIComponent.isCompositeComponent((UIComponent) base)
170 && (property != null))
171 {
172 String propName = property.toString();
173 UIComponent baseComponent = (UIComponent) base;
174
175 if (propName.equals(ATTRIBUTES_MAP))
176 {
177
178
179 context.setPropertyResolved(true);
180
181 return _getCompositeComponentAttributesMapWrapper(baseComponent, context);
182 }
183
184 else if (propName.equals(PARENT_COMPOSITE_COMPONENT))
185 {
186
187
188 context.setPropertyResolved(true);
189
190 return UIComponent.getCompositeComponentParent(baseComponent);
191 }
192 }
193
194
195
196 return null;
197 }
198
199 @SuppressWarnings("unchecked")
200 private Map<String, Object> _getCompositeComponentAttributesMapWrapper(
201 UIComponent baseComponent, ELContext elContext)
202 {
203 Map<Object, Object> contextMap = (Map<Object, Object>) facesContext(
204 elContext).getAttributes();
205
206
207
208
209
210
211
212
213 Map<UIComponent, WeakReference<Map<String, Object>>> compositeComponentAttributesMaps =
214 (Map<UIComponent, WeakReference<Map<String, Object>>>) contextMap
215 .get(COMPOSITE_COMPONENT_ATTRIBUTES_MAPS);
216
217 Map<String, Object> attributesMap = null;
218 WeakReference<Map<String, Object>> weakReference;
219 if (compositeComponentAttributesMaps != null)
220 {
221 weakReference = compositeComponentAttributesMaps.get(baseComponent);
222 if (weakReference != null)
223 {
224 attributesMap = weakReference.get();
225 }
226 if (attributesMap == null)
227 {
228
229 attributesMap = new CompositeComponentAttributesMapWrapper(
230 baseComponent);
231 compositeComponentAttributesMaps.put(baseComponent,
232 new WeakReference<Map<String, Object>>(attributesMap));
233 }
234 }
235 else
236 {
237
238 attributesMap = new CompositeComponentAttributesMapWrapper(
239 baseComponent);
240 compositeComponentAttributesMaps = new WeakHashMap<UIComponent, WeakReference<Map<String, Object>>>();
241 compositeComponentAttributesMaps.put(baseComponent,
242 new WeakReference<Map<String, Object>>(attributesMap));
243 contextMap.put(COMPOSITE_COMPONENT_ATTRIBUTES_MAPS,
244 compositeComponentAttributesMaps);
245 }
246 return attributesMap;
247 }
248
249
250 private static FacesContext facesContext(final ELContext context)
251 {
252 return (FacesContext)context.getContext(FacesContext.class);
253 }
254
255 @Override
256 public boolean isReadOnly(ELContext context, Object base, Object property)
257 {
258
259
260 return true;
261 }
262
263 @Override
264 public void setValue(ELContext context, Object base, Object property,
265 Object value)
266 {
267
268 }
269
270
271 private final class CompositeComponentAttributesMapWrapper
272 implements CompositeComponentExpressionHolder, Map<String, Object>
273 {
274
275 private final UIComponent _component;
276 private final BeanInfo _beanInfo;
277 private final Map<String, Object> _originalMap;
278 private final PropertyDescriptor [] _propertyDescriptors;
279 private final CompositeComponentBeanInfo _ccBeanInfo;
280
281 private CompositeComponentAttributesMapWrapper(UIComponent component)
282 {
283 this._component = component;
284 this._originalMap = component.getAttributes();
285 this._beanInfo = (BeanInfo) _originalMap.get(UIComponent.BEANINFO_KEY);
286 this._propertyDescriptors = _beanInfo.getPropertyDescriptors();
287 this._ccBeanInfo = (this._beanInfo instanceof CompositeComponentBeanInfo) ?
288 (CompositeComponentBeanInfo) this._beanInfo : null;
289 }
290
291 public ValueExpression getExpression(String name)
292 {
293 ValueExpression valueExpr = _component.getValueExpression(name);
294
295 return valueExpr;
296 }
297
298 public void clear()
299 {
300 _originalMap.clear();
301 }
302
303 public boolean containsKey(Object key)
304 {
305 boolean value = _originalMap.containsKey(key);
306 if (value)
307 {
308 return value;
309 }
310 else
311 {
312 if (_ccBeanInfo == null)
313 {
314 for (PropertyDescriptor attribute : _propertyDescriptors)
315 {
316 if (attribute.getName().equals(key))
317 {
318 return attribute.getValue("default") != null;
319 }
320 }
321 }
322 else
323 {
324 PropertyDescriptor attribute = _ccBeanInfo.getPropertyDescriptorsMap().get(key);
325 if (attribute != null)
326 {
327 return attribute.getValue("default") != null;
328 }
329 }
330 }
331 return false;
332 }
333
334 public boolean containsValue(Object value)
335 {
336 return _originalMap.containsValue(value);
337 }
338
339 public Set<java.util.Map.Entry<String, Object>> entrySet()
340 {
341 return _originalMap.entrySet();
342 }
343
344 public Object get(Object key)
345 {
346 Object obj = _originalMap.get(key);
347 if (obj != null)
348 {
349
350
351
352
353
354
355
356 return obj;
357 }
358 else
359 {
360 if (_ccBeanInfo == null)
361 {
362 for (PropertyDescriptor attribute : _propertyDescriptors)
363 {
364 if (attribute.getName().equals(key))
365 {
366 obj = attribute.getValue("default");
367 break;
368 }
369 }
370 }
371 else
372 {
373 PropertyDescriptor attribute = _ccBeanInfo.getPropertyDescriptorsMap().get(key);
374 if (attribute != null)
375 {
376 obj = attribute.getValue("default");
377 }
378 }
379
380
381
382 if (obj != null && obj instanceof ValueExpression)
383 {
384 return ((ValueExpression) obj).getValue(FacesContext.getCurrentInstance().getELContext());
385 }
386 else
387 {
388 return obj;
389 }
390 }
391 }
392
393 public boolean isEmpty()
394 {
395 return _originalMap.isEmpty();
396 }
397
398 public Set<String> keySet()
399 {
400 return _originalMap.keySet();
401 }
402
403 public Object put(String key, Object value)
404 {
405 ValueExpression valueExpression = _component.getValueExpression(key);
406
407
408 if (valueExpression != null)
409 {
410 valueExpression.setValue(FacesContext.getCurrentInstance().getELContext(), value);
411
412 return null;
413 }
414
415
416
417
418 return _originalMap.put(key, value);
419 }
420
421 public void putAll(Map<? extends String, ? extends Object> m)
422 {
423 for (String key : m.keySet())
424 {
425 put(key, m.get(key));
426 }
427 }
428
429 public Object remove(Object key)
430 {
431 return _originalMap.remove(key);
432 }
433
434 public int size()
435 {
436 return _originalMap.size();
437 }
438
439 public Collection<Object> values()
440 {
441 return _originalMap.values();
442 }
443 }
444 }