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