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.view.facelets.FaceletViewDeclarationLanguage;
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 = FaceletViewDeclarationLanguage._javaTypeToClass((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 return _originalMap.containsKey(key);
306 }
307
308 public boolean containsValue(Object value)
309 {
310 return _originalMap.containsValue(value);
311 }
312
313 public Set<java.util.Map.Entry<String, Object>> entrySet()
314 {
315 return _originalMap.entrySet();
316 }
317
318 public Object get(Object key)
319 {
320 Object obj = _originalMap.get(key);
321 if (obj != null)
322 {
323
324
325
326
327
328
329
330 return obj;
331 }
332 else
333 {
334 if (_ccBeanInfo == null)
335 {
336 for (PropertyDescriptor attribute : _propertyDescriptors)
337 {
338 if (attribute.getName().equals(key))
339 {
340 obj = attribute.getValue("default");
341 break;
342 }
343 }
344 }
345 else
346 {
347 PropertyDescriptor attribute = _ccBeanInfo.getPropertyDescriptorsMap().get(key);
348 if (attribute != null)
349 {
350 obj = attribute.getValue("default");
351 }
352 }
353
354
355
356 if (obj != null && obj instanceof ValueExpression)
357 {
358 return ((ValueExpression) obj).getValue(FacesContext.getCurrentInstance().getELContext());
359 }
360 else
361 {
362 return obj;
363 }
364 }
365 }
366
367 public boolean isEmpty()
368 {
369 return _originalMap.isEmpty();
370 }
371
372 public Set<String> keySet()
373 {
374 return _originalMap.keySet();
375 }
376
377 public Object put(String key, Object value)
378 {
379 ValueExpression valueExpression = _component.getValueExpression(key);
380
381
382 if (valueExpression != null)
383 {
384 valueExpression.setValue(FacesContext.getCurrentInstance().getELContext(), value);
385
386 return null;
387 }
388
389
390
391
392 return _originalMap.put(key, value);
393 }
394
395 public void putAll(Map<? extends String, ? extends Object> m)
396 {
397 for (String key : m.keySet())
398 {
399 put(key, m.get(key));
400 }
401 }
402
403 public Object remove(Object key)
404 {
405 return _originalMap.remove(key);
406 }
407
408 public int size()
409 {
410 return _originalMap.size();
411 }
412
413 public Collection<Object> values()
414 {
415 return _originalMap.values();
416 }
417 }
418 }