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