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