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