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