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