org.springframework.beans.support.PagedListHolder Maven / Gradle / Ivy
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.support;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* PagedListHolder is a simple state holder for handling lists of objects,
* separating them into pages. Page numbering starts with 0.
*
* This is mainly targetted at usage in web UIs. Typically, an instance will be
* instantiated with a list of beans, put into the session, and exported as model.
* The properties can all be set/get programmatically, but the most common way will
* be data binding, i.e. populating the bean from request parameters. The getters
* will mainly be used by the view.
*
*
Supports sorting the underlying list via a SortDefinition implementation,
* available as property "sort". By default, a MutableSortDefinition instance
* that toggles the ascending value on setting the same property again is used.
*
*
The data binding names have to be called "pageSize" and "sort.ascending",
* as expected by BeanWrapper. Note that the names and the nesting syntax match
* the respective JSTL EL expressions, like "myModelAttr.pageSize" and
* "myModelAttr.sort.ascending".
*
*
This class just provides support for an unmodifiable List of beans.
* If you need on-demand refresh because of Locale or filter changes,
* consider RefreshablePagedListHolder.
*
* @author Juergen Hoeller
* @since 19.05.2003
* @see #getPageList
* @see org.springframework.beans.support.RefreshablePagedListHolder
* @see org.springframework.beans.support.MutableSortDefinition
*/
public class PagedListHolder implements Serializable {
public static final int DEFAULT_PAGE_SIZE = 10;
public static final int DEFAULT_MAX_LINKED_PAGES = 10;
private List source;
private Date refreshDate;
private SortDefinition sort;
private SortDefinition sortUsed;
private int pageSize = DEFAULT_PAGE_SIZE;
private int page = 0;
private boolean newPageSet;
private int maxLinkedPages = DEFAULT_MAX_LINKED_PAGES;
/**
* Create a new holder instance.
* You'll need to set a source list to be able to use the holder.
*/
public PagedListHolder() {
this(new ArrayList(0));
}
/**
* Create a new holder instance with the given source list.
*/
public PagedListHolder(List source) {
setSource(source);
setSort(new MutableSortDefinition(true));
}
/**
* Set the source list for this holder.
*/
public void setSource(List source) {
this.source = source;
this.refreshDate = new Date();
this.sortUsed = null;
}
/**
* Return the source list for this holder.
*/
public List getSource() {
return source;
}
/**
* Return the last time the list has been fetched from the source provider.
*/
public Date getRefreshDate() {
return refreshDate;
}
/**
* Set the sort definition for this holder.
* Typically an instance of MutableSortDefinition.
* @see org.springframework.beans.support.MutableSortDefinition
*/
public void setSort(SortDefinition sort) {
this.sort = sort;
}
/**
* Return the sort definition for this holder.
*/
public SortDefinition getSort() {
return sort;
}
/**
* Set the current page size.
* Resets the current page number if changed.
*
Default value is 10.
*/
public void setPageSize(int pageSize) {
if (pageSize != this.pageSize) {
this.pageSize = pageSize;
if (!this.newPageSet) {
this.page = 0;
}
}
}
/**
* Return the current page size.
*/
public int getPageSize() {
return pageSize;
}
/**
* Set the current page number.
* Page numbering starts with 0.
*/
public void setPage(int page) {
this.page = page;
this.newPageSet = true;
}
/**
* Return the current page number.
* Page numbering starts with 0.
*/
public int getPage() {
this.newPageSet = false;
if (this.page >= getPageCount()) {
this.page = getPageCount() - 1;
}
return this.page;
}
/**
* Set the maximum number of page links to a few pages around the current one.
*/
public void setMaxLinkedPages(int maxLinkedPages) {
this.maxLinkedPages = maxLinkedPages;
}
/**
* Return the maximum number of page links to a few pages around the current one.
*/
public int getMaxLinkedPages() {
return maxLinkedPages;
}
/**
* Return the number of pages for the current source list.
*/
public int getPageCount() {
float nrOfPages = (float) getSource().size() / getPageSize();
return (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages);
}
/**
* Return if the current page is the first one.
*/
public boolean isFirstPage() {
return getPage() == 0;
}
/**
* Return if the current page is the last one.
*/
public boolean isLastPage() {
return getPage() == getPageCount() -1;
}
/**
* Switch to previous page.
* Will stay on first page if already on first page.
*/
public void previousPage() {
if (!isFirstPage()) {
this.page--;
}
}
/**
* Switch to next page.
* Will stay on last page if already on last page.
*/
public void nextPage() {
if (!isLastPage()) {
this.page++;
}
}
/**
* Return the total number of elements in the source list.
*/
public int getNrOfElements() {
return getSource().size();
}
/**
* Return the element index of the first element on the current page.
* Element numbering starts with 0.
*/
public int getFirstElementOnPage() {
return (getPageSize() * getPage());
}
/**
* Return the element index of the last element on the current page.
* Element numbering starts with 0.
*/
public int getLastElementOnPage() {
int endIndex = getPageSize() * (getPage() + 1);
return (endIndex > getSource().size() ? getSource().size() : endIndex) -1;
}
/**
* Return a sub-list representing the current page.
*/
public List getPageList() {
return getSource().subList(getFirstElementOnPage(), getLastElementOnPage() +1);
}
/**
* Return the first page to which create a link around the current page.
*/
public int getFirstLinkedPage() {
return Math.max(0, this.getPage() - (getMaxLinkedPages() /2));
}
/**
* Return the last page to which create a link around the current page.
*/
public int getLastLinkedPage() {
return Math.min(getFirstLinkedPage() + getMaxLinkedPages() -1, this.getPageCount() -1);
}
/**
* Resort the list if necessary, i.e. if the current sort instance isn't equal
* to the backed-up sortUsed instance.
*/
public void resort() {
if (this.sort != null && !"".equals(this.sort.getProperty()) && !this.sort.equals(this.sortUsed)) {
PropertyComparator.sort(getSource(), this.sort);
this.sortUsed = new MutableSortDefinition(this.sort);
setPage(0);
}
}
}