1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.trinidad.component;
20
21 import java.io.ByteArrayOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.io.ObjectOutputStream;
25
26 import java.net.URL;
27
28 import java.util.ArrayList;
29 import java.util.Collection;
30 import java.util.Collections;
31 import java.util.Iterator;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Properties;
35
36 import javax.el.ELContext;
37 import javax.el.ELException;
38 import javax.el.MethodExpression;
39 import javax.el.ValueExpression;
40
41 import javax.faces.FacesException;
42 import javax.faces.application.ProjectStage;
43 import javax.faces.application.Resource;
44 import javax.faces.component.ContextCallback;
45 import javax.faces.component.NamingContainer;
46 import javax.faces.component.StateHolder;
47 import javax.faces.component.UIComponent;
48 import javax.faces.component.UIViewRoot;
49 import javax.faces.component.behavior.Behavior;
50 import javax.faces.component.behavior.ClientBehavior;
51 import javax.faces.component.behavior.ClientBehaviorHolder;
52 import javax.faces.context.ExternalContext;
53 import javax.faces.context.FacesContext;
54 import javax.faces.el.EvaluationException;
55 import javax.faces.el.MethodBinding;
56 import javax.faces.el.ValueBinding;
57 import javax.faces.event.AbortProcessingException;
58 import javax.faces.event.BehaviorEvent;
59 import javax.faces.event.ComponentSystemEvent;
60 import javax.faces.event.ComponentSystemEventListener;
61 import javax.faces.event.FacesEvent;
62 import javax.faces.event.FacesListener;
63 import javax.faces.event.PostAddToViewEvent;
64 import javax.faces.event.PreRemoveFromViewEvent;
65 import javax.faces.event.PreRenderComponentEvent;
66 import javax.faces.event.SystemEvent;
67 import javax.faces.event.SystemEventListener;
68 import javax.faces.render.RenderKit;
69 import javax.faces.render.Renderer;
70
71 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
72 import org.apache.myfaces.trinidad.bean.AttachedObjects;
73 import org.apache.myfaces.trinidad.bean.FacesBean;
74 import org.apache.myfaces.trinidad.bean.FacesBeanFactory;
75 import org.apache.myfaces.trinidad.bean.PropertyKey;
76 import org.apache.myfaces.trinidad.bean.util.StateUtils;
77 import org.apache.myfaces.trinidad.bean.util.ValueMap;
78 import org.apache.myfaces.trinidad.change.AttributeComponentChange;
79 import org.apache.myfaces.trinidad.change.ComponentChange;
80 import org.apache.myfaces.trinidad.change.ComponentChangeFilter;
81 import org.apache.myfaces.trinidad.change.RowKeySetAttributeChange;
82 import org.apache.myfaces.trinidad.component.ComponentProcessingContext.ProcessingHint;
83 import org.apache.myfaces.trinidad.context.RenderingContext;
84 import org.apache.myfaces.trinidad.context.RequestContext;
85 import org.apache.myfaces.trinidad.event.AttributeChangeEvent;
86 import org.apache.myfaces.trinidad.event.AttributeChangeListener;
87 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
88 import org.apache.myfaces.trinidad.model.RowKeySet;
89 import org.apache.myfaces.trinidad.render.CoreRenderer;
90 import org.apache.myfaces.trinidad.render.ExtendedRenderer;
91 import org.apache.myfaces.trinidad.render.LifecycleRenderer;
92 import org.apache.myfaces.trinidad.util.CollectionUtils;
93 import org.apache.myfaces.trinidad.util.ThreadLocalUtils;
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 @JSFComponent
126 abstract public class UIXComponentBase extends UIXComponent
127 {
128
129
130 static private final TrinidadLogger _LOG = TrinidadLogger.createTrinidadLogger(UIXComponentBase.class);
131
132 static public final FacesBean.Type TYPE = _createType();
133 static public final PropertyKey ID_KEY =
134 TYPE.registerKey("id", String.class, PropertyKey.CAP_NOT_BOUND);
135 static public final PropertyKey RENDERED_KEY =
136 TYPE.registerKey("rendered", Boolean.class, Boolean.TRUE);
137 static public final PropertyKey BINDING_KEY =
138 TYPE.registerKey("binding");
139 static public final PropertyKey TRANSIENT_KEY =
140 TYPE.registerKey("transient", Boolean.class,
141 PropertyKey.CAP_NOT_BOUND |
142 PropertyKey.CAP_TRANSIENT);
143 static public final PropertyKey RENDERER_TYPE_KEY =
144 TYPE.registerKey("rendererType", String.class, PropertyKey.CAP_NOT_BOUND);
145 static private final PropertyKey _LISTENERS_KEY =
146 TYPE.registerKey("listeners", FacesListener[].class, PropertyKey.CAP_LIST);
147 static private final PropertyKey _ATTRIBUTE_CHANGE_LISTENER_KEY =
148 TYPE.registerKey("attributeChangeListener", MethodExpression.class);
149 static private final PropertyKey _CLIENT_BEHAVIORS_KEY =
150 TYPE.registerKey("clientBehaviors", AttachedObjects.class,
151 PropertyKey.CAP_NOT_BOUND|PropertyKey.CAP_PARTIAL_STATE_HOLDER|PropertyKey.CAP_STATE_HOLDER);
152 static private final PropertyKey _SYSTEM_EVENT_LISTENERS_KEY =
153 TYPE.registerKey("systemEventListeners", AttachedObjects.class,
154 PropertyKey.CAP_NOT_BOUND|PropertyKey.CAP_PARTIAL_STATE_HOLDER|PropertyKey.CAP_STATE_HOLDER);
155 static private final PropertyKey _COMPONENT_CHANGE_FILTERS_KEY =
156 TYPE.registerKey("componentChangeFilters", ComponentChangeFilter[].class, PropertyKey.CAP_LIST);
157 static final PropertyKey _PASS_THROUGH_ATTRIBUTES_KEY =
158 TYPE.registerKey("passThroughAttributes", AttachedObjects.class);
159
160
161
162
163
164 static
165 {
166
167
168
169
170 TYPE.registerKey("javax.faces.webapp.COMPONENT_IDS",
171 List.class,
172 PropertyKey.CAP_NOT_BOUND);
173 TYPE.registerKey("javax.faces.webapp.FACET_NAMES",
174 List.class,
175 PropertyKey.CAP_NOT_BOUND);
176
177
178
179 TYPE.registerKey(Resource.COMPONENT_RESOURCE_KEY,
180 PropertyKey.CAP_NOT_BOUND);
181
182 TYPE.lock();
183 }
184
185 public UIXComponentBase()
186 {
187 }
188
189 public UIXComponentBase(String rendererType)
190 {
191 setRendererType(rendererType);
192 }
193
194 protected FacesBean createFacesBean(
195 String rendererType)
196 {
197 FacesBean bean = FacesBeanFactory.createFacesBean(getClass(),
198 rendererType);
199 UIXFacesBean uixBean = (UIXFacesBean) bean;
200 uixBean.init(this, getBeanType());
201 return uixBean;
202 }
203
204 protected PropertyKey getPropertyKey(String name)
205 {
206 PropertyKey key = getBeanType().findKey(name);
207 if (key == null)
208 key = PropertyKey.createPropertyKey(name);
209
210 return key;
211 }
212
213 protected FacesBean.Type getBeanType()
214 {
215 return TYPE;
216 }
217
218 @Override
219 public FacesBean getFacesBean()
220 {
221 if (_facesBean == null)
222 _init(null);
223
224 return _facesBean;
225 }
226
227 @Override
228 public String getContainerClientId(FacesContext context, UIComponent child)
229 {
230 return getContainerClientId(context);
231 }
232
233 @Override
234 public void addAttributeChangeListener(AttributeChangeListener acl)
235 {
236 addFacesListener(acl);
237 }
238
239 @Override
240 public void removeAttributeChangeListener(AttributeChangeListener acl)
241 {
242 removeFacesListener(acl);
243 }
244
245 @Override
246 public AttributeChangeListener[] getAttributeChangeListeners()
247 {
248 return (AttributeChangeListener[])
249 getFacesListeners(AttributeChangeListener.class);
250 }
251
252 @Override
253 public void setAttributeChangeListener(MethodExpression mb)
254 {
255 setProperty(_ATTRIBUTE_CHANGE_LISTENER_KEY, mb);
256 }
257
258 @Deprecated
259 public void setAttributeChangeListener(MethodBinding mb)
260 {
261 setAttributeChangeListener(adaptMethodBinding(mb));
262 }
263
264 @Override
265 public MethodExpression getAttributeChangeListener()
266 {
267 return (MethodExpression) getProperty(_ATTRIBUTE_CHANGE_LISTENER_KEY);
268 }
269
270
271 @Override
272 public ValueExpression getValueExpression(String name)
273 {
274 if (name == null)
275 throw new NullPointerException();
276
277 PropertyKey key = getPropertyKey(name);
278
279
280
281
282 if (!key.getSupportsBinding())
283 return null;
284
285 return getFacesBean().getValueExpression(key);
286 }
287
288 @Override
289 public void setValueExpression(String name,
290 ValueExpression expression)
291 {
292 if (name == null)
293 throw new NullPointerException();
294
295 if ((expression != null) && expression.isLiteralText())
296 {
297 ELContext context =
298 FacesContext.getCurrentInstance().getELContext();
299 getAttributes().put(name, expression.getValue(context));
300 }
301 else
302 {
303 PropertyKey key = getPropertyKey(name);
304 getFacesBean().setValueExpression(key, expression);
305 }
306 }
307
308
309
310 @Override
311 public ValueBinding getValueBinding(String name)
312 {
313 if (name == null)
314 throw new NullPointerException();
315
316 PropertyKey key = getPropertyKey(name);
317
318
319
320
321 if (!key.getSupportsBinding())
322 return null;
323
324 return getFacesBean().getValueBinding(key);
325 }
326
327 @Override
328 public void setValueBinding(String name, ValueBinding binding)
329 {
330 if (name == null)
331 throw new NullPointerException();
332
333 PropertyKey key = getPropertyKey(name);
334 getFacesBean().setValueBinding(key, binding);
335 }
336
337 @Override
338 public Map<String, Object> getAttributes()
339 {
340 if (_attributes == null)
341 _init(null);
342
343 return _attributes;
344 }
345
346
347
348
349
350
351
352
353
354
355 public final ComponentChange addComponentChange(ComponentChange change)
356 {
357 return addComponentChange(this, change);
358 }
359
360
361
362
363
364
365
366
367
368 public final void addComponentChangeFilter(ComponentChangeFilter componentChangeFilter)
369 {
370 if (componentChangeFilter == null)
371 throw new NullPointerException();
372
373 getFacesBean().addEntry(_COMPONENT_CHANGE_FILTERS_KEY, componentChangeFilter);
374 }
375
376
377
378
379
380
381 public final void removeComponentChangeFilter(ComponentChangeFilter componentChangeFilter)
382 {
383 if (componentChangeFilter == null)
384 throw new NullPointerException();
385
386 getFacesBean().removeEntry(_COMPONENT_CHANGE_FILTERS_KEY, componentChangeFilter);
387 }
388
389
390
391
392
393
394 public final ComponentChangeFilter[] getComponentChangeFilters()
395 {
396 Iterator<ComponentChangeFilter> filterIter =
397 (Iterator<ComponentChangeFilter>)getFacesBean().entries(_COMPONENT_CHANGE_FILTERS_KEY);
398
399 ArrayList<ComponentChangeFilter> filterList = CollectionUtils.arrayList(filterIter);
400 return filterList.toArray(new ComponentChangeFilter[filterList.size()]);
401 }
402
403 @Override
404 protected Iterator<UIComponent> getRenderedFacetsAndChildren(
405 FacesContext facesContext)
406 {
407 _cacheRenderer(facesContext);
408 return super.getRenderedFacetsAndChildren(facesContext);
409 }
410
411
412
413
414
415
416
417
418
419 protected void setupFlattenedContext(
420 FacesContext facesContext,
421 ComponentProcessingContext cpContext
422 )
423 {
424 if (cpContext.getHints().contains(ProcessingHint.PROCESS_FOR_ENCODING))
425 {
426 setupEncodingContext(facesContext, RenderingContext.getCurrentInstance());
427 }
428 else
429 {
430 setupVisitingContext(facesContext);
431 }
432 }
433
434
435
436
437
438
439
440
441
442 protected void setupFlattenedChildrenContext(
443 FacesContext facesContext,
444 ComponentProcessingContext cpContext
445 )
446 {
447 if (cpContext.getHints().contains(ProcessingHint.PROCESS_FOR_ENCODING))
448 {
449 setupChildrenEncodingContext(facesContext, RenderingContext.getCurrentInstance());
450 }
451 else
452 {
453 setupChildrenVisitingContext(facesContext);
454 }
455 }
456
457
458
459
460
461
462
463
464
465 protected void tearDownFlattenedContext(
466 FacesContext facesContext,
467 ComponentProcessingContext cpContext
468 )
469 {
470 if (cpContext.getHints().contains(ProcessingHint.PROCESS_FOR_ENCODING))
471 {
472 tearDownEncodingContext(facesContext, RenderingContext.getCurrentInstance());
473 }
474 else
475 {
476 tearDownVisitingContext(facesContext);
477 }
478 }
479
480
481
482
483
484
485
486
487
488 protected void tearDownFlattenedChildrenContext(
489 FacesContext facesContext,
490 ComponentProcessingContext cpContext
491 )
492 {
493 if (cpContext.getHints().contains(ProcessingHint.PROCESS_FOR_ENCODING))
494 {
495 tearDownChildrenEncodingContext(facesContext, RenderingContext.getCurrentInstance());
496 }
497 else
498 {
499 tearDownChildrenVisitingContext(facesContext);
500 }
501 }
502
503
504
505
506
507
508 private String _calculateClientId(FacesContext context)
509 {
510
511
512
513 String clientId = getId();
514
515
516 UIComponent lastParent = null;
517 UIComponent currParent = getParent();
518
519 while (true)
520 {
521
522 if (currParent instanceof NamingContainer)
523 {
524 String contClientId;
525
526
527 if (currParent instanceof UIXComponent)
528 contClientId = ((UIXComponent)currParent).getContainerClientId(context, this);
529 else
530 contClientId = currParent.getContainerClientId(context);
531
532 StringBuilder bld = __getSharedStringBuilder();
533 bld.append(contClientId).append(NamingContainer.SEPARATOR_CHAR).append(clientId);
534 clientId = bld.toString();
535 break;
536 }
537 else if (currParent == null)
538 {
539 if (lastParent instanceof UIViewRoot)
540 {
541
542 break;
543 }
544 else
545 {
546
547
548
549 break;
550
551
552
553
554
555 }
556 }
557
558 lastParent = currParent;
559 currParent = lastParent.getParent();
560 }
561
562 Renderer renderer = getRenderer(context);
563 if (null != renderer)
564 clientId = renderer.convertClientId(context, clientId);
565
566 return clientId;
567 }
568
569 private List<UIComponent> _getAncestors()
570 {
571 List<UIComponent> ancestors = new ArrayList<UIComponent>();
572
573 UIComponent parent = getParent();
574
575 while (parent != null)
576 {
577 ancestors.add(parent);
578
579 parent = parent.getParent();
580 }
581
582 Collections.reverse(ancestors);
583
584 return ancestors;
585 }
586
587 private String _getAncestorPath()
588 {
589 StringBuilder ancestorPath = new StringBuilder(1000);
590
591 List<UIComponent> ancestors = _getAncestors();
592
593 if (ancestors.isEmpty())
594 {
595 return "<none>";
596 }
597 else
598 {
599 Iterator<UIComponent> ancestorsIter = ancestors.iterator();
600
601 boolean first = true;
602
603 while (ancestorsIter.hasNext())
604 {
605 if (!first)
606 {
607 ancestorPath.append('/');
608 }
609 else
610 {
611 first = false;
612 }
613
614 ancestorPath.append(ancestorsIter.next().toString());
615 }
616
617 return ancestorPath.toString();
618 }
619 }
620
621 @Override
622 public String getClientId(FacesContext context)
623 {
624 if (_isClientIdCachingEnabled())
625 {
626 String clientId = _clientId;
627
628 if (clientId == null)
629 {
630
631
632
633 if (_parent == null)
634 {
635 _LOG.warning("INVALID_CALL_TO_GETCLIENTID", getId());
636
637 return _calculateClientId(context);
638 }
639
640 clientId = _calculateClientId(context);
641
642 if (_usesFacesBeanImpl)
643 {
644 _clientId = clientId;
645 }
646 }
647 else if (_isClientIdDebuggingEnabled())
648 {
649 _warnClientIdCachingConfig(context);
650
651
652
653 String realID = _calculateClientId(context);
654
655 if (!clientId.equals(realID))
656 throw new IllegalStateException(
657 String.format("Cached client id %s for %s doesn't match client id: %s",
658 clientId, this, realID));
659 }
660
661 return clientId;
662 }
663 else
664 {
665 _warnClientIdCachingConfig(context);
666
667 return _calculateClientId(context);
668 }
669 }
670
671
672
673
674
675 @Override
676 public String getId()
677 {
678
679 if (_usesFacesBeanImpl)
680 {
681
682
683
684 if (_id == null)
685 {
686 FacesContext context = FacesContext.getCurrentInstance();
687 UIViewRoot viewRoot = context.getViewRoot();
688
689 _id = viewRoot.createUniqueId();
690 }
691
692 return _id;
693 }
694 else
695 {
696
697 FacesBean facesBean = getFacesBean();
698
699 String id = (String)facesBean.getProperty(ID_KEY);
700
701
702 if (id == null)
703 {
704 id = FacesContext.getCurrentInstance().getViewRoot().createUniqueId();
705
706 facesBean.setProperty(ID_KEY, id);
707 }
708
709 return id;
710 }
711 }
712
713
714
715
716
717
718
719
720
721
722
723
724
725 @Override
726 public void setId(String id)
727 {
728 FacesBean facesBean = getFacesBean();
729
730
731
732
733
734 if (_usesFacesBeanImpl)
735 {
736
737 if ((_id == null) || !_id.equals(id))
738 {
739 _validateId(id);
740 _id = id;
741
742
743
744 if ((_clientId != null) && (this instanceof NamingContainer))
745 {
746 clearCachedClientIds();
747 }
748 }
749 }
750 else
751 {
752 _validateId(id);
753 facesBean.setProperty(ID_KEY, id);
754 }
755
756 _clientId = null;
757 }
758
759
760
761
762 @Override
763 public void clearCachedClientIds()
764 {
765
766 _clientId = null;
767
768
769 Iterator<UIComponent> allChildren = getFacetsAndChildren();
770
771 while (allChildren.hasNext())
772 {
773 clearCachedClientIds(allChildren.next());
774 }
775 }
776
777 @Override
778 abstract public String getFamily();
779
780 @Override
781 public UIComponent getParent()
782 {
783 return _parent;
784 }
785
786
787
788
789
790
791
792
793 @Override
794 public void setParent(UIComponent parent)
795 {
796
797 if (parent != _parent)
798 {
799 if (parent != null)
800 {
801
802 _parent = parent;
803
804 boolean isInView = parent.isInView();
805
806 _resetClientId(isInView);
807
808 if (isInView)
809 {
810
811
812
813
814
815 _publishPostAddToViewEvent(getFacesContext(), this);
816 }
817 }
818 else
819 {
820 boolean wasInView = _parent != null && _parent.isInView();
821
822 if (wasInView)
823 {
824
825
826
827 _publishPreRemoveFromViewEvent(getFacesContext(), this);
828 }
829
830
831 _parent = null;
832 _resetClientId(false);
833 }
834 }
835 }
836
837 private void _resetClientId(boolean isInView)
838 {
839
840 if (_clientId != null)
841 {
842 String newClientId;
843
844
845 if (isInView)
846 {
847 newClientId = _calculateClientId(FacesContext.getCurrentInstance());
848 }
849 else
850 {
851 newClientId = null;
852 }
853
854
855
856 boolean clearCachedIds = !_clientId.equals(newClientId);
857
858
859 if (clearCachedIds)
860 {
861 clearCachedClientIds();
862 _clientId = newClientId;
863 }
864 }
865 }
866
867 @Override
868 public boolean isRendered()
869 {
870 return getBooleanProperty(RENDERED_KEY, true);
871 }
872
873 @Override
874 public void setRendered(boolean rendered)
875 {
876 setBooleanProperty(RENDERED_KEY, rendered);
877 }
878
879 public boolean isTransient()
880 {
881 return getBooleanProperty(TRANSIENT_KEY, false);
882 }
883
884 public void setTransient(boolean newTransient)
885 {
886 setBooleanProperty(TRANSIENT_KEY, newTransient);
887 }
888
889 @Override
890 public String getRendererType()
891 {
892
893
894
895
896 if (_facesBean == null)
897 return null;
898
899 return (String) getProperty(RENDERER_TYPE_KEY);
900 }
901
902 @Override
903 public void setRendererType(String rendererType)
904 {
905 String oldRendererType = getRendererType();
906 if (oldRendererType == null)
907 {
908 if (rendererType == null)
909 return;
910 }
911 else if (oldRendererType.equals(rendererType))
912 {
913 return;
914 }
915
916
917 _init(rendererType);
918 setProperty(RENDERER_TYPE_KEY, rendererType);
919 }
920
921 @Override
922 public boolean getRendersChildren()
923 {
924 Renderer renderer = getRenderer(getFacesContext());
925 if (renderer == null)
926 return false;
927
928 return renderer.getRendersChildren();
929 }
930
931
932
933 @Override
934 public UIComponent findComponent(String id)
935 {
936 if (id == null)
937 throw new NullPointerException();
938
939 if ("".equals(id))
940 throw new IllegalArgumentException();
941
942 UIComponent from = this;
943
944
945 if (id.charAt(0) == NamingContainer.SEPARATOR_CHAR)
946 {
947 id = id.substring(1);
948 while (from.getParent() != null)
949 from = from.getParent();
950 }
951
952 else if (this instanceof NamingContainer)
953 {
954 ;
955 }
956
957 else
958 {
959 while (from.getParent() != null)
960 {
961 from = from.getParent();
962 if (from instanceof NamingContainer)
963 break;
964 }
965 }
966
967
968 String searchId;
969 int separatorIndex = id.indexOf(NamingContainer.SEPARATOR_CHAR);
970 if (separatorIndex < 0)
971 searchId = id;
972 else
973 searchId = id.substring(0, separatorIndex);
974
975 if (searchId.equals(from.getId()))
976 {
977
978 ;
979 }
980 else
981 {
982 from = _findInsideOf(from, searchId);
983 }
984
985
986 if (separatorIndex < 0)
987 {
988 return from;
989 }
990
991
992 else
993 {
994 if (from == null)
995 return null;
996
997 if (!(from instanceof NamingContainer))
998 throw new IllegalArgumentException();
999 return from.findComponent(id.substring(separatorIndex + 1));
1000 }
1001 }
1002
1003
1004
1005
1006
1007 @Override
1008 public List<UIComponent> getChildren()
1009 {
1010 if (_children == null)
1011 _children = new ChildArrayList(this);
1012
1013 return _children;
1014 }
1015
1016 @Override
1017 public int getChildCount()
1018 {
1019 if (_children == null)
1020 return 0;
1021 else
1022 return getChildren().size();
1023 }
1024
1025
1026
1027
1028
1029 @Override
1030 public Map<String, UIComponent> getFacets()
1031 {
1032
1033 if (_facets == null)
1034 _facets = new FacetHashMap(this);
1035
1036 return _facets;
1037 }
1038
1039 @Override
1040 public UIComponent getFacet(String facetName)
1041 {
1042 if (facetName == null)
1043 throw new NullPointerException();
1044
1045 if (_facets == null)
1046 return null;
1047 else
1048 return getFacets().get(facetName);
1049 }
1050
1051
1052
1053
1054
1055
1056
1057
1058 public Iterator<String> getFacetNames()
1059 {
1060 if (_facets == null)
1061 return _EMPTY_STRING_ITERATOR;
1062 else
1063 return _facets.keySet().iterator();
1064 }
1065
1066 @Override
1067 public Iterator<UIComponent> getFacetsAndChildren()
1068 {
1069
1070 if (_facets == null)
1071 {
1072 if (_children == null)
1073 return _EMPTY_UICOMPONENT_ITERATOR;
1074
1075 return _children.iterator();
1076 }
1077 else
1078 {
1079 if (_children == null)
1080 return _facets.values().iterator();
1081 }
1082
1083 return new CompositeIterator<UIComponent>(_children.iterator(), _facets.values().iterator());
1084 }
1085
1086
1087
1088 @Override
1089 public void broadcast(FacesEvent event)
1090 throws AbortProcessingException
1091 {
1092 if (event == null)
1093 throw new NullPointerException();
1094
1095 if (_LOG.isFine())
1096 _LOG.fine("Broadcasting event " + event + " to " + this);
1097
1098 UIComponent component = event.getComponent();
1099
1100 FacesContext context = getFacesContext();
1101 assert _isCurrentComponent(context, component);
1102 assert _isCompositeParentCurrent(context, component);
1103
1104 if (component != null && satisfiesPartialTrigger(event))
1105 {
1106 RequestContext adfContext = RequestContext.getCurrentInstance();
1107 if (adfContext != null)
1108 adfContext.partialUpdateNotify(component);
1109 }
1110
1111 Renderer renderer = getRenderer(context);
1112 if (renderer instanceof CoreRenderer)
1113 {
1114
1115 ((CoreRenderer)renderer).broadcast(this, event);
1116 }
1117
1118 Iterator<FacesListener> iter =
1119 (Iterator<FacesListener>)getFacesBean().entries(_LISTENERS_KEY);
1120
1121
1122 if (event instanceof BehaviorEvent)
1123 {
1124 BehaviorEvent behaviorEvent = (BehaviorEvent) event;
1125 Behavior behavior = behaviorEvent.getBehavior();
1126 behavior.broadcast(behaviorEvent);
1127 }
1128
1129
1130 while (iter.hasNext())
1131 {
1132 FacesListener listener = iter.next();
1133 if (event.isAppropriateListener(listener))
1134 {
1135 event.processListener(listener);
1136 }
1137 }
1138
1139 if (event instanceof AttributeChangeEvent)
1140 {
1141 broadcastToMethodExpression(event, getAttributeChangeListener());
1142 }
1143 }
1144
1145
1146
1147
1148
1149
1150
1151
1152 protected boolean satisfiesPartialTrigger(
1153 FacesEvent event)
1154 {
1155 return true;
1156 }
1157
1158
1159
1160 @Override
1161 public void decode(FacesContext context)
1162 {
1163 if (context == null)
1164 throw new NullPointerException();
1165
1166
1167 Map<String, Object> attrs = getAttributes();
1168 Object triggers = attrs.get("partialTriggers");
1169 if (triggers instanceof String[])
1170 {
1171 RequestContext adfContext = RequestContext.getCurrentInstance();
1172 if (adfContext != null)
1173 adfContext.addPartialTriggerListeners(this, (String[]) triggers);
1174 }
1175
1176 __rendererDecode(context);
1177 }
1178
1179 @Override
1180 public void encodeBegin(FacesContext context) throws IOException
1181 {
1182 if (context == null)
1183 throw new NullPointerException();
1184
1185
1186 pushComponentToEL(context, this);
1187
1188 if (!isRendered())
1189 return;
1190
1191 context.getApplication().publishEvent(context, PreRenderComponentEvent.class, UIComponent.class, this);
1192
1193 _cacheRenderer(context);
1194 Renderer renderer = getRenderer(context);
1195
1196
1197 if (renderer != null)
1198 {
1199 renderer.encodeBegin(context, this);
1200 }
1201 }
1202
1203 @Override
1204 public void encodeChildren(FacesContext context) throws IOException
1205 {
1206 if (context == null)
1207 throw new NullPointerException();
1208
1209 if (!isRendered())
1210 return;
1211
1212 Renderer renderer = getRenderer(context);
1213
1214 if (renderer != null)
1215 {
1216 renderer.encodeChildren(context, this);
1217 }
1218 }
1219
1220 @Override
1221 public void encodeEnd(FacesContext context) throws IOException
1222 {
1223 if (context == null)
1224 throw new NullPointerException();
1225
1226 try
1227 {
1228 if (isRendered())
1229 {
1230 RequestContext requestContext = RequestContext.getCurrentInstance();
1231 requestContext.pushCurrentComponent(context, this);
1232
1233 try
1234 {
1235 Renderer renderer = getRenderer(context);
1236
1237 if (renderer != null)
1238 {
1239 renderer.encodeEnd(context, this);
1240 }
1241 }
1242 finally
1243 {
1244 requestContext.popCurrentComponent(context, this);
1245 }
1246 }
1247 }
1248 finally
1249 {
1250 popComponentFromEL(context);
1251 }
1252 }
1253
1254 @Override
1255 public void queueEvent(FacesEvent event)
1256 {
1257 if (event == null)
1258 throw new NullPointerException();
1259
1260 UIComponent parent = getParent();
1261 if (parent == null)
1262 throw new IllegalStateException();
1263
1264 parent.queueEvent(event);
1265 }
1266
1267
1268
1269 @Override
1270 public void processDecodes(FacesContext context)
1271 {
1272 if (context == null)
1273 throw new NullPointerException();
1274
1275 if (!isRendered())
1276 return;
1277
1278 RequestContext requestContext = RequestContext.getCurrentInstance();
1279 requestContext.pushCurrentComponent(context, this);
1280 pushComponentToEL(context, this);
1281
1282 try
1283 {
1284
1285 decodeChildren(context);
1286
1287
1288 decode(context);
1289 }
1290 finally
1291 {
1292
1293
1294
1295 popComponentFromEL(context);
1296 requestContext.popCurrentComponent(context, this);
1297 }
1298 }
1299
1300 @Override
1301 public void processValidators(FacesContext context)
1302 {
1303 if (context == null)
1304 throw new NullPointerException();
1305
1306 if (!isRendered())
1307 return;
1308
1309 RequestContext requestContext = RequestContext.getCurrentInstance();
1310 requestContext.pushCurrentComponent(context, this);
1311 pushComponentToEL(context, this);
1312
1313 try
1314 {
1315
1316 validateChildren(context);
1317 }
1318 finally
1319 {
1320 popComponentFromEL(context);
1321 requestContext.popCurrentComponent(context, this);
1322 }
1323 }
1324
1325 @Override
1326 public void processUpdates(FacesContext context)
1327 {
1328 if (context == null)
1329 throw new NullPointerException();
1330
1331 if (!isRendered())
1332 return;
1333
1334 RequestContext requestContext = RequestContext.getCurrentInstance();
1335 requestContext.pushCurrentComponent(context, this);
1336 pushComponentToEL(context, this);
1337
1338 try
1339 {
1340
1341 updateChildren(context);
1342 }
1343 finally
1344 {
1345 popComponentFromEL(context);
1346 requestContext.popCurrentComponent(context, this);
1347 }
1348 }
1349
1350 @Override
1351 public Object processSaveState(FacesContext context)
1352 {
1353 if (context == null)
1354 throw new NullPointerException();
1355
1356 if (_LOG.isFiner())
1357 _LOG.finer("processSaveState() on " + this);
1358
1359 RequestContext requestContext = RequestContext.getCurrentInstance();
1360 requestContext.pushCurrentComponent(context, this);
1361 pushComponentToEL(context, this);
1362
1363 Object state = null;
1364
1365 try
1366 {
1367 if (((_children == null) || _children.isEmpty()) &&
1368 ((_facets == null) || _facets.isEmpty()))
1369 {
1370 state = saveState(context);
1371 }
1372 else
1373 {
1374 TreeState treeState = new TreeState();
1375 treeState.saveState(context, this);
1376 if (treeState.isEmpty())
1377 state = null;
1378
1379 state = treeState;
1380 }
1381 }
1382 catch (RuntimeException e)
1383 {
1384 _LOG.warning(_LOG.getMessage("COMPONENT_CHILDREN_SAVED_STATE_FAILED", this));
1385
1386 throw e;
1387 }
1388
1389 finally
1390 {
1391 popComponentFromEL(context);
1392 requestContext.popCurrentComponent(context, this);
1393 }
1394
1395 return state;
1396 }
1397
1398
1399
1400
1401
1402 @Override
1403 public void processRestoreState(FacesContext context, Object state)
1404 {
1405 if (context == null)
1406 throw new NullPointerException();
1407
1408 if (_LOG.isFiner())
1409 _LOG.finer("processRestoreState() on " + this);
1410
1411 RequestContext requestContext = RequestContext.getCurrentInstance();
1412 requestContext.pushCurrentComponent(context, this);
1413 pushComponentToEL(context, this);
1414
1415 try
1416 {
1417
1418 if (state instanceof TreeState)
1419 {
1420 ((TreeState) state).restoreState(context, this);
1421 }
1422
1423
1424 else
1425 {
1426 restoreState(context, state);
1427 }
1428 }
1429 finally
1430 {
1431 popComponentFromEL(context);
1432 requestContext.popCurrentComponent(context, this);
1433 }
1434 }
1435
1436 @Override
1437 public void markInitialState()
1438 {
1439
1440
1441
1442 getFacesBean().markInitialState();
1443 }
1444
1445 @Override
1446 public void clearInitialState()
1447 {
1448 getFacesBean().clearInitialState();
1449 }
1450
1451 @Override
1452 public boolean initialStateMarked()
1453 {
1454 return getFacesBean().initialStateMarked();
1455 }
1456
1457 public Object saveState(FacesContext facesContext)
1458 {
1459 Object state = getFacesBean().saveState(facesContext);
1460
1461
1462
1463
1464 if (StateUtils.checkComponentStateSerialization(facesContext))
1465 {
1466 try
1467 {
1468 new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(state);
1469 }
1470 catch (IOException e)
1471 {
1472 throw new RuntimeException(_LOG.getMessage("COMPONENT_SAVED_STATE_FAILED", this), e);
1473 }
1474 }
1475
1476 return state;
1477 }
1478
1479 public void restoreState(
1480 FacesContext facesContext,
1481 Object stateObj)
1482 {
1483 getFacesBean().restoreState(facesContext, stateObj);
1484 }
1485
1486 @Override
1487 public String toString()
1488 {
1489 String className = getClass().getName();
1490 int periodIndex = className.lastIndexOf('.');
1491 if (periodIndex >= 0)
1492 className = className.substring(periodIndex + 1);
1493
1494 return className + "[" + getFacesBean().toString() + ", id=" + getId() + "]";
1495 }
1496
1497
1498
1499
1500 @Override
1501 protected FacesContext getFacesContext()
1502 {
1503
1504
1505
1506 return FacesContext.getCurrentInstance();
1507 }
1508
1509
1510
1511
1512
1513
1514
1515 final protected void decodeChildren(FacesContext context)
1516 {
1517 LifecycleRenderer renderer = getLifecycleRenderer(context);
1518
1519 if (renderer != null)
1520 {
1521 if (renderer.decodeChildren(context, this))
1522 return;
1523 }
1524
1525 decodeChildrenImpl(context);
1526 }
1527
1528
1529
1530
1531
1532
1533 protected void decodeChildrenImpl(FacesContext context)
1534 {
1535 Iterator<UIComponent> kids = getRenderedFacetsAndChildren(context);
1536 while (kids.hasNext())
1537 {
1538 UIComponent kid = kids.next();
1539 kid.processDecodes(context);
1540 }
1541 }
1542
1543
1544
1545
1546
1547
1548
1549 final protected void validateChildren(FacesContext context)
1550 {
1551 LifecycleRenderer renderer = getLifecycleRenderer(context);
1552
1553 if (renderer != null)
1554 {
1555 if (renderer.validateChildren(context, this))
1556 return;
1557 }
1558
1559 validateChildrenImpl(context);
1560 }
1561
1562
1563
1564
1565
1566
1567 protected void validateChildrenImpl(FacesContext context)
1568 {
1569
1570 Iterator<UIComponent> kids = getRenderedFacetsAndChildren(context);
1571 while (kids.hasNext())
1572 {
1573 UIComponent kid = kids.next();
1574 kid.processValidators(context);
1575 }
1576 }
1577
1578
1579
1580
1581
1582
1583
1584 final protected void updateChildren(FacesContext context)
1585 {
1586 LifecycleRenderer renderer = getLifecycleRenderer(context);
1587
1588 if (renderer != null)
1589 {
1590 if (renderer.updateChildren(context, this))
1591 return;
1592 }
1593
1594 updateChildrenImpl(context);
1595 }
1596
1597 protected void updateChildrenImpl(FacesContext context)
1598 {
1599
1600 Iterator<UIComponent> kids = getRenderedFacetsAndChildren(context);
1601 while (kids.hasNext())
1602 {
1603 UIComponent kid = kids.next();
1604 kid.processUpdates(context);
1605 }
1606 }
1607
1608 @Override
1609 protected void addFacesListener(FacesListener listener)
1610 {
1611 if (listener == null)
1612 throw new NullPointerException();
1613
1614 getFacesBean().addEntry(_LISTENERS_KEY, listener);
1615 }
1616
1617 @Override
1618 protected void removeFacesListener(FacesListener listener)
1619 {
1620 if (listener == null)
1621 throw new NullPointerException();
1622
1623 getFacesBean().removeEntry(_LISTENERS_KEY, listener);
1624 }
1625
1626 @Override
1627 protected FacesListener[] getFacesListeners(Class clazz)
1628 {
1629 if (clazz == null)
1630 throw new NullPointerException();
1631
1632 if (!FacesListener.class.isAssignableFrom(clazz))
1633 throw new IllegalArgumentException();
1634
1635 return (FacesListener[])
1636 getFacesBean().getEntries(_LISTENERS_KEY, clazz);
1637 }
1638
1639
1640
1641
1642
1643 private boolean _isAnyFilterRejectingChange(UIComponent uic, ComponentChange cc)
1644 {
1645
1646 boolean rejectsChange = false;
1647
1648 Iterator<ComponentChangeFilter> iter =
1649 (Iterator<ComponentChangeFilter>)getFacesBean().entries(_COMPONENT_CHANGE_FILTERS_KEY);
1650
1651 while (iter.hasNext())
1652 {
1653 ComponentChangeFilter currentFilter = iter.next();
1654 if (currentFilter.accept(cc, uic) == ComponentChangeFilter.Result.REJECT)
1655 {
1656
1657 rejectsChange = true;
1658 break;
1659 }
1660 }
1661
1662 return rejectsChange;
1663 }
1664
1665 private UIXComponentBase _getNextUIXComponentBaseAnxcestor()
1666 {
1667 UIComponent parent = getParent();
1668
1669 while (parent != null)
1670 {
1671 if (parent instanceof UIXComponentBase)
1672 {
1673 return (UIXComponentBase)parent;
1674 }
1675
1676 parent = parent.getParent();
1677 }
1678
1679 return null;
1680 }
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694 protected ComponentChange addComponentChange(UIComponent component, ComponentChange change)
1695 {
1696
1697 if ((component == this) && (change instanceof AttributeComponentChange))
1698 {
1699 AttributeComponentChange aa = (AttributeComponentChange)change;
1700 Object attributeValue = aa.getAttributeValue();
1701
1702 if (attributeValue instanceof RowKeySet)
1703 {
1704 change = new RowKeySetAttributeChange(getClientId(getFacesContext()),
1705 aa.getAttributeName(),
1706 attributeValue);
1707 }
1708 }
1709
1710
1711 if (!_isAnyFilterRejectingChange(component, change))
1712 {
1713 UIXComponentBase nextUIXParent = _getNextUIXComponentBaseAnxcestor();
1714
1715 if (nextUIXParent != null)
1716 {
1717 return nextUIXParent.addComponentChange(component, change);
1718 }
1719 else
1720 {
1721 RequestContext trinContext = RequestContext.getCurrentInstance();
1722 trinContext.getChangeManager().addComponentChange(getFacesContext(), component, change);
1723 return change;
1724 }
1725 }
1726 else
1727 {
1728 return null;
1729 }
1730 }
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742 protected void addAttributeChange(
1743 String attributeName,
1744 Object attributeValue)
1745 {
1746 addComponentChange(new AttributeComponentChange(attributeName, attributeValue));
1747 }
1748
1749 void __rendererDecode(FacesContext context)
1750 {
1751 _cacheRenderer(context);
1752 Renderer renderer = getRenderer(context);
1753
1754 if (renderer != null)
1755 {
1756 renderer.decode(context, this);
1757 }
1758 }
1759
1760
1761
1762
1763
1764
1765
1766 private void _publishPostAddToViewEvent(
1767 FacesContext context,
1768 UIComponent component)
1769 {
1770 component.setInView(true);
1771 context.getApplication().publishEvent(context, PostAddToViewEvent.class, UIComponent.class, component);
1772
1773 if (component.getChildCount() > 0)
1774 {
1775 List<UIComponent> children = component.getChildren();
1776 UIComponent child = null;
1777 UIComponent currentChild = null;
1778 int i = 0;
1779 while (i < children.size())
1780 {
1781 child = children.get(i);
1782
1783
1784
1785 do
1786 {
1787 _publishPostAddToViewEvent(context, child);
1788 currentChild = child;
1789 }
1790 while ((i < children.size()) &&
1791 ((child = children.get(i)) != currentChild) );
1792 i++;
1793 }
1794 }
1795
1796 if (component.getFacetCount() > 0)
1797 {
1798 for (UIComponent child : component.getFacets().values())
1799 {
1800 _publishPostAddToViewEvent(context, child);
1801 }
1802 }
1803 }
1804
1805
1806
1807
1808
1809
1810
1811 private void _publishPreRemoveFromViewEvent(
1812 FacesContext context,
1813 UIComponent component)
1814 {
1815 context.getApplication().publishEvent(context, PreRemoveFromViewEvent.class, UIComponent.class, component);
1816
1817 if (component.getChildCount() > 0)
1818 {
1819 for (UIComponent child : component.getChildren())
1820 {
1821 _publishPreRemoveFromViewEvent(context, child);
1822 }
1823 }
1824
1825 if (component.getFacetCount() > 0)
1826 {
1827 for (UIComponent child : component.getFacets().values())
1828 {
1829 _publishPreRemoveFromViewEvent(context, child);
1830 }
1831 }
1832
1833 component.setInView(false);
1834 }
1835
1836 private void _cacheRenderer(FacesContext context)
1837 {
1838 Renderer renderer = _getRendererImpl(context);
1839 _cachedRenderer = renderer;
1840
1841
1842 if (renderer instanceof LifecycleRenderer)
1843 {
1844 _cachedLifecycleRenderer = (LifecycleRenderer)renderer;
1845 }
1846 else
1847 {
1848 _cachedLifecycleRenderer = null;
1849 }
1850 }
1851
1852 private Renderer _getRendererImpl(FacesContext context)
1853 {
1854 String rendererType = getRendererType();
1855 if (rendererType != null)
1856 {
1857 RenderKit renderKit = context.getRenderKit();
1858 Renderer renderer = renderKit.getRenderer(getFamily(), rendererType);
1859 if (renderer == null)
1860 {
1861 _LOG.warning("CANNOT_FIND_RENDERER", new Object[]{this, rendererType});
1862 }
1863
1864 return renderer;
1865 }
1866
1867 return null;
1868 }
1869
1870 private LifecycleRenderer _getLifecycleRendererImpl(FacesContext context)
1871 {
1872 Renderer renderer = _getRendererImpl(context);
1873 if (renderer instanceof LifecycleRenderer)
1874 {
1875 return (LifecycleRenderer)renderer;
1876 }
1877
1878 return null;
1879 }
1880
1881 private boolean _isCurrentComponent(FacesContext context, UIComponent component)
1882 {
1883 return component.equals(UIComponent.getCurrentComponent(context));
1884 }
1885
1886 private boolean _isCompositeParentCurrent(FacesContext context, UIComponent component)
1887 {
1888 UIComponent currentCompositeComponent = UIComponent.getCurrentCompositeComponent(context);
1889 if(UIComponent.isCompositeComponent(component))
1890 {
1891 return component.equals(currentCompositeComponent);
1892 }
1893 else
1894 {
1895 UIComponent compositeParent = UIComponent.getCompositeComponentParent(component);
1896 if(compositeParent == null)
1897 {
1898 return currentCompositeComponent == null;
1899 }
1900 else
1901 {
1902 return compositeParent.equals(currentCompositeComponent);
1903 }
1904 }
1905 }
1906
1907 @Override
1908 protected Renderer getRenderer(FacesContext context)
1909 {
1910 Renderer renderer = _cachedRenderer;
1911 if (renderer != _UNDEFINED_RENDERER)
1912 return renderer;
1913
1914 return _getRendererImpl(context);
1915 }
1916
1917 protected LifecycleRenderer getLifecycleRenderer(FacesContext context)
1918 {
1919 LifecycleRenderer renderer = _cachedLifecycleRenderer;
1920 if (renderer != _UNDEFINED_LIFECYCLE_RENDERER)
1921 return renderer;
1922
1923 return _getLifecycleRendererImpl(context);
1924
1925 }
1926
1927 protected void setProperty(PropertyKey key, Object value)
1928 {
1929 getFacesBean().setProperty(key, value);
1930 }
1931
1932 protected Object getProperty(PropertyKey key)
1933 {
1934 return getFacesBean().getProperty(key);
1935 }
1936
1937 protected void setBooleanProperty(PropertyKey key, boolean value)
1938 {
1939 getFacesBean().setProperty(key, value ? Boolean.TRUE : Boolean.FALSE);
1940 }
1941
1942 protected boolean getBooleanProperty(PropertyKey key, boolean defaultValue)
1943 {
1944 Object o = getFacesBean().getProperty(key);
1945 if (defaultValue)
1946 return !Boolean.FALSE.equals(o);
1947 else
1948 return Boolean.TRUE.equals(o);
1949 }
1950
1951 protected void setIntProperty(PropertyKey key, int value)
1952 {
1953 getFacesBean().setProperty(key, Integer.valueOf(value));
1954 }
1955
1956 protected int getIntProperty(PropertyKey key, int defaultValue)
1957 {
1958 Number n = (Number) getFacesBean().getProperty(key);
1959 if (n == null)
1960 return defaultValue;
1961
1962 return n.intValue();
1963 }
1964
1965
1966
1967
1968
1969 @Override
1970 public int getFacetCount()
1971 {
1972 if (_facets == null)
1973 return 0;
1974
1975 return _facets.size();
1976 }
1977
1978
1979
1980
1981
1982
1983
1984
1985 protected final void broadcastToMethodBinding(
1986 FacesEvent event,
1987 MethodBinding method) throws AbortProcessingException
1988 {
1989 if (method != null)
1990 {
1991 try
1992 {
1993 FacesContext context = getFacesContext();
1994 method.invoke(context, new Object[] { event });
1995 }
1996 catch (EvaluationException ee)
1997 {
1998
1999
2000 Throwable currentThrowable = ee.getCause();
2001 while (currentThrowable != null)
2002 {
2003 if (currentThrowable instanceof AbortProcessingException)
2004 {
2005 throw ((AbortProcessingException)currentThrowable);
2006 }
2007 currentThrowable = currentThrowable.getCause();
2008 }
2009 throw ee;
2010 }
2011 }
2012 }
2013
2014
2015
2016
2017
2018 static public MethodExpression adaptMethodBinding(MethodBinding binding)
2019 {
2020 return new MethodBindingMethodExpression(binding);
2021 }
2022
2023
2024
2025
2026
2027
2028
2029 protected final void broadcastToMethodExpression(
2030 FacesEvent event,
2031 MethodExpression method) throws AbortProcessingException
2032 {
2033 if (method != null)
2034 {
2035 try
2036 {
2037 FacesContext context = getFacesContext();
2038 method.invoke(context.getELContext(), new Object[] { event });
2039 }
2040 catch (ELException ee)
2041 {
2042 Throwable t = ee.getCause();
2043
2044 if (t instanceof AbortProcessingException)
2045 throw ((AbortProcessingException) t);
2046 throw ee;
2047 }
2048 }
2049 }
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060 protected final boolean invokeOnChildrenComponents(
2061 FacesContext context,
2062 String clientId,
2063 ContextCallback callback)
2064 throws FacesException
2065 {
2066 setupChildrenVisitingContext(context);
2067
2068 boolean found = false;
2069
2070 try
2071 {
2072 Iterator<UIComponent> children = getFacetsAndChildren();
2073
2074 while (children.hasNext() && !found)
2075 {
2076 found = children.next().invokeOnComponent(context, clientId, callback);
2077 }
2078 }
2079 finally
2080 {
2081 tearDownChildrenVisitingContext(context);
2082 }
2083
2084 return found;
2085 }
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096 protected final boolean invokeOnNamingContainerComponent(
2097 FacesContext context,
2098 String clientId,
2099 ContextCallback callback)
2100 throws FacesException
2101 {
2102 assert this instanceof NamingContainer : "Only use invokeOnNamingContainerComponent on NamingContainers";
2103
2104 boolean invokedComponent;
2105
2106 setupVisitingContext(context);
2107
2108 try
2109 {
2110 String thisClientId = getClientId(context);
2111
2112 if (clientId.equals(thisClientId))
2113 {
2114 RequestContext requestContext = RequestContext.getCurrentInstance();
2115 requestContext.pushCurrentComponent(context, this);
2116 pushComponentToEL(context, null);
2117
2118 try
2119 {
2120
2121 callback.invokeContextCallback(context, this);
2122 }
2123 finally
2124 {
2125 popComponentFromEL(context);
2126 requestContext.popCurrentComponent(context, this);
2127 }
2128
2129 invokedComponent = true;
2130 }
2131 else
2132 {
2133
2134
2135 if ((!clientId.startsWith(thisClientId) ||
2136 (clientId.charAt(thisClientId.length()) != NamingContainer.SEPARATOR_CHAR)))
2137 {
2138 invokedComponent = false;
2139 }
2140 else
2141 {
2142
2143
2144
2145 invokedComponent = invokeOnChildrenComponents(context, clientId, callback);
2146 }
2147 }
2148 }
2149 finally
2150 {
2151
2152 tearDownVisitingContext(context);
2153 }
2154
2155 return invokedComponent;
2156 }
2157
2158
2159
2160
2161
2162
2163
2164 @Override
2165 public boolean invokeOnComponent(
2166 FacesContext context,
2167 String clientId,
2168 ContextCallback callback)
2169 throws FacesException
2170 {
2171 boolean invokedComponent;
2172
2173
2174 setupVisitingContext(context);
2175
2176 try
2177 {
2178 String thisClientId = getClientId(context);
2179
2180 if (clientId.equals(thisClientId))
2181 {
2182
2183 RequestContext requestContext = RequestContext.getCurrentInstance();
2184 requestContext.pushCurrentComponent(context, this);
2185 pushComponentToEL(context, null);
2186
2187 try
2188 {
2189
2190 callback.invokeContextCallback(context, this);
2191 }
2192 finally
2193 {
2194 popComponentFromEL(context);
2195 requestContext.popCurrentComponent(context, this);
2196 }
2197
2198
2199 invokedComponent = true;
2200 }
2201 else
2202 {
2203
2204
2205
2206 invokedComponent = invokeOnChildrenComponents(context, clientId, callback);
2207 }
2208 }
2209 finally
2210 {
2211
2212 tearDownVisitingContext(context);
2213 }
2214
2215 return invokedComponent;
2216 }
2217
2218
2219 @Override
2220 public void subscribeToEvent(Class<? extends SystemEvent> eventClass, ComponentSystemEventListener componentListener)
2221 {
2222 if (eventClass == null)
2223 {
2224 throw new NullPointerException("eventClass required");
2225 }
2226 if (componentListener == null)
2227 {
2228 throw new NullPointerException("componentListener required");
2229 }
2230
2231 FacesBean bean = getFacesBean();
2232
2233 AttachedObjects<Class<? extends SystemEvent>, SystemEventListener> eventStorage =
2234 (AttachedObjects<Class<? extends SystemEvent>, SystemEventListener>)bean.getProperty(_SYSTEM_EVENT_LISTENERS_KEY);
2235
2236 if (eventStorage == null)
2237 {
2238 eventStorage = new AttachedObjects<Class<? extends SystemEvent>, SystemEventListener>();
2239 bean.setProperty(_SYSTEM_EVENT_LISTENERS_KEY, eventStorage);
2240 }
2241
2242 if (componentListener instanceof SystemEventListener && componentListener instanceof StateHolder)
2243 eventStorage.addAttachedObject(eventClass, (SystemEventListener) componentListener);
2244 else
2245 eventStorage.addAttachedObject(eventClass, new ComponentSystemEventListenerWrapper(componentListener, this));
2246 }
2247
2248 @Override
2249 public void unsubscribeFromEvent(Class<? extends SystemEvent> eventClass,
2250 ComponentSystemEventListener componentListener)
2251 {
2252 if (eventClass == null)
2253 {
2254 throw new NullPointerException("eventClass required");
2255 }
2256 if (componentListener == null)
2257 {
2258 throw new NullPointerException("componentListener required");
2259 }
2260
2261 FacesBean bean = getFacesBean();
2262
2263 AttachedObjects<Class<? extends SystemEvent>, SystemEventListener> eventStorage =
2264 (AttachedObjects<Class<? extends SystemEvent>, SystemEventListener>)bean.getProperty(_SYSTEM_EVENT_LISTENERS_KEY);
2265
2266 if (eventStorage == null)
2267 {
2268 return;
2269 }
2270
2271 if (componentListener instanceof SystemEventListener && componentListener instanceof StateHolder)
2272 {
2273 eventStorage.removeAttachedObject(eventClass, (SystemEventListener) componentListener);
2274 }
2275 else
2276 {
2277
2278 eventStorage.removeAttachedObject(eventClass, new ComponentSystemEventListenerWrapper(componentListener, this));
2279 }
2280 }
2281
2282 @Override
2283 public List<SystemEventListener> getListenersForEventClass(Class<? extends SystemEvent> eventClass)
2284 {
2285 FacesBean bean = getFacesBean();
2286
2287 AttachedObjects<Class<? extends SystemEvent>, SystemEventListener> eventStorage =
2288 (AttachedObjects<Class<? extends SystemEvent>, SystemEventListener>)bean.getProperty(_SYSTEM_EVENT_LISTENERS_KEY);
2289
2290 if (eventStorage == null)
2291 {
2292 return Collections.emptyList();
2293 }
2294
2295 return eventStorage.getAttachedObjectList(eventClass);
2296 }
2297
2298 public Map<String, Object> getPassThroughAttributes(boolean create)
2299 {
2300 if (_passthroughAttributesMap == null && create)
2301 {
2302 _passthroughAttributesMap = new PassThroughAttributesMap(getFacesBean());
2303 }
2304 return _passthroughAttributesMap;
2305 }
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319 protected void addClientBehavior(
2320 String eventName,
2321 ClientBehavior behavior)
2322 {
2323
2324
2325 Collection<String> events = ((ClientBehaviorHolder)this).getEventNames();
2326
2327
2328
2329
2330 if (!events.contains(eventName))
2331 {
2332 return;
2333 }
2334
2335 FacesBean bean = getFacesBean();
2336
2337 AttachedObjects<String, ClientBehavior> behaviors = (
2338 AttachedObjects<String, ClientBehavior>)bean.getProperty(_CLIENT_BEHAVIORS_KEY);
2339
2340 if (behaviors == null)
2341 {
2342 behaviors = new AttachedObjects<String, ClientBehavior>();
2343 bean.setProperty(_CLIENT_BEHAVIORS_KEY, behaviors);
2344 }
2345
2346 behaviors.addAttachedObject(eventName, behavior);
2347 }
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365 protected Map<String, List<ClientBehavior>> getClientBehaviors()
2366 {
2367 AttachedObjects<String, ClientBehavior> behaviors = (
2368 AttachedObjects<String, ClientBehavior>)getFacesBean().getProperty(_CLIENT_BEHAVIORS_KEY);
2369
2370 if (behaviors == null)
2371 {
2372 return Collections.emptyMap();
2373 }
2374
2375 return behaviors.getAttachedObjectMap();
2376 }
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387 protected String getDefaultEventName()
2388 {
2389 _ensureClientBehaviorHolder();
2390 return null;
2391 }
2392
2393 private void _ensureClientBehaviorHolder()
2394 {
2395 if (!(this instanceof ClientBehaviorHolder))
2396 {
2397 throw new IllegalStateException("Component must implement ClientBehaviorHolder in order " +
2398 "to make use of this method.");
2399 }
2400 }
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436 static StringBuilder __getSharedStringBuilder()
2437 {
2438 StringBuilder sb = _STRING_BUILDER.get();
2439
2440 if (sb == null)
2441 {
2442 sb = new StringBuilder();
2443 _STRING_BUILDER.set(sb);
2444 }
2445
2446
2447 sb.setLength(0);
2448
2449 return sb;
2450 }
2451
2452
2453
2454
2455
2456
2457 @Deprecated
2458 void __encodeRecursive(FacesContext context, UIComponent component)
2459 throws IOException
2460 {
2461 component.encodeAll(context);
2462 }
2463
2464 static private UIComponent _findInsideOf(
2465 UIComponent from,
2466 String id)
2467 {
2468 Iterator<UIComponent> kids = from.getFacetsAndChildren();
2469 while (kids.hasNext())
2470 {
2471 UIComponent kid = kids.next();
2472 if (id.equals(kid.getId()))
2473 return kid;
2474
2475 if (!(kid instanceof NamingContainer))
2476 {
2477 UIComponent returned = _findInsideOf(kid, id);
2478 if (returned != null)
2479 return returned;
2480 }
2481 }
2482
2483 return null;
2484 }
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495 private void _validateId(String id)
2496 {
2497 if (id == null)
2498 return;
2499
2500
2501 int n = id.length();
2502 if (0 == n ||
2503 NamingContainer.SEPARATOR_CHAR == id.charAt(0))
2504 _throwBadId(id);
2505
2506 for (int i = 0; i < n; i++)
2507 {
2508 char c = id.charAt(i);
2509 if (i == 0)
2510 {
2511 if (!Character.isLetter(c) && (c != '_'))
2512 _throwBadId(id);
2513 }
2514 else
2515 {
2516 if (!(Character.isLetter(c) ||
2517 Character.isDigit(c) ||
2518 (c == '-') || (c == '_')))
2519 {
2520 _throwBadId(id);
2521 }
2522 }
2523 }
2524 }
2525
2526 private void _throwBadId(String id)
2527 {
2528 throw new IllegalArgumentException(_LOG.getMessage(
2529 "ILLEGAL_ID", id));
2530 }
2531
2532 private void _init(
2533 String rendererType)
2534 {
2535 FacesBean oldBean = _facesBean;
2536 FacesBean newBean = createFacesBean(rendererType);;
2537
2538 if (oldBean != null)
2539 newBean.addAll(oldBean);
2540
2541 _attributes = new ValueMap(newBean);
2542
2543 _facesBean = newBean;
2544
2545
2546
2547 boolean usesFacesBeanImpl = false;
2548
2549 if (newBean instanceof UIXFacesBeanImpl)
2550 usesFacesBeanImpl = true;
2551 else
2552 {
2553
2554 FacesBean currImpl = newBean;
2555
2556 while (currImpl instanceof FacesBeanWrapper)
2557 {
2558 currImpl = ((FacesBeanWrapper)currImpl).getWrappedBean();
2559
2560 if (currImpl instanceof UIXFacesBeanImpl)
2561 {
2562 usesFacesBeanImpl = true;
2563 break;
2564 }
2565 }
2566 }
2567
2568 _usesFacesBeanImpl = usesFacesBeanImpl;
2569 }
2570
2571 private FacesBean _facesBean;
2572 private List<UIComponent> _children;
2573 private Map<String, Object> _attributes;
2574 private Map<String, UIComponent> _facets;
2575 private UIComponent _parent;
2576 private String _id;
2577 private String _clientId;
2578 private boolean _usesFacesBeanImpl;
2579 private Map<String, Object> _passthroughAttributesMap;
2580
2581
2582
2583 private transient Renderer _cachedRenderer = _UNDEFINED_RENDERER;
2584 private transient LifecycleRenderer _cachedLifecycleRenderer =
2585 _UNDEFINED_LIFECYCLE_RENDERER;
2586
2587
2588
2589
2590
2591
2592 private static final Iterator<String> _EMPTY_STRING_ITERATOR = CollectionUtils.emptyIterator();
2593 private static final Iterator<UIComponent> _EMPTY_UICOMPONENT_ITERATOR =
2594 CollectionUtils.emptyIterator();
2595
2596 static private final ThreadLocal<StringBuilder> _STRING_BUILDER =
2597 ThreadLocalUtils.newRequestThreadLocal();
2598
2599 static private FacesBean.Type _createType()
2600 {
2601 try
2602 {
2603 ClassLoader cl = _getClassLoader();
2604 URL url = cl.getResource("META-INF/faces-bean-type.properties");
2605 if (url != null)
2606 {
2607 Properties properties = new Properties();
2608 InputStream is = url.openStream();
2609 try
2610 {
2611 properties.load(is);
2612 String className = (String)
2613 properties.get(UIXComponentBase.class.getName());
2614 return (FacesBean.Type) cl.loadClass(className).newInstance();
2615 }
2616 finally
2617 {
2618 is.close();
2619 }
2620 }
2621 }
2622 catch (Exception e)
2623 {
2624 _LOG.severe("CANNOT_LOAD_TYPE_PROPERTIES", e);
2625 }
2626
2627
2628 return new FacesBean.Type();
2629 }
2630
2631 static private ClassLoader _getClassLoader()
2632 {
2633 ClassLoader loader = Thread.currentThread().getContextClassLoader();
2634 if (loader == null)
2635 loader = FacesBeanFactory.class.getClassLoader();
2636 return loader;
2637 }
2638
2639 static private class RendererImpl extends Renderer
2640 {
2641 }
2642
2643 static private class ExtendedRendererImpl extends ExtendedRenderer
2644 {
2645 }
2646
2647 private static boolean _isClientIdCachingEnabled()
2648 {
2649 return (_CLIENT_ID_CACHING != ClientIdCaching.OFF);
2650 }
2651
2652 private static boolean _isClientIdDebuggingEnabled()
2653 {
2654 return (_CLIENT_ID_CACHING == ClientIdCaching.DEBUG);
2655 }
2656
2657
2658
2659 private static void _warnClientIdCachingConfig(FacesContext context)
2660 {
2661 if (_CLIENT_ID_CACHING != ClientIdCaching.ON &&
2662 context.isProjectStage(ProjectStage.Production) &&
2663 !_warnedClientIdCachingConfig(context))
2664 {
2665 _LOG.warning(
2666 "The org.apache.myfaces.trinidad.CLIENT_ID_CACHING system property is set to: " +
2667 _CLIENT_ID_CACHING +
2668 ". For best performance, client id caching should be ON in production environments.");
2669
2670 _clientIdCachingConfigWarned(context);
2671 }
2672 }
2673
2674
2675
2676 private static boolean _warnedClientIdCachingConfig(FacesContext context)
2677 {
2678 ExternalContext external = context.getExternalContext();
2679 Map<String, Object> appMap = external.getApplicationMap();
2680
2681 return Boolean.TRUE.equals(appMap.get(_WARNED_CLIENT_ID_CACHING_KEY));
2682 }
2683
2684
2685 private static void _clientIdCachingConfigWarned(FacesContext context)
2686 {
2687 ExternalContext external = context.getExternalContext();
2688 Map<String, Object> appMap = external.getApplicationMap();
2689
2690 appMap.put(_WARNED_CLIENT_ID_CACHING_KEY, Boolean.TRUE);
2691 }
2692
2693
2694 private static ClientIdCaching _initClientIdCaching()
2695 {
2696 String cachingProperty = _getClientIdCachingSystemProperty();
2697 ClientIdCaching caching = _toClientIdCachingEnum(cachingProperty);
2698
2699 _LOG.config("Client id caching configuration: " + caching);
2700
2701 return caching;
2702 }
2703
2704 private static String _getClientIdCachingSystemProperty()
2705 {
2706 try
2707 {
2708 return System.getProperty(_SYSTEM_PROP_CLIENT_ID_CACHING);
2709 }
2710 catch (Throwable t)
2711 {
2712 _LOG.warning(t);
2713 }
2714
2715 return null;
2716 }
2717
2718 private static ClientIdCaching _toClientIdCachingEnum(String cachingProperty)
2719 {
2720 try
2721 {
2722 return Enum.valueOf(ClientIdCaching.class,
2723 (cachingProperty == null) ?
2724 "ON" :
2725 cachingProperty.toUpperCase());
2726 }
2727 catch (IllegalArgumentException e)
2728 {
2729 _LOG.warning("Invalid value specified for " +
2730 _SYSTEM_PROP_CLIENT_ID_CACHING +
2731 " system property: " +
2732 cachingProperty +
2733 ". Valid values are: on | off | debug.");
2734
2735 }
2736
2737 return ClientIdCaching.ON;
2738 }
2739
2740
2741 private enum ClientIdCaching
2742 {
2743 ON,
2744 OFF,
2745 DEBUG
2746 }
2747
2748
2749 public static class ComponentSystemEventListenerWrapper implements SystemEventListener, StateHolder, ComponentSystemEventListener
2750 {
2751 ComponentSystemEventListenerWrapper(ComponentSystemEventListener listener, UIComponent component)
2752 {
2753 _delegate = listener;
2754 _componentClass = component.getClass();
2755 }
2756
2757
2758 public ComponentSystemEventListenerWrapper()
2759 {
2760 }
2761
2762 @Override
2763 public boolean equals(Object o)
2764 {
2765 if (o == this)
2766 {
2767 return true;
2768 }
2769 else if (o instanceof ComponentSystemEventListenerWrapper)
2770 {
2771 ComponentSystemEventListenerWrapper other = (ComponentSystemEventListenerWrapper) o;
2772 return _componentClass.equals(other._componentClass) && _delegate.equals(other._delegate);
2773 }
2774
2775 return false;
2776 }
2777
2778 @Override
2779 public int hashCode()
2780 {
2781 return _componentClass.hashCode() + _delegate.hashCode();
2782 }
2783
2784
2785
2786 @Override
2787 public void processEvent(SystemEvent event) throws AbortProcessingException
2788 {
2789 assert (event instanceof ComponentSystemEvent);
2790 processEvent((ComponentSystemEvent) event);
2791 }
2792
2793 @Override
2794 public void processEvent(ComponentSystemEvent event)
2795 {
2796 _delegate.processEvent((ComponentSystemEvent) event);
2797 }
2798
2799 @Override
2800 public boolean isListenerForSource(Object source)
2801 {
2802 if (_delegate instanceof SystemEventListener)
2803 {
2804 return ((SystemEventListener)_delegate).isListenerForSource(source);
2805 }
2806
2807
2808
2809 return _componentClass.isAssignableFrom(source.getClass());
2810 }
2811
2812
2813
2814 @Override
2815 public Object saveState(FacesContext context)
2816 {
2817 if (_delegate instanceof UIComponent)
2818 {
2819 return null;
2820 }
2821
2822 Object[] state = new Object[2];
2823 state[0] = StateUtils.saveStateHolder(context, _delegate);
2824 state[1] = _componentClass;
2825
2826 return state;
2827 }
2828
2829 @Override
2830 public void restoreState(FacesContext context, Object state)
2831 {
2832 if (state == null)
2833 {
2834 return;
2835 }
2836
2837 Object[] stateArr = (Object[]) state;
2838 Object saved = stateArr[0];
2839
2840 _delegate = (ComponentSystemEventListener) ((saved == null) ? UIComponent .getCurrentComponent(context)
2841 : StateUtils.restoreStateHolder(context, saved));
2842 _componentClass = (Class<?>)stateArr[1];
2843 }
2844
2845 @Override
2846 public boolean isTransient()
2847 {
2848 if (_delegate instanceof StateHolder)
2849 {
2850 return ((StateHolder)_delegate).isTransient();
2851 }
2852 return false;
2853 }
2854
2855 @Override
2856 public void setTransient(boolean isTransient)
2857 {
2858 if (_delegate instanceof StateHolder)
2859 {
2860 ((StateHolder)_delegate).setTransient(isTransient);
2861 }
2862 }
2863
2864
2865 private ComponentSystemEventListener _delegate;
2866 private Class<?> _componentClass;
2867 }
2868
2869 private static final ClientIdCaching _CLIENT_ID_CACHING = _initClientIdCaching();
2870
2871
2872 private static final String _SYSTEM_PROP_CLIENT_ID_CACHING =
2873 "org.apache.myfaces.trinidad.CLIENT_ID_CACHING";
2874
2875
2876
2877
2878 private static final String _WARNED_CLIENT_ID_CACHING_KEY =
2879 "org.apache.myfaces.trinidad.WARNED_CLIENT_ID_CACHING";
2880
2881 static private final LifecycleRenderer _UNDEFINED_LIFECYCLE_RENDERER =
2882 new ExtendedRendererImpl();
2883 static private final Renderer _UNDEFINED_RENDERER = new RendererImpl();
2884 }