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