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.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.Enumeration;
26 import java.util.HashMap;
27 import java.util.HashSet;
28 import java.util.Iterator;
29 import java.util.LinkedList;
30 import java.util.List;
31 import java.util.Locale;
32 import java.util.Map;
33 import java.util.MissingResourceException;
34 import java.util.PropertyResourceBundle;
35 import java.util.ResourceBundle;
36 import java.util.Set;
37
38 import javax.el.ELException;
39 import javax.el.ValueExpression;
40 import javax.faces.FacesException;
41 import javax.faces.application.Application;
42 import javax.faces.application.Resource;
43 import javax.faces.component.visit.VisitCallback;
44 import javax.faces.component.visit.VisitContext;
45 import javax.faces.component.visit.VisitHint;
46 import javax.faces.component.visit.VisitResult;
47 import javax.faces.context.FacesContext;
48 import javax.faces.el.ValueBinding;
49 import javax.faces.event.AbortProcessingException;
50 import javax.faces.event.ComponentSystemEvent;
51 import javax.faces.event.ComponentSystemEventListener;
52 import javax.faces.event.FacesEvent;
53 import javax.faces.event.FacesListener;
54 import javax.faces.event.PostRestoreStateEvent;
55 import javax.faces.event.SystemEvent;
56 import javax.faces.event.SystemEventListener;
57 import javax.faces.event.SystemEventListenerHolder;
58 import javax.faces.render.Renderer;
59 import javax.faces.view.ViewDeclarationLanguage;
60
61 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
62
63
64
65
66
67
68
69
70
71 @JSFComponent(type = "javax.faces.Component", family = "javax.faces.Component", desc = "abstract base component", configExcluded = true)
72 public abstract class UIComponent implements PartialStateHolder, SystemEventListenerHolder, ComponentSystemEventListener {
73
74
75
76
77
78
79
80
81
82
83 public static final String BEANINFO_KEY = "javax.faces.component.BEANINFO_KEY";
84
85
86
87
88
89
90
91 public static final String COMPOSITE_COMPONENT_TYPE_KEY = "javax.faces.component.COMPOSITE_COMPONENT_TYPE";
92
93
94
95
96
97
98
99 public static final String COMPOSITE_FACET_NAME = "javax.faces.component.COMPOSITE_FACET_NAME";
100
101
102
103
104
105
106
107 public static final String CURRENT_COMPONENT = "javax.faces.component.CURRENT_COMPONENT";
108
109
110
111
112
113
114
115 public static final String CURRENT_COMPOSITE_COMPONENT = "javax.faces.component.CURRENT_COMPOSITE_COMPONENT";
116
117
118
119
120
121
122
123
124 public static final String FACETS_KEY = "javax.faces.component.FACETS_KEY";
125
126
127
128
129
130 public static final String VIEW_LOCATION_KEY = "javax.faces.component.VIEW_LOCATION_KEY";
131
132
133
134
135
136 private static final String _COMPONENT_STACK = "componentStack:" + UIComponent.class.getName();
137
138 Map<Class<? extends SystemEvent>, List<SystemEventListener>> _systemEventListenerClassMap;
139
140
141
142
143 @Deprecated
144 protected Map<String, ValueExpression> bindings;
145
146
147
148
149
150
151 private transient Map<String, String> _resourceBundleMap = null;
152 private boolean _inView = false;
153 private StateHelper _stateHelper = null;
154
155
156
157
158
159
160 private boolean _initialStateMarked = false;
161
162 public UIComponent()
163 {
164 }
165
166 public abstract Map<String, Object> getAttributes();
167
168
169
170
171
172
173
174 public boolean initialStateMarked()
175 {
176 return _initialStateMarked;
177 }
178
179
180
181
182
183
184
185
186
187
188
189
190
191 public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
192 throws FacesException
193 {
194
195 if (context == null || clientId == null || callback == null)
196 {
197 throw new NullPointerException();
198 }
199
200 pushComponentToEL(context, this);
201 try
202 {
203
204 boolean found = clientId.equals(this.getClientId(context));
205 if (found)
206 {
207 try
208 {
209 callback.invokeContextCallback(context, this);
210 }
211 catch (Exception e)
212 {
213 throw new FacesException(e);
214 }
215 return found;
216 }
217
218 for (Iterator<UIComponent> it = this.getFacetsAndChildren(); !found && it.hasNext(); )
219 {
220 found = it.next().invokeOnComponent(context, clientId, callback);
221 }
222 return found;
223 }
224 finally
225 {
226
227 popComponentFromEL(context);
228 }
229 }
230
231
232
233
234
235
236
237
238
239
240 public static boolean isCompositeComponent(UIComponent component)
241 {
242
243
244
245
246
247
248 return component.getAttributes().containsKey(Resource.COMPONENT_RESOURCE_KEY);
249 }
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265 public boolean isInView()
266 {
267 return _inView;
268 }
269
270 public abstract boolean isRendered();
271
272 public void markInitialState()
273 {
274 _initialStateMarked = true;
275 }
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292 protected boolean isVisitable(VisitContext context)
293 {
294
295 Collection<VisitHint> hints = context.getHints();
296
297 if (hints.contains(VisitHint.SKIP_TRANSIENT) && this.isTransient())
298 {
299 return false;
300 }
301
302 if (hints.contains(VisitHint.SKIP_UNRENDERED) && !this.isRendered())
303 {
304 return false;
305 }
306
307
308
309
310
311
312 return true;
313 }
314
315
316
317
318 public abstract void setValueBinding(String name, ValueBinding binding);
319
320 public void setValueExpression(String name, ValueExpression expression)
321 {
322 if (name == null)
323 {
324 throw new NullPointerException("name");
325 }
326 if (name.equals("id"))
327 {
328 throw new IllegalArgumentException("Can't set a ValueExpression for the 'id' property.");
329 }
330 if (name.equals("parent"))
331 {
332 throw new IllegalArgumentException("Can't set a ValueExpression for the 'parent' property.");
333 }
334
335 if (expression == null)
336 {
337
338
339
340
341
342
343 getStateHelper().remove(PropertyKeys.bindings, name);
344 }
345 else
346 {
347 if (expression.isLiteralText())
348 {
349 try
350 {
351 Object value = expression.getValue(getFacesContext().getELContext());
352 getAttributes().put(name, value);
353 return;
354 }
355 catch (ELException e)
356 {
357 throw new FacesException(e);
358 }
359 }
360
361
362
363
364
365
366 getStateHelper().put(PropertyKeys.bindings, name, expression);
367 }
368 }
369
370 public String getClientId()
371 {
372 return getClientId(getFacesContext());
373 }
374
375 public abstract String getClientId(FacesContext context);
376
377
378
379
380
381
382
383
384
385
386
387
388 public static UIComponent getCompositeComponentParent(UIComponent component)
389 {
390
391 if (component == null)
392 {
393 return null;
394 }
395 UIComponent parent = component;
396
397 do
398 {
399 parent = parent.getParent();
400 if (parent != null && UIComponent.isCompositeComponent(parent))
401 {
402 return parent;
403 }
404 } while (parent != null);
405 return null;
406 }
407
408
409
410
411 public String getContainerClientId(FacesContext ctx)
412 {
413 if (ctx == null)
414 {
415 throw new NullPointerException("FacesContext ctx");
416 }
417
418 return getClientId(ctx);
419 }
420
421
422
423
424
425
426
427
428 public static UIComponent getCurrentComponent(FacesContext context)
429 {
430 return (UIComponent) context.getAttributes().get(UIComponent.CURRENT_COMPONENT);
431 }
432
433
434
435
436
437
438
439
440 public static UIComponent getCurrentCompositeComponent(FacesContext context)
441 {
442 return (UIComponent) context.getAttributes().get(UIComponent.CURRENT_COMPOSITE_COMPONENT);
443 }
444
445 public abstract String getFamily();
446
447 public abstract String getId();
448
449 public List<SystemEventListener> getListenersForEventClass(Class<? extends SystemEvent> eventClass)
450 {
451 List<SystemEventListener> listeners;
452 if (_systemEventListenerClassMap == null)
453 {
454 listeners = Collections.emptyList();
455 }
456 else
457 {
458 listeners = _systemEventListenerClassMap.get(eventClass);
459 if (listeners == null)
460 {
461 listeners = Collections.emptyList();
462 }
463 else
464 {
465 listeners = Collections.unmodifiableList(listeners);
466 }
467 }
468
469 return listeners;
470 }
471
472
473
474
475
476
477
478 public UIComponent getNamingContainer()
479 {
480
481
482 UIComponent component = this;
483 do
484 {
485 if (component instanceof NamingContainer)
486 {
487 return component;
488 }
489
490 component = component.getParent();
491 } while (component != null);
492
493 return null;
494 }
495
496 public abstract void setId(String id);
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515 public void setInView(boolean isInView)
516 {
517 _inView = isInView;
518 }
519
520
521
522
523
524 public abstract void setParent(UIComponent parent);
525
526
527
528
529
530 public abstract UIComponent getParent();
531
532 public abstract void setRendered(boolean rendered);
533
534 public abstract String getRendererType();
535
536 public abstract void setRendererType(String rendererType);
537
538 public abstract boolean getRendersChildren();
539
540 public Map<String, String> getResourceBundleMap()
541 {
542 if (_resourceBundleMap == null)
543 {
544 FacesContext context = getFacesContext();
545 Locale locale = context.getViewRoot().getLocale();
546 ClassLoader loader = _ClassUtils.getContextClassLoader();
547
548 try
549 {
550
551
552 _resourceBundleMap = new BundleMap(ResourceBundle.getBundle(getClass().getName(), locale, loader));
553 }
554 catch (MissingResourceException e)
555 {
556
557 if (this._isCompositeComponent())
558 {
559
560
561 Resource componentResource = (Resource) getAttributes().get(Resource.COMPONENT_RESOURCE_KEY);
562
563
564 int extensionIndex = componentResource.getResourceName().lastIndexOf('.');
565 String resourceName = (extensionIndex < 0
566 ? componentResource.getResourceName()
567 : componentResource.getResourceName().substring(0, extensionIndex)) + ".properties";
568
569
570
571
572
573 Resource bundleResource = context.getApplication().getResourceHandler()
574 .createResource(resourceName, componentResource.getLibraryName());
575
576 if (bundleResource != null)
577 {
578
579
580
581
582
583 try
584 {
585 _resourceBundleMap
586 = new BundleMap(new PropertyResourceBundle(bundleResource.getInputStream()));
587 }
588 catch (IOException e1)
589 {
590
591 }
592 }
593 }
594
595 if (_resourceBundleMap == null)
596 {
597 _resourceBundleMap = Collections.emptyMap();
598 }
599 }
600 }
601
602 return _resourceBundleMap;
603 }
604
605
606
607
608 public abstract ValueBinding getValueBinding(String name);
609
610 public ValueExpression getValueExpression(String name)
611 {
612 if (name == null)
613 {
614 throw new NullPointerException("name can not be null");
615 }
616
617 Map<String, Object> bindings = (Map<String, Object>) getStateHelper().
618 get(PropertyKeys.bindings);
619
620 if (bindings == null)
621 {
622 if (!(this instanceof UIComponentBase))
623 {
624
625 ValueBinding vb = getValueBinding(name);
626 if (vb != null)
627 {
628
629 ValueExpression ve = new _ValueBindingToValueExpression(vb);
630 getStateHelper().put(PropertyKeys.bindings, name, ve);
631 return ve;
632 }
633 }
634 }
635 else
636 {
637
638 return (ValueExpression) bindings.get(name);
639 }
640 return null;
641 }
642
643 public abstract List<UIComponent> getChildren();
644
645 public abstract int getChildCount();
646
647 public abstract UIComponent findComponent(String expr);
648
649 public abstract Map<String, UIComponent> getFacets();
650
651 public abstract UIComponent getFacet(String name);
652
653 public abstract Iterator<UIComponent> getFacetsAndChildren();
654
655 public abstract void broadcast(FacesEvent event) throws AbortProcessingException;
656
657
658
659
660
661
662 public void clearInitialState()
663 {
664 _initialStateMarked = false;
665 }
666
667 public abstract void decode(FacesContext context);
668
669 public abstract void encodeBegin(FacesContext context) throws IOException;
670
671 public abstract void encodeChildren(FacesContext context) throws IOException;
672
673 public abstract void encodeEnd(FacesContext context) throws IOException;
674
675 public void encodeAll(FacesContext context) throws IOException
676 {
677 if (context == null)
678 {
679 throw new NullPointerException();
680 }
681
682 pushComponentToEL(context, this);
683 try
684 {
685 if (!isRendered())
686 {
687 return;
688 }
689 }
690 finally
691 {
692 popComponentFromEL(context);
693 }
694
695
696 this.encodeBegin(context);
697
698
699 if (this.getRendersChildren())
700 {
701 this.encodeChildren(context);
702 }
703 else
704 {
705 if (this.getChildCount() > 0)
706 {
707 for (int i = 0; i < this.getChildCount(); i++)
708 {
709 UIComponent comp = this.getChildren().get(i);
710 comp.encodeAll(context);
711 }
712 }
713 }
714 this.encodeEnd(context);
715
716 }
717
718 protected abstract void addFacesListener(FacesListener listener);
719
720 protected abstract FacesListener[] getFacesListeners(Class clazz);
721
722 protected abstract void removeFacesListener(FacesListener listener);
723
724 public abstract void queueEvent(FacesEvent event);
725
726 public abstract void processRestoreState(FacesContext context, Object state);
727
728 public abstract void processDecodes(FacesContext context);
729
730 public void processEvent(ComponentSystemEvent event) throws AbortProcessingException
731 {
732
733
734 if (event instanceof PostRestoreStateEvent)
735 {
736
737
738 ValueExpression expression = getValueExpression("binding");
739
740
741 if (expression != null)
742 {
743 expression.setValue(getFacesContext().getELContext(), this);
744 }
745
746
747
748
749
750
751
752
753
754
755
756 }
757
758 }
759
760 public abstract void processValidators(FacesContext context);
761
762 public abstract void processUpdates(FacesContext context);
763
764 public abstract java.lang.Object processSaveState(FacesContext context);
765
766 public void subscribeToEvent(Class<? extends SystemEvent> eventClass,
767 ComponentSystemEventListener componentListener)
768 {
769
770
771 if (eventClass == null)
772 {
773 throw new NullPointerException("eventClass required");
774 }
775 if (componentListener == null)
776 {
777 throw new NullPointerException("componentListener required");
778 }
779
780 SystemEventListener listener = new EventListenerWrapper(this, componentListener);
781
782
783 if (_systemEventListenerClassMap == null)
784 {
785 _systemEventListenerClassMap = new HashMap<Class<? extends SystemEvent>, List<SystemEventListener>>();
786 }
787
788 List<SystemEventListener> listeners = _systemEventListenerClassMap.get(eventClass);
789
790 if (listeners == null)
791 {
792
793
794 listeners = new _DeltaList<SystemEventListener>(new ArrayList<SystemEventListener>(3));
795 _systemEventListenerClassMap.put(eventClass, listeners);
796 }
797
798
799 listeners.add(listener);
800 }
801
802 public void unsubscribeFromEvent(Class<? extends SystemEvent> eventClass,
803 ComponentSystemEventListener componentListener)
804 {
805
806
807
808
809
810
811
812
813
814
815 if (eventClass == null)
816 {
817 throw new NullPointerException("eventClass required");
818 }
819 if (componentListener == null)
820 {
821 throw new NullPointerException("componentListener required");
822 }
823
824 if (_systemEventListenerClassMap != null)
825 {
826 List<SystemEventListener> listeners = _systemEventListenerClassMap.get(eventClass);
827
828 if (listeners != null && !listeners.isEmpty())
829 {
830 for (Iterator<SystemEventListener> it = listeners.iterator(); it.hasNext(); )
831 {
832 ComponentSystemEventListener listener
833 = ((EventListenerWrapper) it.next()).getComponentSystemEventListener();
834 if (listener != null && listener.equals(componentListener))
835 {
836 it.remove();
837 break;
838 }
839 }
840 }
841 }
842 }
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867 public boolean visitTree(VisitContext context, VisitCallback callback)
868 {
869 try
870 {
871 pushComponentToEL(context.getFacesContext(), this);
872
873 if (!isVisitable(context))
874 {
875 return false;
876 }
877
878 VisitResult res = context.invokeVisitCallback(this, callback);
879 switch (res)
880 {
881
882 case COMPLETE:
883 return true;
884
885 case REJECT:
886 return false;
887
888
889 default:
890 if (getFacetCount() > 0)
891 {
892 for (UIComponent facet : getFacets().values())
893 {
894 if (facet.visitTree(context, callback))
895 {
896 return true;
897 }
898 }
899 }
900 int childCount = getChildCount();
901 if (childCount > 0)
902 {
903 for (int i = 0; i < childCount; i++)
904 {
905 UIComponent child = getChildren().get(i);
906 if (child.visitTree(context, callback))
907 {
908 return true;
909 }
910 }
911 }
912 return false;
913 }
914 }
915 finally
916 {
917
918 popComponentFromEL(context.getFacesContext());
919 }
920 }
921
922 protected abstract FacesContext getFacesContext();
923
924 protected abstract Renderer getRenderer(FacesContext context);
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946 enum PropertyKeys
947 {
948 rendered,
949 rendererType,
950 attributesMap,
951 bindings,
952 facesListeners
953 }
954
955 protected StateHelper getStateHelper()
956 {
957 return getStateHelper(true);
958 }
959
960
961
962
963
964
965
966 protected StateHelper getStateHelper(boolean create)
967 {
968 if (_stateHelper != null)
969 {
970 return _stateHelper;
971 }
972 if (create)
973 {
974 _stateHelper = new _DeltaStateHelper(this);
975 }
976 return _stateHelper;
977 }
978
979 @SuppressWarnings("unchecked")
980 public final void popComponentFromEL(FacesContext context)
981 {
982 Map<Object, Object> contextAttributes = context.getAttributes();
983
984
985
986 List<UIComponent> componentStack
987 = (List<UIComponent>) contextAttributes.get(UIComponent._COMPONENT_STACK);
988
989 UIComponent oldCurrent = (UIComponent) contextAttributes.get(UIComponent.CURRENT_COMPONENT);
990
991 UIComponent newCurrent = null;
992 if (componentStack != null && !componentStack.isEmpty())
993 {
994 if (!this.equals(oldCurrent))
995 {
996
997 int componentIndex = componentStack.lastIndexOf(this);
998 if (componentIndex >= 0)
999 {
1000
1001 for (int i = componentStack.size()-1; i >= componentIndex ; i--)
1002 {
1003 newCurrent = componentStack.remove(componentStack.size()-1);
1004 }
1005 }
1006 else
1007 {
1008
1009 return;
1010 }
1011 }
1012 else
1013 {
1014 newCurrent = componentStack.remove(componentStack.size()-1);
1015 }
1016 }
1017 else
1018 {
1019
1020 contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, null);
1021 }
1022 oldCurrent = (UIComponent) contextAttributes.put(UIComponent.CURRENT_COMPONENT, newCurrent);
1023
1024 if (oldCurrent != null && oldCurrent._isCompositeComponent())
1025 {
1026
1027 if (newCurrent != null)
1028 {
1029 if (newCurrent._isCompositeComponent())
1030 {
1031 contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, newCurrent);
1032 }
1033 else
1034 {
1035 UIComponent previousCompositeComponent = null;
1036 for (int i = componentStack.size()-1; i >= 0; i--)
1037 {
1038 UIComponent component = componentStack.get(i);
1039 if (component._isCompositeComponent())
1040 {
1041 previousCompositeComponent = component;
1042 break;
1043 }
1044 }
1045 contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, previousCompositeComponent);
1046 }
1047 }
1048 }
1049 }
1050
1051 @SuppressWarnings("unchecked")
1052 public final void pushComponentToEL(FacesContext context, UIComponent component)
1053 {
1054 if (component == null)
1055 {
1056 component = this;
1057 }
1058 Map<Object, Object> contextAttributes = context.getAttributes();
1059 UIComponent currentComponent = (UIComponent) contextAttributes.get(UIComponent.CURRENT_COMPONENT);
1060
1061 if (currentComponent != null)
1062 {
1063 List<UIComponent> componentStack
1064 = (List<UIComponent>) contextAttributes.get(UIComponent._COMPONENT_STACK);
1065 if (componentStack == null)
1066 {
1067 componentStack = new ArrayList<UIComponent>();
1068 contextAttributes.put(UIComponent._COMPONENT_STACK, componentStack);
1069 }
1070
1071 componentStack.add(currentComponent);
1072 }
1073
1074
1075
1076
1077 contextAttributes.put(UIComponent.CURRENT_COMPONENT, component);
1078
1079 if (component._isCompositeComponent())
1080 {
1081 contextAttributes.put(UIComponent.CURRENT_COMPOSITE_COMPONENT, component);
1082 }
1083 }
1084
1085
1086
1087
1088 public int getFacetCount()
1089 {
1090
1091
1092 Map<String, UIComponent> facets = getFacets();
1093 return facets == null ? 0 : facets.size();
1094 }
1095
1096 private boolean _isCompositeComponent()
1097 {
1098
1099 return UIComponent.isCompositeComponent(this);
1100 }
1101
1102 private static class BundleMap implements Map<String, String>
1103 {
1104
1105 private ResourceBundle _bundle;
1106 private List<String> _values;
1107
1108 public BundleMap(ResourceBundle bundle)
1109 {
1110 _bundle = bundle;
1111 }
1112
1113
1114 public String get(Object key)
1115 {
1116 try
1117 {
1118 return (String) _bundle.getObject(key.toString());
1119 }
1120 catch (Exception e)
1121 {
1122 return "???" + key + "???";
1123 }
1124 }
1125
1126 public boolean isEmpty()
1127 {
1128 return !_bundle.getKeys().hasMoreElements();
1129 }
1130
1131 public boolean containsKey(Object key)
1132 {
1133 try
1134 {
1135 return _bundle.getObject(key.toString()) != null;
1136 }
1137 catch (MissingResourceException e)
1138 {
1139 return false;
1140 }
1141 }
1142
1143
1144 public Collection<String> values()
1145 {
1146 if (_values == null)
1147 {
1148 _values = new ArrayList<String>();
1149 for (Enumeration<String> enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
1150 {
1151 String v = _bundle.getString(enumer.nextElement());
1152 _values.add(v);
1153 }
1154 }
1155 return _values;
1156 }
1157
1158 public int size()
1159 {
1160 return values().size();
1161 }
1162
1163 public boolean containsValue(Object value)
1164 {
1165 return values().contains(value);
1166 }
1167
1168 public Set<Map.Entry<String, String>> entrySet()
1169 {
1170 Set<Entry<String, String>> set = new HashSet<Entry<String, String>>();
1171 for (Enumeration<String> enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
1172 {
1173 final String k = enumer.nextElement();
1174 set.add(new Map.Entry<String, String>()
1175 {
1176
1177 public String getKey()
1178 {
1179 return k;
1180 }
1181
1182 public String getValue()
1183 {
1184 return (String) _bundle.getObject(k);
1185 }
1186
1187 public String setValue(String value)
1188 {
1189 throw new UnsupportedOperationException();
1190 }
1191 });
1192 }
1193
1194 return set;
1195 }
1196
1197 public Set<String> keySet()
1198 {
1199 Set<String> set = new HashSet<String>();
1200 for (Enumeration<String> enumer = _bundle.getKeys(); enumer.hasMoreElements(); )
1201 {
1202 set.add(enumer.nextElement());
1203 }
1204 return set;
1205 }
1206
1207
1208 public String remove(Object key)
1209 {
1210 throw new UnsupportedOperationException();
1211 }
1212
1213 public void putAll(Map<? extends String, ? extends String> t)
1214 {
1215 throw new UnsupportedOperationException();
1216 }
1217
1218 public String put(String key, String value)
1219 {
1220 throw new UnsupportedOperationException();
1221 }
1222
1223 public void clear()
1224 {
1225 throw new UnsupportedOperationException();
1226 }
1227 }
1228
1229 static class EventListenerWrapper implements SystemEventListener, PartialStateHolder
1230 {
1231
1232 private Class<?> componentClass;
1233 private ComponentSystemEventListener listener;
1234
1235 private boolean _initialStateMarked;
1236
1237 private int listenerCapability;
1238
1239 private static final int LISTENER_SAVE_STATE_HOLDER = 1;
1240 private static final int LISTENER_SAVE_PARTIAL_STATE_HOLDER = 2;
1241 private static final int LISTENER_TYPE_COMPONENT = 4;
1242 private static final int LISTENER_TYPE_RENDERER = 8;
1243 private static final int LISTENER_TYPE_OTHER = 16;
1244
1245 public EventListenerWrapper()
1246 {
1247
1248 super();
1249 }
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267 public EventListenerWrapper(UIComponent component, ComponentSystemEventListener listener)
1268 {
1269 assert component != null;
1270 assert listener != null;
1271
1272 this.componentClass = component.getClass();
1273 this.listener = listener;
1274
1275 initListenerCapability();
1276 }
1277
1278 private void initListenerCapability()
1279 {
1280 this.listenerCapability = 0;
1281 if (this.listener instanceof UIComponent)
1282 {
1283 this.listenerCapability = LISTENER_TYPE_COMPONENT;
1284 }
1285 else if (this.listener instanceof Renderer)
1286 {
1287 this.listenerCapability = LISTENER_TYPE_RENDERER;
1288 }
1289 else
1290 {
1291 if (this.listener instanceof PartialStateHolder)
1292 {
1293 this.listenerCapability = LISTENER_TYPE_OTHER | LISTENER_SAVE_PARTIAL_STATE_HOLDER;
1294 }
1295 else if (this.listener instanceof StateHolder)
1296 {
1297 this.listenerCapability = LISTENER_TYPE_OTHER | LISTENER_SAVE_STATE_HOLDER;
1298 }
1299 else
1300 {
1301 this.listenerCapability = LISTENER_TYPE_OTHER;
1302 }
1303 }
1304 }
1305
1306 @Override
1307 public boolean equals(Object o)
1308 {
1309 if (o == this)
1310 {
1311 return true;
1312 }
1313 else if (o instanceof EventListenerWrapper)
1314 {
1315 EventListenerWrapper other = (EventListenerWrapper) o;
1316 return componentClass.equals(other.componentClass) && listener.equals(other.listener);
1317 }
1318 else
1319 {
1320 return false;
1321 }
1322 }
1323
1324 @Override
1325 public int hashCode()
1326 {
1327 return componentClass.hashCode() + listener.hashCode();
1328 }
1329
1330 public boolean isListenerForSource(Object source)
1331 {
1332
1333
1334
1335 return source.getClass().isAssignableFrom(componentClass);
1336 }
1337
1338 public ComponentSystemEventListener getComponentSystemEventListener()
1339 {
1340 return listener;
1341 }
1342
1343 public void processEvent(SystemEvent event)
1344 {
1345
1346
1347
1348 assert event instanceof ComponentSystemEvent;
1349
1350 listener.processEvent((ComponentSystemEvent) event);
1351 }
1352
1353 public void clearInitialState()
1354 {
1355
1356 if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0)
1357 {
1358 ((PartialStateHolder) listener).clearInitialState();
1359 }
1360 _initialStateMarked = false;
1361 }
1362
1363 public boolean initialStateMarked()
1364 {
1365
1366 if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0)
1367 {
1368 return ((PartialStateHolder) listener).initialStateMarked();
1369 }
1370
1371 return _initialStateMarked;
1372 }
1373
1374 public void markInitialState()
1375 {
1376
1377 if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0)
1378 {
1379 ((PartialStateHolder) listener).markInitialState();
1380 }
1381 _initialStateMarked = true;
1382 }
1383
1384 public boolean isTransient()
1385 {
1386
1387 if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0 ||
1388 (listenerCapability & LISTENER_SAVE_STATE_HOLDER) != 0)
1389 {
1390 return ((StateHolder) listener).isTransient();
1391 }
1392 return false;
1393 }
1394
1395 public void restoreState(FacesContext context, Object state)
1396 {
1397 if (state == null)
1398 {
1399 return;
1400 }
1401 Object[] values = (Object[]) state;
1402 componentClass = (Class) values[0];
1403 if (values[1] instanceof _AttachedDeltaWrapper)
1404 {
1405 ((StateHolder) listener).restoreState(context,
1406 ((_AttachedDeltaWrapper) values[1]).getWrappedStateObject());
1407 }
1408 else
1409 {
1410
1411 listenerCapability = (Integer) values[2];
1412
1413 if ((listenerCapability & LISTENER_TYPE_COMPONENT) != 0)
1414 {
1415 listener = UIComponent.getCurrentComponent(context);
1416 }
1417 else if ((listenerCapability & LISTENER_TYPE_RENDERER) != 0)
1418 {
1419 listener = (ComponentSystemEventListener)
1420 UIComponent.getCurrentComponent(context).getRenderer(context);
1421 }
1422 else
1423 {
1424 listener = (ComponentSystemEventListener)
1425 UIComponentBase.restoreAttachedState(context, values[1]);
1426 }
1427
1428
1429
1430
1431
1432 }
1433 }
1434
1435 public Object saveState(FacesContext context)
1436 {
1437 if (!initialStateMarked())
1438 {
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448 Object[] state = new Object[3];
1449 state[0] = componentClass;
1450
1451 if (!((listenerCapability & LISTENER_TYPE_COMPONENT) != 0 ||
1452 (listenerCapability & LISTENER_TYPE_RENDERER) != 0))
1453 {
1454 state[1] = UIComponentBase.saveAttachedState(context, listener);
1455 }
1456 else
1457 {
1458 state[1] = null;
1459 }
1460 state[2] = (Integer) listenerCapability;
1461 return state;
1462 }
1463 else
1464 {
1465
1466
1467 if ((listenerCapability & LISTENER_TYPE_COMPONENT) != 0)
1468 {
1469 return null;
1470 }
1471 else if ((listenerCapability & LISTENER_TYPE_RENDERER) != 0)
1472 {
1473 return null;
1474 }
1475 else
1476 {
1477 if ((listenerCapability & LISTENER_SAVE_STATE_HOLDER) != 0 ||
1478 (listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0)
1479 {
1480 Object listenerSaved = ((StateHolder) listener).saveState(context);
1481 if (listenerSaved == null)
1482 {
1483 return null;
1484 }
1485 return new Object[]{componentClass,
1486 new _AttachedDeltaWrapper(listener.getClass(), listenerSaved)};
1487 }
1488 else
1489 {
1490
1491 return null;
1492 }
1493 }
1494
1495
1496
1497
1498
1499
1500
1501
1502 }
1503 }
1504
1505 public void setTransient(boolean newTransientValue)
1506 {
1507 if ((listenerCapability & LISTENER_SAVE_PARTIAL_STATE_HOLDER) != 0 ||
1508 (listenerCapability & LISTENER_SAVE_STATE_HOLDER) != 0)
1509 {
1510 ((StateHolder) listener).setTransient(newTransientValue);
1511 }
1512 }
1513 }
1514 }