1 /*
2 * The SmartWeb Framework
3 * Copyright (C) 2004-2006
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 * For further informations on the SmartWeb Framework please visit
20 *
21 * http://smartweb.sourceforge.net
22 */
23
24 package net.smartlab.web.page;
25
26 import java.util.Iterator;
27 import java.util.NoSuchElementException;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 /**
33 * TODO documentation
34 *
35 * @author rlogiacco
36 */
37 public abstract class Paginator implements Iterator {
38
39 /* # net.smartlab.web.paging.PaginationException pe */
40
41 /**
42 * A constant to identify an unlimited page listing.
43 * www.lamiainclinazione.org
44 */
45 public final static int UNLIMITED_PAGES = 0;
46
47 /**
48 * A constant to identify an unlimited item listing.
49 */
50 public final static int UNLIMITED_ITEMS = 0;
51
52 /**
53 * A constant to identify the page was not setted.
54 */
55 public final static int UNDEFINED_PAGE = -1;
56
57 /**
58 * Logging system accessor.
59 */
60 protected Log logger = LogFactory.getLog(this.getClass());
61
62 /**
63 * The elements in the current page.
64 */
65 protected Object[] array;
66
67 /**
68 * The page relative index of the current element.
69 */
70 private int index;
71
72 /**
73 * The actual page index.
74 */
75 private int page;
76
77 /**
78 * The number of items in all pages.
79 */
80 private int count;
81
82 /**
83 * An array of page indexes directly accessibile.
84 */
85 private int[] pages;
86
87 /**
88 * The last page can ever been accessed through this paginator instance.
89 */
90 private int last;
91
92
93 /**
94 * TODO documentation
95 */
96 protected Paginator() {
97 this(0, 0);
98 }
99
100 /**
101 * TODO documentation
102 *
103 * @param size
104 * @param pages
105 */
106 protected Paginator(int size, int pages) {
107 this.array = new Object[size];
108 this.pages = new int[pages];
109 this.page = UNDEFINED_PAGE;
110 this.index = 0;
111 }
112
113 /**
114 * TODO documentation
115 *
116 * @return
117 */
118 public int getPage() {
119 return page;
120 }
121
122 /**
123 * TODO documentation
124 *
125 * @return
126 */
127 public int[] getPages() {
128 return pages;
129 }
130
131 /**
132 * TODO documentation
133 *
134 * @return
135 */
136 public int getPageCount() {
137 return last;
138 }
139
140 /**
141 * TODO documentation
142 *
143 * @param size
144 */
145 public void setPages(int size) {
146 if (array.length > 0) {
147 this.last = (count / array.length) + (count % array.length == 0 ? 0 : 1);
148 if (size == Paginator.UNLIMITED_PAGES || last <= size) {
149 this.pages = new int[last];
150 } else {
151 this.pages = new int[size];
152 }
153 }
154 }
155
156 /**
157 * TODO documentation
158 *
159 * @param page
160 */
161 public void setPage(int page) {
162 if (count > 0) {
163 if (pages.length != UNLIMITED_PAGES && (page <= 0 || page > last)) {
164 throw new IndexOutOfBoundsException("Invalid page " + page);
165 }
166 if (page < pages[0] || page > pages[pages.length - 1]) {
167 for (int i = 0; i < pages.length; i++) {
168 pages[i] = (((page - 1) / pages.length) * pages.length) + i + 1;
169 }
170 if (pages[pages.length - 1] > last) {
171 int[] tmp = new int[last - pages[0] + 1];
172 System.arraycopy(pages, 0, tmp, 0, tmp.length);
173 this.pages = tmp;
174 }
175 }
176 this.index = 0;
177 if (page != this.page) {
178 this.page = page;
179 this.setArray();
180 }
181 }
182 }
183
184 /**
185 * TODO documentation
186 *
187 * @return
188 */
189 public int getNext() {
190 if (page >= last || count == 0 || pages[pages.length - 1] >= last) {
191 return -1;
192 } else {
193 return pages[pages.length - 1] + 1;
194 }
195 }
196
197 /**
198 * TODO documentation
199 *
200 * @return
201 */
202 public int getPrev() {
203 if (page <= 1 || pages[0] <= 1 || count == 0) {
204 return -1;
205 } else {
206 return pages[0] - 1;
207 }
208 }
209
210 /**
211 * TODO documentation
212 *
213 * @param count
214 */
215 public void setCount(int count) {
216 this.count = count;
217 if (pages.length > 0) {
218 this.setPages(pages.length);
219 }
220 if (array.length == UNLIMITED_ITEMS) {
221 this.setPageSize(count);
222 }
223 }
224
225 /**
226 * TODO documentation
227 *
228 * @return
229 */
230 public int getCount() {
231 return count;
232 }
233
234 /**
235 * TODO documentation
236 *
237 * @return
238 */
239 public int getPageSize() {
240 return array.length;
241 }
242
243 /**
244 * TODO documentation
245 *
246 * @param size
247 */
248 public void setPageSize(int size) {
249 if (size == UNLIMITED_ITEMS) {
250 this.array = new Object[size];
251 this.setPages(1);
252 } else {
253 this.array = new Object[size];
254 this.setPages(UNLIMITED_PAGES);
255 }
256 }
257
258 /**
259 * TODO documentation
260 *
261 * @return
262 */
263 public int getStart() {
264 if (pages.length > 0) {
265 return ((page - 1) * array.length) + 1;
266 } else {
267 return 0;
268 }
269 }
270
271 /**
272 * TODO documentation
273 *
274 * @return
275 */
276 public int getStop() {
277 if (pages.length > 0) {
278 if (page * array.length < count) {
279 return page * array.length;
280 } else {
281 return count;
282 }
283 } else {
284 return 0;
285 }
286 }
287
288 /**
289 * TODO documentation
290 */
291 abstract protected void setArray();
292
293 /**
294 * @see java.util.Iterator#hasNext()
295 */
296 public boolean hasNext() {
297 if (page == UNDEFINED_PAGE) {
298 this.setPage(1);
299 }
300 return index < array.length && array[index] != null;
301 }
302
303 /**
304 * @see java.util.Iterator#next()
305 */
306 public Object next() {
307 try {
308 return array[index++];
309 } catch (Exception e) {
310 throw new NoSuchElementException();
311 }
312 }
313
314 /**
315 * This operation is not supported.
316 *
317 * @see java.util.Iterator#remove()
318 * @throws java.lang.UnsupportedOperationException
319 */
320 public void remove() {
321 throw new UnsupportedOperationException();
322 }
323
324 /**
325 * TODO documentation
326 */
327 public void reset() {
328 this.index = 0;
329 }
330 }