1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package javax.faces.component;
20
21 import java.io.IOException;
22 import java.io.Serializable;
23 import java.lang.reflect.InvocationTargetException;
24 import java.lang.reflect.Method;
25 import java.sql.ResultSet;
26 import java.util.ArrayList;
27 import java.util.Collection;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Map;
32
33 import javax.el.ValueExpression;
34 import javax.faces.FacesException;
35 import javax.faces.application.FacesMessage;
36 import javax.faces.application.StateManager;
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.el.ValueBinding;
43 import javax.faces.event.AbortProcessingException;
44 import javax.faces.event.FacesEvent;
45 import javax.faces.event.FacesListener;
46 import javax.faces.event.PhaseId;
47 import javax.faces.event.PostValidateEvent;
48 import javax.faces.event.PreValidateEvent;
49 import javax.faces.model.ArrayDataModel;
50 import javax.faces.model.CollectionDataModel;
51 import javax.faces.model.DataModel;
52 import javax.faces.model.IterableDataModel;
53 import javax.faces.model.ListDataModel;
54 import javax.faces.model.ResultDataModel;
55 import javax.faces.model.ResultSetDataModel;
56 import javax.faces.model.ScalarDataModel;
57 import javax.servlet.jsp.jstl.sql.Result;
58
59 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
60 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFFacet;
61 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
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
119
120
121
122 @JSFComponent(defaultRendererType = "javax.faces.Table")
123 public class UIData extends UIComponentBase implements NamingContainer, UniqueIdVendor
124 {
125 public static final String COMPONENT_FAMILY = "javax.faces.Data";
126 public static final String COMPONENT_TYPE = "javax.faces.Data";
127
128 private static final String DATAMODEL_BUILDER_CLASS_NAME = "org.apache.myfaces.cdi.model.DataModelBuilderProxy";
129 private static final Class<?> DATAMODEL_BUILDER_CLASS;
130 private static final Method DATAMODEL_BUILDER_CREATE_DATAMODEL_METHOD;
131
132 static
133 {
134 Class<?> dataModelBuilderClass = null;
135 Method createDataModelMethod = null;
136 try
137 {
138 dataModelBuilderClass = _ClassUtils.classForName(DATAMODEL_BUILDER_CLASS_NAME);
139 if (dataModelBuilderClass != null)
140 {
141 createDataModelMethod = dataModelBuilderClass.getMethod("createDataModel",
142 new Class[]{FacesContext.class, Class.class, Object.class});
143 }
144 }
145 catch(Exception e)
146 {
147
148 }
149 DATAMODEL_BUILDER_CLASS = dataModelBuilderClass;
150 DATAMODEL_BUILDER_CREATE_DATAMODEL_METHOD = createDataModelMethod;
151 }
152
153 private static final String FOOTER_FACET_NAME = "footer";
154 private static final String HEADER_FACET_NAME = "header";
155 private static final Class<Object[]> OBJECT_ARRAY_CLASS = Object[].class;
156 private static final int PROCESS_DECODES = 1;
157 private static final int PROCESS_VALIDATORS = 2;
158 private static final int PROCESS_UPDATES = 3;
159
160
161 private static final Object[] LEAF_NO_STATE = new Object[]{null,null};
162
163 private int _rowIndex = -1;
164
165
166
167
168 private Map<String, Object> _rowStates = new HashMap<String, Object>();
169 private Map<String, Map<String, Object> > _rowDeltaStates = new HashMap<String, Map<String, Object> >();
170 private Map<String, Map<String, Object> > _rowTransientStates = new HashMap<String, Map<String, Object> >();
171
172
173
174
175
176
177 private Map<String, DataModel> _dataModelMap = new HashMap<String, DataModel>();
178
179
180 private boolean _isValidChilds = true;
181
182 private Object _initialDescendantComponentState = null;
183
184 private Object _initialDescendantFullComponentState = null;
185
186
187
188
189
190
191
192 private static class FacesEventWrapper extends FacesEvent
193 {
194 private static final long serialVersionUID = 6648047974065628773L;
195 private FacesEvent _wrappedFacesEvent;
196 private int _rowIndex;
197
198 public FacesEventWrapper(FacesEvent facesEvent, int rowIndex, UIData redirectComponent)
199 {
200 super(redirectComponent);
201 _wrappedFacesEvent = facesEvent;
202 _rowIndex = rowIndex;
203 }
204
205 @Override
206 public PhaseId getPhaseId()
207 {
208 return _wrappedFacesEvent.getPhaseId();
209 }
210
211 @Override
212 public void setPhaseId(PhaseId phaseId)
213 {
214 _wrappedFacesEvent.setPhaseId(phaseId);
215 }
216
217 @Override
218 public void queue()
219 {
220 _wrappedFacesEvent.queue();
221 }
222
223 @Override
224 public String toString()
225 {
226 return _wrappedFacesEvent.toString();
227 }
228
229 @Override
230 public boolean isAppropriateListener(FacesListener faceslistener)
231 {
232 return _wrappedFacesEvent.isAppropriateListener(faceslistener);
233 }
234
235 @Override
236 public void processListener(FacesListener faceslistener)
237 {
238 _wrappedFacesEvent.processListener(faceslistener);
239 }
240
241 public FacesEvent getWrappedFacesEvent()
242 {
243 return _wrappedFacesEvent;
244 }
245
246 public int getRowIndex()
247 {
248 return _rowIndex;
249 }
250 }
251
252 private static final DataModel EMPTY_DATA_MODEL = new DataModel()
253 {
254 @Override
255 public boolean isRowAvailable()
256 {
257 return false;
258 }
259
260 @Override
261 public int getRowCount()
262 {
263 return 0;
264 }
265
266 @Override
267 public Object getRowData()
268 {
269 throw new IllegalArgumentException();
270 }
271
272 @Override
273 public int getRowIndex()
274 {
275 return -1;
276 }
277
278 @Override
279 public void setRowIndex(int i)
280 {
281 if (i < -1)
282 {
283 throw new IllegalArgumentException();
284 }
285 }
286
287 @Override
288 public Object getWrappedData()
289 {
290 return null;
291 }
292
293 @Override
294 public void setWrappedData(Object obj)
295 {
296 if (obj == null)
297 {
298 return;
299 }
300 throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException");
301 }
302 };
303
304 private static class EditableValueHolderState implements Serializable
305 {
306 private final Object _value;
307 private final boolean _localValueSet;
308 private final boolean _valid;
309 private final Object _submittedValue;
310
311 public EditableValueHolderState(EditableValueHolder evh)
312 {
313 _value = evh.getLocalValue();
314 _localValueSet = evh.isLocalValueSet();
315 _valid = evh.isValid();
316 _submittedValue = evh.getSubmittedValue();
317 }
318
319 public void restoreState(EditableValueHolder evh)
320 {
321 evh.setValue(_value);
322 evh.setLocalValueSet(_localValueSet);
323 evh.setValid(_valid);
324 evh.setSubmittedValue(_submittedValue);
325 }
326 }
327
328
329
330
331 public UIData()
332 {
333 setRendererType("javax.faces.Table");
334 }
335
336 @Override
337 public boolean invokeOnComponent(FacesContext context, String clientId, ContextCallback callback)
338 throws FacesException
339 {
340 if (context == null || clientId == null || callback == null)
341 {
342 throw new NullPointerException();
343 }
344
345 final String baseClientId = getClientId(context);
346
347
348 boolean returnValue = baseClientId.equals(clientId);
349
350 boolean isCachedFacesContext = isCachedFacesContext();
351 if (!isCachedFacesContext)
352 {
353 setCachedFacesContext(context);
354 }
355
356 pushComponentToEL(context, this);
357 try
358 {
359 if (returnValue)
360 {
361 try
362 {
363 callback.invokeContextCallback(context, this);
364 return true;
365 }
366 catch (Exception e)
367 {
368 throw new FacesException(e);
369 }
370 }
371
372
373 if (this.getFacetCount() > 0)
374 {
375 for (Iterator<UIComponent> it = this.getFacets().values().iterator(); !returnValue && it.hasNext();)
376 {
377 returnValue = it.next().invokeOnComponent(context, clientId, callback);
378 }
379 }
380
381 if (returnValue)
382 {
383 return returnValue;
384 }
385
386
387 if (clientId.startsWith(baseClientId))
388 {
389
390
391 char separator = context.getNamingContainerSeparatorChar();
392 String subId = clientId.substring(baseClientId.length() + 1);
393
394
395 if (clientId.charAt(baseClientId.length()) == separator &&
396 subId.matches("[0-9]+"+separator+".*"))
397 {
398 String clientRow = subId.substring(0, subId.indexOf(separator));
399
400
401 int oldRow = this.getRowIndex();
402
403
404 try
405 {
406
407
408 this.setRowIndex(Integer.parseInt(clientRow));
409
410
411 if (!isRowAvailable())
412 {
413 return false;
414 }
415
416 for (Iterator<UIComponent> it1 = getChildren().iterator();
417 !returnValue && it1.hasNext();)
418 {
419
420 returnValue = it1.next().invokeOnComponent(context, clientId, callback);
421 }
422 }
423 finally
424 {
425
426
427 this.setRowIndex(oldRow);
428 }
429 }
430 else
431 {
432
433
434
435
436
437 for (Iterator<UIComponent> itChildren = this.getChildren().iterator();
438 !returnValue && itChildren.hasNext();)
439 {
440 UIComponent child = itChildren.next();
441 if (child instanceof UIColumn && clientId.equals(child.getClientId(context)))
442 {
443 try
444 {
445 callback.invokeContextCallback(context, child);
446 }
447 catch (Exception e)
448 {
449 throw new FacesException(e);
450 }
451 returnValue = true;
452 }
453
454 if (child.getFacetCount() > 0)
455 {
456 for (Iterator<UIComponent> itChildFacets =
457 child.getFacets().values().iterator();
458 !returnValue && itChildFacets.hasNext();)
459 {
460
461 returnValue = itChildFacets.next().invokeOnComponent(
462 context, clientId, callback);
463 }
464 }
465 }
466 }
467 }
468 }
469 finally
470 {
471
472 popComponentFromEL(context);
473 if (!isCachedFacesContext)
474 {
475 setCachedFacesContext(null);
476 }
477 }
478
479 return returnValue;
480 }
481
482 public void setFooter(UIComponent footer)
483 {
484 getFacets().put(FOOTER_FACET_NAME, footer);
485 }
486
487 @JSFFacet
488 public UIComponent getFooter()
489 {
490 return getFacets().get(FOOTER_FACET_NAME);
491 }
492
493 public void setHeader(UIComponent header)
494 {
495 getFacets().put(HEADER_FACET_NAME, header);
496 }
497
498 @JSFFacet
499 public UIComponent getHeader()
500 {
501 return getFacets().get(HEADER_FACET_NAME);
502 }
503
504 public boolean isRowAvailable()
505 {
506 return getDataModel().isRowAvailable();
507 }
508
509 public int getRowCount()
510 {
511 return getDataModel().getRowCount();
512 }
513
514 public Object getRowData()
515 {
516 return getDataModel().getRowData();
517 }
518
519 public int getRowIndex()
520 {
521 return _rowIndex;
522 }
523
524
525
526
527
528
529
530
531
532 public void setRowIndex(int rowIndex)
533 {
534 if (isRowStatePreserved())
535 {
536 setRowIndexPreserveComponentState(rowIndex);
537 }
538 else
539 {
540 setRowIndexWithoutPreserveComponentState(rowIndex);
541 }
542 }
543
544 private void setRowIndexWithoutPreserveComponentState(int rowIndex)
545 {
546 if (rowIndex < -1)
547 {
548 throw new IllegalArgumentException("rowIndex is less than -1");
549 }
550
551 if (_rowIndex == rowIndex)
552 {
553 return;
554 }
555
556 FacesContext facesContext = getFacesContext();
557
558 if (_rowIndex == -1)
559 {
560 if (_initialDescendantComponentState == null)
561 {
562
563
564
565
566 _initialDescendantComponentState = saveDescendantComponentStates(this, false, false);
567 }
568 }
569 else
570 {
571
572
573
574 if (_initialDescendantComponentState != null)
575 {
576
577
578
579
580 Collection<Object[]> savedRowState = saveDescendantComponentStates(this, false, false);
581 if (savedRowState != null)
582 {
583 _rowStates.put(getContainerClientId(facesContext), savedRowState);
584 }
585 }
586 }
587
588 _rowIndex = rowIndex;
589
590 DataModel dataModel = getDataModel();
591 dataModel.setRowIndex(rowIndex);
592
593 String var = (String) getStateHelper().get(PropertyKeys.var);
594 if (rowIndex == -1)
595 {
596 if (var != null)
597 {
598 facesContext.getExternalContext().getRequestMap().remove(var);
599 }
600 }
601 else
602 {
603 if (var != null)
604 {
605 if (isRowAvailable())
606 {
607 Object rowData = dataModel.getRowData();
608 facesContext.getExternalContext().getRequestMap().put(var, rowData);
609 }
610 else
611 {
612 facesContext.getExternalContext().getRequestMap().remove(var);
613 }
614 }
615 }
616
617 if (_rowIndex == -1)
618 {
619
620
621 if (_initialDescendantComponentState != null)
622 {
623 restoreDescendantComponentStates(this, false, _initialDescendantComponentState, false);
624 }
625 else
626 {
627 restoreDescendantComponentWithoutRestoreState(this, false, false);
628 }
629 }
630 else
631 {
632 Object rowState = _rowStates.get(getContainerClientId(facesContext));
633 if (rowState == null)
634 {
635
636
637
638
639 if (_initialDescendantComponentState != null)
640 {
641 restoreDescendantComponentStates(this, false, _initialDescendantComponentState, false);
642 }
643 else
644 {
645 restoreDescendantComponentWithoutRestoreState(this, false, false);
646 }
647 }
648 else
649 {
650
651
652
653
654 restoreDescendantComponentStates(this, false, rowState, false);
655 }
656 }
657 }
658
659 private void setRowIndexPreserveComponentState(int rowIndex)
660 {
661 if (rowIndex < -1)
662 {
663 throw new IllegalArgumentException("rowIndex is less than -1");
664 }
665
666 if (_rowIndex == rowIndex)
667 {
668 return;
669 }
670
671 FacesContext facesContext = getFacesContext();
672
673 if (_initialDescendantFullComponentState != null)
674 {
675
676 Map<String, Object> sm = saveFullDescendantComponentStates(facesContext, null,
677 getChildren().iterator(), false);
678 if (sm != null && !sm.isEmpty())
679 {
680 _rowDeltaStates.put(getContainerClientId(facesContext), sm);
681 }
682 if (_rowIndex != -1)
683 {
684 _rowTransientStates.put(getContainerClientId(facesContext),
685 saveTransientDescendantComponentStates(facesContext, null, getChildren().iterator(), false));
686 }
687 }
688
689 _rowIndex = rowIndex;
690
691 DataModel dataModel = getDataModel();
692 dataModel.setRowIndex(rowIndex);
693
694 String var = (String) getStateHelper().get(PropertyKeys.var);
695 if (rowIndex == -1)
696 {
697 if (var != null)
698 {
699 facesContext.getExternalContext().getRequestMap().remove(var);
700 }
701 }
702 else
703 {
704 if (var != null)
705 {
706 if (isRowAvailable())
707 {
708 Object rowData = dataModel.getRowData();
709 facesContext.getExternalContext().getRequestMap().put(var, rowData);
710 }
711 else
712 {
713 facesContext.getExternalContext().getRequestMap().remove(var);
714 }
715 }
716 }
717
718 if (_initialDescendantFullComponentState != null)
719 {
720 Map<String, Object> rowState = _rowDeltaStates.get(getContainerClientId(facesContext));
721 if (rowState == null)
722 {
723
724 restoreFullDescendantComponentStates(facesContext, getChildren().iterator(),
725 _initialDescendantFullComponentState, false);
726 }
727 else
728 {
729
730 restoreFullDescendantComponentDeltaStates(facesContext, getChildren().iterator(),
731 rowState, _initialDescendantFullComponentState, false);
732 }
733 if (_rowIndex == -1)
734 {
735 restoreTransientDescendantComponentStates(facesContext, getChildren().iterator(), null, false);
736 }
737 else
738 {
739 rowState = _rowTransientStates.get(getContainerClientId(facesContext));
740 if (rowState == null)
741 {
742 restoreTransientDescendantComponentStates(facesContext, getChildren().iterator(), null, false);
743 }
744 else
745 {
746 restoreTransientDescendantComponentStates(facesContext, getChildren().iterator(), rowState, false);
747 }
748 }
749 }
750
751 }
752
753
754
755
756
757
758
759
760
761 @SuppressWarnings("unchecked")
762 private void restoreDescendantComponentStates(UIComponent parent, boolean iterateFacets, Object state,
763 boolean restoreChildFacets)
764 {
765 int descendantStateIndex = -1;
766 List<? extends Object[]> stateCollection = null;
767
768 if (iterateFacets && parent.getFacetCount() > 0)
769 {
770 Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
771
772 while (childIterator.hasNext())
773 {
774 UIComponent component = childIterator.next();
775
776
777 component.setId(component.getId());
778 if (!component.isTransient())
779 {
780 if (descendantStateIndex == -1)
781 {
782 stateCollection = ((List<? extends Object[]>) state);
783 descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
784 }
785
786 if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size())
787 {
788 Object[] object = stateCollection.get(descendantStateIndex);
789 if (object[0] != null && component instanceof EditableValueHolder)
790 {
791 ((EditableValueHolderState) object[0]).restoreState((EditableValueHolder) component);
792 }
793
794
795 if (object[1] != null)
796 {
797 restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
798 }
799 else
800 {
801 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
802 }
803 }
804 else
805 {
806 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
807 }
808 descendantStateIndex++;
809 }
810 }
811 }
812
813 if (parent.getChildCount() > 0)
814 {
815 for (int i = 0; i < parent.getChildCount(); i++)
816 {
817 UIComponent component = parent.getChildren().get(i);
818
819
820 component.setId(component.getId());
821 if (!component.isTransient())
822 {
823 if (descendantStateIndex == -1)
824 {
825 stateCollection = ((List<? extends Object[]>) state);
826 descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
827 }
828
829 if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size())
830 {
831 Object[] object = stateCollection.get(descendantStateIndex);
832 if (object[0] != null && component instanceof EditableValueHolder)
833 {
834 ((EditableValueHolderState) object[0]).restoreState((EditableValueHolder) component);
835 }
836
837
838 if (object[1] != null)
839 {
840 restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
841 }
842 else
843 {
844 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
845 }
846 }
847 else
848 {
849 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
850 }
851 descendantStateIndex++;
852 }
853 }
854 }
855 }
856
857
858
859
860
861
862
863
864
865
866 private void restoreDescendantComponentWithoutRestoreState(UIComponent parent, boolean iterateFacets,
867 boolean restoreChildFacets)
868 {
869 if (iterateFacets && parent.getFacetCount() > 0)
870 {
871 Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
872
873 while (childIterator.hasNext())
874 {
875 UIComponent component = childIterator.next();
876
877
878 component.setId(component.getId());
879 if (!component.isTransient())
880 {
881 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
882 }
883 }
884 }
885
886 if (parent.getChildCount() > 0)
887 {
888 for (int i = 0; i < parent.getChildCount(); i++)
889 {
890 UIComponent component = parent.getChildren().get(i);
891
892
893 component.setId(component.getId());
894 if (!component.isTransient())
895 {
896 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
897 }
898 }
899 }
900 }
901
902
903
904
905
906
907
908
909
910
911
912
913
914 private Collection<Object[]> saveDescendantComponentStates(UIComponent parent, boolean iterateFacets,
915 boolean saveChildFacets)
916 {
917 Collection<Object[]> childStates = null;
918
919 int childEmptyIndex = 0;
920 int totalChildCount = 0;
921
922 if (iterateFacets && parent.getFacetCount() > 0)
923 {
924 Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
925
926 while (childIterator.hasNext())
927 {
928 UIComponent child = childIterator.next();
929 if (!child.isTransient())
930 {
931
932
933
934
935
936 if (child instanceof EditableValueHolder)
937 {
938 if (childStates == null)
939 {
940 childStates = new ArrayList<Object[]>(
941 parent.getFacetCount()
942 + parent.getChildCount()
943 - totalChildCount
944 + childEmptyIndex);
945 for (int ci = 0; ci < childEmptyIndex; ci++)
946 {
947 childStates.add(LEAF_NO_STATE);
948 }
949 }
950
951 childStates.add(child.getChildCount() > 0 ?
952 new Object[]{new EditableValueHolderState((EditableValueHolder) child),
953 saveDescendantComponentStates(child, saveChildFacets, true)} :
954 new Object[]{new EditableValueHolderState((EditableValueHolder) child),
955 null});
956 }
957 else if (child.getChildCount() > 0 || (saveChildFacets && child.getFacetCount() > 0))
958 {
959 Object descendantSavedState = saveDescendantComponentStates(child, saveChildFacets, true);
960
961 if (descendantSavedState == null)
962 {
963 if (childStates == null)
964 {
965 childEmptyIndex++;
966 }
967 else
968 {
969 childStates.add(LEAF_NO_STATE);
970 }
971 }
972 else
973 {
974 if (childStates == null)
975 {
976 childStates = new ArrayList<Object[]>(
977 parent.getFacetCount()
978 + parent.getChildCount()
979 - totalChildCount
980 + childEmptyIndex);
981 for (int ci = 0; ci < childEmptyIndex; ci++)
982 {
983 childStates.add(LEAF_NO_STATE);
984 }
985 }
986 childStates.add(new Object[]{null, descendantSavedState});
987 }
988 }
989 else
990 {
991 if (childStates == null)
992 {
993 childEmptyIndex++;
994 }
995 else
996 {
997 childStates.add(LEAF_NO_STATE);
998 }
999 }
1000 }
1001 totalChildCount++;
1002 }
1003 }
1004
1005 if (parent.getChildCount() > 0)
1006 {
1007 for (int i = 0; i < parent.getChildCount(); i++)
1008 {
1009 UIComponent child = parent.getChildren().get(i);
1010 if (!child.isTransient())
1011 {
1012
1013
1014
1015
1016
1017 if (child instanceof EditableValueHolder)
1018 {
1019 if (childStates == null)
1020 {
1021 childStates = new ArrayList<Object[]>(
1022 parent.getFacetCount()
1023 + parent.getChildCount()
1024 - totalChildCount
1025 + childEmptyIndex);
1026 for (int ci = 0; ci < childEmptyIndex; ci++)
1027 {
1028 childStates.add(LEAF_NO_STATE);
1029 }
1030 }
1031
1032 childStates.add(child.getChildCount() > 0 ?
1033 new Object[]{new EditableValueHolderState((EditableValueHolder) child),
1034 saveDescendantComponentStates(child, saveChildFacets, true)} :
1035 new Object[]{new EditableValueHolderState((EditableValueHolder) child),
1036 null});
1037 }
1038 else if (child.getChildCount() > 0 || (saveChildFacets && child.getFacetCount() > 0))
1039 {
1040 Object descendantSavedState = saveDescendantComponentStates(child, saveChildFacets, true);
1041
1042 if (descendantSavedState == null)
1043 {
1044 if (childStates == null)
1045 {
1046 childEmptyIndex++;
1047 }
1048 else
1049 {
1050 childStates.add(LEAF_NO_STATE);
1051 }
1052 }
1053 else
1054 {
1055 if (childStates == null)
1056 {
1057 childStates = new ArrayList<Object[]>(
1058 parent.getFacetCount()
1059 + parent.getChildCount()
1060 - totalChildCount
1061 + childEmptyIndex);
1062 for (int ci = 0; ci < childEmptyIndex; ci++)
1063 {
1064 childStates.add(LEAF_NO_STATE);
1065 }
1066 }
1067 childStates.add(new Object[]{null, descendantSavedState});
1068 }
1069 }
1070 else
1071 {
1072 if (childStates == null)
1073 {
1074 childEmptyIndex++;
1075 }
1076 else
1077 {
1078 childStates.add(LEAF_NO_STATE);
1079 }
1080 }
1081 }
1082 totalChildCount++;
1083 }
1084 }
1085
1086 return childStates;
1087 }
1088
1089
1090
1091 @Override
1092 public void markInitialState()
1093 {
1094 if (isRowStatePreserved() &&
1095 getFacesContext().getAttributes().containsKey(StateManager.IS_BUILDING_INITIAL_STATE))
1096 {
1097 _initialDescendantFullComponentState
1098 = saveDescendantInitialComponentStates(getFacesContext(), getChildren().iterator(), false);
1099 }
1100 super.markInitialState();
1101 }
1102
1103 private void restoreFullDescendantComponentStates(FacesContext facesContext,
1104 Iterator<UIComponent> childIterator, Object initialState,
1105 boolean restoreChildFacets)
1106 {
1107 Iterator<? extends Object[]> descendantStateIterator = null;
1108 while (childIterator.hasNext())
1109 {
1110 if (descendantStateIterator == null && initialState != null)
1111 {
1112 descendantStateIterator = ((Collection<? extends Object[]>) initialState)
1113 .iterator();
1114 }
1115 UIComponent component = childIterator.next();
1116
1117
1118 component.setId(component.getId());
1119 if (!component.isTransient())
1120 {
1121 Object childState = null;
1122 Object descendantState = null;
1123 String childId = null;
1124 if (descendantStateIterator != null
1125 && descendantStateIterator.hasNext())
1126 {
1127 do
1128 {
1129 Object[] object = descendantStateIterator.next();
1130 childState = object[0];
1131 descendantState = object[1];
1132 childId = (String) object[2];
1133 }
1134 while(descendantStateIterator.hasNext() && !component.getId().equals(childId));
1135
1136 if (!component.getId().equals(childId))
1137 {
1138
1139 throw new IllegalStateException("Cannot restore row correctly.");
1140 }
1141 }
1142
1143 component.clearInitialState();
1144 component.restoreState(facesContext, childState);
1145 component.markInitialState();
1146
1147 Iterator<UIComponent> childsIterator;
1148 if (restoreChildFacets)
1149 {
1150 childsIterator = component.getFacetsAndChildren();
1151 }
1152 else
1153 {
1154 childsIterator = component.getChildren().iterator();
1155 }
1156 restoreFullDescendantComponentStates(facesContext, childsIterator,
1157 descendantState, true);
1158 }
1159 }
1160 }
1161
1162 private Collection<Object[]> saveDescendantInitialComponentStates(FacesContext facesContext,
1163 Iterator<UIComponent> childIterator, boolean saveChildFacets)
1164 {
1165 Collection<Object[]> childStates = null;
1166 while (childIterator.hasNext())
1167 {
1168 if (childStates == null)
1169 {
1170 childStates = new ArrayList<Object[]>();
1171 }
1172
1173 UIComponent child = childIterator.next();
1174 if (!child.isTransient())
1175 {
1176
1177
1178
1179
1180
1181 Iterator<UIComponent> childsIterator;
1182 if (saveChildFacets)
1183 {
1184 childsIterator = child.getFacetsAndChildren();
1185 }
1186 else
1187 {
1188 childsIterator = child.getChildren().iterator();
1189 }
1190 Object descendantState = saveDescendantInitialComponentStates(
1191 facesContext, childsIterator, true);
1192 Object state = null;
1193 if (child.initialStateMarked())
1194 {
1195 child.clearInitialState();
1196 state = child.saveState(facesContext);
1197 child.markInitialState();
1198 }
1199 else
1200 {
1201 state = child.saveState(facesContext);
1202 }
1203
1204 childStates.add(new Object[] { state, descendantState, child.getId()});
1205 }
1206 }
1207 return childStates;
1208 }
1209
1210 private Map<String,Object> saveFullDescendantComponentStates(FacesContext facesContext, Map<String,Object> stateMap,
1211 Iterator<UIComponent> childIterator, boolean saveChildFacets)
1212 {
1213 while (childIterator.hasNext())
1214 {
1215 UIComponent child = childIterator.next();
1216 if (!child.isTransient())
1217 {
1218
1219
1220
1221
1222
1223 Iterator<UIComponent> childsIterator;
1224 if (saveChildFacets)
1225 {
1226 childsIterator = child.getFacetsAndChildren();
1227 }
1228 else
1229 {
1230 childsIterator = child.getChildren().iterator();
1231 }
1232 stateMap = saveFullDescendantComponentStates(facesContext, stateMap,
1233 childsIterator, true);
1234 Object state = child.saveState(facesContext);
1235 if (state != null)
1236 {
1237 if (stateMap == null)
1238 {
1239 stateMap = new HashMap<String,Object>();
1240 }
1241 stateMap.put(child.getClientId(facesContext), state);
1242 }
1243 }
1244 }
1245 return stateMap;
1246 }
1247
1248 private void restoreFullDescendantComponentDeltaStates(FacesContext facesContext,
1249 Iterator<UIComponent> childIterator, Map<String, Object> state, Object initialState,
1250 boolean restoreChildFacets)
1251 {
1252 Iterator<? extends Object[]> descendantFullStateIterator = null;
1253 while (childIterator.hasNext())
1254 {
1255 if (descendantFullStateIterator == null && initialState != null)
1256 {
1257 descendantFullStateIterator = ((Collection<? extends Object[]>) initialState).iterator();
1258 }
1259 UIComponent component = childIterator.next();
1260
1261
1262 component.setId(component.getId());
1263 if (!component.isTransient())
1264 {
1265 Object childInitialState = null;
1266 Object descendantInitialState = null;
1267 Object childState = null;
1268 String childId = null;
1269 childState = (state == null) ? null : state.get(component.getClientId(facesContext));
1270 if (descendantFullStateIterator != null
1271 && descendantFullStateIterator.hasNext())
1272 {
1273 do
1274 {
1275 Object[] object = descendantFullStateIterator.next();
1276 childInitialState = object[0];
1277 descendantInitialState = object[1];
1278 childId = (String) object[2];
1279 }while(descendantFullStateIterator.hasNext() && !component.getId().equals(childId));
1280
1281 if (!component.getId().equals(childId))
1282 {
1283
1284 throw new IllegalStateException("Cannot restore row correctly.");
1285 }
1286 }
1287
1288 component.clearInitialState();
1289 if (childInitialState != null)
1290 {
1291 component.restoreState(facesContext, childInitialState);
1292 component.markInitialState();
1293 component.restoreState(facesContext, childState);
1294 }
1295 else
1296 {
1297 component.restoreState(facesContext, childState);
1298 component.markInitialState();
1299 }
1300
1301 Iterator<UIComponent> childsIterator;
1302 if (restoreChildFacets)
1303 {
1304 childsIterator = component.getFacetsAndChildren();
1305 }
1306 else
1307 {
1308 childsIterator = component.getChildren().iterator();
1309 }
1310 restoreFullDescendantComponentDeltaStates(facesContext, childsIterator,
1311 state, descendantInitialState , true);
1312 }
1313 }
1314 }
1315
1316
1317
1318
1319
1320
1321
1322
1323 @SuppressWarnings("unchecked")
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365 private void restoreTransientDescendantComponentStates(FacesContext facesContext,
1366 Iterator<UIComponent> childIterator,
1367 Map<String, Object> state,
1368 boolean restoreChildFacets)
1369 {
1370 while (childIterator.hasNext())
1371 {
1372 UIComponent component = childIterator.next();
1373
1374
1375 component.setId(component.getId());
1376 if (!component.isTransient())
1377 {
1378 component.restoreTransientState(facesContext,
1379 (state == null)
1380 ? null
1381 : state.get(component.getClientId(facesContext)));
1382
1383 Iterator<UIComponent> childsIterator;
1384 if (restoreChildFacets)
1385 {
1386 childsIterator = component.getFacetsAndChildren();
1387 }
1388 else
1389 {
1390 childsIterator = component.getChildren().iterator();
1391 }
1392 restoreTransientDescendantComponentStates(facesContext, childsIterator, state, true);
1393 }
1394 }
1395
1396 }
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449 private Map<String, Object> saveTransientDescendantComponentStates(FacesContext facesContext,
1450 Map<String, Object> childStates,
1451 Iterator<UIComponent> childIterator,
1452 boolean saveChildFacets)
1453 {
1454 while (childIterator.hasNext())
1455 {
1456 UIComponent child = childIterator.next();
1457 if (!child.isTransient())
1458 {
1459 Iterator<UIComponent> childsIterator;
1460 if (saveChildFacets)
1461 {
1462 childsIterator = child.getFacetsAndChildren();
1463 }
1464 else
1465 {
1466 childsIterator = child.getChildren().iterator();
1467 }
1468 childStates = saveTransientDescendantComponentStates(facesContext, childStates, childsIterator, true);
1469 Object state = child.saveTransientState(facesContext);
1470 if (state != null)
1471 {
1472 if (childStates == null)
1473 {
1474 childStates = new HashMap<String, Object>();
1475 }
1476 childStates.put(child.getClientId(facesContext), state);
1477 }
1478 }
1479 }
1480 return childStates;
1481 }
1482
1483 @Override
1484 public void restoreState(FacesContext context, Object state)
1485 {
1486 if (state == null)
1487 {
1488 return;
1489 }
1490
1491 Object values[] = (Object[]) state;
1492 super.restoreState(context, values[0]);
1493 Object restoredRowStates = UIComponentBase.restoreAttachedState(context, values[1]);
1494 if (restoredRowStates == null)
1495 {
1496 if (!_rowDeltaStates.isEmpty())
1497 {
1498 _rowDeltaStates.clear();
1499 }
1500 }
1501 else
1502 {
1503 _rowDeltaStates = (Map<String, Map<String, Object> >) restoredRowStates;
1504 }
1505 if (values.length > 2)
1506 {
1507 Object rs = UIComponentBase.restoreAttachedState(context, values[2]);
1508 if (rs == null)
1509 {
1510 if (!_rowStates.isEmpty())
1511 {
1512 _rowStates.clear();
1513 }
1514 }
1515 else
1516 {
1517 _rowStates = (Map<String, Object>) rs;
1518 }
1519 }
1520 if (values.length > 3)
1521 {
1522 Object rs = UIComponentBase.restoreAttachedState(context, values[3]);
1523 if (rs == null)
1524 {
1525 if (!_rowTransientStates.isEmpty())
1526 {
1527 _rowTransientStates.clear();
1528 }
1529 }
1530 else
1531 {
1532 _rowTransientStates = (Map<String, Map<String, Object> >) rs;
1533 }
1534 }
1535 }
1536
1537 @Override
1538 public Object saveState(FacesContext context)
1539 {
1540 if (context.getViewRoot() != null)
1541 {
1542 if (context.getViewRoot().getResetSaveStateMode() == RESET_MODE_SOFT)
1543 {
1544 _dataModelMap.clear();
1545 _isValidChilds=true;
1546 _rowTransientStates.clear();
1547 }
1548 if (context.getViewRoot().getResetSaveStateMode() == RESET_MODE_HARD)
1549 {
1550 _dataModelMap.clear();
1551 _isValidChilds=true;
1552 _rowTransientStates.clear();
1553 _rowStates.clear();
1554 _rowDeltaStates.clear();
1555 }
1556 }
1557 if (initialStateMarked())
1558 {
1559 Object parentSaved = super.saveState(context);
1560 if (context.getCurrentPhaseId() != null &&
1561 !PhaseId.RENDER_RESPONSE.equals(context.getCurrentPhaseId()))
1562 {
1563 if (parentSaved == null &&_rowDeltaStates.isEmpty() && _rowStates.isEmpty())
1564 {
1565 return null;
1566 }
1567 else
1568 {
1569 Object values[] = new Object[4];
1570 values[0] = super.saveState(context);
1571 values[1] = UIComponentBase.saveAttachedState(context, _rowDeltaStates);
1572 values[2] = UIComponentBase.saveAttachedState(context, _rowStates);
1573 values[3] = UIComponentBase.saveAttachedState(context, _rowTransientStates);
1574 return values;
1575 }
1576 }
1577 else
1578 {
1579 if (parentSaved == null &&_rowDeltaStates.isEmpty())
1580 {
1581 return null;
1582 }
1583 else
1584 {
1585 Object values[] = new Object[2];
1586 values[0] = super.saveState(context);
1587 values[1] = UIComponentBase.saveAttachedState(context, _rowDeltaStates);
1588 return values;
1589 }
1590 }
1591 }
1592 else
1593 {
1594 if (context.getCurrentPhaseId() != null &&
1595 !PhaseId.RENDER_RESPONSE.equals(context.getCurrentPhaseId()))
1596 {
1597 Object values[] = new Object[4];
1598 values[0] = super.saveState(context);
1599 values[1] = UIComponentBase.saveAttachedState(context, _rowDeltaStates);
1600 values[2] = UIComponentBase.saveAttachedState(context, _rowStates);
1601 values[3] = UIComponentBase.saveAttachedState(context, _rowTransientStates);
1602 return values;
1603 }
1604 else
1605 {
1606 Object values[] = new Object[2];
1607 values[0] = super.saveState(context);
1608 values[1] = UIComponentBase.saveAttachedState(context, _rowDeltaStates);
1609 return values;
1610 }
1611 }
1612 }
1613
1614
1615
1616
1617 @Override
1618 public void setValueBinding(String name, ValueBinding binding)
1619 {
1620 if (name == null)
1621 {
1622 throw new NullPointerException("name");
1623 }
1624 else if (name.equals("value"))
1625 {
1626 _dataModelMap.clear();
1627 }
1628 else if (name.equals("rowIndex"))
1629 {
1630 throw new IllegalArgumentException("name " + name);
1631 }
1632 super.setValueBinding(name, binding);
1633 }
1634
1635 @Override
1636 public void setValueExpression(String name, ValueExpression binding)
1637 {
1638 if (name == null)
1639 {
1640 throw new NullPointerException("name");
1641 }
1642 else if (name.equals("value"))
1643 {
1644 _dataModelMap.clear();
1645 }
1646 else if (name.equals("rowIndex"))
1647 {
1648 throw new IllegalArgumentException("name " + name);
1649 }
1650 super.setValueExpression(name, binding);
1651 }
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668 @Override
1669 public String getContainerClientId(FacesContext context)
1670 {
1671
1672 String clientId = super.getContainerClientId(context);
1673
1674 int rowIndex = getRowIndex();
1675 if (rowIndex == -1)
1676 {
1677 return clientId;
1678 }
1679
1680 StringBuilder bld = _getSharedStringBuilder(context);
1681 return bld.append(clientId).append(context.getNamingContainerSeparatorChar()).append(rowIndex).toString();
1682 }
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697 @Override
1698 public void queueEvent(FacesEvent event)
1699 {
1700 if (event == null)
1701 {
1702 throw new NullPointerException("event");
1703 }
1704 super.queueEvent(new FacesEventWrapper(event, getRowIndex(), this));
1705 }
1706
1707
1708
1709
1710
1711
1712
1713 @Override
1714 public void broadcast(FacesEvent event) throws AbortProcessingException
1715 {
1716 if (event instanceof FacesEventWrapper)
1717 {
1718 FacesEvent originalEvent = ((FacesEventWrapper) event).getWrappedFacesEvent();
1719 int eventRowIndex = ((FacesEventWrapper) event).getRowIndex();
1720 final int currentRowIndex = getRowIndex();
1721 UIComponent source = originalEvent.getComponent();
1722 UIComponent compositeParent = UIComponent.getCompositeComponentParent(source);
1723
1724 setRowIndex(eventRowIndex);
1725 if (compositeParent != null)
1726 {
1727 pushComponentToEL(getFacesContext(), compositeParent);
1728 }
1729 pushComponentToEL(getFacesContext(), source);
1730 try
1731 {
1732 source.broadcast(originalEvent);
1733 }
1734 finally
1735 {
1736 source.popComponentFromEL(getFacesContext());
1737 if (compositeParent != null)
1738 {
1739 compositeParent.popComponentFromEL(getFacesContext());
1740 }
1741 setRowIndex(currentRowIndex);
1742 }
1743 }
1744 else
1745 {
1746 super.broadcast(event);
1747 }
1748 }
1749
1750
1751
1752
1753
1754
1755
1756 public String createUniqueId(FacesContext context, String seed)
1757 {
1758 StringBuilder bld = _getSharedStringBuilder(context);
1759
1760
1761
1762 if(seed==null)
1763 {
1764 Long uniqueIdCounter = (Long) getStateHelper().get(PropertyKeys.uniqueIdCounter);
1765 uniqueIdCounter = (uniqueIdCounter == null) ? 0 : uniqueIdCounter;
1766 getStateHelper().put(PropertyKeys.uniqueIdCounter, (uniqueIdCounter+1L));
1767 return bld.append(UIViewRoot.UNIQUE_ID_PREFIX).append(uniqueIdCounter).toString();
1768 }
1769
1770
1771 else
1772 {
1773 return bld.append(UIViewRoot.UNIQUE_ID_PREFIX).append(seed).toString();
1774 }
1775 }
1776
1777
1778
1779
1780
1781 @Override
1782 public void encodeBegin(FacesContext context) throws IOException
1783 {
1784 _initialDescendantComponentState = null;
1785 if (_isValidChilds && !hasErrorMessages(context))
1786 {
1787
1788
1789
1790 _dataModelMap.clear();
1791
1792
1793
1794
1795
1796 if (!isRowStatePreserved())
1797 {
1798 _rowStates.clear();
1799 }
1800 }
1801 super.encodeBegin(context);
1802 }
1803
1804 private boolean hasErrorMessages(FacesContext context)
1805 {
1806
1807
1808 List<FacesMessage> messageList = context.getMessageList();
1809 for (int i = 0, size = messageList.size(); i < size; i++)
1810 {
1811 FacesMessage message = messageList.get(i);
1812 if (FacesMessage.SEVERITY_ERROR.compareTo(message.getSeverity()) <= 0)
1813 {
1814 return true;
1815 }
1816 }
1817 return false;
1818 }
1819
1820
1821
1822
1823 @Override
1824 public void encodeEnd(FacesContext context) throws IOException
1825 {
1826 try
1827 {
1828 setCachedFacesContext(context);
1829 setRowIndex(-1);
1830 }
1831 finally
1832 {
1833 setCachedFacesContext(null);
1834 }
1835 super.encodeEnd(context);
1836 }
1837
1838 @Override
1839 public void processDecodes(FacesContext context)
1840 {
1841 if (context == null)
1842 {
1843 throw new NullPointerException("context");
1844 }
1845 try
1846 {
1847 setCachedFacesContext(context);
1848 pushComponentToEL(context, this);
1849 if (!isRendered())
1850 {
1851 return;
1852 }
1853 setRowIndex(-1);
1854 processFacets(context, PROCESS_DECODES);
1855 processColumnFacets(context, PROCESS_DECODES);
1856 processColumnChildren(context, PROCESS_DECODES);
1857 setRowIndex(-1);
1858 try
1859 {
1860 decode(context);
1861 }
1862 catch (RuntimeException e)
1863 {
1864 context.renderResponse();
1865 throw e;
1866 }
1867 }
1868 finally
1869 {
1870 popComponentFromEL(context);
1871 setCachedFacesContext(null);
1872 }
1873 }
1874
1875 @Override
1876 public void processValidators(FacesContext context)
1877 {
1878 if (context == null)
1879 {
1880 throw new NullPointerException("context");
1881 }
1882
1883 try
1884 {
1885 setCachedFacesContext(context);
1886 pushComponentToEL(context, this);
1887 if (!isRendered())
1888 {
1889 return;
1890 }
1891
1892
1893 context.getApplication().publishEvent(context, PreValidateEvent.class, getClass(), this);
1894
1895 try
1896 {
1897 setRowIndex(-1);
1898 processFacets(context, PROCESS_VALIDATORS);
1899 processColumnFacets(context, PROCESS_VALIDATORS);
1900 processColumnChildren(context, PROCESS_VALIDATORS);
1901 setRowIndex(-1);
1902 }
1903 finally
1904 {
1905 context.getApplication().publishEvent(context, PostValidateEvent.class, getClass(), this);
1906 }
1907
1908
1909 if (context.getRenderResponse())
1910 {
1911 _isValidChilds = false;
1912 }
1913 }
1914 finally
1915 {
1916 popComponentFromEL(context);
1917 setCachedFacesContext(null);
1918 }
1919 }
1920
1921 @Override
1922 public void processUpdates(FacesContext context)
1923 {
1924 if (context == null)
1925 {
1926 throw new NullPointerException("context");
1927 }
1928 try
1929 {
1930 setCachedFacesContext(context);
1931 pushComponentToEL(context, this);
1932 if (!isRendered())
1933 {
1934 return;
1935 }
1936 setRowIndex(-1);
1937 processFacets(context, PROCESS_UPDATES);
1938 processColumnFacets(context, PROCESS_UPDATES);
1939 processColumnChildren(context, PROCESS_UPDATES);
1940 setRowIndex(-1);
1941
1942 if (context.getRenderResponse())
1943 {
1944 _isValidChilds = false;
1945 }
1946 }
1947 finally
1948 {
1949 popComponentFromEL(context);
1950 setCachedFacesContext(null);
1951 }
1952 }
1953
1954 private void processFacets(FacesContext context, int processAction)
1955 {
1956 if (this.getFacetCount() > 0)
1957 {
1958 for (UIComponent facet : getFacets().values())
1959 {
1960 process(context, facet, processAction);
1961 }
1962 }
1963 }
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974 private void processColumnFacets(FacesContext context, int processAction)
1975 {
1976 for (int i = 0, childCount = getChildCount(); i < childCount; i++)
1977 {
1978 UIComponent child = getChildren().get(i);
1979 if (child instanceof UIColumn)
1980 {
1981 if (! _ComponentUtils.isRendered(context, child))
1982 {
1983
1984 continue;
1985 }
1986
1987 if (child.getFacetCount() > 0)
1988 {
1989 for (UIComponent facet : child.getFacets().values())
1990 {
1991 process(context, facet, processAction);
1992 }
1993 }
1994 }
1995 }
1996 }
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007 private void processColumnChildren(FacesContext context, int processAction)
2008 {
2009 int first = getFirst();
2010 int rows = getRows();
2011 int last;
2012 if (rows == 0)
2013 {
2014 last = getRowCount();
2015 }
2016 else
2017 {
2018 last = first + rows;
2019 }
2020 for (int rowIndex = first; last == -1 || rowIndex < last; rowIndex++)
2021 {
2022 setRowIndex(rowIndex);
2023
2024
2025 if (!isRowAvailable())
2026 {
2027 break;
2028 }
2029
2030 for (int i = 0, childCount = getChildCount(); i < childCount; i++)
2031 {
2032 UIComponent child = getChildren().get(i);
2033 if (child instanceof UIColumn)
2034 {
2035 if (! _ComponentUtils.isRendered(context, child))
2036 {
2037
2038 continue;
2039 }
2040 for (int j = 0, columnChildCount = child.getChildCount(); j < columnChildCount; j++)
2041 {
2042 UIComponent columnChild = child.getChildren().get(j);
2043 process(context, columnChild, processAction);
2044 }
2045 }
2046 }
2047 }
2048 }
2049
2050 private void process(FacesContext context, UIComponent component, int processAction)
2051 {
2052 switch (processAction)
2053 {
2054 case PROCESS_DECODES:
2055 component.processDecodes(context);
2056 break;
2057 case PROCESS_VALIDATORS:
2058 component.processValidators(context);
2059 break;
2060 case PROCESS_UPDATES:
2061 component.processUpdates(context);
2062 break;
2063 default:
2064
2065 }
2066 }
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079 protected DataModel getDataModel()
2080 {
2081 DataModel dataModel;
2082 String clientID = "";
2083
2084 UIComponent parent = getParent();
2085 if (parent != null)
2086 {
2087 clientID = parent.getContainerClientId(getFacesContext());
2088 }
2089 dataModel = _dataModelMap.get(clientID);
2090 if (dataModel == null)
2091 {
2092 dataModel = createDataModel();
2093 _dataModelMap.put(clientID, dataModel);
2094 }
2095 return dataModel;
2096 }
2097
2098 protected void setDataModel(DataModel dataModel)
2099 {
2100 String clientID = "";
2101
2102 UIComponent parent = getParent();
2103 if (parent != null)
2104 {
2105 clientID = parent.getContainerClientId(getFacesContext());
2106 }
2107 if (dataModel == null)
2108 {
2109 _dataModelMap.remove(clientID);
2110 }
2111 else
2112 {
2113 _dataModelMap.put(clientID, dataModel);
2114 }
2115 }
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127 private DataModel createDataModel()
2128 {
2129 Object value = getValue();
2130
2131 if (value == null)
2132 {
2133 return EMPTY_DATA_MODEL;
2134 }
2135 else if (value instanceof DataModel)
2136 {
2137 return (DataModel) value;
2138 }
2139 else
2140 {
2141 DataModel dataModel = null;
2142 if (DATAMODEL_BUILDER_CLASS != null && value != null)
2143 {
2144 try
2145 {
2146 Object dataModelBuilderProxy = DATAMODEL_BUILDER_CLASS.newInstance();
2147 dataModel = (DataModel) DATAMODEL_BUILDER_CREATE_DATAMODEL_METHOD.invoke(dataModelBuilderProxy,
2148 getFacesContext(), value.getClass(), value);
2149 }
2150 catch (InstantiationException ex)
2151 {
2152
2153 }
2154 catch (IllegalAccessException ex)
2155 {
2156
2157 }
2158 catch (IllegalArgumentException ex)
2159 {
2160
2161 }
2162 catch (InvocationTargetException ex)
2163 {
2164
2165 }
2166 }
2167 if (dataModel == null)
2168 {
2169 if (value instanceof List)
2170 {
2171 return new ListDataModel((List<?>) value);
2172 }
2173 else if (OBJECT_ARRAY_CLASS.isAssignableFrom(value.getClass()))
2174 {
2175 return new ArrayDataModel((Object[]) value);
2176 }
2177 else if (value instanceof ResultSet)
2178 {
2179 return new ResultSetDataModel((ResultSet) value);
2180 }
2181 else if (value instanceof Result)
2182 {
2183 return new ResultDataModel((Result) value);
2184 }
2185 else if (value instanceof Iterable)
2186 {
2187 return new IterableDataModel<>((Iterable<?>) value);
2188 }
2189 else if (value instanceof Map)
2190 {
2191 return new IterableDataModel<>(((Map<?, ?>) value).entrySet());
2192 }
2193 else if (value instanceof Collection)
2194 {
2195 return new CollectionDataModel((Collection) value);
2196 }
2197 else
2198 {
2199 return new ScalarDataModel(value);
2200 }
2201 }
2202 else
2203 {
2204 return dataModel;
2205 }
2206 }
2207 }
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226 @JSFProperty
2227 public Object getValue()
2228 {
2229 return getStateHelper().eval(PropertyKeys.value);
2230 }
2231
2232 public void setValue(Object value)
2233 {
2234 getStateHelper().put(PropertyKeys.value, value );
2235 _dataModelMap.clear();
2236 _rowStates.clear();
2237 _isValidChilds = true;
2238 }
2239
2240
2241
2242
2243 @JSFProperty
2244 public int getFirst()
2245 {
2246 return (Integer) getStateHelper().eval(PropertyKeys.first,0);
2247 }
2248
2249 public void setFirst(int first)
2250 {
2251 if (first < 0)
2252 {
2253 throw new IllegalArgumentException("Illegal value for first row: " + first);
2254 }
2255 getStateHelper().put(PropertyKeys.first, first );
2256 }
2257
2258
2259
2260
2261
2262
2263
2264 @JSFProperty
2265 public int getRows()
2266 {
2267 return (Integer) getStateHelper().eval(PropertyKeys.rows,0);
2268 }
2269
2270
2271
2272
2273 public void setRows(int rows)
2274 {
2275 if (rows < 0)
2276 {
2277 throw new IllegalArgumentException("rows: " + rows);
2278 }
2279 getStateHelper().put(PropertyKeys.rows, rows );
2280 }
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292 @JSFProperty(literalOnly = true)
2293 public String getVar()
2294 {
2295 return (String) getStateHelper().get(PropertyKeys.var);
2296 }
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310 @Override
2311 public boolean visitTree(VisitContext context, VisitCallback callback)
2312 {
2313
2314 pushComponentToEL(context.getFacesContext(), this);
2315 try
2316 {
2317 if (!isVisitable(context))
2318 {
2319 return false;
2320 }
2321
2322 boolean isCachedFacesContext = isCachedFacesContext();
2323 if (!isCachedFacesContext)
2324 {
2325 setCachedFacesContext(context.getFacesContext());
2326 }
2327
2328 int oldRowIndex = getRowIndex();
2329
2330 setRowIndex(-1);
2331 try
2332 {
2333 VisitResult visitResult = context.invokeVisitCallback(this,
2334 callback);
2335 switch (visitResult)
2336 {
2337
2338 case COMPLETE:
2339 return true;
2340
2341 case REJECT:
2342 return false;
2343
2344
2345 default:
2346
2347 Collection<String> subtreeIdsToVisit = context
2348 .getSubtreeIdsToVisit(this);
2349 boolean doVisitChildren = subtreeIdsToVisit != null
2350 && !subtreeIdsToVisit.isEmpty();
2351 if (doVisitChildren)
2352 {
2353
2354 if (getFacetCount() > 0)
2355 {
2356 for (UIComponent facet : getFacets().values())
2357 {
2358 if (facet.visitTree(context, callback))
2359 {
2360 return true;
2361 }
2362 }
2363 }
2364
2365 boolean skipIterationHint = context.getHints().contains(VisitHint.SKIP_ITERATION);
2366 if (skipIterationHint)
2367 {
2368
2369 for (int i = 0, childCount = getChildCount(); i < childCount; i++ )
2370 {
2371 UIComponent child = getChildren().get(i);
2372 if (child.visitTree(context, callback))
2373 {
2374 return true;
2375 }
2376 }
2377 }
2378 else
2379 {
2380
2381
2382
2383 for (int i = 0, childCount = getChildCount(); i < childCount; i++)
2384 {
2385 UIComponent child = getChildren().get(i);
2386 if (child instanceof UIColumn)
2387 {
2388 VisitResult columnResult = context.invokeVisitCallback(child, callback);
2389 if (columnResult == VisitResult.COMPLETE)
2390 {
2391 return true;
2392 }
2393 if (child.getFacetCount() > 0)
2394 {
2395 for (UIComponent facet : child.getFacets().values())
2396 {
2397 if (facet.visitTree(context, callback))
2398 {
2399 return true;
2400 }
2401 }
2402 }
2403 }
2404 }
2405
2406 int rowsToProcess = getRows();
2407
2408 if (rowsToProcess == 0)
2409 {
2410 rowsToProcess = getRowCount();
2411 }
2412 int rowIndex = getFirst();
2413 for (int rowsProcessed = 0; rowsProcessed < rowsToProcess; rowsProcessed++, rowIndex++)
2414 {
2415 setRowIndex(rowIndex);
2416 if (!isRowAvailable())
2417 {
2418 return false;
2419 }
2420
2421 for (int i = 0, childCount = getChildCount(); i < childCount; i++)
2422 {
2423 UIComponent child = getChildren().get(i);
2424 if (child instanceof UIColumn)
2425 {
2426 for (int j = 0, grandChildCount = child.getChildCount();
2427 j < grandChildCount; j++)
2428 {
2429 UIComponent grandchild = child.getChildren().get(j);
2430 if (grandchild.visitTree(context, callback))
2431 {
2432 return true;
2433 }
2434 }
2435 }
2436 }
2437 }
2438 }
2439 }
2440 }
2441 }
2442 finally
2443 {
2444
2445 setRowIndex(oldRowIndex);
2446 if (!isCachedFacesContext)
2447 {
2448 setCachedFacesContext(null);
2449 }
2450 }
2451 }
2452 finally
2453 {
2454
2455 popComponentFromEL(context.getFacesContext());
2456 }
2457
2458 return false;
2459 }
2460
2461 public void setVar(String var)
2462 {
2463 getStateHelper().put(PropertyKeys.var, var );
2464 }
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478 @JSFProperty(literalOnly=true, faceletsOnly=true)
2479 public boolean isRowStatePreserved()
2480 {
2481 Boolean b = (Boolean) getStateHelper().get(PropertyKeys.rowStatePreserved);
2482 return b == null ? false : b.booleanValue();
2483 }
2484
2485 public void setRowStatePreserved(boolean preserveComponentState)
2486 {
2487 getStateHelper().put(PropertyKeys.rowStatePreserved, preserveComponentState);
2488 }
2489
2490 enum PropertyKeys
2491 {
2492 value
2493 , first
2494 , rows
2495 , var
2496 , uniqueIdCounter
2497 , rowStatePreserved
2498 }
2499
2500 @Override
2501 public String getFamily()
2502 {
2503 return COMPONENT_FAMILY;
2504 }
2505 }