KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > beans > support > PagedListHolder


1 /*
2  * Copyright 2002-2005 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.beans.support;
18
19 import java.io.Serializable JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.List JavaDoc;
23
24 /**
25  * PagedListHolder is a simple state holder for handling lists of objects,
26  * separating them into pages. Page numbering starts with 0.
27  *
28  * <p>This is mainly targetted at usage in web UIs. Typically, an instance will be
29  * instantiated with a list of beans, put into the session, and exported as model.
30  * The properties can all be set/get programmatically, but the most common way will
31  * be data binding, i.e. populating the bean from request parameters. The getters
32  * will mainly be used by the view.
33  *
34  * <p>Supports sorting the underlying list via a SortDefinition implementation,
35  * available as property "sort". By default, a MutableSortDefinition instance
36  * that toggles the ascending value on setting the same property again is used.
37  *
38  * <p>The data binding names have to be called "pageSize" and "sort.ascending",
39  * as expected by BeanWrapper. Note that the names and the nesting syntax match
40  * the respective JSTL EL expressions, like "myModelAttr.pageSize" and
41  * "myModelAttr.sort.ascending".
42  *
43  * <p>This class just provides support for an unmodifiable List of beans.
44  * If you need on-demand refresh because of Locale or filter changes,
45  * consider RefreshablePagedListHolder.
46  *
47  * @author Juergen Hoeller
48  * @since 19.05.2003
49  * @see #getPageList
50  * @see org.springframework.beans.support.RefreshablePagedListHolder
51  * @see org.springframework.beans.support.MutableSortDefinition
52  */

