1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.myfaces.view.facelets.component;
20
21 import java.io.IOException;
22 import java.io.Serializable;
23 import java.sql.ResultSet;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.List;
30 import java.util.Map;
31
32 import javax.el.ValueExpression;
33 import javax.faces.FacesException;
34 import javax.faces.application.FacesMessage;
35 import javax.faces.component.ContextCallback;
36 import javax.faces.component.EditableValueHolder;
37 import javax.faces.component.NamingContainer;
38 import javax.faces.component.UIComponent;
39 import javax.faces.component.UIComponentBase;
40 import javax.faces.component.UINamingContainer;
41 import javax.faces.component.visit.VisitCallback;
42 import javax.faces.component.visit.VisitContext;
43 import javax.faces.component.visit.VisitHint;
44 import javax.faces.component.visit.VisitResult;
45 import javax.faces.context.FacesContext;
46 import javax.faces.event.AbortProcessingException;
47 import javax.faces.event.FacesEvent;
48 import javax.faces.event.FacesListener;
49 import javax.faces.event.PhaseId;
50 import javax.faces.model.ArrayDataModel;
51 import javax.faces.model.DataModel;
52 import javax.faces.model.ListDataModel;
53 import javax.faces.model.ResultSetDataModel;
54 import javax.faces.model.ScalarDataModel;
55 import javax.faces.render.Renderer;
56
57 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFComponent;
58 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFProperty;
59
60
61
62
63 @JSFComponent(name="ui:repeat", defaultRendererType="facelets.ui.Repeat")
64 public class UIRepeat extends UIComponentBase implements NamingContainer
65 {
66 public static final String COMPONENT_TYPE = "facelets.ui.Repeat";
67
68 public static final String COMPONENT_FAMILY = "facelets";
69
70
71
72 private final static DataModel<?> EMPTY_MODEL = new ListDataModel<Object>(Collections.emptyList());
73
74 private static final Class<Object[]> OBJECT_ARRAY_CLASS = Object[].class;
75
76 private static final Object[] LEAF_NO_STATE = new Object[]{null,null};
77
78 private Object _initialDescendantComponentState = null;
79
80
81
82
83 private Map<String, Collection<Object[]>> _rowStates = new HashMap<String, Collection<Object[]>>();
84
85
86
87
88
89
90 private Map<String, DataModel> _dataModelMap = new HashMap<String, DataModel>();
91
92
93 private boolean _isValidChilds = true;
94
95 private int _end = -1;
96
97 private int _count;
98
99 private int _index = -1;
100
101 private transient StringBuilder _clientIdBuffer;
102 private transient Object _origValue;
103 private transient Object _origVarStatus;
104
105 private transient FacesContext _facesContext;
106
107 public UIRepeat()
108 {
109 setRendererType("facelets.ui.Repeat");
110 }
111
112 public String getFamily()
113 {
114 return COMPONENT_FAMILY;
115 }
116
117 @JSFProperty
118 public int getOffset()
119 {
120 return (Integer) getStateHelper().eval(PropertyKeys.offset, 0);
121 }
122
123 public void setOffset(int offset)
124 {
125 getStateHelper().put(PropertyKeys.offset, offset );
126 }
127
128 @JSFProperty
129 public int getSize()
130 {
131 return (Integer) getStateHelper().eval(PropertyKeys.size, -1);
132 }
133
134 public void setSize(int size)
135 {
136 getStateHelper().put(PropertyKeys.size, size );
137 }
138
139 @JSFProperty
140 public int getStep()
141 {
142 return (Integer) getStateHelper().eval(PropertyKeys.step, 1);
143 }
144
145 public void setStep(int step)
146 {
147 getStateHelper().put(PropertyKeys.step, step );
148 }
149
150 @JSFProperty(literalOnly=true)
151 public String getVar()
152 {
153 return (String) getStateHelper().get(PropertyKeys.var);
154 }
155
156 public void setVar(String var)
157 {
158 getStateHelper().put(PropertyKeys.var, var );
159 }
160
161 @JSFProperty(literalOnly=true)
162 public String getVarStatus ()
163 {
164 return (String) getStateHelper().get(PropertyKeys.varStatus);
165 }
166
167 public void setVarStatus (String varStatus)
168 {
169 getStateHelper().put(PropertyKeys.varStatus, varStatus );
170 }
171
172 protected DataModel getDataModel()
173 {
174 DataModel dataModel;
175 String clientID = "";
176
177 UIComponent parent = getParent();
178 if (parent != null)
179 {
180 clientID = parent.getContainerClientId(getFacesContext());
181 }
182 dataModel = _dataModelMap.get(clientID);
183 if (dataModel == null)
184 {
185 dataModel = createDataModel();
186 _dataModelMap.put(clientID, dataModel);
187 }
188 return dataModel;
189 }
190
191 private DataModel createDataModel()
192 {
193 Object value = getValue();
194
195 if (value == null)
196 {
197 return EMPTY_MODEL;
198 }
199 else if (value instanceof DataModel)
200 {
201 return (DataModel) value;
202 }
203 else if (value instanceof List)
204 {
205 return new ListDataModel((List<?>) value);
206 }
207 else if (OBJECT_ARRAY_CLASS.isAssignableFrom(value.getClass()))
208 {
209 return new ArrayDataModel((Object[]) value);
210 }
211 else if (value instanceof ResultSet)
212 {
213 return new ResultSetDataModel((ResultSet) value);
214 }
215 else
216 {
217 return new ScalarDataModel(value);
218 }
219 }
220
221 @Override
222 public void setValueExpression(String name, ValueExpression binding)
223 {
224 if (name == null)
225 {
226 throw new NullPointerException("name");
227 }
228 else if (name.equals("value"))
229 {
230 _dataModelMap.clear();
231 }
232 else if (name.equals("rowIndex"))
233 {
234 throw new IllegalArgumentException("name " + name);
235 }
236 super.setValueExpression(name, binding);
237 }
238
239 @JSFProperty
240 public Object getValue()
241 {
242 return getStateHelper().eval(PropertyKeys.value);
243 }
244
245 public void setValue(Object value)
246 {
247 getStateHelper().put(PropertyKeys.value, value);
248 _dataModelMap.clear();
249 _rowStates.clear();
250 _isValidChilds = true;
251 }
252
253 @Override
254 public String getContainerClientId(FacesContext context)
255 {
256
257 String clientId = super.getContainerClientId(context);
258
259 int index = getIndex();
260 if (index == -1)
261 {
262 return clientId;
263 }
264
265 StringBuilder bld = _getBuffer();
266 return bld.append(clientId).append(UINamingContainer.getSeparatorChar(context)).append(index).toString();
267 }
268
269 private RepeatStatus _getRepeatStatus()
270 {
271 return new RepeatStatus(_count == 0, _index + getStep() >= getDataModel().getRowCount(),
272 _count, _index, getOffset(), _end, getStep());
273 }
274
275 private void _captureScopeValues()
276 {
277 String var = getVar();
278 if (var != null)
279 {
280 _origValue = getFacesContext().getExternalContext().getRequestMap().get(var);
281 }
282 String varStatus = getVarStatus();
283 if (varStatus != null)
284 {
285 _origVarStatus = getFacesContext().getExternalContext().getRequestMap().get(varStatus);
286 }
287 }
288
289 private StringBuilder _getBuffer()
290 {
291 if (_clientIdBuffer == null)
292 {
293 _clientIdBuffer = new StringBuilder();
294 }
295
296 _clientIdBuffer.setLength(0);
297
298 return _clientIdBuffer;
299 }
300
301 private boolean _isIndexAvailable()
302 {
303 return getDataModel().isRowAvailable();
304 }
305
306 private void _restoreScopeValues()
307 {
308 String var = getVar();
309 if (var != null)
310 {
311 Map<String, Object> attrs = getFacesContext().getExternalContext().getRequestMap();
312 if (_origValue != null)
313 {
314 attrs.put(var, _origValue);
315 _origValue = null;
316 }
317 else
318 {
319 attrs.remove(var);
320 }
321 }
322 String varStatus = getVarStatus();
323 if (getVarStatus() != null)
324 {
325 Map<String, Object> attrs = getFacesContext().getExternalContext().getRequestMap();
326 if (_origVarStatus != null)
327 {
328 attrs.put(varStatus, _origVarStatus);
329 _origVarStatus = null;
330 }
331 else
332 {
333 attrs.remove(varStatus);
334 }
335 }
336 }
337
338
339
340
341
342
343
344
345 @SuppressWarnings("unchecked")
346 private void restoreDescendantComponentStates(UIComponent parent, boolean iterateFacets, Object state,
347 boolean restoreChildFacets)
348 {
349 int descendantStateIndex = -1;
350 List<? extends Object[]> stateCollection = null;
351
352 if (iterateFacets && parent.getFacetCount() > 0)
353 {
354 Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
355
356 while (childIterator.hasNext())
357 {
358 UIComponent component = childIterator.next();
359
360
361 component.setId(component.getId());
362 if (!component.isTransient())
363 {
364 if (descendantStateIndex == -1)
365 {
366 stateCollection = ((List<? extends Object[]>) state);
367 descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
368 }
369
370 if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size())
371 {
372 Object[] object = stateCollection.get(descendantStateIndex);
373 if (object[0] != null && component instanceof EditableValueHolder)
374 {
375 ((SavedState) object[0]).restoreState((EditableValueHolder) component);
376 }
377
378
379 if (object[1] != null)
380 {
381 restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
382 }
383 else
384 {
385 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
386 }
387 }
388 else
389 {
390 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
391 }
392 descendantStateIndex++;
393 }
394 }
395 }
396
397 if (parent.getChildCount() > 0)
398 {
399 for (int i = 0; i < parent.getChildCount(); i++)
400 {
401 UIComponent component = parent.getChildren().get(i);
402
403
404 component.setId(component.getId());
405 if (!component.isTransient())
406 {
407 if (descendantStateIndex == -1)
408 {
409 stateCollection = ((List<? extends Object[]>) state);
410 descendantStateIndex = stateCollection.isEmpty() ? -1 : 0;
411 }
412
413 if (descendantStateIndex != -1 && descendantStateIndex < stateCollection.size())
414 {
415 Object[] object = stateCollection.get(descendantStateIndex);
416 if (object[0] != null && component instanceof EditableValueHolder)
417 {
418 ((SavedState) object[0]).restoreState((EditableValueHolder) component);
419 }
420
421
422 if (object[1] != null)
423 {
424 restoreDescendantComponentStates(component, restoreChildFacets, object[1], true);
425 }
426 else
427 {
428 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
429 }
430 }
431 else
432 {
433 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
434 }
435 descendantStateIndex++;
436 }
437 }
438 }
439 }
440
441
442
443
444
445
446
447
448
449
450 private void restoreDescendantComponentWithoutRestoreState(UIComponent parent, boolean iterateFacets,
451 boolean restoreChildFacets)
452 {
453 if (iterateFacets && parent.getFacetCount() > 0)
454 {
455 Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
456
457 while (childIterator.hasNext())
458 {
459 UIComponent component = childIterator.next();
460
461
462 component.setId(component.getId());
463 if (!component.isTransient())
464 {
465 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
466 }
467 }
468 }
469
470 if (parent.getChildCount() > 0)
471 {
472 for (int i = 0; i < parent.getChildCount(); i++)
473 {
474 UIComponent component = parent.getChildren().get(i);
475
476
477 component.setId(component.getId());
478 if (!component.isTransient())
479 {
480 restoreDescendantComponentWithoutRestoreState(component, restoreChildFacets, true);
481 }
482 }
483 }
484 }
485
486
487
488
489
490
491
492
493
494
495
496
497
498 private Collection<Object[]> saveDescendantComponentStates(UIComponent parent, boolean iterateFacets,
499 boolean saveChildFacets)
500 {
501 Collection<Object[]> childStates = null;
502
503 int childEmptyIndex = 0;
504 int totalChildCount = 0;
505
506 if (iterateFacets && parent.getFacetCount() > 0)
507 {
508 Iterator<UIComponent> childIterator = parent.getFacets().values().iterator();
509
510 while (childIterator.hasNext())
511 {
512 UIComponent child = childIterator.next();
513 if (!child.isTransient())
514 {
515
516
517
518
519
520 if (child instanceof EditableValueHolder)
521 {
522 if (childStates == null)
523 {
524 childStates = new ArrayList<Object[]>(
525 parent.getFacetCount()
526 + parent.getChildCount()
527 - totalChildCount
528 + childEmptyIndex);
529 for (int ci = 0; ci < childEmptyIndex; ci++)
530 {
531 childStates.add(LEAF_NO_STATE);
532 }
533 }
534
535 childStates.add(child.getChildCount() > 0 ?
536 new Object[]{new SavedState((EditableValueHolder) child),
537 saveDescendantComponentStates(child, saveChildFacets, true)} :
538 new Object[]{new SavedState((EditableValueHolder) child),
539 null});
540 }
541 else if (child.getChildCount() > 0 || (saveChildFacets && child.getFacetCount() > 0))
542 {
543 Object descendantSavedState = saveDescendantComponentStates(child, saveChildFacets, true);
544
545 if (descendantSavedState == null)
546 {
547 if (childStates == null)
548 {
549 childEmptyIndex++;
550 }
551 else
552 {
553 childStates.add(LEAF_NO_STATE);
554 }
555 }
556 else
557 {
558 if (childStates == null)
559 {
560 childStates = new ArrayList<Object[]>(
561 parent.getFacetCount()
562 + parent.getChildCount()
563 - totalChildCount
564 + childEmptyIndex);
565 for (int ci = 0; ci < childEmptyIndex; ci++)
566 {
567 childStates.add(LEAF_NO_STATE);
568 }
569 }
570 childStates.add(new Object[]{null, descendantSavedState});
571 }
572 }
573 else
574 {
575 if (childStates == null)
576 {
577 childEmptyIndex++;
578 }
579 else
580 {
581 childStates.add(LEAF_NO_STATE);
582 }
583 }
584 }
585 totalChildCount++;
586 }
587 }
588
589 if (parent.getChildCount() > 0)
590 {
591 for (int i = 0; i < parent.getChildCount(); i++)
592 {
593 UIComponent child = parent.getChildren().get(i);
594 if (!child.isTransient())
595 {
596
597
598
599
600
601 if (child instanceof EditableValueHolder)
602 {
603 if (childStates == null)
604 {
605 childStates = new ArrayList<Object[]>(
606 parent.getFacetCount()
607 + parent.getChildCount()
608 - totalChildCount
609 + childEmptyIndex);
610 for (int ci = 0; ci < childEmptyIndex; ci++)
611 {
612 childStates.add(LEAF_NO_STATE);
613 }
614 }
615
616 childStates.add(child.getChildCount() > 0 ?
617 new Object[]{new SavedState((EditableValueHolder) child),
618 saveDescendantComponentStates(child, saveChildFacets, true)} :
619 new Object[]{new SavedState((EditableValueHolder) child),
620 null});
621 }
622 else if (child.getChildCount() > 0 || (saveChildFacets && child.getFacetCount() > 0))
623 {
624 Object descendantSavedState = saveDescendantComponentStates(child, saveChildFacets, true);
625
626 if (descendantSavedState == null)
627 {
628 if (childStates == null)
629 {
630 childEmptyIndex++;
631 }
632 else
633 {
634 childStates.add(LEAF_NO_STATE);
635 }
636 }
637 else
638 {
639 if (childStates == null)
640 {
641 childStates = new ArrayList<Object[]>(
642 parent.getFacetCount()
643 + parent.getChildCount()
644 - totalChildCount
645 + childEmptyIndex);
646 for (int ci = 0; ci < childEmptyIndex; ci++)
647 {
648 childStates.add(LEAF_NO_STATE);
649 }
650 }
651 childStates.add(new Object[]{null, descendantSavedState});
652 }
653 }
654 else
655 {
656 if (childStates == null)
657 {
658 childEmptyIndex++;
659 }
660 else
661 {
662 childStates.add(LEAF_NO_STATE);
663 }
664 }
665 }
666 totalChildCount++;
667 }
668 }
669
670 return childStates;
671 }
672
673
674
675
676
677 public int getRowCount()
678 {
679 return getDataModel().getRowCount();
680 }
681
682
683
684
685 public int getIndex()
686 {
687 return _index;
688 }
689
690 private void _setIndex(int index)
691 {
692
693
694 if (index < -1)
695 {
696 throw new IllegalArgumentException("rowIndex is less than -1");
697 }
698
699 if (_index == index)
700 {
701 return;
702 }
703
704 FacesContext facesContext = getFacesContext();
705
706 if (_index == -1)
707 {
708 if (_initialDescendantComponentState == null)
709 {
710
711
712
713
714 _initialDescendantComponentState = saveDescendantComponentStates(this, true, true);
715 }
716 }
717 else
718 {
719
720
721
722 if (_initialDescendantComponentState != null)
723 {
724
725
726
727
728 Collection<Object[]> savedRowState = saveDescendantComponentStates(this, true, true);
729 if (savedRowState != null)
730 {
731 _rowStates.put(getContainerClientId(facesContext), savedRowState);
732 }
733 }
734 }
735
736 _index = index;
737
738 DataModel<?> localModel = getDataModel();
739 localModel.setRowIndex(index);
740
741 if (_index != -1)
742 {
743 String var = getVar();
744 if (var != null && localModel.isRowAvailable())
745 {
746 getFacesContext().getExternalContext().getRequestMap()
747 .put(var, localModel.getRowData());
748 }
749 String varStatus = getVarStatus();
750 if (varStatus != null)
751 {
752 getFacesContext().getExternalContext().getRequestMap()
753 .put(varStatus, _getRepeatStatus());
754 }
755 }
756
757
758
759
760 if (_index == -1)
761 {
762
763
764 if (_initialDescendantComponentState != null)
765 {
766 restoreDescendantComponentStates(this, true, _initialDescendantComponentState, true);
767 }
768 else
769 {
770 restoreDescendantComponentWithoutRestoreState(this, true, true);
771 }
772 }
773 else
774 {
775 Object rowState = _rowStates.get(getContainerClientId(facesContext));
776 if (rowState == null)
777 {
778
779
780
781
782 if (_initialDescendantComponentState != null)
783 {
784 restoreDescendantComponentStates(this, true, _initialDescendantComponentState, true);
785 }
786 else
787 {
788 restoreDescendantComponentWithoutRestoreState(this, true, true);
789 }
790 }
791 else
792 {
793
794
795
796
797 restoreDescendantComponentStates(this, true, rowState, true);
798 }
799 }
800 }
801
802
803
804
805
806
807 private int _calculateCountForIndex(int index)
808 {
809 return (index - getOffset()) / getStep();
810 }
811
812 private void _validateAttributes() throws FacesException
813 {
814 int begin = getOffset();
815 int end = getDataModel().getRowCount();
816 int size = getSize();
817 int step = getStep();
818 boolean sizeIsEnd = false;
819
820 if (size == -1)
821 {
822 size = end;
823 sizeIsEnd = true;
824 }
825
826 if (end >= 0)
827 {
828 if (size < 0)
829 {
830 throw new FacesException("iteration size cannot be less " +
831 "than zero");
832 }
833
834 else if (!sizeIsEnd && (begin + size) > end)
835 {
836 throw new FacesException("iteration size cannot be greater " +
837 "than collection size");
838 }
839 }
840
841 if ((size > -1) && (begin > end))
842 {
843 throw new FacesException("iteration offset cannot be greater " +
844 "than collection size");
845 }
846
847 if (step == -1)
848 {
849 setStep(1);
850 }
851
852 if (step < 0)
853 {
854 throw new FacesException("iteration step size cannot be less " +
855 "than zero");
856 }
857
858 else if (step == 0)
859 {
860 throw new FacesException("iteration step size cannot be equal " +
861 "to zero");
862 }
863
864 _end = size;
865
866 }
867
868 public void process(FacesContext faces, PhaseId phase)
869 {
870
871 if (!isRendered())
872 {
873 return;
874 }
875
876
877 _validateAttributes();
878
879
880 _captureScopeValues();
881 _setIndex(-1);
882
883 try
884 {
885
886 if (getChildCount() > 0)
887 {
888 int i = getOffset();
889 int end = getSize();
890 int step = getStep();
891 end = (end >= 0) ? i + end : Integer.MAX_VALUE - 1;
892
893
894 String rendererType = getRendererType();
895 Renderer renderer = null;
896 if (rendererType != null)
897 {
898 renderer = getRenderer(faces);
899 }
900
901 _count = 0;
902
903 _setIndex(i);
904 while (i <= end && _isIndexAvailable())
905 {
906
907 if (PhaseId.RENDER_RESPONSE.equals(phase) && renderer != null)
908 {
909 renderer.encodeChildren(faces, this);
910 }
911 else
912 {
913 for (int j = 0, childCount = getChildCount(); j < childCount; j++)
914 {
915 UIComponent child = getChildren().get(j);
916 if (PhaseId.APPLY_REQUEST_VALUES.equals(phase))
917 {
918 child.processDecodes(faces);
919 }
920 else if (PhaseId.PROCESS_VALIDATIONS.equals(phase))
921 {
922 child.processValidators(faces);
923 }
924 else if (PhaseId.UPDATE_MODEL_VALUES.equals(phase))
925 {
926 child.processUpdates(faces);
927 }
928 else if (PhaseId.RENDER_RESPONSE.equals(phase))
929 {
930 child.encodeAll(faces);
931 }
932 }
933 }
934
935 ++_count;
936
937 i += step;
938
939 _setIndex(i);
940 }
941 }
942 }
943 catch (IOException e)
944 {
945 throw new FacesException(e);
946 }
947 finally
948 {
949 _setIndex(-1);
950 _restoreScopeValues();
951 }
952 }
953
954 @Override
955 public boolean invokeOnComponent(FacesContext context, String clientId,
956 ContextCallback callback) throws FacesException
957 {
958 if (context == null || clientId == null || callback == null)
959 {
960 throw new NullPointerException();
961 }
962
963 final String baseClientId = getClientId(context);
964
965
966 boolean returnValue = baseClientId.equals(clientId);
967
968 boolean isCachedFacesContext = isTemporalFacesContext();
969 if (!isCachedFacesContext)
970 {
971 setTemporalFacesContext(context);
972 }
973
974 pushComponentToEL(context, this);
975 try
976 {
977 if (returnValue)
978 {
979 try
980 {
981 callback.invokeContextCallback(context, this);
982 return true;
983 }
984 catch (Exception e)
985 {
986 throw new FacesException(e);
987 }
988 }
989
990
991 if (this.getFacetCount() > 0)
992 {
993 for (Iterator<UIComponent> it = this.getFacets().values().iterator(); !returnValue && it.hasNext();)
994 {
995 returnValue = it.next().invokeOnComponent(context, clientId, callback);
996 }
997 }
998
999 if (returnValue)
1000 {
1001 return returnValue;
1002 }
1003
1004
1005 if (clientId.startsWith(baseClientId))
1006 {
1007
1008
1009 char separator = UINamingContainer.getSeparatorChar(context);
1010 String subId = clientId.substring(baseClientId.length() + 1);
1011
1012
1013 if (clientId.charAt(baseClientId.length()) == separator &&
1014 subId.matches("[0-9]+"+separator+".*"))
1015 {
1016 String clientRow = subId.substring(0, subId.indexOf(separator));
1017
1018
1019 final int prevIndex = _index;
1020 final int prevCount = _count;
1021
1022 try
1023 {
1024 int invokeIndex = Integer.parseInt(clientRow);
1025
1026 _captureScopeValues();
1027 if (invokeIndex != -1)
1028 {
1029
1030 _count = _calculateCountForIndex(invokeIndex);
1031 }
1032 _setIndex(invokeIndex);
1033
1034 if (!_isIndexAvailable())
1035 {
1036 return false;
1037 }
1038
1039 for (Iterator<UIComponent> it1 = getChildren().iterator();
1040 !returnValue && it1.hasNext();)
1041 {
1042
1043 returnValue = it1.next().invokeOnComponent(context, clientId, callback);
1044 }
1045 }
1046 finally
1047 {
1048
1049 _count = prevCount;
1050 _setIndex(prevIndex);
1051 _restoreScopeValues();
1052 }
1053 }
1054 else
1055 {
1056
1057 if (this.getChildCount() > 0)
1058 {
1059
1060 for (Iterator<UIComponent> it = this.getChildren().iterator(); !returnValue && it.hasNext();)
1061 {
1062 returnValue = it.next().invokeOnComponent(context, clientId, callback);
1063 }
1064 }
1065 }
1066 }
1067 }
1068 finally
1069 {
1070
1071 popComponentFromEL(context);
1072 if (!isCachedFacesContext)
1073 {
1074 setTemporalFacesContext(null);
1075 }
1076 }
1077
1078 return returnValue;
1079 }
1080
1081 @Override
1082 protected FacesContext getFacesContext()
1083 {
1084 if (_facesContext == null)
1085 {
1086 return super.getFacesContext();
1087 }
1088 else
1089 {
1090 return _facesContext;
1091 }
1092 }
1093
1094 private boolean isTemporalFacesContext()
1095 {
1096 return _facesContext != null;
1097 }
1098
1099 private void setTemporalFacesContext(FacesContext facesContext)
1100 {
1101 _facesContext = facesContext;
1102 }
1103
1104 @Override
1105 public boolean visitTree(VisitContext context, VisitCallback callback)
1106 {
1107
1108
1109
1110
1111 Boolean skipIterationHint = context.getHints().contains(VisitHint.SKIP_ITERATION);
1112 if (skipIterationHint != null && skipIterationHint.booleanValue())
1113 {
1114 return super.visitTree(context, callback);
1115 }
1116
1117 if (!isVisitable(context))
1118 {
1119 return false;
1120 }
1121
1122
1123 final int prevIndex = _index;
1124 final int prevCount = _count;
1125
1126
1127 _validateAttributes();
1128
1129
1130 _captureScopeValues();
1131 _setIndex(-1);
1132
1133
1134 pushComponentToEL(context.getFacesContext(), this);
1135 try
1136 {
1137 VisitResult res = context.invokeVisitCallback(this, callback);
1138 switch (res)
1139 {
1140
1141 case COMPLETE:
1142 return true;
1143
1144 case REJECT:
1145 return false;
1146
1147
1148 default:
1149
1150
1151 Collection<String> subtreeIdsToVisit = context
1152 .getSubtreeIdsToVisit(this);
1153 boolean doVisitChildren = subtreeIdsToVisit != null
1154 && !subtreeIdsToVisit.isEmpty();
1155 if (doVisitChildren)
1156 {
1157
1158 if (getFacetCount() > 0)
1159 {
1160 for (UIComponent facet : getFacets().values())
1161 {
1162 if (facet.visitTree(context, callback))
1163 {
1164 return true;
1165 }
1166 }
1167 }
1168
1169
1170 if (getChildCount() > 0)
1171 {
1172 int i = getOffset();
1173 int end = getSize();
1174 int step = getStep();
1175 end = (end >= 0) ? i + end : Integer.MAX_VALUE - 1;
1176 _count = 0;
1177
1178 _setIndex(i);
1179 while (i <= end && _isIndexAvailable())
1180 {
1181 for (int j = 0, childCount = getChildCount(); j < childCount; j++)
1182 {
1183 UIComponent child = getChildren().get(j);
1184 if (child.visitTree(context, callback))
1185 {
1186 return true;
1187 }
1188 }
1189
1190 _count++;
1191 i += step;
1192
1193 _setIndex(i);
1194 }
1195 }
1196 }
1197 return false;
1198 }
1199 }
1200 finally
1201 {
1202
1203 popComponentFromEL(context.getFacesContext());
1204
1205
1206 _count = prevCount;
1207 _setIndex(prevIndex);
1208 _restoreScopeValues();
1209 }
1210 }
1211
1212 @Override
1213 public void processDecodes(FacesContext faces)
1214 {
1215 if (!isRendered())
1216 {
1217 return;
1218 }
1219
1220 process(faces, PhaseId.APPLY_REQUEST_VALUES);
1221 decode(faces);
1222 }
1223
1224 @Override
1225 public void processUpdates(FacesContext faces)
1226 {
1227 if (!isRendered())
1228 {
1229 return;
1230 }
1231
1232 process(faces, PhaseId.UPDATE_MODEL_VALUES);
1233
1234 if (faces.getRenderResponse())
1235 {
1236 _isValidChilds = false;
1237 }
1238 }
1239
1240 @Override
1241 public void processValidators(FacesContext faces)
1242 {
1243 if (!isRendered())
1244 {
1245 return;
1246 }
1247
1248 process(faces, PhaseId.PROCESS_VALIDATIONS);
1249
1250
1251 if (faces.getRenderResponse())
1252 {
1253 _isValidChilds = false;
1254 }
1255 }
1256
1257
1258 private final static class SavedState implements Serializable
1259 {
1260 private boolean _localValueSet;
1261 private Object _submittedValue;
1262 private boolean _valid = true;
1263 private Object _value;
1264
1265 private static final long serialVersionUID = 2920252657338389849L;
1266
1267 public SavedState(EditableValueHolder evh)
1268 {
1269 _value = evh.getLocalValue();
1270 _localValueSet = evh.isLocalValueSet();
1271 _valid = evh.isValid();
1272 _submittedValue = evh.getSubmittedValue();
1273 }
1274
1275 Object getSubmittedValue()
1276 {
1277 return (_submittedValue);
1278 }
1279
1280 void setSubmittedValue(Object submittedValue)
1281 {
1282 _submittedValue = submittedValue;
1283 }
1284
1285 boolean isValid()
1286 {
1287 return (_valid);
1288 }
1289
1290 void setValid(boolean valid)
1291 {
1292 _valid = valid;
1293 }
1294
1295 Object getValue()
1296 {
1297 return _value;
1298 }
1299
1300 public void setValue(Object value)
1301 {
1302 _value = value;
1303 }
1304
1305 boolean isLocalValueSet()
1306 {
1307 return _localValueSet;
1308 }
1309
1310 public void setLocalValueSet(boolean localValueSet)
1311 {
1312 _localValueSet = localValueSet;
1313 }
1314
1315 @Override
1316 public String toString()
1317 {
1318 return ("submittedValue: " + _submittedValue + " value: " + _value + " localValueSet: " + _localValueSet);
1319 }
1320
1321 public void restoreState(EditableValueHolder evh)
1322 {
1323 evh.setValue(_value);
1324 evh.setValid(_valid);
1325 evh.setSubmittedValue(_submittedValue);
1326 evh.setLocalValueSet(_localValueSet);
1327 }
1328
1329 public void populate(EditableValueHolder evh)
1330 {
1331 _value = evh.getLocalValue();
1332 _valid = evh.isValid();
1333 _submittedValue = evh.getSubmittedValue();
1334 _localValueSet = evh.isLocalValueSet();
1335 }
1336
1337 public void apply(EditableValueHolder evh)
1338 {
1339 evh.setValue(_value);
1340 evh.setValid(_valid);
1341 evh.setSubmittedValue(_submittedValue);
1342 evh.setLocalValueSet(_localValueSet);
1343 }
1344 }
1345
1346 private final class IndexedEvent extends FacesEvent
1347 {
1348 private final FacesEvent _target;
1349
1350 private final int _index;
1351
1352 public IndexedEvent(UIRepeat owner, FacesEvent target, int index)
1353 {
1354 super(owner);
1355 _target = target;
1356 _index = index;
1357 }
1358
1359 @Override
1360 public PhaseId getPhaseId()
1361 {
1362 return _target.getPhaseId();
1363 }
1364
1365 @Override
1366 public void setPhaseId(PhaseId phaseId)
1367 {
1368 _target.setPhaseId(phaseId);
1369 }
1370
1371 public boolean isAppropriateListener(FacesListener listener)
1372 {
1373 return _target.isAppropriateListener(listener);
1374 }
1375
1376 public void processListener(FacesListener listener)
1377 {
1378 UIRepeat owner = (UIRepeat) getComponent();
1379
1380
1381 final int prevIndex = owner._index;
1382 final int prevCount = owner._count;
1383
1384 try
1385 {
1386 owner._captureScopeValues();
1387 if (this._index != -1)
1388 {
1389
1390 _count = _calculateCountForIndex(this._index);
1391 }
1392 owner._setIndex(this._index);
1393 if (owner._isIndexAvailable())
1394 {
1395 _target.processListener(listener);
1396 }
1397 }
1398 finally
1399 {
1400
1401 owner._count = prevCount;
1402 owner._setIndex(prevIndex);
1403 owner._restoreScopeValues();
1404 }
1405 }
1406
1407 public int getIndex()
1408 {
1409 return _index;
1410 }
1411
1412 public FacesEvent getTarget()
1413 {
1414 return _target;
1415 }
1416
1417 }
1418
1419 @Override
1420 public void broadcast(FacesEvent event) throws AbortProcessingException
1421 {
1422 if (event instanceof IndexedEvent)
1423 {
1424 IndexedEvent idxEvent = (IndexedEvent) event;
1425
1426
1427 final int prevIndex = _index;
1428 final int prevCount = _count;
1429
1430 try
1431 {
1432 _captureScopeValues();
1433 if (idxEvent.getIndex() != -1)
1434 {
1435
1436 _count = _calculateCountForIndex(idxEvent.getIndex());
1437 }
1438 _setIndex(idxEvent.getIndex());
1439 if (_isIndexAvailable())
1440 {
1441
1442 FacesEvent target = idxEvent.getTarget();
1443 FacesContext facesContext = getFacesContext();
1444
1445
1446
1447
1448
1449 UIComponent targetComponent = target.getComponent();
1450 UIComponent compositeParent = UIComponent
1451 .getCompositeComponentParent(targetComponent);
1452 if (compositeParent != null)
1453 {
1454 pushComponentToEL(facesContext, compositeParent);
1455 }
1456 pushComponentToEL(facesContext, targetComponent);
1457
1458 try
1459 {
1460
1461 targetComponent.broadcast(target);
1462 }
1463 finally
1464 {
1465
1466 popComponentFromEL(facesContext);
1467 if (compositeParent != null)
1468 {
1469 popComponentFromEL(facesContext);
1470 }
1471 }
1472 }
1473 }
1474 finally
1475 {
1476
1477 _count = prevCount;
1478 _setIndex(prevIndex);
1479 _restoreScopeValues();
1480 }
1481 }
1482 else
1483 {
1484 super.broadcast(event);
1485 }
1486 }
1487
1488 @Override
1489 public void queueEvent(FacesEvent event)
1490 {
1491 super.queueEvent(new IndexedEvent(this, event, _index));
1492 }
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545 @Override
1546 public void encodeBegin(FacesContext context) throws IOException
1547 {
1548 _initialDescendantComponentState = null;
1549 if (_isValidChilds && !hasErrorMessages(context))
1550 {
1551
1552
1553
1554 _dataModelMap.clear();
1555
1556
1557
1558
1559
1560 _rowStates.clear();
1561 }
1562
1563 super.encodeBegin(context);
1564 }
1565
1566 private boolean hasErrorMessages(FacesContext context)
1567 {
1568 for (Iterator<FacesMessage> iter = context.getMessages(); iter.hasNext();)
1569 {
1570 FacesMessage message = iter.next();
1571 if (FacesMessage.SEVERITY_ERROR.compareTo(message.getSeverity()) <= 0)
1572 {
1573 return true;
1574 }
1575 }
1576 return false;
1577 }
1578
1579 @Override
1580 public void encodeChildren(FacesContext faces) throws IOException
1581 {
1582 if (!isRendered())
1583 {
1584 return;
1585 }
1586
1587 process(faces, PhaseId.RENDER_RESPONSE);
1588 }
1589
1590 @Override
1591 public boolean getRendersChildren()
1592 {
1593 if (getRendererType() != null)
1594 {
1595 Renderer renderer = getRenderer(getFacesContext());
1596 if (renderer != null)
1597 {
1598 return renderer.getRendersChildren();
1599 }
1600 }
1601
1602 return true;
1603 }
1604
1605 enum PropertyKeys
1606 {
1607 value
1608 , var
1609 , size
1610 , varStatus
1611 , offset
1612 , step
1613 }
1614 }