KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > displaytag > pagination > SmartListHelper


1 /**
2  * Licensed under the Artistic License; you may not use this file
3  * except in compliance with the License.
4  * You may obtain a copy of the License at
5  *
6  * http://displaytag.sourceforge.net/license.html
7  *
8  * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */

12 package org.displaytag.pagination;
13
14 import java.text.MessageFormat JavaDoc;
15 import java.util.List JavaDoc;
16
17 import org.apache.commons.lang.builder.ToStringBuilder;
18 import org.apache.commons.lang.builder.ToStringStyle;
19 import org.apache.commons.logging.Log;
20 import org.apache.commons.logging.LogFactory;
21 import org.displaytag.Messages;
22 import org.displaytag.properties.TableProperties;
23 import org.displaytag.util.Href;
24
25
26 /**
27  * <p>
28  * Utility class that chops up a List of objects into small bite size pieces that are more suitable for display.
29  * </p>
30  * <p>
31  * This class is a stripped down version of the WebListHelper from Tim Dawson (tdawson@is.com)
32  * </p>
33  * @author epesh
34  * @author Fabrizio Giustina
35  * @version $Revision: 887 $ ($Author: fgiust $)
36  */

37 public class SmartListHelper
38 {
39
40     /**
41      * logger.
42      */

43     private static Log log = LogFactory.getLog(SmartListHelper.class);
44
45     /**
46      * full list.
47      */

48     private List JavaDoc fullList;
49
50     /**
51      * sixe of the full list.
52      */

53     private int fullListSize;
54
55     /**
56      * number of items in a page.
57      */

58     private int pageSize;
59
60     /**
61      * number of pages.
62      */

63     private int pageCount;
64
65     /**
66      * the list we hold is only part of the full dataset
67      */

68     private boolean partialList;
69
70     /**
71      * index of current page.
72      */

73     private int currentPage;
74
75     /**
76      * TableProperties.
77      */

78     private TableProperties properties;
79
80     /**
81      * Creates a SmarListHelper instance that will help you chop up a list into bite size pieces that are suitable for
82      * display.
83      * @param list List
84      * @param fullSize size of the full list
85      * @param itemsInPage number of items in a page (int > 0)
86      * @param tableProperties TableProperties
87      */

88     public SmartListHelper(
89         List JavaDoc list,
90         int fullSize,
91         int itemsInPage,
92         TableProperties tableProperties,
93         boolean partialList)
94     {
95         if (log.isDebugEnabled())
96         {
97             log.debug(Messages.getString("SmartListHelper.debug.instantiated", //$NON-NLS-1$
98
new Object JavaDoc[]{new Integer JavaDoc(list.size()), new Integer JavaDoc(itemsInPage), new Integer JavaDoc(fullSize)}));
99         }
100
101         this.properties = tableProperties;
102         this.pageSize = itemsInPage;
103         this.fullList = list;
104         this.fullListSize = fullSize;
105         this.pageCount = computedPageCount();
106         this.currentPage = 1;
107         this.partialList = partialList;
108     }
109
110     /**
111      * Constructor that can be used by subclasses. Subclasses that use this constructor must also override all the
112      * public methods, since this constructor does nothing.
113      */

114     protected SmartListHelper()
115     {
116     }
117
118     /**
119      * Returns the computed number of pages it would take to show all the elements in the list given the pageSize we are
120      * working with.
121      * @return int computed number of pages
122      */

123     protected int computedPageCount()
124     {
125         int size = this.fullListSize;
126         int div = size / this.pageSize;
127         int result = (size % this.pageSize == 0) ? div : div + 1;
128
129         return result;
130     }
131
132     /**
133      * Returns the index into the master list of the first object that should appear on the current page that the user
134      * is viewing.
135      * @return int index of the first object that should appear on the current page
136      */

137     public int getFirstIndexForCurrentPage()
138     {
139         return getFirstIndexForPage(this.currentPage);
140     }
141
142     /**
143      * Returns the index into the master list of the last object that should appear on the current page that the user is
144      * viewing.
145      * @return int
146      */

147     protected int getLastIndexForCurrentPage()
148     {
149
150         return getLastIndexForPage(this.currentPage);
151     }
152
153     /**
154      * Returns the index into the master list of the first object that should appear on the given page.
155      * @param pageNumber page number
156      * @return int index of the first object that should appear on the given page
157      */

158     protected int getFirstIndexForPage(int pageNumber)
159     {
160         if (this.partialList)
161         {
162             return 0;
163         }
164         else
165         {
166             return (pageNumber - 1) * this.pageSize;
167         }
168     }
169
170     /**
171      * Returns the index into the master list of the last object that should appear on the given page.
172      * @param pageNumber page number
173      * @return int index of the last object that should appear on the given page
174      */

175     protected int getLastIndexForPage(int pageNumber)
176     {
177         if (this.partialList)
178         {
179             // return the min of pageSize or list size on the off chance they gave us more data than pageSize allows
180
return Math.min(this.pageSize - 1, this.fullList.size() - 1);
181         }
182         else
183         {
184             int firstIndex = getFirstIndexForPage(pageNumber);
185             int pageIndex = this.pageSize - 1;
186             int lastIndex = this.fullListSize - 1;
187
188             return Math.min(firstIndex + pageIndex, lastIndex);
189         }
190     }
191
192     /**
193      * Returns a subsection of the list that contains just the elements that are supposed to be shown on the current
194      * page the user is viewing.
195      * @return List subsection of the list that contains the elements that are supposed to be shown on the current page
196      */

197     public List JavaDoc getListForCurrentPage()
198     {
199
200         return getListForPage(this.currentPage);
201     }
202
203     /**
204      * Returns a subsection of the list that contains just the elements that are supposed to be shown on the given page.
205      * @param pageNumber page number
206      * @return List subsection of the list that contains just the elements that are supposed to be shown on the given
207      * page
208      */

209     protected List JavaDoc getListForPage(int pageNumber)
210     {
211         if (log.isDebugEnabled())
212         {
213             log.debug(Messages.getString("SmartListHelper.debug.sublist", //$NON-NLS-1$
214
new Object JavaDoc[]{new Integer JavaDoc(pageNumber)}));
215         }
216
217         int firstIndex = getFirstIndexForPage(pageNumber);
218         int lastIndex = getLastIndexForPage(pageNumber);
219         return this.fullList.subList(firstIndex, lastIndex + 1);
220     }
221
222     /**
223      * Set's the page number that the user is viewing.
224      * @param pageNumber page number
225      */

226     public void setCurrentPage(int pageNumber)
227     {
228         if (log.isDebugEnabled())
229         {
230             log.debug(Messages.getString("SmartListHelper.debug.currentpage", //$NON-NLS-1$
231
new Object JavaDoc[]{new Integer JavaDoc(pageNumber), new Integer JavaDoc(this.pageCount)}));
232         }
233
234         if (pageNumber < 1)
235         {
236             // invalid page: better don't throw an exception, since this could easily happen
237
// (list changed, user bookmarked the page)
238
this.currentPage = 1;
239         }
240         else if (pageNumber != 1 && pageNumber > this.pageCount)
241         {
242             // invalid page: set to last page
243
this.currentPage = this.pageCount;
244         }
245         else
246         {
247             this.currentPage = pageNumber;
248         }
249     }
250
251     /**
252      * Return the little summary message that lets the user know how many objects are in the list they are viewing, and
253      * where in the list they are currently positioned. The message looks like: nnn [item(s)] found, displaying nnn to
254      * nnn. [item(s)] is replaced by either itemName or itemNames depending on if it should be signular or plural.
255      * @return String
256      */

257     public String JavaDoc getSearchResultsSummary()
258     {
259
260         Object JavaDoc[] objs;
261         String JavaDoc message;
262
263         if (this.fullListSize == 0)
264         {
265             objs = new Object JavaDoc[]{this.properties.getPagingItemsName()};
266             message = this.properties.getPagingFoundNoItems();
267
268         }
269         else if (this.fullListSize == 1)
270         {
271             objs = new Object JavaDoc[]{this.properties.getPagingItemName()};
272             message = this.properties.getPagingFoundOneItem();
273         }
274         else if (computedPageCount() == 1)
275         {
276             objs = new Object JavaDoc[]{
277                 new Integer JavaDoc(this.fullListSize),
278                 this.properties.getPagingItemsName(),
279                 this.properties.getPagingItemsName()};
280             message = this.properties.getPagingFoundAllItems();
281         }
282         else
283         {
284             objs = new Object JavaDoc[]{
285                 new Integer JavaDoc(this.fullListSize),
286                 this.properties.getPagingItemsName(),
287                 new Integer JavaDoc(getFirstIndexForCurrentPage() + 1),
288                 new Integer JavaDoc(getLastIndexForCurrentPage() + 1),
289                 new Integer JavaDoc(this.currentPage),
290                 new Integer JavaDoc(this.pageCount)};
291             message = this.properties.getPagingFoundSomeItems();
292         }
293
294         return MessageFormat.format(message, objs);
295     }
296
297     /**
298      * Returns a string containing the nagivation bar that allows the user to move between pages within the list. The
299      * urlFormatString should be a URL that looks like the following: somepage.page?page={0}
300      * @param baseHref Href used for links
301      * @param pageParameter name for the page parameter
302      * @return String
303      */

304     public String JavaDoc getPageNavigationBar(Href baseHref, String JavaDoc pageParameter)
305     {
306
307         int groupSize = this.properties.getPagingGroupSize();
308         int startPage;
309         int endPage;
310
311         Pagination pagination = new Pagination(baseHref, pageParameter);
312         pagination.setCurrent(new Integer JavaDoc(this.currentPage));
313
314         // if no items are found still add pagination?
315
if (this.pageCount == 0)
316         {
317             pagination.addPage(1, true);
318         }
319
320         // center the selected page, but only if there are {groupSize} pages available after it, and check that the
321
// result is not < 1
322
startPage = Math.max(Math.min(this.currentPage - groupSize / 2, this.pageCount - (groupSize - 1)), 1);
323         endPage = Math.min(startPage + groupSize - 1, this.pageCount);
324
325         if (log.isDebugEnabled())
326         {
327             log.debug("Displaying pages from " + startPage + " to " + endPage);
328         }
329
330         if (this.currentPage != 1)
331         {
332             pagination.setFirst(new Integer JavaDoc(1));
333             pagination.setPrevious(new Integer JavaDoc(this.currentPage - 1));
334         }
335
336         for (int j = startPage; j <= endPage; j++)
337         {
338             if (log.isDebugEnabled())
339             {
340                 log.debug("adding page " + j); //$NON-NLS-1$
341
}
342             pagination.addPage(j, (j == this.currentPage));
343         }
344
345         if (this.currentPage != this.pageCount)
346         {
347             pagination.setNext(new Integer JavaDoc(this.currentPage + 1));
348             pagination.setLast(new Integer JavaDoc(this.pageCount));
349         }
350
351         // format for previous/next banner
352
String JavaDoc bannerFormat;
353
354         if (pagination.isOnePage())
355         {
356             bannerFormat = this.properties.getPagingBannerOnePage();
357         }
358         else if (pagination.isFirst())
359         {
360             bannerFormat = this.properties.getPagingBannerFirst();
361         }
362         else if (pagination.isLast())
363         {
364             bannerFormat = this.properties.getPagingBannerLast();
365         }
366         else
367         {
368             bannerFormat = this.properties.getPagingBannerFull();
369         }
370
371         return pagination.getFormattedBanner(this.properties.getPagingPageLink(), this.properties
372             .getPagingPageSelected(), this.properties.getPagingPageSeparator(), bannerFormat);
373     }
374
375     /**
376      * @see java.lang.Object#toString()
377      */

378     public String JavaDoc toString()
379     {
380         return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) //
381
.append("fullList", this.fullList) //$NON-NLS-1$
382
.append("fullListSize", this.fullListSize) //$NON-NLS-1$
383
.append("pageSize", this.pageSize) //$NON-NLS-1$
384
.append("pageCount", this.pageCount) //$NON-NLS-1$
385
.append("properties", this.properties) //$NON-NLS-1$
386
.append("currentPage", this.currentPage) //$NON-NLS-1$
387
.append("partialList", this.partialList) //$NON-NLS-1$
388
.toString();
389     }
390 }
Popular Tags