Index: displaytag/src/main/java/org/displaytag/pagination/PaginationHelper.java =================================================================== --- displaytag/src/main/java/org/displaytag/pagination/PaginationHelper.java (revision 0) +++ displaytag/src/main/java/org/displaytag/pagination/PaginationHelper.java (revision 0) @@ -0,0 +1,66 @@ +package org.displaytag.pagination; + +import java.util.Iterator; +import java.util.List; + +import org.apache.commons.collections.IteratorUtils; + +/** + *

Class to help pagination when dealing with lists.

+ * + *

The class will attempt to use java.util.List.subList(int,int) + * to index into the list for the appropriate page.

+ * + *

If the list does not contain enough elements to support the sub list, then + * the first pageSize elements will be returned.

+ * + * @author Kevin Conaway + */ +public class PaginationHelper { + + private final int pageNumber; + private final int pageSize; + + public PaginationHelper(int pageNumber, int pageSize) { + this.pageNumber = pageNumber; + this.pageSize = pageSize; + } + + public Iterator getIterator(Object data) { + if (data instanceof List) { + return getIterator((List) data); + } + + return IteratorUtils.getIterator(data); + } + + public Iterator getIterator(List data) { + int start = getStart(data.size()); + int end = getEnd(data.size(), start); + return data.subList(start, end).iterator(); + } + + protected int getStart(int listSize) { + int start = (pageNumber - 1) * pageSize; + + if (start >= listSize) { + start = 0; + } + + return start; + } + + protected int getEnd(int listSize, int start) { + + int end = pageNumber * pageSize; + + if (end > listSize) { + end = listSize; + if ((end - start) > pageSize) { + end = pageSize; + } + } + + return end; + } +} Index: displaytag/src/main/java/org/displaytag/tags/TableTag.java =================================================================== --- displaytag/src/main/java/org/displaytag/tags/TableTag.java (revision 1123) +++ displaytag/src/main/java/org/displaytag/tags/TableTag.java (working copy) @@ -53,6 +53,7 @@ import org.displaytag.model.TableModel; import org.displaytag.pagination.PaginatedList; import org.displaytag.pagination.PaginatedListSmartListHelper; +import org.displaytag.pagination.PaginationHelper; import org.displaytag.pagination.SmartListHelper; import org.displaytag.properties.MediaTypeEnum; import org.displaytag.properties.SortOrderEnum; @@ -971,6 +972,11 @@ "InvalidTypeException.msg", new Object[]{"size", "Integer"})); } + + PaginationHelper paginationHelper = new PaginationHelper(pageNumber, pagesize); + this.tableIterator = paginationHelper.getIterator(this.list); + } else { + this.tableIterator = IteratorUtils.getIterator(this.list); } // do we really need to skip any row? @@ -1019,9 +1025,7 @@ else { filteredRows = new LongRange(1, Long.MAX_VALUE); - } - - this.tableIterator = IteratorUtils.getIterator(this.list); + } } /** @@ -1235,7 +1239,7 @@ * * @return Name of the table decorator that should be applied to this table. */ - private String getConfiguredDecoratorName() + private String getConfiguredDecoratorName() { String tableDecoratorName = (this.decoratorName == null) ? @@ -1245,7 +1249,7 @@ this.properties.getExportDecoratorName(this.currentMediaType) : tableDecoratorName; return tableDecoratorName; - } + } /** * clean up instance variables, but not the ones representing tag attributes. @@ -1675,4 +1679,4 @@ return this.paramEncoder.encodeParameterName(parameterName); } -} \ No newline at end of file +} Index: displaytag/src/test/java/org/displaytag/pagination/PaginationHelperTestCase.java =================================================================== --- displaytag/src/test/java/org/displaytag/pagination/PaginationHelperTestCase.java (revision 0) +++ displaytag/src/test/java/org/displaytag/pagination/PaginationHelperTestCase.java (revision 0) @@ -0,0 +1,105 @@ +package org.displaytag.pagination; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import junit.framework.TestCase; + +public class PaginationHelperTestCase extends TestCase { + + public void testEnsureOnlyListsAreHandled() { + Set data = new HashSet(); + add(data, 2); + + assertEquals(data.iterator(), getIterator(data, 1, 25)); + } + + public void testGetSublistOtherPage() { + List expected = Arrays.asList(new Integer[] { new Integer(4), + new Integer(5), new Integer(6) }); + List data = new ArrayList(); + add(data, 7); + + assertEquals(expected.iterator(), getIterator(data, 2, 3)); + } + + public void testGetSublistFirstPage() { + List expected = Arrays.asList(new Integer[] { new Integer(1), + new Integer(2), new Integer(3) }); + List data = new ArrayList(); + add(data, 7); + + assertEquals(expected.iterator(), getIterator(data, 1, 3)); + } + + public void testGetSublistLastPage() { + List expected = Arrays.asList(new Integer[] { new Integer(9) }); + List data = new ArrayList(); + add(data, 9); + + assertEquals(expected.iterator(), getIterator(data, 3, 4)); + } + + public void testGetSublistOutOfBounds() { + List expected = Arrays + .asList(new Integer[] { new Integer(1), new Integer(2), + new Integer(3), new Integer(4), new Integer(5) }); + List data = new ArrayList(); + add(data, 7); + + // This is out of bounds, it should just take the first page, 1-5 + assertEquals(expected.iterator(), getIterator(data, 3, 5)); + } + + public void testGetSublistPageSizeBiggerThanList() { + List expected = Arrays + .asList(new Integer[] { new Integer(1), new Integer(2), + new Integer(3), new Integer(4), new Integer(5) }); + List data = new ArrayList(); + add(data, 5); + + assertEquals(expected.iterator(), getIterator(data, 1, 25)); + assertEquals(expected.iterator(), getIterator(data, 2, 25)); + } + + public void testGetSublistForEntirePage() { + List data = new ArrayList(); + add(data, 5); + + assertEquals(data.iterator(), getIterator(data, 1, 5)); + } + + /** + * Ensures that the data passed to the helper is cast as an object + */ + protected Iterator getIterator(Object data, int pageNumber, int pageSize) { + PaginationHelper helper = new PaginationHelper(pageNumber, pageSize); + return helper.getIterator(data); + } + + protected void print(Iterator iterator, String message) { + while (iterator.hasNext()) { + System.out.println(message + iterator.next()); + } + } + + protected void add(Collection collection, int number) { + for (int i = 0; i < number; i++) { + collection.add(new Integer(i + 1)); + } + } + + protected void assertEquals(Iterator expected, Iterator actual) { + while (expected.hasNext()) { + assertEquals(expected.next(), actual.next()); + } + + assertFalse(actual.hasNext()); + } + +}