53 public class PagedListHolder implements Serializable JavaDoc {
54
55     public static final int DEFAULT_PAGE_SIZE = 10;
56
57     public static final int DEFAULT_MAX_LINKED_PAGES = 10;
58
59
60     private List JavaDoc source;
61
62     private Date JavaDoc refreshDate;
63
64     private SortDefinition sort;
65
66     private SortDefinition sortUsed;
67
68     private int pageSize = DEFAULT_PAGE_SIZE;
69
70     private int page = 0;
71
72     private boolean newPageSet;
73
74     private int maxLinkedPages = DEFAULT_MAX_LINKED_PAGES;
75
76
77     /**
78      * Create a new holder instance.
79      * You'll need to set a source list to be able to use the holder.
80      * @see #setSource
81      */

82     public PagedListHolder() {
83         this(new ArrayList JavaDoc(0));
84     }
85
86     /**
87      * Create a new holder instance with the given source list, starting with
88      * a default sort definition (with "toggleAscendingOnProperty" activated).
89      * @param source the source List
90      * @see MutableSortDefinition#setToggleAscendingOnProperty
91      */

92     public PagedListHolder(List JavaDoc source) {
93         this(source, new MutableSortDefinition(true));
94     }
95
96     /**
97      * Create a new holder instance with the given source list.
98      * @param source the source List
99      * @param sort the SortDefinition to start with
100      */

101     public PagedListHolder(List JavaDoc source, SortDefinition sort) {
102         setSource(source);
103         setSort(sort);
104     }
105
106
107     /**
108      * Set the source list for this holder.
109      */

110     public void setSource(List JavaDoc source) {
111         this.source = source;
112         this.refreshDate = new Date JavaDoc();
113         this.sortUsed = null;
114     }
115
116     /**
117      * Return the source list for this holder.
118      */

119     public List JavaDoc getSource() {
120         return source;
121     }
122
123     /**
124      * Return the last time the list has been fetched from the source provider.
125      */

126     public Date JavaDoc getRefreshDate() {
127         return refreshDate;
128     }
129
130     /**
131      * Set the sort definition for this holder.
132      * Typically an instance of MutableSortDefinition.
133      * @see org.springframework.beans.support.MutableSortDefinition
134      */

135     public void setSort(SortDefinition sort) {
136         this.sort = sort;
137     }
138
139     /**
140      * Return the sort definition for this holder.
141      */

142     public SortDefinition getSort() {
143         return sort;
144     }
145
146     /**
147      * Set the current page size.
148      * Resets the current page number if changed.
149      * <p>Default value is 10.
150      */

151     public void setPageSize(int pageSize) {
152         if (pageSize != this.pageSize) {
153             this.pageSize = pageSize;
154             if (!this.newPageSet) {
155                 this.page = 0;
156             }
157         }
158     }
159
160     /**
161      * Return the current page size.
162      */

163     public int getPageSize() {
164         return pageSize;
165     }
166
167     /**
168      * Set the current page number.
169      * Page numbering starts with 0.
170      */

171     public void setPage(int page) {
172         this.page = page;
173         this.newPageSet = true;
174     }
175
176     /**
177      * Return the current page number.
178      * Page numbering starts with 0.
179      */

180     public int getPage() {
181         this.newPageSet = false;
182         if (this.page >= getPageCount()) {
183             this.page = getPageCount() - 1;
184         }
185         return this.page;
186     }
187
188     /**
189      * Set the maximum number of page links to a few pages around the current one.
190      */

191     public void setMaxLinkedPages(int maxLinkedPages) {
192         this.maxLinkedPages = maxLinkedPages;
193     }
194
195     /**
196      * Return the maximum number of page links to a few pages around the current one.
197      */

198     public int getMaxLinkedPages() {
199         return maxLinkedPages;
200     }
201
202
203     /**
204      * Return the number of pages for the current source list.
205      */

206     public int getPageCount() {
207         float nrOfPages = (float) getSource().size() / getPageSize();
208         return (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages);
209     }
210
211     /**
212      * Return if the current page is the first one.
213      */

214     public boolean isFirstPage() {
215         return getPage() == 0;
216     }
217
218     /**
219      * Return if the current page is the last one.
220      */

221     public boolean isLastPage() {
222         return getPage() == getPageCount() -1;
223     }
224
225     /**
226      * Switch to previous page.
227      * Will stay on first page if already on first page.
228      */

229     public void previousPage() {
230         if (!isFirstPage()) {
231             this.page--;
232         }
233     }
234
235     /**
236      * Switch to next page.
237      * Will stay on last page if already on last page.
238      */

239     public void nextPage() {
240         if (!isLastPage()) {
241             this.page++;
242         }
243     }
244
245     /**
246      * Return the total number of elements in the source list.
247      */

248     public int getNrOfElements() {
249         return getSource().size();
250     }
251
252     /**
253      * Return the element index of the first element on the current page.
254      * Element numbering starts with 0.
255      */

256     public int getFirstElementOnPage() {
257         return (getPageSize() * getPage());
258     }
259
260     /**
261      * Return the element index of the last element on the current page.
262      * Element numbering starts with 0.
263      */

264     public int getLastElementOnPage() {
265         int endIndex = getPageSize() * (getPage() + 1);
266         return (endIndex > getSource().size() ? getSource().size() : endIndex) -1;
267     }
268
269     /**
270      * Return a sub-list representing the current page.
271      */

272     public List JavaDoc getPageList() {
273         return getSource().subList(getFirstElementOnPage(), getLastElementOnPage() +1);
274     }
275
276     /**
277      * Return the first page to which create a link around the current page.
278      */

279     public int getFirstLinkedPage() {
280         return Math.max(0, getPage() - (getMaxLinkedPages() /2));
281     }
282
283     /**
284      * Return the last page to which create a link around the current page.
285      */

286     public int getLastLinkedPage() {
287         return Math.min(getFirstLinkedPage() + getMaxLinkedPages() -1, getPageCount() -1);
288     }
289
290
291     /**
292      * Resort the list if necessary, i.e. if the current <code>sort</code> instance
293      * isn't equal to the backed-up <code>sortUsed</code> instance.
294      * <p>Calls <code>doSort</code> to trigger actual sorting.
295      * @see #doSort
296      */

297     public void resort() {
298         SortDefinition sort = getSort();
299         if (sort != null && !sort.equals(this.sortUsed)) {
300             this.sortUsed = copySortDefinition(sort);
301             doSort(getSource(), sort);
302             setPage(0);
303         }
304     }
305
306     /**
307      * Create a deep copy of the given sort definition,
308      * for use as state holder to compare a modified sort definition against.
309      * <p>Default implementation creates a MutableSortDefinition instance.
310      * Can be overridden in subclasses, in particular in case of custom
311      * extensions to the SortDefinition interface. Is allowed to return
312      * null, which means that no sort state will be held, triggering
313      * actual sorting for each <code>resort</code> call.
314      * @param sort the current SortDefinition object
315      * @return a deep copy of the SortDefinition object
316      * @see MutableSortDefinition#MutableSortDefinition(SortDefinition)
317      */

318     protected SortDefinition copySortDefinition(SortDefinition sort) {
319         return new MutableSortDefinition(sort);
320     }
321
322     /**
323      * Actually perform sorting of the given source list, according to
324      * the given sort definition.
325      * <p>The default implementation uses Spring's PropertyComparator.
326      * Can be overridden in subclasses.
327      * @see PropertyComparator#sort(java.util.List, SortDefinition)
328      */

329     protected void doSort(List JavaDoc source, SortDefinition sort) {
330         PropertyComparator.sort(source, sort);
331     }
332
333 }
334
Popular Tags