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.IOException;
22
23 import java.util.Collection;
24 import java.util.Iterator;
25
26 import javax.el.MethodExpression;
27
28 import javax.faces.FactoryFinder;
29 import javax.faces.application.Application;
30 import javax.faces.application.ApplicationFactory;
31 import javax.faces.application.ProjectStage;
32 import javax.faces.component.NamingContainer;
33 import javax.faces.component.StateHelper;
34 import javax.faces.component.UIComponent;
35 import javax.faces.component.UINamingContainer;
36 import javax.faces.component.UIPanel;
37 import javax.faces.component.visit.VisitCallback;
38 import javax.faces.component.visit.VisitContext;
39 import javax.faces.component.visit.VisitHint;
40 import javax.faces.component.visit.VisitResult;
41 import javax.faces.context.FacesContext;
42 import javax.faces.event.FacesEvent;
43 import javax.faces.event.PhaseId;
44 import javax.faces.render.Renderer;
45
46 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
47 import org.apache.myfaces.trinidad.bean.FacesBean;
48 import org.apache.myfaces.trinidad.context.ComponentContextChange;
49 import org.apache.myfaces.trinidad.context.ComponentContextManager;
50 import org.apache.myfaces.trinidad.context.PartialPageContext;
51 import org.apache.myfaces.trinidad.context.RenderingContext;
52 import org.apache.myfaces.trinidad.context.RequestContext;
53 import org.apache.myfaces.trinidad.event.AttributeChangeListener;
54 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
55 import org.apache.myfaces.trinidad.render.CoreRenderer;
56
57
58
59
60
61 @JSFComponent
62 abstract public class UIXComponent extends UIComponent
63 {
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82 public static <S> boolean processFlattenedChildren(
83 FacesContext context,
84 ComponentProcessor<S> childProcessor,
85 UIComponent child,
86 S callbackContext) throws IOException
87 {
88 return processFlattenedChildren(context,
89 new ComponentProcessingContext(),
90 childProcessor,
91 child,
92 callbackContext);
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
119
120
121
122
123
124 public static <S> boolean encodeFlattenedChild(
125 FacesContext context,
126 ComponentProcessor<S> childProcessor,
127 UIComponent child,
128 S callbackContext) throws IOException
129 {
130 ComponentProcessingContext processingContext = new ComponentProcessingContext();
131 processingContext.__setIsRendering();
132
133 return processFlattenedChildren(context,
134 processingContext,
135 childProcessor,
136 child,
137 callbackContext);
138 }
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160 public static <S> boolean processFlattenedChildren(
161 FacesContext context,
162 ComponentProcessingContext cpContext,
163 ComponentProcessor<S> childProcessor,
164 UIComponent child,
165 S callbackContext) throws IOException
166 {
167 if (child.isRendered())
168 {
169
170 if ((child instanceof FlattenedComponent) &&
171 ((FlattenedComponent)child).isFlatteningChildren(context))
172 {
173 return ((FlattenedComponent)child).processFlattenedChildren(context,
174 cpContext,
175 childProcessor,
176 callbackContext);
177 }
178 else
179 {
180 boolean processed = true;
181 RequestContext requestContext = cpContext.getRequestContext();
182 requestContext.pushCurrentComponent(context, child);
183 child.pushComponentToEL(context, null);
184 try
185 {
186 if (isFlattenableCoreComponent(child))
187 {
188 processed =
189 processFlattenedChildren(context, cpContext, childProcessor,
190 child.getChildren(),
191 callbackContext);
192 }
193 else
194 {
195 try
196 {
197
198 childProcessor.processComponent(context, cpContext, child,
199 callbackContext);
200 }
201 finally
202 {
203
204 cpContext.resetStartDepth();
205 }
206 }
207 }
208 finally
209 {
210 child.popComponentFromEL(context);
211 requestContext.popCurrentComponent(context, child);
212 }
213
214 return processed;
215 }
216 }
217 else
218 {
219
220 return false;
221 }
222 }
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243 public static <S> boolean processFlattenedChildren(
244 FacesContext context,
245 ComponentProcessor<S> childProcessor,
246 Iterable<UIComponent> children,
247 S callbackContext) throws IOException
248 {
249 return processFlattenedChildren(context,
250 new ComponentProcessingContext(),
251 childProcessor,
252 children,
253 callbackContext);
254 }
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 public static <S> boolean encodeFlattenedChildren(
287 FacesContext context,
288 ComponentProcessor<S> childProcessor,
289 Iterable<UIComponent> children,
290 S callbackContext) throws IOException
291 {
292 ComponentProcessingContext processingContext = new ComponentProcessingContext();
293 processingContext.__setIsRendering();
294
295 return processFlattenedChildren(context,
296 processingContext,
297 childProcessor,
298 children,
299 callbackContext);
300 }
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317 public static <S> boolean processFlattenedChildren(
318 FacesContext context,
319 ComponentProcessingContext cpContext,
320 ComponentProcessor<S> childProcessor,
321 Iterable<UIComponent> children,
322 S callbackContext) throws IOException
323 {
324
325 boolean processedChild = false;
326
327 for (UIComponent currChild : children)
328 {
329
330 processedChild |= processFlattenedChildren(context,
331 cpContext, childProcessor,
332 currChild,
333 callbackContext);
334 }
335
336 return processedChild;
337 }
338
339
340
341
342
343
344
345
346 public static void broadcastInContext(FacesContext context, FacesEvent event)
347 {
348 UIComponent component = event.getComponent();
349 UIComponent compositeParent = null;
350 RequestContext requestContext = RequestContext.getCurrentInstance();
351 if (!UIComponent.isCompositeComponent(component))
352 {
353 compositeParent = UIComponent.getCompositeComponentParent(component);
354 if (compositeParent != null)
355 {
356 requestContext.pushCurrentComponent(context, compositeParent);
357 compositeParent.pushComponentToEL(context, null);
358 }
359 }
360 requestContext.pushCurrentComponent(context, component);
361 component.pushComponentToEL(context, null);
362 try
363 {
364 component.broadcast(event);
365 }
366 finally
367 {
368 component.popComponentFromEL(context);
369 requestContext.popCurrentComponent(context, component);
370 if (compositeParent != null)
371 {
372 compositeParent.popComponentFromEL(context);
373 requestContext.popCurrentComponent(context, compositeParent);
374 }
375 }
376 }
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401 public boolean visitTree(
402 VisitContext visitContext,
403 VisitCallback callback)
404 {
405 return visitTree(visitContext, this, callback);
406 }
407
408
409
410
411
412
413
414
415
416
417 protected Iterator<UIComponent> getRenderedFacetsAndChildren(
418 FacesContext facesContext)
419 {
420 return defaultGetRenderedFacetsAndChildren(facesContext);
421 }
422
423
424
425
426
427
428
429
430
431
432
433 protected final Iterator<UIComponent> defaultGetRenderedFacetsAndChildren(
434 FacesContext facesContext)
435 {
436 Renderer renderer = getRenderer(facesContext);
437 if (renderer instanceof CoreRenderer)
438 {
439 return ((CoreRenderer)renderer).getRenderedFacetsAndChildren(facesContext, this);
440 }
441 else
442 {
443 return getFacetsAndChildren();
444 }
445 }
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464 protected boolean visitChildren(
465 VisitContext visitContext,
466 VisitCallback callback)
467 {
468
469
470
471 if (_isEncodingVisit(visitContext))
472 {
473 Renderer renderer = getRenderer(visitContext.getFacesContext());
474 if (renderer instanceof CoreRenderer)
475 {
476 CoreRenderer coreRenderer = (CoreRenderer)renderer;
477 return coreRenderer.visitChildrenForEncoding(this, visitContext, callback);
478 }
479 }
480
481
482 return visitAllChildren(visitContext, callback);
483 }
484
485
486
487
488
489
490
491 protected final boolean visitAllChildren(
492 VisitContext visitContext,
493 VisitCallback callback)
494 {
495
496 Iterator<UIComponent> kids =
497 visitContext.getHints().contains(VisitHint.SKIP_UNRENDERED) ?
498 getRenderedFacetsAndChildren(visitContext.getFacesContext()) :
499 getFacetsAndChildren();
500
501 while (kids.hasNext())
502 {
503
504 if (kids.next().visitTree(visitContext, callback))
505 {
506 return true;
507 }
508 }
509
510 return false;
511 }
512
513
514
515
516
517 private static boolean _isEncodingVisit(VisitContext visitContext)
518 {
519 return(visitContext.getHints().contains(VisitHint.EXECUTE_LIFECYCLE) &&
520 FacesContext.getCurrentInstance().getCurrentPhaseId() == PhaseId.RENDER_RESPONSE);
521 }
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546 public static boolean visitTree(
547 VisitContext visitContext,
548 UIComponent component,
549 VisitCallback callback)
550 {
551
552 RequestContext requestContext = RequestContext.getCurrentInstance();
553 requestContext.pushCurrentComponent(visitContext.getFacesContext(), component);
554
555 try
556 {
557 if (!(component instanceof UIXComponent))
558 {
559
560 return component.visitTree(visitContext, callback);
561 }
562 else
563 {
564 UIXComponent uixComponent = (UIXComponent)component;
565
566 FacesContext context = visitContext.getFacesContext();
567
568
569 if (!uixComponent.isVisitable(visitContext))
570 return false;
571
572
573
574
575
576
577 component.pushComponentToEL(context, null);
578
579 boolean doneVisiting = false;
580 RuntimeException re = null;
581
582 try
583 {
584 RenderingContext rc = (_isEncodingVisit(visitContext))
585 ? RenderingContext.getCurrentInstance()
586 : null;
587
588
589
590
591
592
593
594 if (rc == null)
595 {
596 uixComponent.setupVisitingContext(context);
597 }
598
599 VisitResult visitResult = VisitResult.REJECT;
600
601 try
602 {
603
604 visitResult = visitContext.invokeVisitCallback(component, callback);
605
606 if (visitResult == VisitResult.COMPLETE)
607 doneVisiting = true;
608 else if (visitResult == VisitResult.ACCEPT)
609 {
610
611
612
613
614
615
616 boolean skipChildren = (uixComponent instanceof NamingContainer) &&
617 visitContext.getSubtreeIdsToVisit(uixComponent).isEmpty();
618
619
620 if (!skipChildren)
621 {
622
623
624 if (rc != null)
625 {
626 uixComponent.setupEncodingContext(context, rc);
627 }
628
629 try
630 {
631 doneVisiting = visitChildren(visitContext, uixComponent, callback);
632 }
633 finally
634 {
635
636 if (rc != null)
637 {
638 uixComponent.tearDownEncodingContext(context, rc);
639 }
640 }
641 }
642 }
643 else
644 {
645
646 assert(visitResult == VisitResult.REJECT);
647 }
648 }
649 catch (RuntimeException ex)
650 {
651 re = ex;
652 }
653 finally
654 {
655 try
656 {
657
658 if (rc == null)
659 {
660 uixComponent.tearDownVisitingContext(context);
661 }
662 }
663 catch (RuntimeException ex)
664 {
665 if (re == null)
666 {
667 throw ex;
668 }
669 else
670 {
671 _LOG.warning(ex);
672 }
673 }
674 }
675 }
676 finally
677 {
678 component.popComponentFromEL(context);
679
680 if (re != null)
681 {
682 throw re;
683 }
684 }
685
686
687 return doneVisiting;
688 }
689 }
690 finally
691 {
692
693 requestContext.popCurrentComponent(visitContext.getFacesContext(), component);
694 }
695 }
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727 public static boolean visitChildren(
728 VisitContext visitContext,
729 UIComponent parentComponent,
730 VisitCallback callback)
731 {
732 if (!(parentComponent instanceof UIXComponent))
733 {
734
735
736 for (Iterator<UIComponent> iter = parentComponent.getFacetsAndChildren(); iter.hasNext();)
737 {
738 UIComponent child = iter.next();
739
740 if (child.visitTree(visitContext, callback))
741 {
742 return true;
743 }
744 }
745
746 return false;
747 }
748
749 UIXComponent uixParentComponent = (UIXComponent)parentComponent;
750 FacesContext context = visitContext.getFacesContext();
751 RenderingContext rc = (_isEncodingVisit(visitContext))
752 ? RenderingContext.getCurrentInstance()
753 : null;
754 boolean doneVisiting = false;
755 RuntimeException re = null;
756
757
758
759
760 if (parentComponent instanceof UIXComponent)
761 {
762 if (rc != null)
763 {
764 uixParentComponent.setupChildrenEncodingContext(context, rc);
765 }
766 else
767 {
768 uixParentComponent.setupChildrenVisitingContext(context);
769 }
770 }
771
772 try
773 {
774 doneVisiting = uixParentComponent.visitChildren(visitContext, callback);
775 }
776 catch (RuntimeException ex)
777 {
778 re = ex;
779 }
780 finally
781 {
782 try
783 {
784
785 if (rc != null)
786 {
787 uixParentComponent.tearDownChildrenEncodingContext(context, rc);
788 }
789 else
790 {
791 uixParentComponent.tearDownChildrenVisitingContext(context);
792 }
793 }
794 catch (RuntimeException ex)
795 {
796 if (re == null)
797 {
798 throw ex;
799 }
800 else
801 {
802 _LOG.warning(ex);
803 }
804 }
805
806 if (re != null)
807 {
808 throw re;
809 }
810 }
811
812 return doneVisiting;
813 }
814
815
816
817
818
819
820
821
822
823
824
825 public static void addPartialTarget(FacesContext facesContext,
826 PartialPageContext partialContext, UIComponent component)
827 {
828 if(component == null)
829 {
830 throw new NullPointerException("UIComponent is null");
831 }
832
833 if (component instanceof UIXComponent)
834 {
835 ((UIXComponent)component).setPartialTarget(facesContext, partialContext);
836 }
837 else
838 {
839
840 _addPartialTargetImpl(facesContext, partialContext, component);
841 }
842 }
843
844
845
846
847 public void clearCachedClientIds()
848 {
849 clearCachedClientIds(this);
850 }
851
852
853
854
855
856 public static void clearCachedClientIds(UIComponent component)
857 {
858 if (component instanceof UIXComponent)
859 {
860 ((UIXComponent)component).clearCachedClientIds();
861 }
862 else
863 {
864 _clearCachedClientIds(component);
865 }
866 }
867
868
869
870
871 private static void _clearCachedClientIds(UIComponent component)
872 {
873
874 String id = component.getId();
875 component.setId(id);
876
877
878 Iterator<UIComponent> allChildren = component.getFacetsAndChildren();
879
880 while (allChildren.hasNext())
881 {
882 clearCachedClientIds(allChildren.next());
883 }
884 }
885
886
887
888
889
890
891
892
893
894
895
896 protected void setPartialTarget(FacesContext facesContext,
897 PartialPageContext partialContext)
898 {
899 UIXComponent._addPartialTargetImpl(facesContext, partialContext, this);
900 }
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917 protected boolean isVisitable(VisitContext visitContext)
918 {
919 return _isVisitable(visitContext, this);
920 }
921
922
923
924
925
926 private static void _addPartialTargetImpl(
927 FacesContext facesContext, PartialPageContext partialContext, UIComponent component)
928 {
929 if (component.getRendererType() == null)
930 {
931 if (component.getParent() != null)
932 {
933
934
935 addPartialTarget(facesContext, partialContext, component.getParent());
936 }
937 }
938 else
939 {
940 partialContext.addPartialTarget(component.getClientId(facesContext));
941 }
942 }
943
944
945
946
947
948 private static boolean _isVisitable(VisitContext visitContext, UIComponent component)
949 {
950 Collection<VisitHint> hints = visitContext.getHints();
951
952 if (hints.contains(VisitHint.SKIP_TRANSIENT) && component.isTransient())
953 return false;
954
955 if (hints.contains(VisitHint.SKIP_UNRENDERED) && !component.isRendered())
956 return false;
957
958 return true;
959 }
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980 public VisitResult partialEncodeVisit(
981 VisitContext visitContext,
982 PartialPageContext partialContext,
983 VisitCallback callback)
984 {
985 FacesContext context = visitContext.getFacesContext();
986 Renderer renderer = getRenderer(context);
987
988 if (renderer instanceof CoreRenderer)
989 {
990
991 return ((CoreRenderer)renderer).partialEncodeVisit(visitContext,
992 partialContext,
993 this,
994 callback);
995 }
996 else
997 {
998
999 if (partialContext.isPossiblePartialTarget(getId()) &&
1000 partialContext.isPartialTarget(getClientId(context)))
1001 {
1002
1003 return callback.visit(visitContext, this);
1004 }
1005 else
1006 {
1007
1008
1009
1010 return VisitResult.ACCEPT;
1011 }
1012 }
1013 }
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 protected void setupVisitingContext(@SuppressWarnings("unused") FacesContext context)
1029 {
1030
1031 if (_inTestingPhase)
1032 {
1033
1034 if (_inVisitingContext)
1035 {
1036 _handleInvalidContextUsage("COMPONENT_ALREADY_IN_VISITING_CONTEXT", _setupVisitingCaller);
1037 }
1038
1039
1040
1041 ComponentContextManager componentContextManager =
1042 RequestContext.getCurrentInstance().getComponentContextManager();
1043 componentContextManager.pushChange(new VisitDebugContextChange(this));
1044 _inVisitingContext = true;
1045 _setupVisitingCaller = _getStackTraceElementForCaller();
1046 }
1047 }
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062 protected void setupChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context)
1063 {
1064
1065 if (_inTestingPhase)
1066 {
1067
1068 if (_inChildrenVisitingContext)
1069 {
1070 _handleInvalidContextUsage("COMPONENT_ALREADY_IN_CHILDREN_VISITING_CONTEXT",
1071 _setupChildrenVisitingCaller);
1072 }
1073
1074
1075
1076
1077
1078
1079 ComponentContextManager componentContextManager =
1080 RequestContext.getCurrentInstance().getComponentContextManager();
1081 componentContextManager.pushChange(new VisitChildrenDebugContextChange(this));
1082 _inChildrenVisitingContext = true;
1083 _setupChildrenVisitingCaller = _getStackTraceElementForCaller();
1084 }
1085 }
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100 protected void tearDownVisitingContext(@SuppressWarnings("unused") FacesContext context)
1101 {
1102
1103 if (_inTestingPhase)
1104 {
1105
1106 if (!_inVisitingContext)
1107 {
1108 _handleInvalidContextUsage("COMPONENT_NOT_IN_VISITING_CONTEXT", _tearDownVisitingCaller);
1109 }
1110
1111
1112 ComponentContextManager componentContextManager =
1113 RequestContext.getCurrentInstance().getComponentContextManager();
1114
1115 ComponentContextChange contextChange = componentContextManager.popChange();
1116
1117
1118 if (!(contextChange instanceof VisitDebugContextChange) ||
1119 ((VisitDebugContextChange)contextChange)._component != this)
1120 {
1121 throw new IllegalStateException(_getInvalidContextChangeMessage(
1122 VisitDebugContextChange.class,
1123 contextChange));
1124 }
1125
1126 _inVisitingContext = false;
1127 _tearDownVisitingCaller = _getStackTraceElementForCaller();
1128 }
1129 }
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143 protected void tearDownChildrenVisitingContext(@SuppressWarnings("unused") FacesContext context)
1144 {
1145
1146 if (_inTestingPhase)
1147 {
1148
1149 if (!_inChildrenVisitingContext)
1150 {
1151 _handleInvalidContextUsage("COMPONENT_NOT_IN_CHILDREN_VISITING_CONTEXT",
1152 _tearDownChildrenVisitingCaller);
1153 }
1154
1155
1156 ComponentContextManager componentContextManager =
1157 RequestContext.getCurrentInstance().getComponentContextManager();
1158
1159 ComponentContextChange contextChange = componentContextManager.popChange();
1160
1161 if (!(contextChange instanceof VisitChildrenDebugContextChange) ||
1162 ((VisitChildrenDebugContextChange)contextChange)._component != this)
1163 {
1164 throw new IllegalStateException(_getInvalidContextChangeMessage(
1165 VisitChildrenDebugContextChange.class,
1166 contextChange));
1167 }
1168
1169 _inChildrenVisitingContext = false;
1170 _tearDownChildrenVisitingCaller = _getStackTraceElementForCaller();
1171 }
1172 }
1173
1174 @Deprecated
1175 protected final void setUpEncodingContext(FacesContext context, RenderingContext rc)
1176 {
1177 setupEncodingContext(context, rc);
1178 }
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206 protected void setupEncodingContext(FacesContext context, RenderingContext rc)
1207 {
1208 setupVisitingContext(context);
1209
1210
1211 if (_inTestingPhase)
1212 {
1213
1214 if (_inEncodingContext)
1215 {
1216 _handleInvalidContextUsage("COMPONENT_ALREADY_IN_ENCODING_CONTEXT", _setupEncodingCaller);
1217 }
1218
1219 _inEncodingContext = true;
1220 _setupEncodingCaller = _getStackTraceElementForCaller();
1221 }
1222
1223 Renderer renderer = getRenderer(context);
1224
1225 if (renderer instanceof CoreRenderer)
1226 {
1227 CoreRenderer coreRenderer = (CoreRenderer)renderer;
1228
1229 coreRenderer.setupEncodingContext(context, rc, (UIComponent)this);
1230 }
1231
1232 _inEncodingContext = true;
1233 }
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244 public void setupChildrenEncodingContext(FacesContext context, RenderingContext rc)
1245 {
1246 setupChildrenVisitingContext(context);
1247
1248
1249 if (_inTestingPhase)
1250 {
1251
1252 if (_inChildrenEncodingContext)
1253 {
1254 _handleInvalidContextUsage("COMPONENT_ALREADY_IN_CHILDREN_ENCODING_CONTEXT",
1255 _setupChildrenEncodingCaller);
1256 }
1257
1258 _inChildrenEncodingContext = true;
1259 _setupChildrenEncodingCaller = _getStackTraceElementForCaller();
1260 }
1261
1262 Renderer renderer = getRenderer(context);
1263
1264 if (renderer instanceof CoreRenderer)
1265 {
1266 CoreRenderer coreRenderer = (CoreRenderer)renderer;
1267
1268 coreRenderer.setupChildrenEncodingContext(context, rc, this);
1269 }
1270 _inChildrenEncodingContext = true;
1271 }
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290 protected void tearDownEncodingContext(
1291 FacesContext context,
1292 RenderingContext rc)
1293 {
1294
1295 if (_inTestingPhase)
1296 {
1297
1298 if (!_inEncodingContext)
1299 {
1300 _handleInvalidContextUsage("COMPONENT_NOT_IN_ENCODING_CONTEXT", _tearDownEncodingCaller);
1301 }
1302
1303 _inEncodingContext = false;
1304 _tearDownEncodingCaller = _getStackTraceElementForCaller();
1305 }
1306
1307 Renderer renderer = getRenderer(context);
1308
1309 try
1310 {
1311 if (renderer instanceof CoreRenderer)
1312 {
1313 CoreRenderer coreRenderer = (CoreRenderer)renderer;
1314
1315 coreRenderer.tearDownEncodingContext(context, rc, (UIComponent)this);
1316 }
1317 }
1318 finally
1319 {
1320 tearDownVisitingContext(context);
1321 }
1322 }
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333 public void tearDownChildrenEncodingContext(
1334 FacesContext context,
1335 RenderingContext rc)
1336 {
1337
1338 if (_inTestingPhase)
1339 {
1340
1341 if (!_inChildrenEncodingContext)
1342 {
1343 _handleInvalidContextUsage("COMPONENT_NOT_IN_CHILDREN_ENCODING_CONTEXT",
1344 _tearDownChildrenEncodingCaller);
1345 }
1346
1347 _inChildrenEncodingContext = false;
1348 _tearDownChildrenEncodingCaller = _getStackTraceElementForCaller();
1349 }
1350
1351 Renderer renderer = getRenderer(context);
1352
1353 try
1354 {
1355 if (renderer instanceof CoreRenderer)
1356 {
1357 CoreRenderer coreRenderer = (CoreRenderer)renderer;
1358
1359 coreRenderer.tearDownChildrenEncodingContext(context, rc, this);
1360 }
1361 }
1362 finally
1363 {
1364 tearDownChildrenVisitingContext(context);
1365 _inChildrenEncodingContext = false;
1366 }
1367 }
1368
1369
1370
1371
1372 abstract public FacesBean getFacesBean();
1373
1374
1375
1376
1377
1378
1379
1380
1381 abstract public void addAttributeChangeListener(AttributeChangeListener acl);
1382
1383
1384
1385
1386
1387
1388
1389
1390 abstract public void removeAttributeChangeListener(AttributeChangeListener acl);
1391
1392
1393
1394
1395 abstract public AttributeChangeListener[] getAttributeChangeListeners();
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405 abstract public void setAttributeChangeListener(MethodExpression me);
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415 abstract public MethodExpression getAttributeChangeListener();
1416
1417 abstract public void markInitialState();
1418
1419
1420
1421
1422
1423
1424
1425
1426 abstract public String getContainerClientId(FacesContext context, UIComponent child);
1427
1428
1429
1430
1431
1432
1433
1434
1435 public UIComponent getLogicalParent()
1436 {
1437 return getParent();
1438 }
1439
1440
1441
1442
1443
1444
1445
1446
1447 public static UIComponent getLogicalParent(UIComponent component)
1448 {
1449 if (component instanceof UIXComponent)
1450 {
1451 return ((UIXComponent)component).getLogicalParent();
1452 }
1453
1454 return component.getParent();
1455 }
1456
1457
1458
1459
1460
1461 @Override
1462 protected StateHelper getStateHelper()
1463 {
1464 throw new UnsupportedOperationException();
1465 }
1466
1467
1468
1469
1470
1471 @Override
1472 protected StateHelper getStateHelper(boolean create)
1473 {
1474 throw new UnsupportedOperationException();
1475 }
1476
1477 private String _getStackTraceElementForCaller()
1478 {
1479 StackTraceElement[] elements = Thread.currentThread().getStackTrace();
1480
1481
1482
1483
1484 String lineSep = System.getProperty("line.separator");
1485 StringBuilder stack = new StringBuilder();
1486 for (int i = 3, size = elements.length; i < size && i < 10; ++i)
1487 {
1488 stack.append(elements[i].toString());
1489 stack.append(lineSep);
1490 }
1491
1492 return stack.toString();
1493 }
1494
1495
1496
1497
1498
1499
1500
1501 private static boolean isFlattenableCoreComponent(UIComponent component)
1502 {
1503
1504
1505
1506
1507
1508 Class<? extends UIComponent> componentClass = component.getClass();
1509
1510 if (UINamingContainer.class == componentClass)
1511 {
1512
1513
1514 return component.getFacet(UIComponent.COMPOSITE_FACET_NAME) == null;
1515 }
1516
1517
1518
1519 return UIPanel.class == componentClass;
1520 }
1521
1522 private void _handleInvalidContextUsage(
1523 String bundleKey,
1524 String originalStackTrace
1525 ) throws IllegalStateException
1526 {
1527 String errorMessage = _LOG.getMessage(bundleKey,
1528 new Object[] { getClientId(), originalStackTrace });
1529
1530 if (_treatContextualIssuesAsErrors)
1531 {
1532 throw new IllegalStateException(errorMessage);
1533 }
1534 else
1535 {
1536 _LOG.warning(errorMessage);
1537 }
1538 }
1539
1540 private String _getInvalidContextChangeMessage(
1541 Class<? extends ComponentContextChange> expectedClass,
1542 ComponentContextChange foundChange)
1543 {
1544 String type = expectedClass.getName();
1545 String id = (getParent() == null) ? getId() : getClientId();
1546
1547 return _LOG.getMessage("INVALID_CONTEXT_CHANGE_FOUND",
1548 new Object[] { type, id, foundChange });
1549 }
1550
1551 private static class VisitDebugContextChange
1552 extends ComponentContextChange
1553 {
1554 private VisitDebugContextChange(
1555 UIXComponent component)
1556 {
1557 _component = component;
1558 }
1559
1560 @Override
1561 public void resume(FacesContext facesContext)
1562 {
1563 _component._inVisitingContext = _inVisitingContext;
1564 _component._inEncodingContext = _inEncodingContext;
1565 _component._setupVisitingCaller = _setupVisitingCaller;
1566 _component._tearDownVisitingCaller = _tearDownVisitingCaller;
1567 _component._setupEncodingCaller = _setupEncodingCaller;
1568 _component._tearDownEncodingCaller = _tearDownEncodingCaller;
1569 }
1570
1571 @Override
1572 public void suspend(FacesContext facesContext)
1573 {
1574 _inVisitingContext = _component._inVisitingContext;
1575 _inEncodingContext = _component._inEncodingContext;
1576 _setupVisitingCaller = _component._setupVisitingCaller;
1577 _tearDownVisitingCaller = _component._tearDownVisitingCaller;
1578 _setupEncodingCaller = _component._setupEncodingCaller;
1579 _tearDownEncodingCaller = _component._tearDownEncodingCaller;
1580
1581 _component._inVisitingContext = false;
1582 _component._inEncodingContext = false;
1583 _component._setupVisitingCaller = null;
1584 _component._tearDownVisitingCaller = null;
1585 _component._setupEncodingCaller = null;
1586 _component._tearDownEncodingCaller = null;
1587 }
1588
1589 @Override
1590 public String toString()
1591 {
1592 return String.format("VisitDebugContextChange(component: %s, id: %s)",
1593 _component,
1594 _component == null ? null :
1595 _component.getParent() == null ? _component.getId() : _component.getClientId());
1596 }
1597
1598 private final UIXComponent _component;
1599 private boolean _inVisitingContext;
1600 private boolean _inEncodingContext;
1601 private String _setupVisitingCaller;
1602 private String _tearDownVisitingCaller;
1603 private String _setupEncodingCaller;
1604 private String _tearDownEncodingCaller;
1605 }
1606
1607 private static class VisitChildrenDebugContextChange
1608 extends ComponentContextChange
1609 {
1610 private VisitChildrenDebugContextChange(
1611 UIXComponent component)
1612 {
1613 _component = component;
1614 }
1615
1616 @Override
1617 public void resume(FacesContext facesContext)
1618 {
1619 _component._inChildrenVisitingContext = _inChildrenVisitingContext;
1620 _component._inChildrenEncodingContext = _inChildrenEncodingContext;
1621 _component._setupChildrenEncodingCaller = _setupChildrenEncodingCaller;
1622 _component._tearDownChildrenEncodingCaller = _tearDownChildrenEncodingCaller;
1623 _component._setupChildrenVisitingCaller = _setupChildrenVisitingCaller;
1624 _component._tearDownChildrenVisitingCaller = _tearDownChildrenVisitingCaller;
1625 }
1626
1627 @Override
1628 public void suspend(FacesContext facesContext)
1629 {
1630 _inChildrenVisitingContext = _component._inChildrenVisitingContext;
1631 _inChildrenEncodingContext = _component._inChildrenEncodingContext;
1632 _setupChildrenEncodingCaller = _component._setupChildrenEncodingCaller;
1633 _tearDownChildrenEncodingCaller = _component._tearDownChildrenEncodingCaller;
1634 _setupChildrenVisitingCaller = _component._setupChildrenVisitingCaller;
1635 _tearDownChildrenVisitingCaller = _component._tearDownChildrenVisitingCaller;
1636
1637 _component._inChildrenVisitingContext = false;
1638 _component._inChildrenEncodingContext = false;
1639 _component._setupChildrenEncodingCaller = null;
1640 _component._tearDownChildrenEncodingCaller = null;
1641 _component._setupChildrenVisitingCaller = null;
1642 _component._tearDownChildrenVisitingCaller = null;
1643 }
1644
1645 @Override
1646 public String toString()
1647 {
1648 return String.format("VisitChildrenDebugContextChange(component: %s, id: %s)",
1649 _component,
1650 _component == null ? null :
1651 _component.getParent() == null ? _component.getId() : _component.getClientId());
1652 }
1653
1654 private final UIXComponent _component;
1655 private boolean _inChildrenVisitingContext;
1656 private boolean _inChildrenEncodingContext;
1657 private String _setupChildrenEncodingCaller;
1658 private String _tearDownChildrenEncodingCaller;
1659 private String _setupChildrenVisitingCaller;
1660 private String _tearDownChildrenVisitingCaller;
1661 }
1662
1663
1664 private final static boolean _treatContextualIssuesAsErrors;
1665 private final static boolean _inTestingPhase;
1666 private static final TrinidadLogger _LOG =
1667 TrinidadLogger.createTrinidadLogger(UIXComponent.class);
1668
1669 static
1670 {
1671
1672
1673 Application app = null;
1674 try
1675 {
1676 FacesContext facesContext = FacesContext.getCurrentInstance();
1677 app = facesContext == null ? null : facesContext.getApplication();
1678 if (app == null)
1679 {
1680 ApplicationFactory appFactory = (ApplicationFactory)
1681 FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
1682 app = appFactory.getApplication();
1683 }
1684 }
1685 catch (Throwable t)
1686 {
1687
1688 ;
1689 }
1690
1691 _inTestingPhase = app == null ? false : app.getProjectStage() == ProjectStage.UnitTest;
1692 if (_inTestingPhase)
1693 {
1694 _LOG.info("Application is running in testing phase, UIXComponent will " +
1695 "perform extra validation steps to ensure proper component usage");
1696 }
1697
1698 _treatContextualIssuesAsErrors = "true".equals(
1699 System.getProperty("uixcomponent.contextual.issue.throw"));
1700 };
1701
1702 private String _setupVisitingCaller;
1703 private String _tearDownVisitingCaller;
1704 private String _setupEncodingCaller;
1705 private String _tearDownEncodingCaller;
1706 private String _setupChildrenEncodingCaller;
1707 private String _tearDownChildrenEncodingCaller;
1708 private String _setupChildrenVisitingCaller;
1709 private String _tearDownChildrenVisitingCaller;
1710 private boolean _inVisitingContext;
1711 private boolean _inChildrenVisitingContext;
1712 private boolean _inEncodingContext;
1713 private boolean _inChildrenEncodingContext;
1714 }