KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fr > improve > struts > taglib > layout > collection > CollectionsIterator


1 package fr.improve.struts.taglib.layout.collection;
2
3 import java.util.Collection JavaDoc;
4 import java.util.Collections JavaDoc;
5 import java.util.Iterator JavaDoc;
6 import java.util.Map JavaDoc;
7
8 import javax.servlet.jsp.JspException JavaDoc;
9 import javax.servlet.jsp.PageContext JavaDoc;
10
11 import fr.improve.struts.taglib.layout.util.LayoutUtils;
12
13 /**
14  * A kind of iterator that can iterates on nested collections.
15  *
16  * @author jer80876
17  */

18 public class CollectionsIterator {
19     private Iterator JavaDoc mainIterator;
20     private String JavaDoc id;
21     private String JavaDoc indexId;
22     private String JavaDoc property;
23     private int index = 0;
24     
25     private CollectionsIterator nestedIterator;
26
27     /**
28      * Build a new CollectionsIterator.
29      */

30     public CollectionsIterator(Object JavaDoc in_bean, String JavaDoc in_property, String JavaDoc in_id, String JavaDoc in_indexId) throws JspException JavaDoc {
31         Object JavaDoc lc_collection = in_bean;
32         if (in_bean!=null) {
33             // mainIterator is lazy instanciated for subcollections
34
lc_collection = LayoutUtils.getProperty(in_bean, in_property);
35             mainIterator = LayoutUtils.getCollection(lc_collection).iterator();
36         }
37         id = in_id;
38         property = in_property;
39         indexId = in_indexId;
40     }
41     
42     /**
43      * Add a nested collection.
44      */

45     public void addLastIterator(CollectionsIterator in_iterator) {
46         if (nestedIterator==null) {
47             nestedIterator = in_iterator;
48         } else {
49             nestedIterator.addLastIterator(in_iterator);
50         }
51     }
52         
53     /**
54      * Return true if one of the iterators has a next element.
55      */

56     public boolean hasNext(PageContext JavaDoc in_pageContext) {
57         if ((mainIterator!=null && mainIterator.hasNext()) || (nestedIterator!=null && nestedIterator.hasNext(in_pageContext))) {
58             return true;
59         } else {
60             if (id!=null) {
61                 in_pageContext.removeAttribute(id, PageContext.PAGE_SCOPE);
62             }
63             if (indexId!=null) {
64                 in_pageContext.removeAttribute(indexId, PageContext.PAGE_SCOPE);
65             }
66             return false;
67         }
68     }
69     
70     /**
71      * Return true if the iterator is initialized.
72      */

73     private boolean isInitialized() {
74         return mainIterator != null;
75     }
76     
77     /**
78      * Return true if there is a nested iterator.
79      */

80     protected boolean hasNestedIterator() {
81         return nestedIterator!=null;
82     }
83
84     /**
85      * Get the next value(s) to iterator on.
86      * out_changes is updated and contains the span of the element that have changed.
87      */

88     public Object JavaDoc next(PageContext JavaDoc in_pageContext, Map JavaDoc out_changes) throws JspException JavaDoc {
89         return next(in_pageContext, out_changes, true);
90     }
91     
92     private Object JavaDoc next(PageContext JavaDoc in_pageContext, Map JavaDoc out_changes, boolean in_increment) throws JspException JavaDoc {
93         if (nestedIterator==null) {
94             Object JavaDoc lc_bean = mainIterator.next();
95             if (id!=null) {
96                 in_pageContext.setAttribute(id, lc_bean);
97                 out_changes.put(id, new Integer JavaDoc(1));
98             }
99             if (indexId!=null) {
100                 in_pageContext.setAttribute(indexId, new Integer JavaDoc(index));
101             }
102             if (in_increment) {
103                 index++;
104             }
105             return lc_bean;
106         } else {
107             if (nestedIterator.hasNext(in_pageContext)) {
108                 nestedIterator.next(in_pageContext, out_changes, in_increment);
109                 return null;
110             } else {
111                 Object JavaDoc lc_bean = mainIterator.next();
112                 int lc_span = 1;
113                 lc_span = nestedIterator.reset(in_pageContext, lc_bean);
114                 
115                 if (nestedIterator.hasNext(in_pageContext)) {
116                     nestedIterator.next(in_pageContext, out_changes, in_increment);
117                 } else {
118                     nestedIterator.emptyNext(in_pageContext, out_changes);
119                 }
120                 
121                 if (id!=null) {
122                     in_pageContext.setAttribute(id, lc_bean);
123                     out_changes.put(id, new Integer JavaDoc(lc_span));
124                 }
125                 if (indexId!=null) {
126                     in_pageContext.setAttribute(indexId, new Integer JavaDoc(index));
127                 }
128                 if (in_increment) {
129                     index++;
130                 }
131                 return lc_bean;
132             }
133             
134         }
135     }
136     
137     /**
138      * Skip an element. Used by the pagination and offset system.
139      */

140     public void skip(PageContext JavaDoc in_pageContext, Map JavaDoc out_changes) throws JspException JavaDoc {
141         if (nestedIterator==null) {
142             // No nested iterator : easy !
143
next(in_pageContext, out_changes, false);
144         } else {
145             // finish the nested iterator.
146
while (nestedIterator.hasNext(in_pageContext)) {
147                 nestedIterator.next(in_pageContext, out_changes, false);
148                 out_changes.clear();
149             }
150             // next main element.
151
next(in_pageContext, out_changes, false);
152             // finish the nested iterator for the next element.
153
while (nestedIterator.hasNext(in_pageContext)) {
154                 nestedIterator.next(in_pageContext, out_changes, false);
155                 out_changes.clear();
156             }
157         }
158     }
159     
160     /**
161      * Effectue une itétation vide...
162      */

163     private void emptyNext(PageContext JavaDoc in_pg, Map JavaDoc out_changes) {
164         if (nestedIterator==null) {
165             if (id!=null) {
166                 in_pg.removeAttribute(id, PageContext.PAGE_SCOPE);
167                 out_changes.put(id, new Integer JavaDoc(1));
168             }
169         } else {
170             throw new IllegalStateException JavaDoc("Case not implemented");
171         }
172     }
173     
174     /**
175      * Reinitialize this iterator with a new bean.
176      */

177     private int reset(PageContext JavaDoc in_pg, Object JavaDoc in_bean) throws JspException JavaDoc {
178         Collection JavaDoc lc_collection = LayoutUtils.getCollection(LayoutUtils.getProperty(in_bean, property));
179         if (lc_collection==null) {
180             // deal with null nested collections.
181
lc_collection = Collections.EMPTY_LIST;
182         }
183         mainIterator = lc_collection.iterator();
184         index = 0;
185         if (indexId!=null) {
186             in_pg.removeAttribute(indexId, PageContext.PAGE_SCOPE);
187         }
188         if (nestedIterator==null) {
189             return lc_collection.size();
190         } else {
191             // need to pre-compute the length of the nested iterator so that we can generate correct rowspan values...
192
return nestedIterator.computeLength(lc_collection);
193         }
194     }
195     
196     /**
197      * Compute the length of this subiterator applied to the specified collection.
198      */

199     private int computeLength(Collection JavaDoc in_collection) throws JspException JavaDoc {
200         Iterator JavaDoc lc_it = in_collection.iterator();
201         int lc_length = 0;
202         while (lc_it.hasNext()) {
203             Object JavaDoc lc_bean = lc_it.next();
204             Collection JavaDoc lc_collection = LayoutUtils.getCollection(LayoutUtils.getProperty(lc_bean, property));
205             if (nestedIterator==null) {
206                 int lc_size = lc_collection.size();
207                 lc_length += lc_size > 1 ? lc_size : 1;
208             } else {
209                 lc_length += nestedIterator.computeLength(lc_collection);
210             }
211         }
212         return lc_length;
213     }
214     
215     public int getIndex() {
216         return index;
217     }
218     
219     protected CollectionsIterator getNestedIterator() {
220         return nestedIterator;
221     }
222 }
223
Popular Tags