View Javadoc

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 }