1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.component;
20
21 import java.beans.BeanInfo;
22 import java.beans.IntrospectionException;
23 import java.beans.Introspector;
24 import java.beans.PropertyDescriptor;
25 import java.io.Serializable;
26 import java.lang.reflect.Method;
27 import java.util.Collection;
28 import java.util.Collections;
29 import java.util.HashMap;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.WeakHashMap;
33
34 import javax.el.ValueExpression;
35 import javax.faces.FacesException;
36 import javax.faces.application.Resource;
37 import javax.faces.context.FacesContext;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58 class _ComponentAttributesMap implements Map<String, Object>, Serializable
59 {
60 private static final long serialVersionUID = -9106832179394257866L;
61
62 private static final Object[] EMPTY_ARGS = new Object[0];
63
64 private final static String MARK_CREATED = "oam.vf.MARK_ID";
65
66 private final static String FACET_NAME_KEY = "facelets.FACET_NAME";
67
68 public final static String FACET_CREATED_UIPANEL_MARKER = "oam.vf.createdUIPanel";
69
70 private final static String COMPONENT_ADDED_BY_HANDLER_MARKER = "oam.vf.addedByHandler";
71
72 public static final String PROPERTY_DESCRIPTOR_MAP_KEY = "oam.cc.beanInfo.PDM";
73
74
75
76
77
78
79 private final static int MIN_LENGHT_CHECK = MARK_CREATED.length();
80
81
82 private UIComponentBase _component;
83
84
85
86
87
88
89
90
91
92
93 private transient Map<String, _PropertyDescriptorHolder> _propertyDescriptorMap = null;
94
95
96 private static Map<Class<?>, Map<String, _PropertyDescriptorHolder>> propertyDescriptorCache =
97 new WeakHashMap<Class<?>, Map<String, _PropertyDescriptorHolder>>();
98
99 private boolean _isCompositeComponent;
100 private boolean _isCompositeComponentSet;
101
102 private BeanInfo _ccBeanInfo;
103
104
105
106
107
108
109 _ComponentAttributesMap(UIComponentBase component)
110 {
111 _component = component;
112 }
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 public int size()
139 {
140 return getUnderlyingMap().size();
141 }
142
143
144
145
146
147
148
149
150
151
152 public void clear()
153 {
154 getUnderlyingMap().clear();
155 }
156
157
158
159
160
161
162
163
164
165
166 public boolean isEmpty()
167 {
168 return getUnderlyingMap().isEmpty();
169 }
170
171
172
173
174
175
176
177
178
179
180
181
182
183 public boolean containsKey(Object key)
184 {
185 checkKey(key);
186
187 int keyLength = ((String)key).length();
188 if (keyLength >= MIN_LENGHT_CHECK)
189 {
190 if (MARK_CREATED.length() == keyLength &&
191 MARK_CREATED.equals(key))
192 {
193 return ((UIComponentBase)_component).getOamVfMarkCreated() != null;
194 }
195 else if (FACET_NAME_KEY.length() == keyLength &&
196 FACET_NAME_KEY.equals(key))
197 {
198 return _component.getOamVfFacetName() != null;
199 }
200 else if (COMPONENT_ADDED_BY_HANDLER_MARKER.length() == keyLength &&
201 COMPONENT_ADDED_BY_HANDLER_MARKER.equals(key))
202 {
203 return _component.isOamVfAddedByHandler();
204 }
205 else if (FACET_CREATED_UIPANEL_MARKER.length() == keyLength &&
206 FACET_CREATED_UIPANEL_MARKER.equals(key))
207 {
208 return _component.isOamVfFacetCreatedUIPanel();
209 }
210
211
212
213 if (Resource.COMPONENT_RESOURCE_KEY.length() == keyLength &&
214 Resource.COMPONENT_RESOURCE_KEY.equals(key))
215 {
216 if (!_isCompositeComponentSet)
217 {
218
219
220
221
222
223 _isCompositeComponent = getUnderlyingMap().containsKey(Resource.COMPONENT_RESOURCE_KEY);
224 }
225 return _isCompositeComponent;
226 }
227 }
228 return getPropertyDescriptor((String) key) == null ? getUnderlyingMap().containsKey(key) : false;
229 }
230
231
232
233
234
235
236
237
238 public boolean containsValue(Object value)
239 {
240 return getUnderlyingMap().containsValue(value);
241 }
242
243
244
245
246
247 public Collection<Object> values()
248 {
249 return getUnderlyingMap().values();
250 }
251
252
253
254
255 public void putAll(Map<? extends String, ?> t)
256 {
257 for (Map.Entry<? extends String, ?> entry : t.entrySet())
258 {
259 put(entry.getKey(), entry.getValue());
260 }
261 }
262
263
264
265
266
267 public Set<Map.Entry<String, Object>> entrySet()
268 {
269 return getUnderlyingMap().entrySet();
270 }
271
272
273
274
275
276 public Set<String> keySet()
277 {
278 return getUnderlyingMap().keySet();
279 }
280
281
282
283
284
285
286
287
288 public Object get(Object key)
289 {
290 checkKey(key);
291
292 Object value;
293
294 int keyLength = ((String)key).length();
295 if (keyLength >= MIN_LENGHT_CHECK)
296 {
297 if (MARK_CREATED.length() == keyLength &&
298 MARK_CREATED.equals(key))
299 {
300 return _component.getOamVfMarkCreated();
301 }
302 else if (FACET_NAME_KEY.length() == keyLength &&
303 FACET_NAME_KEY.equals(key))
304 {
305 return _component.getOamVfFacetName();
306 }
307 else if (COMPONENT_ADDED_BY_HANDLER_MARKER.length() == keyLength &&
308 COMPONENT_ADDED_BY_HANDLER_MARKER.equals(key))
309 {
310 return _component.isOamVfAddedByHandler();
311 }
312 else if (FACET_CREATED_UIPANEL_MARKER.length() == keyLength &&
313 FACET_CREATED_UIPANEL_MARKER.equals(key))
314 {
315 return _component.isOamVfFacetCreatedUIPanel();
316 }
317 }
318
319 _PropertyDescriptorHolder propertyDescriptor = getPropertyDescriptor((String) key);
320 if (propertyDescriptor != null)
321 {
322 value = getComponentProperty(propertyDescriptor);
323 }
324 else
325 {
326
327 value = getUnderlyingMap().get(key);
328 if (value == null)
329 {
330
331 ValueExpression ve = _component.getValueExpression((String) key);
332 if (ve != null)
333 {
334 value = ve.getValue(_component.getFacesContext().getELContext());
335 }
336 else
337 {
338 if (!_isCompositeComponentSet)
339 {
340 _isCompositeComponent = getUnderlyingMap().containsKey(Resource.COMPONENT_RESOURCE_KEY);
341 _isCompositeComponentSet = true;
342 }
343 if (_isCompositeComponent)
344 {
345 BeanInfo ccBeanInfo = _ccBeanInfo != null ? _ccBeanInfo :
346 (BeanInfo) getUnderlyingMap().get(UIComponent.BEANINFO_KEY);
347 if (ccBeanInfo != null)
348 {
349
350 Map<String, PropertyDescriptor> attributeMap = (Map<String, PropertyDescriptor>)
351 ccBeanInfo.getBeanDescriptor().getValue(
352 PROPERTY_DESCRIPTOR_MAP_KEY);
353 if (attributeMap != null)
354 {
355 PropertyDescriptor attribute = attributeMap.get(key);
356 if (attribute != null)
357 {
358 String attributeName = attribute.getName();
359 boolean isKnownMethod = "action".equals(attributeName)
360 || "actionListener".equals(attributeName)
361 || "validator".equals(attributeName)
362 || "valueChangeListener".equals(attributeName);
363
364
365
366 ValueExpression methodSignatureExpression
367 = (ValueExpression) attribute.getValue("method-signature");
368 String methodSignature = null;
369 if (methodSignatureExpression != null)
370 {
371
372
373
374 methodSignature = (String) methodSignatureExpression.getValue(
375 _component.getFacesContext().getELContext());
376 }
377
378
379
380 if (isKnownMethod || methodSignature != null)
381 {
382
383 return attribute.getValue("default");
384 }
385 else
386 {
387 value = attribute.getValue("default");
388 }
389 }
390 }
391 else
392 {
393
394 for (PropertyDescriptor attribute : ccBeanInfo.getPropertyDescriptors())
395 {
396 if (attribute.getName().equals(key))
397 {
398 String attributeName = attribute.getName();
399 boolean isKnownMethod = "action".equals(attributeName)
400 || "actionListener".equals(attributeName)
401 || "validator".equals(attributeName)
402 || "valueChangeListener".equals(attributeName);
403
404
405
406 ValueExpression methodSignatureExpression
407 = (ValueExpression) attribute.getValue("method-signature");
408 String methodSignature = null;
409 if (methodSignatureExpression != null)
410 {
411
412
413
414 methodSignature = (String) methodSignatureExpression.getValue(
415 _component.getFacesContext().getELContext());
416 }
417
418
419
420 if (isKnownMethod || methodSignature != null)
421 {
422
423 return attribute.getValue("default");
424 }
425 else
426 {
427 value = attribute.getValue("default");
428 break;
429 }
430 }
431 }
432 }
433
434
435
436 if (value != null && value instanceof ValueExpression)
437 {
438 return ((ValueExpression) value).getValue(_component.getFacesContext().getELContext());
439 }
440 }
441 }
442
443
444 }
445 }
446 }
447
448
449 return value;
450 }
451
452
453
454
455
456
457
458
459
460 public Object remove(Object key)
461 {
462 checkKey(key);
463 int keyLength = ((String)key).length();
464 if (keyLength >= MIN_LENGHT_CHECK)
465 {
466 if (MARK_CREATED.length() == keyLength &&
467 MARK_CREATED.equals(key))
468 {
469 Object oldValue = _component.getOamVfMarkCreated();
470 _component.setOamVfMarkCreated(null);
471 return oldValue;
472 }
473 else if (FACET_NAME_KEY.length() == keyLength &&
474 FACET_NAME_KEY.equals(key))
475 {
476 Object oldValue = _component.getOamVfFacetName();
477 _component.setOamVfFacetName(null);
478 return oldValue;
479 }
480 else if (COMPONENT_ADDED_BY_HANDLER_MARKER.length() == keyLength &&
481 COMPONENT_ADDED_BY_HANDLER_MARKER.equals(key))
482 {
483 Object oldValue = _component.isOamVfAddedByHandler();
484 _component.setOamVfAddedByHandler(false);
485 return oldValue;
486 }
487 else if (FACET_CREATED_UIPANEL_MARKER.length() == keyLength &&
488 FACET_CREATED_UIPANEL_MARKER.equals(key))
489 {
490 Object oldValue = _component.isOamVfFacetCreatedUIPanel();
491 _component.setOamVfFacetCreatedUIPanel(false);
492 return oldValue;
493 }
494 else if (UIComponent.BEANINFO_KEY.length() == keyLength
495 && UIComponent.BEANINFO_KEY.equals(key))
496 {
497 _ccBeanInfo = null;
498 }
499 }
500 _PropertyDescriptorHolder propertyDescriptor = getPropertyDescriptor((String) key);
501 if (propertyDescriptor != null)
502 {
503 throw new IllegalArgumentException("Cannot remove component property attribute");
504 }
505 return _component.getStateHelper().remove(
506 UIComponentBase.PropertyKeys.attributesMap, key);
507 }
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536 public Object put(String key, Object value)
537 {
538 if (key == null)
539 {
540 throw new NullPointerException("key");
541 }
542 int keyLength = ((String)key).length();
543 if (keyLength >= MIN_LENGHT_CHECK)
544 {
545 if (MARK_CREATED.length() == keyLength &&
546 MARK_CREATED.equals(key))
547 {
548 String oldValue = _component.getOamVfMarkCreated();
549 _component.setOamVfMarkCreated((String)value);
550 return oldValue;
551 }
552 else if (FACET_NAME_KEY.length() == keyLength &&
553 FACET_NAME_KEY.equals(key))
554 {
555 Object oldValue = _component.getOamVfFacetName();
556 _component.setOamVfFacetName((String)value);
557 return oldValue;
558 }
559 else if (COMPONENT_ADDED_BY_HANDLER_MARKER.length() == keyLength &&
560 COMPONENT_ADDED_BY_HANDLER_MARKER.equals(key))
561 {
562 Object oldValue = _component.isOamVfAddedByHandler();
563 _component.setOamVfAddedByHandler((Boolean)value);
564 return oldValue;
565 }
566 else if (FACET_CREATED_UIPANEL_MARKER.length() == keyLength &&
567 FACET_CREATED_UIPANEL_MARKER.equals(key))
568 {
569 Object oldValue = _component.isOamVfFacetCreatedUIPanel();
570 _component.setOamVfFacetCreatedUIPanel((Boolean)value);
571 return oldValue;
572 }
573 }
574 _PropertyDescriptorHolder propertyDescriptor = getPropertyDescriptor(key);
575 if (propertyDescriptor == null)
576 {
577 if (value == null)
578 {
579 throw new NullPointerException("value is null for a not available property: " + key);
580 }
581 }
582 else
583 {
584 if (propertyDescriptor.getReadMethod() != null)
585 {
586 Object oldValue = getComponentProperty(propertyDescriptor);
587 setComponentProperty(propertyDescriptor, value);
588 return oldValue;
589 }
590 setComponentProperty(propertyDescriptor, value);
591 return null;
592 }
593
594
595 if ( Resource.COMPONENT_RESOURCE_KEY.length() == keyLength
596 && Resource.COMPONENT_RESOURCE_KEY.equals(key))
597 {
598 _isCompositeComponent = true;
599 _isCompositeComponentSet = true;
600 }
601 if (UIComponent.BEANINFO_KEY.length() == keyLength
602 && UIComponent.BEANINFO_KEY.equals(key))
603 {
604 _ccBeanInfo = (BeanInfo) value;
605 }
606 return _component.getStateHelper().put(UIComponentBase.PropertyKeys.attributesMap, key, value);
607 }
608
609
610
611
612
613
614
615
616
617
618
619
620
621 private _PropertyDescriptorHolder getPropertyDescriptor(String key)
622 {
623 if (_propertyDescriptorMap == null)
624 {
625
626 _propertyDescriptorMap = propertyDescriptorCache.get(_component.getClass());
627
628 if (_propertyDescriptorMap == null)
629 {
630
631 BeanInfo beanInfo;
632 try
633 {
634 beanInfo = Introspector.getBeanInfo(_component.getClass());
635 }
636 catch (IntrospectionException e)
637 {
638 throw new FacesException(e);
639 }
640 PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
641 _propertyDescriptorMap = new HashMap<String, _PropertyDescriptorHolder>();
642 for (int i = 0; i < propertyDescriptors.length; i++)
643 {
644 PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
645 Method readMethod = propertyDescriptor.getReadMethod();
646 if (readMethod != null)
647 {
648 _propertyDescriptorMap.put(propertyDescriptor.getName(),
649 new _PropertyDescriptorHolder(propertyDescriptor, readMethod));
650 }
651 }
652
653 synchronized(propertyDescriptorCache)
654 {
655
656
657
658
659
660 propertyDescriptorCache.put(_component.getClass(), _propertyDescriptorMap);
661 }
662 }
663 }
664 return _propertyDescriptorMap.get(key);
665 }
666
667
668
669
670
671
672
673
674
675
676
677
678 private Object getComponentProperty(_PropertyDescriptorHolder propertyDescriptor)
679 {
680 Method readMethod = propertyDescriptor.getReadMethod();
681 if (readMethod == null)
682 {
683 throw new IllegalArgumentException("Component property " + propertyDescriptor.getName()
684 + " is not readable");
685 }
686 try
687 {
688 return readMethod.invoke(_component, EMPTY_ARGS);
689 }
690 catch (Exception e)
691 {
692 FacesContext facesContext = _component.getFacesContext();
693 throw new FacesException("Could not get property " + propertyDescriptor.getName() + " of component "
694 + _component.getClientId(facesContext), e);
695 }
696 }
697
698
699
700
701
702
703
704
705
706
707 private void setComponentProperty(_PropertyDescriptorHolder propertyDescriptor, Object value)
708 {
709 Method writeMethod = propertyDescriptor.getWriteMethod();
710 if (writeMethod == null)
711 {
712 throw new IllegalArgumentException("Component property " + propertyDescriptor.getName()
713 + " is not writable");
714 }
715 try
716 {
717 writeMethod.invoke(_component, new Object[]{value});
718 }
719 catch (Exception e)
720 {
721 FacesContext facesContext = _component.getFacesContext();
722 throw new FacesException("Could not set property " + propertyDescriptor.getName() +
723 " of component " + _component.getClientId(facesContext) + " to value : " + value + " with type : " +
724 (value == null ? "null" : value.getClass().getName()), e);
725 }
726 }
727
728 private void checkKey(Object key)
729 {
730 if (key == null)
731 {
732 throw new NullPointerException("key");
733 }
734 if (!(key instanceof String))
735 {
736 throw new ClassCastException("key is not a String");
737 }
738 }
739
740
741
742
743
744
745
746 Map<String, Object> getUnderlyingMap()
747 {
748 StateHelper stateHelper = _component.getStateHelper(false);
749 Map<String, Object> attributes = null;
750 if (stateHelper != null)
751 {
752 attributes = (Map<String, Object>) stateHelper.get(UIComponentBase.PropertyKeys.attributesMap);
753 }
754 return attributes == null ? Collections.EMPTY_MAP : attributes;
755 }
756
757
758
759
760
761 @Override
762 public boolean equals(Object obj)
763 {
764 return getUnderlyingMap().equals(obj);
765 }
766
767 @Override
768 public int hashCode()
769 {
770 return getUnderlyingMap().hashCode();
771 }
772 }