mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merge from SEAMIST3
git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@10719 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
454
source/java/org/alfresco/repo/web/util/PagingCursor.java
Normal file
454
source/java/org/alfresco/repo/web/util/PagingCursor.java
Normal file
@@ -0,0 +1,454 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util;
|
||||
|
||||
/**
|
||||
* Paging cursor. A utility for maintaining paged indexes for a collection of N items.
|
||||
*
|
||||
* There are two types of cursor:
|
||||
*
|
||||
* a) Paged
|
||||
*
|
||||
* This type of cursor is driven from a page number and page size. Random access within
|
||||
* the collection is possible by jumping straight to a page. A simple scroll through
|
||||
* the collection is supported by iterating through each next page.
|
||||
*
|
||||
* b) Rows
|
||||
*
|
||||
* This type of cursor is driven from a skip row count and maximum number of rows. Random
|
||||
* access is not supported. The collection of items is simply scrolled through from
|
||||
* start to end by iterating through each next set of rows.
|
||||
*
|
||||
* In either case, a paging cursor provides a start row and end row which may be used
|
||||
* to extract the items for the page from the collection of N items.
|
||||
*
|
||||
* A zero (or less) page size or row maximum means "unlimited".
|
||||
*
|
||||
* Zero or one based Page and Rows indexes are supported. By default, Pages are 1 based and
|
||||
* Rows are 0 based.
|
||||
*
|
||||
* At any time, -1 is returned to represent "out of range" i.e. for next, previous, last page
|
||||
* and next skip count.
|
||||
*
|
||||
* Pseudo-code for traversing through a collection of N items (10 at a time):
|
||||
*
|
||||
* PagingCursor cursor = new PagingCursor();
|
||||
* Page page = cursor.createPageCursor(N, 10, 1);
|
||||
* while (page.isInRange())
|
||||
* {
|
||||
* for (long i = page.getStartRow(); i <= page.getEndRow(); i++)
|
||||
* {
|
||||
* ...collection[i]...
|
||||
* }
|
||||
* page = cursor.createPageCursor(N, 10, page.getNextPage());
|
||||
* }
|
||||
*
|
||||
* Rows rows = cursor.createRowsCursor(N, 10, 0);
|
||||
* while (rows.isInRange())
|
||||
* {
|
||||
* for (long i = page.getStartRow(); i <= page.getEndRow(); i++)
|
||||
* {
|
||||
* ...collection[i]...
|
||||
* }
|
||||
* rows = cursor.createRowsCursor(N, 10, rows.getNextSkipRows());
|
||||
* }
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class PagingCursor
|
||||
{
|
||||
boolean zeroBasedPage = false;
|
||||
boolean zeroBasedRow = true;
|
||||
|
||||
/**
|
||||
* Sets zero based page index
|
||||
*
|
||||
* Note: scoped to this paging cursor instance
|
||||
*
|
||||
* @param zeroBasedPage true => 0 based, false => 1 based
|
||||
*/
|
||||
public void setZeroBasedPage(boolean zeroBasedPage)
|
||||
{
|
||||
this.zeroBasedPage = zeroBasedPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is zero based page index?
|
||||
*
|
||||
* Note: scoped to this paging cursor instance
|
||||
*
|
||||
* @return true => 0 based, false => 1 based
|
||||
*/
|
||||
public boolean isZeroBasedPage()
|
||||
{
|
||||
return zeroBasedPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets zero based row index
|
||||
*
|
||||
* Note: scoped to this paging cursor instance
|
||||
*
|
||||
* @param zeroBasedRow true => 0 based, false => 1 based
|
||||
*/
|
||||
public void setZeroBasedRow(boolean zeroBasedRow)
|
||||
{
|
||||
this.zeroBasedRow = zeroBasedRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is zero based row index?
|
||||
*
|
||||
* Note: scoped to this paging cursor instance
|
||||
*
|
||||
* @return true => 0 based, false => 1 based
|
||||
*/
|
||||
public boolean isZeroBasedRow()
|
||||
{
|
||||
return zeroBasedRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Page based Cursor
|
||||
*
|
||||
* @param totalRows total rows in collection
|
||||
* @param rowsPerPage page size
|
||||
* @param page page number (0 or 1 based)
|
||||
* @return Page Cursor
|
||||
*/
|
||||
public Page createPageCursor(long totalRows, int rowsPerPage, int page)
|
||||
{
|
||||
return new Page(totalRows, rowsPerPage, page, zeroBasedPage, zeroBasedRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Page based Cursor
|
||||
*
|
||||
* @param totalRows total rows in collection
|
||||
* @param rowsPerPage page size
|
||||
* @param page page number (0 or 1 based)
|
||||
* @param zeroBasedPage true => 0 based, false => 1 based
|
||||
* @param zeroBasedRow true => 0 based, false => 1 based
|
||||
* @return Page Cursor
|
||||
*/
|
||||
public Page createPageCursor(long totalRows, int rowsPerPage, int page, boolean zeroBasedPage, boolean zeroBasedRow)
|
||||
{
|
||||
return new Page(totalRows, rowsPerPage, page, zeroBasedPage, zeroBasedRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Rows based Cursor
|
||||
*
|
||||
* @param totalRows total rows in collection
|
||||
* @param maxRows maximum number of rows in page
|
||||
* @param skipRows number of rows to skip (0 - none)
|
||||
* @return Rows Cursor
|
||||
*/
|
||||
public Rows createRowsCursor(long totalRows, long maxRows, long skipRows)
|
||||
{
|
||||
return new Rows(totalRows, maxRows, skipRows, zeroBasedRow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Rows based Cursor
|
||||
*
|
||||
* @param totalRows total rows in collection
|
||||
* @param maxRows maximum number of rows in page
|
||||
* @param skipRows number of rows to skip (0 - none)
|
||||
* @param zeroBasedRow true => 0 based, false => 1 based
|
||||
* @return Rows Cursor
|
||||
*/
|
||||
public Rows createRowsCursor(long totalRows, long maxRows, long skipRows, boolean zeroBasedRow)
|
||||
{
|
||||
return new Rows(totalRows, maxRows, skipRows, zeroBasedRow);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Page based Cursor
|
||||
*/
|
||||
public static class Page
|
||||
{
|
||||
boolean zeroBasedPage;
|
||||
boolean zeroBasedRow;
|
||||
long totalRows;
|
||||
int rowsPerPage;
|
||||
long pageSize;
|
||||
int currentPage;
|
||||
int currentRow;
|
||||
|
||||
/**
|
||||
* Create a Page based Cursor
|
||||
*
|
||||
* @param totalRows total rows in collection
|
||||
* @param rowsPerPage page size
|
||||
* @param page page number (0 or 1 based)
|
||||
* @param zeroBasedPage true => 0 based, false => 1 based
|
||||
* @param zeroBasedRow true => 0 based, false => 1 based
|
||||
*/
|
||||
public Page(long totalRows, int rowsPerPage, int page, boolean zeroBasedPage, boolean zeroBasedRow)
|
||||
{
|
||||
this.zeroBasedPage = zeroBasedPage;
|
||||
this.zeroBasedRow = zeroBasedRow;
|
||||
this.totalRows = totalRows;
|
||||
this.rowsPerPage = rowsPerPage;
|
||||
this.pageSize = (rowsPerPage <=0) ? totalRows : rowsPerPage;
|
||||
this.currentPage = (zeroBasedPage) ? page : page - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets total rows
|
||||
*
|
||||
* @return total rows
|
||||
*/
|
||||
public long getTotalRows()
|
||||
{
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets total number of pages
|
||||
*
|
||||
* @return total number of pages
|
||||
*/
|
||||
public int getTotalPages()
|
||||
{
|
||||
if (totalRows == 0)
|
||||
return 0;
|
||||
|
||||
int totalPages = (int)(totalRows / pageSize);
|
||||
totalPages += (totalRows % pageSize != 0) ? 1 : 0;
|
||||
return totalPages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets page size
|
||||
*
|
||||
* @return page size
|
||||
*/
|
||||
public int getRowsPerPage()
|
||||
{
|
||||
return rowsPerPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the cursor within range of the total number of rows
|
||||
*
|
||||
* @return true => within range of total rows
|
||||
*/
|
||||
public boolean isInRange()
|
||||
{
|
||||
return currentPage >= 0 && getCurrentPage() <= getLastPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current page number
|
||||
*
|
||||
* @return current page number
|
||||
*/
|
||||
public int getCurrentPage()
|
||||
{
|
||||
return currentPage + (zeroBasedPage ? 0 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next page number
|
||||
*
|
||||
* @return next page number (-1 if no more pages)
|
||||
*/
|
||||
public int getNextPage()
|
||||
{
|
||||
return getCurrentPage() < getLastPage() ? getCurrentPage() + 1 : - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the previous page number
|
||||
*
|
||||
* @return previous page number (-1 if no previous pages)
|
||||
*/
|
||||
public int getPreviousPage()
|
||||
{
|
||||
return currentPage > 0 ? getCurrentPage() - 1 : - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the first page number
|
||||
*
|
||||
* @return first page number
|
||||
*/
|
||||
public int getFirstPage()
|
||||
{
|
||||
if (totalRows == 0)
|
||||
return -1;
|
||||
|
||||
return zeroBasedPage ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the last page number
|
||||
*
|
||||
* @return last page number
|
||||
*/
|
||||
public int getLastPage()
|
||||
{
|
||||
if (totalRows == 0)
|
||||
return -1;
|
||||
|
||||
return getTotalPages() - (zeroBasedPage ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the start row within collection for this page
|
||||
*
|
||||
* @return start row index
|
||||
*/
|
||||
public long getStartRow()
|
||||
{
|
||||
if (totalRows == 0)
|
||||
return -1;
|
||||
|
||||
return (currentPage * pageSize) + (zeroBasedRow ? 0 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the end row within collection for this page
|
||||
*
|
||||
* @return end row index
|
||||
*/
|
||||
public long getEndRow()
|
||||
{
|
||||
if (totalRows == 0)
|
||||
return -1;
|
||||
|
||||
return getStartRow() + Math.min(pageSize, totalRows - (currentPage * pageSize)) - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rows based Cursor
|
||||
*/
|
||||
public static class Rows
|
||||
{
|
||||
boolean zeroBasedRow;
|
||||
long totalRows;
|
||||
long skipRows;
|
||||
long maxRows;
|
||||
long pageSize;
|
||||
|
||||
/**
|
||||
* Create a Rows based Cursor
|
||||
*
|
||||
* @param totalRows total rows in collection
|
||||
* @param maxRows maximum number of rows in page
|
||||
* @param skipRows number of rows to skip (0 - none)
|
||||
* @param zeroBasedRow true => 0 based, false => 1 based
|
||||
*/
|
||||
public Rows(long totalRows, long maxRows, long skipRows, boolean zeroBasedRow)
|
||||
{
|
||||
this.zeroBasedRow = zeroBasedRow;
|
||||
this.totalRows = totalRows;
|
||||
this.maxRows = maxRows;
|
||||
this.skipRows = skipRows;
|
||||
this.pageSize = (maxRows <= 0) ? totalRows - skipRows : maxRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total number of rows
|
||||
*
|
||||
* @return total rows
|
||||
*/
|
||||
public long getTotalRows()
|
||||
{
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number rows skipped
|
||||
*
|
||||
* @return skipped row count
|
||||
*/
|
||||
public long getSkipRows()
|
||||
{
|
||||
return skipRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum number of rows to include in this page
|
||||
*
|
||||
* @return maximum of numbers
|
||||
*/
|
||||
public long getMaxRows()
|
||||
{
|
||||
return maxRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the cursor within range of the total number of rows
|
||||
*
|
||||
* @return true => within range of total rows
|
||||
*/
|
||||
public boolean isInRange()
|
||||
{
|
||||
return skipRows >= 0 && skipRows < totalRows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the start row within collection for this page
|
||||
*
|
||||
* @return start row index
|
||||
*/
|
||||
public long getStartRow()
|
||||
{
|
||||
if (totalRows == 0)
|
||||
return -1;
|
||||
|
||||
return skipRows + (zeroBasedRow ? 0 : 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the end row within collection for this page
|
||||
*
|
||||
* @return end row index
|
||||
*/
|
||||
public long getEndRow()
|
||||
{
|
||||
if (totalRows == 0)
|
||||
return -1;
|
||||
|
||||
return getStartRow() + Math.min(pageSize, totalRows - skipRows) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the next skip count
|
||||
*
|
||||
* @return next skip row
|
||||
*/
|
||||
public long getNextSkipRows()
|
||||
{
|
||||
return (skipRows + pageSize < totalRows) ? skipRows + pageSize : -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
341
source/java/org/alfresco/repo/web/util/PagingCursorTest.java
Normal file
341
source/java/org/alfresco/repo/web/util/PagingCursorTest.java
Normal file
@@ -0,0 +1,341 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.alfresco.repo.web.util.PagingCursor.Page;
|
||||
import org.alfresco.repo.web.util.PagingCursor.Rows;
|
||||
|
||||
|
||||
/**
|
||||
* Test Paged and Row Based Cursors
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class PagingCursorTest extends TestCase
|
||||
{
|
||||
protected PagingCursor pageCursor;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
pageCursor = new PagingCursor();
|
||||
}
|
||||
|
||||
public void testZeroBasedBooleans()
|
||||
{
|
||||
assertFalse(pageCursor.isZeroBasedPage());
|
||||
pageCursor.setZeroBasedPage(true);
|
||||
assertTrue(pageCursor.isZeroBasedPage());
|
||||
assertTrue(pageCursor.isZeroBasedRow());
|
||||
pageCursor.setZeroBasedRow(false);
|
||||
assertFalse(pageCursor.isZeroBasedRow());
|
||||
}
|
||||
|
||||
public void testZeroRowsPageCursor()
|
||||
{
|
||||
Page page = pageCursor.createPageCursor(0, 10, 1);
|
||||
assertNotNull(page);
|
||||
assertEquals(0, page.getTotalRows());
|
||||
assertEquals(0, page.getTotalPages());
|
||||
assertEquals(10, page.getRowsPerPage());
|
||||
assertFalse(page.isInRange());
|
||||
assertEquals(1, page.getCurrentPage());
|
||||
assertEquals(-1, page.getFirstPage());
|
||||
assertEquals(-1, page.getLastPage());
|
||||
assertEquals(-1, page.getPreviousPage());
|
||||
assertEquals(-1, page.getNextPage());
|
||||
assertEquals(-1, page.getStartRow());
|
||||
assertEquals(-1, page.getEndRow());
|
||||
}
|
||||
|
||||
public void testOutOfBoundsPageCursor()
|
||||
{
|
||||
Page page1 = pageCursor.createPageCursor(1, 1, 1);
|
||||
assertNotNull(page1);
|
||||
assertTrue(page1.isInRange());
|
||||
Page page2 = pageCursor.createPageCursor(1, 1, 2);
|
||||
assertNotNull(page2);
|
||||
assertFalse(page2.isInRange());
|
||||
Page page3 = pageCursor.createPageCursor(1, 2, 1);
|
||||
assertNotNull(page3);
|
||||
assertTrue(page3.isInRange());
|
||||
Page page4 = pageCursor.createPageCursor(10, 2, 5);
|
||||
assertNotNull(page4);
|
||||
assertTrue(page4.isInRange());
|
||||
Page page5 = pageCursor.createPageCursor(10, 2, 6);
|
||||
assertNotNull(page5);
|
||||
assertFalse(page5.isInRange());
|
||||
Page page6 = pageCursor.createPageCursor(11, 2, 5);
|
||||
assertNotNull(page6);
|
||||
assertTrue(page6.isInRange());
|
||||
Page page7 = pageCursor.createPageCursor(11, 2, 6);
|
||||
assertNotNull(page7);
|
||||
assertTrue(page7.isInRange());
|
||||
Page page8 = pageCursor.createPageCursor(11, 2, 0);
|
||||
assertNotNull(page8);
|
||||
assertFalse(page8.isInRange());
|
||||
|
||||
pageCursor.setZeroBasedPage(true);
|
||||
Page page10 = pageCursor.createPageCursor(1, 1, 0);
|
||||
assertNotNull(page10);
|
||||
assertTrue(page10.isInRange());
|
||||
Page page11 = pageCursor.createPageCursor(1, 1, 1);
|
||||
assertNotNull(page11);
|
||||
assertFalse(page11.isInRange());
|
||||
Page page12 = pageCursor.createPageCursor(1, 2, 0);
|
||||
assertNotNull(page12);
|
||||
assertTrue(page12.isInRange());
|
||||
Page page13 = pageCursor.createPageCursor(10, 2, 4);
|
||||
assertNotNull(page13);
|
||||
assertTrue(page13.isInRange());
|
||||
Page page14 = pageCursor.createPageCursor(10, 2, 5);
|
||||
assertNotNull(page14);
|
||||
assertFalse(page14.isInRange());
|
||||
Page page15 = pageCursor.createPageCursor(11, 2, 4);
|
||||
assertNotNull(page15);
|
||||
assertTrue(page15.isInRange());
|
||||
Page page16 = pageCursor.createPageCursor(11, 2, 5);
|
||||
assertNotNull(page16);
|
||||
assertTrue(page16.isInRange());
|
||||
Page page17 = pageCursor.createPageCursor(11, 2, -1);
|
||||
assertNotNull(page17);
|
||||
assertFalse(page17.isInRange());
|
||||
}
|
||||
|
||||
public void testTotalPageCursor()
|
||||
{
|
||||
Page page1 = pageCursor.createPageCursor(10, 1, 1);
|
||||
assertEquals(10, page1.getTotalRows());
|
||||
assertEquals(10, page1.getTotalPages());
|
||||
Page page2 = pageCursor.createPageCursor(10, 10, 1);
|
||||
assertEquals(10, page2.getTotalRows());
|
||||
assertEquals(1, page2.getTotalPages());
|
||||
Page page3 = pageCursor.createPageCursor(9, 10, 1);
|
||||
assertEquals(9, page3.getTotalRows());
|
||||
assertEquals(1, page3.getTotalPages());
|
||||
Page page4 = pageCursor.createPageCursor(11, 10, 1);
|
||||
assertEquals(11, page4.getTotalRows());
|
||||
assertEquals(2, page4.getTotalPages());
|
||||
Page page5 = pageCursor.createPageCursor(20, 10, 1);
|
||||
assertEquals(20, page5.getTotalRows());
|
||||
assertEquals(2, page5.getTotalPages());
|
||||
}
|
||||
|
||||
public void testPagingPageCursor()
|
||||
{
|
||||
Page page1 = pageCursor.createPageCursor(10, 1, 1);
|
||||
assertEquals(1, page1.getCurrentPage());
|
||||
assertEquals(1, page1.getFirstPage());
|
||||
assertEquals(10, page1.getLastPage());
|
||||
assertEquals(-1, page1.getPreviousPage());
|
||||
assertEquals(2, page1.getNextPage());
|
||||
assertEquals(0, page1.getStartRow());
|
||||
assertEquals(0, page1.getEndRow());
|
||||
Page page2 = pageCursor.createPageCursor(10, 1, 2);
|
||||
assertEquals(2, page2.getCurrentPage());
|
||||
assertEquals(1, page2.getFirstPage());
|
||||
assertEquals(10, page2.getLastPage());
|
||||
assertEquals(1, page2.getPreviousPage());
|
||||
assertEquals(3, page2.getNextPage());
|
||||
assertEquals(1, page2.getStartRow());
|
||||
assertEquals(1, page2.getEndRow());
|
||||
Page page3 = pageCursor.createPageCursor(10, 10, 1);
|
||||
assertEquals(1, page3.getCurrentPage());
|
||||
assertEquals(1, page3.getFirstPage());
|
||||
assertEquals(1, page3.getLastPage());
|
||||
assertEquals(-1, page3.getPreviousPage());
|
||||
assertEquals(-1, page3.getNextPage());
|
||||
assertEquals(0, page3.getStartRow());
|
||||
assertEquals(9, page3.getEndRow());
|
||||
Page page4 = pageCursor.createPageCursor(9, 10, 1);
|
||||
assertEquals(1, page4.getCurrentPage());
|
||||
assertEquals(1, page4.getFirstPage());
|
||||
assertEquals(1, page4.getLastPage());
|
||||
assertEquals(-1, page4.getPreviousPage());
|
||||
assertEquals(-1, page4.getNextPage());
|
||||
assertEquals(0, page4.getStartRow());
|
||||
assertEquals(8, page4.getEndRow());
|
||||
Page page5 = pageCursor.createPageCursor(11, 10, 1);
|
||||
assertEquals(1, page5.getCurrentPage());
|
||||
assertEquals(1, page5.getFirstPage());
|
||||
assertEquals(2, page5.getLastPage());
|
||||
assertEquals(-1, page5.getPreviousPage());
|
||||
assertEquals(2, page5.getNextPage());
|
||||
assertEquals(0, page5.getStartRow());
|
||||
assertEquals(9, page5.getEndRow());
|
||||
Page page6 = pageCursor.createPageCursor(20, 10, 1);
|
||||
assertEquals(1, page6.getCurrentPage());
|
||||
assertEquals(1, page6.getFirstPage());
|
||||
assertEquals(2, page6.getLastPage());
|
||||
assertEquals(-1, page6.getPreviousPage());
|
||||
assertEquals(2, page6.getNextPage());
|
||||
assertEquals(0, page6.getStartRow());
|
||||
assertEquals(9, page6.getEndRow());
|
||||
Page page7 = pageCursor.createPageCursor(20, 10, 2);
|
||||
assertEquals(2, page7.getCurrentPage());
|
||||
assertEquals(1, page7.getFirstPage());
|
||||
assertEquals(2, page7.getLastPage());
|
||||
assertEquals(1, page7.getPreviousPage());
|
||||
assertEquals(-1, page7.getNextPage());
|
||||
assertEquals(10, page7.getStartRow());
|
||||
assertEquals(19, page7.getEndRow());
|
||||
Page page8 = pageCursor.createPageCursor(11, 10, 2);
|
||||
assertEquals(2, page8.getCurrentPage());
|
||||
assertEquals(1, page8.getFirstPage());
|
||||
assertEquals(2, page8.getLastPage());
|
||||
assertEquals(1, page8.getPreviousPage());
|
||||
assertEquals(-1, page8.getNextPage());
|
||||
assertEquals(10, page8.getStartRow());
|
||||
assertEquals(10, page8.getEndRow());
|
||||
}
|
||||
|
||||
public void testUnlimitedPageCursor()
|
||||
{
|
||||
Page page1 = pageCursor.createPageCursor(100, 0, 1);
|
||||
assertTrue(page1.isInRange());
|
||||
assertEquals(1, page1.getCurrentPage());
|
||||
assertEquals(1, page1.getFirstPage());
|
||||
assertEquals(1, page1.getLastPage());
|
||||
assertEquals(-1, page1.getPreviousPage());
|
||||
assertEquals(-1, page1.getNextPage());
|
||||
assertEquals(0, page1.getStartRow());
|
||||
assertEquals(99, page1.getEndRow());
|
||||
Page page2 = pageCursor.createPageCursor(100, 0, 2);
|
||||
assertFalse(page2.isInRange());
|
||||
}
|
||||
|
||||
public void testScrollPageCursor()
|
||||
{
|
||||
int count = 0;
|
||||
long[] coll = new long[100];
|
||||
|
||||
Page page = pageCursor.createPageCursor(100, 10, 1);
|
||||
while (page.isInRange())
|
||||
{
|
||||
for (long i = page.getStartRow(); i <= page.getEndRow(); i++)
|
||||
{
|
||||
coll[(int)i] = i;
|
||||
count++;
|
||||
}
|
||||
page = pageCursor.createPageCursor(100, 10, page.getNextPage());
|
||||
}
|
||||
|
||||
assertEquals(100, count);
|
||||
for (int test = 0; test < count; test++)
|
||||
{
|
||||
assertEquals(test, coll[test]);
|
||||
}
|
||||
}
|
||||
|
||||
public void testZeroRowsIndexCursor()
|
||||
{
|
||||
Rows rows = pageCursor.createRowsCursor(0, 10, 0);
|
||||
assertNotNull(rows);
|
||||
assertEquals(0, rows.getTotalRows());
|
||||
assertFalse(rows.isInRange());
|
||||
assertEquals(10, rows.getMaxRows());
|
||||
assertEquals(-1, rows.getStartRow());
|
||||
assertEquals(-1, rows.getEndRow());
|
||||
assertEquals(-1, rows.getNextSkipRows());
|
||||
}
|
||||
|
||||
public void testOutOfBoundsRowsCursor()
|
||||
{
|
||||
Rows rows1 = pageCursor.createRowsCursor(1, 1, 0);
|
||||
assertNotNull(rows1);
|
||||
assertTrue(rows1.isInRange());
|
||||
Rows rows2 = pageCursor.createRowsCursor(1, 1, 1);
|
||||
assertNotNull(rows2);
|
||||
assertFalse(rows2.isInRange());
|
||||
Rows rows3 = pageCursor.createRowsCursor(1, -1, 0);
|
||||
assertNotNull(rows3);
|
||||
assertTrue(rows3.isInRange());
|
||||
}
|
||||
|
||||
public void testTotalRowsCursor()
|
||||
{
|
||||
Rows rows1 = pageCursor.createRowsCursor(10, 1, 1);
|
||||
assertEquals(10, rows1.getTotalRows());
|
||||
}
|
||||
|
||||
public void testPagingRowsCursor()
|
||||
{
|
||||
Rows rows1 = pageCursor.createRowsCursor(10, 1, 0);
|
||||
assertEquals(0, rows1.getStartRow());
|
||||
assertEquals(0, rows1.getEndRow());
|
||||
assertEquals(1, rows1.getNextSkipRows());
|
||||
Rows rows2 = pageCursor.createRowsCursor(10, 7, 0);
|
||||
assertEquals(0, rows2.getStartRow());
|
||||
assertEquals(6, rows2.getEndRow());
|
||||
assertEquals(7, rows2.getNextSkipRows());
|
||||
Rows rows3 = pageCursor.createRowsCursor(10, 7, 7);
|
||||
assertEquals(7, rows3.getStartRow());
|
||||
assertEquals(9, rows3.getEndRow());
|
||||
assertEquals(-1, rows3.getNextSkipRows());
|
||||
Rows rows4 = pageCursor.createRowsCursor(10, 10, 0);
|
||||
assertEquals(0, rows4.getStartRow());
|
||||
assertEquals(9, rows4.getEndRow());
|
||||
assertEquals(-1, rows4.getNextSkipRows());
|
||||
Rows rows5 = pageCursor.createRowsCursor(10, 11, 0);
|
||||
assertEquals(0, rows5.getStartRow());
|
||||
assertEquals(9, rows5.getEndRow());
|
||||
assertEquals(-1, rows5.getNextSkipRows());
|
||||
}
|
||||
|
||||
public void testUnlimitedRowsCursor()
|
||||
{
|
||||
Rows rows1 = pageCursor.createRowsCursor(100, 0, 0);
|
||||
assertTrue(rows1.isInRange());
|
||||
assertEquals(0, rows1.getStartRow());
|
||||
assertEquals(99, rows1.getEndRow());
|
||||
assertEquals(-1, rows1.getNextSkipRows());
|
||||
}
|
||||
|
||||
public void testScrollRowsCursor()
|
||||
{
|
||||
int count = 0;
|
||||
long[] coll = new long[100];
|
||||
|
||||
Rows rows = pageCursor.createRowsCursor(100, 10, 0);
|
||||
while (rows.isInRange())
|
||||
{
|
||||
for (long i = rows.getStartRow(); i <= rows.getEndRow(); i++)
|
||||
{
|
||||
coll[(int)i] = i;
|
||||
count++;
|
||||
}
|
||||
rows = pageCursor.createRowsCursor(100, 10, rows.getNextSkipRows());
|
||||
}
|
||||
|
||||
assertEquals(100, count);
|
||||
for (int test = 0; test < count; test++)
|
||||
{
|
||||
assertEquals(test, coll[test]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util.paging;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of Paged Results based on an array result set.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class ArrayPagedResults implements PagedResults, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 5905699888354619269L;
|
||||
|
||||
private Object[] results;
|
||||
private Cursor cursor;
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param results results for the page within cursor
|
||||
* @param cursor the cursor
|
||||
*/
|
||||
/*Package*/ ArrayPagedResults(Object[] results, Cursor cursor)
|
||||
{
|
||||
this.results = results;
|
||||
this.cursor = cursor;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.PagedResults#getResults()
|
||||
*/
|
||||
public Object[] getResults()
|
||||
{
|
||||
return results;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.PagedResults#getCursor()
|
||||
*/
|
||||
public Cursor getCursor()
|
||||
{
|
||||
return cursor;
|
||||
}
|
||||
|
||||
}
|
154
source/java/org/alfresco/repo/web/util/paging/Cursor.java
Normal file
154
source/java/org/alfresco/repo/web/util/paging/Cursor.java
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util.paging;
|
||||
|
||||
|
||||
/**
|
||||
* Cursor - Allows for scrolling through a row set.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public interface Cursor
|
||||
{
|
||||
/**
|
||||
* Gets the page type
|
||||
*
|
||||
* @return page type
|
||||
*/
|
||||
public String getPageType();
|
||||
|
||||
/**
|
||||
* Gets the page size
|
||||
*
|
||||
* @return page size
|
||||
*/
|
||||
int getPageSize();
|
||||
|
||||
/**
|
||||
* Gets total number of pages
|
||||
*
|
||||
* @return total number of pages
|
||||
*/
|
||||
int getTotalPages();
|
||||
|
||||
/**
|
||||
* Gets total rows
|
||||
*
|
||||
* @return total rows
|
||||
*/
|
||||
int getTotalRows();
|
||||
|
||||
/**
|
||||
* Gets the current page number
|
||||
*
|
||||
* @return current page number
|
||||
*/
|
||||
int getCurrentPage();
|
||||
|
||||
/**
|
||||
* Gets the first page number
|
||||
*
|
||||
* @return first page number
|
||||
*/
|
||||
int getFirstPage();
|
||||
|
||||
/**
|
||||
* Gets the last page number
|
||||
*
|
||||
* @return last page number
|
||||
*/
|
||||
int getLastPage();
|
||||
|
||||
/**
|
||||
* Gets the next page number
|
||||
*
|
||||
* @return next page number (-1 if no more pages)
|
||||
*/
|
||||
int getNextPage();
|
||||
|
||||
/**
|
||||
* Gets the previous page number
|
||||
*
|
||||
* @return previous page number (-1 if no previous pages)
|
||||
*/
|
||||
int getPrevPage();
|
||||
|
||||
/**
|
||||
* Is the page within range of the result set
|
||||
*
|
||||
* @return true => page is within range
|
||||
*/
|
||||
boolean isInRange();
|
||||
|
||||
/**
|
||||
* Is there a known first page?
|
||||
*
|
||||
* @return true => getFirstPage() will succeed
|
||||
*/
|
||||
boolean getHasFirstPage();
|
||||
|
||||
/**
|
||||
* Is there a known last page?
|
||||
*
|
||||
* @return true => getLastPage() will succeed
|
||||
*/
|
||||
boolean getHasLastPage();
|
||||
|
||||
/**
|
||||
* Is there a known next page?
|
||||
*
|
||||
* @return true => getNextPage() will succeed
|
||||
*/
|
||||
boolean getHasNextPage();
|
||||
|
||||
/**
|
||||
* Is there a known prev page?
|
||||
*
|
||||
* @return true => getPrevPage() will succeed
|
||||
*/
|
||||
boolean getHasPrevPage();
|
||||
|
||||
/**
|
||||
* Gets the start row within result set for this page
|
||||
*
|
||||
* @return start row index
|
||||
*/
|
||||
int getStartRow();
|
||||
|
||||
/**
|
||||
* Gets the end row within result set for this page
|
||||
*
|
||||
* @return end row index
|
||||
*/
|
||||
int getEndRow();
|
||||
|
||||
/**
|
||||
* Gets the count of rows within result set for this page
|
||||
*
|
||||
* @return row count
|
||||
*/
|
||||
int getRowCount();
|
||||
|
||||
}
|
96
source/java/org/alfresco/repo/web/util/paging/Page.java
Normal file
96
source/java/org/alfresco/repo/web/util/paging/Page.java
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util.paging;
|
||||
|
||||
|
||||
/**
|
||||
* A Page within a Cursor.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class Page
|
||||
{
|
||||
Paging.PageType pageType;
|
||||
boolean zeroBasedIdx;
|
||||
int startIdx;
|
||||
int pageSize;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param pageType Page or Window
|
||||
* @param zeroBasedIdx true => start index from 0
|
||||
* @param startIdx start index
|
||||
* @param pageSize page size
|
||||
*/
|
||||
/*package*/ Page(Paging.PageType pageType, boolean zeroBasedIdx, int startIdx, int pageSize)
|
||||
{
|
||||
this.pageType = pageType;
|
||||
this.zeroBasedIdx = zeroBasedIdx;
|
||||
this.startIdx = startIdx;
|
||||
this.pageSize = pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Page Type
|
||||
*
|
||||
* @return page type
|
||||
*/
|
||||
/*package*/ Paging.PageType getType()
|
||||
{
|
||||
return pageType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the page number
|
||||
*
|
||||
* @return page number
|
||||
*/
|
||||
public int getNumber()
|
||||
{
|
||||
return startIdx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the page size
|
||||
*
|
||||
* @return page size
|
||||
*/
|
||||
public int getSize()
|
||||
{
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is zero based page index
|
||||
*
|
||||
* @return true => page number starts from zero
|
||||
*/
|
||||
public boolean isZeroBasedIdx()
|
||||
{
|
||||
return zeroBasedIdx;
|
||||
}
|
||||
|
||||
}
|
224
source/java/org/alfresco/repo/web/util/paging/PagedCursor.java
Normal file
224
source/java/org/alfresco/repo/web/util/paging/PagedCursor.java
Normal file
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util.paging;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.repo.web.util.paging.Paging.PageType;
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of cursor based on notion of a Page.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class PagedCursor implements Cursor, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = -1041155610387669590L;
|
||||
|
||||
private boolean zeroBasedPage;
|
||||
private boolean zeroBasedRow;
|
||||
private int totalRows;
|
||||
private int pageSize;
|
||||
private int rowsPerPage;
|
||||
private int page;
|
||||
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param zeroBasedRow true => row index starts at zero
|
||||
* @param totalRows total number of rows (-1 for don't know)
|
||||
* @param zeroBasedPage true => page number starts at zero
|
||||
* @param page page number
|
||||
* @param pageSize page size
|
||||
*/
|
||||
/*package*/ PagedCursor(boolean zeroBasedRow, int totalRows, boolean zeroBasedPage, int page, int pageSize)
|
||||
{
|
||||
this.zeroBasedRow = zeroBasedRow;
|
||||
this.totalRows = totalRows;
|
||||
this.zeroBasedPage = zeroBasedPage;
|
||||
this.page = (zeroBasedPage) ? page : page - 1;
|
||||
this.pageSize = pageSize;
|
||||
this.rowsPerPage = (pageSize <=0) ? totalRows : pageSize;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getPageType()
|
||||
*/
|
||||
public String getPageType()
|
||||
{
|
||||
return PageType.PAGE.toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getPageSize()
|
||||
*/
|
||||
public int getPageSize()
|
||||
{
|
||||
return pageSize;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getTotalPages()
|
||||
*/
|
||||
public int getTotalPages()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return 0;
|
||||
|
||||
int totalPages = (int)(totalRows / rowsPerPage);
|
||||
totalPages += (totalRows % rowsPerPage != 0) ? 1 : 0;
|
||||
return totalPages;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getTotalRows()
|
||||
*/
|
||||
public int getTotalRows()
|
||||
{
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getCurrentPage()
|
||||
*/
|
||||
public int getCurrentPage()
|
||||
{
|
||||
return page + (zeroBasedPage ? 0 : 1);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getFirstPage()
|
||||
*/
|
||||
public int getFirstPage()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return -1;
|
||||
|
||||
return zeroBasedPage ? 0 : 1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getLastPage()
|
||||
*/
|
||||
public int getLastPage()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return -1;
|
||||
|
||||
return getTotalPages() - (zeroBasedPage ? 1 : 0);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getNextPage()
|
||||
*/
|
||||
public int getNextPage()
|
||||
{
|
||||
return getCurrentPage() < getLastPage() ? getCurrentPage() + 1 : - 1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getPrevPage()
|
||||
*/
|
||||
public int getPrevPage()
|
||||
{
|
||||
return page > 0 ? getCurrentPage() - 1 : - 1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#isInRange()
|
||||
*/
|
||||
public boolean isInRange()
|
||||
{
|
||||
return page >= 0 && getCurrentPage() <= getLastPage();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#hasFirstPage()
|
||||
*/
|
||||
public boolean getHasFirstPage()
|
||||
{
|
||||
return getFirstPage() != -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#hasLastPage()
|
||||
*/
|
||||
public boolean getHasLastPage()
|
||||
{
|
||||
return getLastPage() != -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#hasNextPage()
|
||||
*/
|
||||
public boolean getHasNextPage()
|
||||
{
|
||||
return getNextPage() != -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#hasPrevPage()
|
||||
*/
|
||||
public boolean getHasPrevPage()
|
||||
{
|
||||
return getPrevPage() != -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getStartRow()
|
||||
*/
|
||||
public int getStartRow()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return 0;
|
||||
|
||||
return (page * rowsPerPage) + (zeroBasedRow ? 0 : 1);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getEndRow()
|
||||
*/
|
||||
public int getEndRow()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return -1;
|
||||
|
||||
return getStartRow() + Math.min(rowsPerPage, totalRows - (page * rowsPerPage)) - 1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getRowCount()
|
||||
*/
|
||||
public int getRowCount()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return 0;
|
||||
|
||||
return getEndRow() - getStartRow() + 1;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util.paging;
|
||||
|
||||
|
||||
/**
|
||||
* A Paged Result Set
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public interface PagedResults
|
||||
{
|
||||
/**
|
||||
* An array of the results for the given page within the cursor
|
||||
* @return the paged results
|
||||
*/
|
||||
Object[] getResults();
|
||||
|
||||
/**
|
||||
* Gets the cursor
|
||||
*
|
||||
* @return cursor
|
||||
*/
|
||||
Cursor getCursor();
|
||||
}
|
193
source/java/org/alfresco/repo/web/util/paging/Paging.java
Normal file
193
source/java/org/alfresco/repo/web/util/paging/Paging.java
Normal file
@@ -0,0 +1,193 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util.paging;
|
||||
|
||||
/**
|
||||
* Paging. A utility for maintaining paged indexes for a collection of N items.
|
||||
*
|
||||
* There are two types of cursor:
|
||||
*
|
||||
* a) Paged
|
||||
*
|
||||
* This type of cursor is driven from a page number and page size. Random access within
|
||||
* the collection is possible by jumping straight to a page. A simple scroll through
|
||||
* the collection is supported by iterating through each next page.
|
||||
*
|
||||
* b) Windowed
|
||||
*
|
||||
* This type of cursor is driven from a skip row count and maximum number of rows. Random
|
||||
* access is not supported. The collection of items is simply scrolled through from
|
||||
* start to end by iterating through each next set of rows.
|
||||
*
|
||||
* In either case, a paging cursor provides a start row and end row which may be used
|
||||
* to extract the items for the page from the collection of N items.
|
||||
*
|
||||
* A zero (or less) page size or row maximum means "unlimited".
|
||||
*
|
||||
* Zero or one based Page and Rows indexes are supported. By default, Pages are 1 based and
|
||||
* Rows are 0 based.
|
||||
*
|
||||
* At any time, -1 is returned to represent "out of range" i.e. for next, previous, last page.
|
||||
*
|
||||
* Pseudo-code for traversing through a collection of N items (10 at a time):
|
||||
*
|
||||
* Paging paging = new Paging();
|
||||
* Cursor page = paging.createCursor(N, paging.createPage(1, 10));
|
||||
* while (page.isInRange())
|
||||
* {
|
||||
* for (long i = page.getStartRow(); i <= page.getEndRow(); i++)
|
||||
* {
|
||||
* ...collection[i]...
|
||||
* }
|
||||
* page = paging.createCursor(N, paging.createPage(page.getNextPage(), page.getPageSize());
|
||||
* }
|
||||
*
|
||||
* Cursor window = paging.createCursor(N, paging.createWindow(0, 10));
|
||||
* while (window.isInRange())
|
||||
* {
|
||||
* for (long i = window.getStartRow(); i <= window.getEndRow(); i++)
|
||||
* {
|
||||
* ...collection[i]...
|
||||
* }
|
||||
* window = paging.createCursor(N, paging.createWindow(window.getNextPage(), window.getPageSize());
|
||||
* }
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class Paging
|
||||
{
|
||||
public enum PageType
|
||||
{
|
||||
PAGE,
|
||||
WINDOW
|
||||
};
|
||||
|
||||
boolean zeroBasedPage = false;
|
||||
boolean zeroBasedRow = true;
|
||||
|
||||
/**
|
||||
* Sets zero based page index
|
||||
*
|
||||
* Note: scoped to this paging cursor instance
|
||||
*
|
||||
* @param zeroBasedPage true => 0 based, false => 1 based
|
||||
*/
|
||||
public void setZeroBasedPage(boolean zeroBasedPage)
|
||||
{
|
||||
this.zeroBasedPage = zeroBasedPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is zero based page index?
|
||||
*
|
||||
* Note: scoped to this paging cursor instance
|
||||
*
|
||||
* @return true => 0 based, false => 1 based
|
||||
*/
|
||||
public boolean isZeroBasedPage()
|
||||
{
|
||||
return zeroBasedPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets zero based row index
|
||||
*
|
||||
* Note: scoped to this paging cursor instance
|
||||
*
|
||||
* @param zeroBasedRow true => 0 based, false => 1 based
|
||||
*/
|
||||
public void setZeroBasedRow(boolean zeroBasedRow)
|
||||
{
|
||||
this.zeroBasedRow = zeroBasedRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is zero based row index?
|
||||
*
|
||||
* Note: scoped to this paging cursor instance
|
||||
*
|
||||
* @return true => 0 based, false => 1 based
|
||||
*/
|
||||
public boolean isZeroBasedRow()
|
||||
{
|
||||
return zeroBasedRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Page
|
||||
*
|
||||
* @param pageNumber page number
|
||||
* @param pageSize page size
|
||||
* @return the page
|
||||
*/
|
||||
public Page createPage(int pageNumber, int pageSize)
|
||||
{
|
||||
return new Page(PageType.PAGE, zeroBasedPage, pageNumber, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Window
|
||||
* @param skipRows number of rows to skip
|
||||
* @param maxRows maximum number of rows in window
|
||||
* @return the window
|
||||
*/
|
||||
public Page createWindow(int skipRows, int maxRows)
|
||||
{
|
||||
return new Page(PageType.WINDOW, zeroBasedRow, skipRows, maxRows);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Cursor
|
||||
*
|
||||
* @param totalRows total number of rows in cursor (< 0 for don't know)
|
||||
* @param page the page / window within cursor
|
||||
* @return the cursor
|
||||
*/
|
||||
public Cursor createCursor(int totalRows, Page page)
|
||||
{
|
||||
if (page.getType() == PageType.PAGE)
|
||||
{
|
||||
return new PagedCursor(zeroBasedRow, totalRows, page.zeroBasedIdx, page.startIdx, page.pageSize);
|
||||
}
|
||||
else if (page.getType() == PageType.WINDOW)
|
||||
{
|
||||
return new WindowedCursor(zeroBasedRow, totalRows, page.startIdx, page.pageSize);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Paged Result Set
|
||||
*
|
||||
* @param results the results for the page within the cursor
|
||||
* @param cursor the cursor
|
||||
* @return the paged result set
|
||||
*/
|
||||
public PagedResults createPagedResults(Object[] results, Cursor cursor)
|
||||
{
|
||||
return new ArrayPagedResults(results, cursor);
|
||||
}
|
||||
|
||||
}
|
371
source/java/org/alfresco/repo/web/util/paging/PagingTest.java
Normal file
371
source/java/org/alfresco/repo/web/util/paging/PagingTest.java
Normal file
@@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util.paging;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
|
||||
/**
|
||||
* Test Paged and Window Based Cursors
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class PagingTest extends TestCase
|
||||
{
|
||||
protected Paging paging;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception
|
||||
{
|
||||
paging = new Paging();
|
||||
}
|
||||
|
||||
public void testZeroBasedBooleans()
|
||||
{
|
||||
assertFalse(paging.isZeroBasedPage());
|
||||
paging.setZeroBasedPage(true);
|
||||
assertTrue(paging.isZeroBasedPage());
|
||||
assertTrue(paging.isZeroBasedRow());
|
||||
paging.setZeroBasedRow(false);
|
||||
assertFalse(paging.isZeroBasedRow());
|
||||
}
|
||||
|
||||
public void testCreatePage()
|
||||
{
|
||||
Page page = paging.createPage(1, 10);
|
||||
assertNotNull(page);
|
||||
assertEquals(Paging.PageType.PAGE, page.getType());
|
||||
assertFalse(page.isZeroBasedIdx());
|
||||
assertEquals(1, page.getNumber());
|
||||
assertEquals(10, page.getSize());
|
||||
|
||||
Page window = paging.createWindow(1, 10);
|
||||
assertNotNull(window);
|
||||
assertEquals(Paging.PageType.WINDOW, window.getType());
|
||||
assertTrue(window.isZeroBasedIdx());
|
||||
assertEquals(1, window.getNumber());
|
||||
assertEquals(10, window.getSize());
|
||||
}
|
||||
|
||||
public void testZeroRowsPage()
|
||||
{
|
||||
Cursor cursor = paging.createCursor(0, paging.createPage(1, 10));
|
||||
assertNotNull(cursor);
|
||||
assertEquals(0, cursor.getTotalRows());
|
||||
assertEquals(0, cursor.getTotalPages());
|
||||
assertEquals(10, cursor.getPageSize());
|
||||
assertFalse(cursor.isInRange());
|
||||
assertEquals(1, cursor.getCurrentPage());
|
||||
assertEquals(-1, cursor.getFirstPage());
|
||||
assertEquals(-1, cursor.getLastPage());
|
||||
assertEquals(-1, cursor.getPrevPage());
|
||||
assertEquals(-1, cursor.getNextPage());
|
||||
assertEquals(0, cursor.getStartRow());
|
||||
assertEquals(-1, cursor.getEndRow());
|
||||
assertEquals(0, cursor.getRowCount());
|
||||
}
|
||||
|
||||
public void testOutOfBoundsPage()
|
||||
{
|
||||
Cursor cursor1 = paging.createCursor(1, paging.createPage(1, 1));
|
||||
assertNotNull(cursor1);
|
||||
assertTrue(cursor1.isInRange());
|
||||
Cursor cursor2 = paging.createCursor(1, paging.createPage(2, 1));
|
||||
assertNotNull(cursor2);
|
||||
assertFalse(cursor2.isInRange());
|
||||
Cursor cursor3 = paging.createCursor(1, paging.createPage(1, 2));
|
||||
assertNotNull(cursor3);
|
||||
assertTrue(cursor3.isInRange());
|
||||
Cursor cursor4 = paging.createCursor(10, paging.createPage(5, 2));
|
||||
assertNotNull(cursor4);
|
||||
assertTrue(cursor4.isInRange());
|
||||
Cursor cursor5 = paging.createCursor(10, paging.createPage(6, 2));
|
||||
assertNotNull(cursor5);
|
||||
assertFalse(cursor5.isInRange());
|
||||
Cursor cursor6 = paging.createCursor(11, paging.createPage(5, 2));
|
||||
assertNotNull(cursor6);
|
||||
assertTrue(cursor6.isInRange());
|
||||
Cursor cursor7 = paging.createCursor(11, paging.createPage(6, 2));
|
||||
assertNotNull(cursor7);
|
||||
assertTrue(cursor7.isInRange());
|
||||
Cursor cursor8 = paging.createCursor(11, paging.createPage(0, 2));
|
||||
assertNotNull(cursor8);
|
||||
assertFalse(cursor8.isInRange());
|
||||
|
||||
paging.setZeroBasedPage(true);
|
||||
Cursor cursor10 = paging.createCursor(1, paging.createPage(0, 1));
|
||||
assertNotNull(cursor10);
|
||||
assertTrue(cursor10.isInRange());
|
||||
Cursor cursor11 = paging.createCursor(1, paging.createPage(1, 1));
|
||||
assertNotNull(cursor11);
|
||||
assertFalse(cursor11.isInRange());
|
||||
Cursor cursor12 = paging.createCursor(1, paging.createPage(0, 2));
|
||||
assertNotNull(cursor12);
|
||||
assertTrue(cursor12.isInRange());
|
||||
Cursor cursor13 = paging.createCursor(10, paging.createPage(4, 2));
|
||||
assertNotNull(cursor13);
|
||||
assertTrue(cursor13.isInRange());
|
||||
Cursor cursor14 = paging.createCursor(10, paging.createPage(5, 2));
|
||||
assertNotNull(cursor14);
|
||||
assertFalse(cursor14.isInRange());
|
||||
Cursor cursor15 = paging.createCursor(11, paging.createPage(4, 2));
|
||||
assertNotNull(cursor15);
|
||||
assertTrue(cursor15.isInRange());
|
||||
Cursor cursor16 = paging.createCursor(11, paging.createPage(5, 2));
|
||||
assertNotNull(cursor16);
|
||||
assertTrue(cursor16.isInRange());
|
||||
Cursor cursor17 = paging.createCursor(11, paging.createPage(-1, 2));
|
||||
assertNotNull(cursor17);
|
||||
assertFalse(cursor17.isInRange());
|
||||
}
|
||||
|
||||
public void testTotalPage()
|
||||
{
|
||||
Cursor cursor1 = paging.createCursor(10, paging.createPage(1, 1));
|
||||
assertEquals(10, cursor1.getTotalRows());
|
||||
assertEquals(10, cursor1.getTotalPages());
|
||||
Cursor cursor2 = paging.createCursor(10, paging.createPage(1, 10));
|
||||
assertEquals(10, cursor2.getTotalRows());
|
||||
assertEquals(1, cursor2.getTotalPages());
|
||||
Cursor cursor3 = paging.createCursor(9, paging.createPage(1, 10));
|
||||
assertEquals(9, cursor3.getTotalRows());
|
||||
assertEquals(1, cursor3.getTotalPages());
|
||||
Cursor cursor4 = paging.createCursor(11, paging.createPage(1, 10));
|
||||
assertEquals(11, cursor4.getTotalRows());
|
||||
assertEquals(2, cursor4.getTotalPages());
|
||||
Cursor cursor5 = paging.createCursor(20, paging.createPage(1, 10));
|
||||
assertEquals(20, cursor5.getTotalRows());
|
||||
assertEquals(2, cursor5.getTotalPages());
|
||||
}
|
||||
|
||||
public void testCursorPage()
|
||||
{
|
||||
Cursor cursor1 = paging.createCursor(10, paging.createPage(1, 1));
|
||||
assertEquals(1, cursor1.getCurrentPage());
|
||||
assertEquals(1, cursor1.getFirstPage());
|
||||
assertEquals(10, cursor1.getLastPage());
|
||||
assertEquals(-1, cursor1.getPrevPage());
|
||||
assertEquals(2, cursor1.getNextPage());
|
||||
assertEquals(0, cursor1.getStartRow());
|
||||
assertEquals(0, cursor1.getEndRow());
|
||||
assertEquals(1, cursor1.getRowCount());
|
||||
Cursor cursor2 = paging.createCursor(10, paging.createPage(2, 1));
|
||||
assertEquals(2, cursor2.getCurrentPage());
|
||||
assertEquals(1, cursor2.getFirstPage());
|
||||
assertEquals(10, cursor2.getLastPage());
|
||||
assertEquals(1, cursor2.getPrevPage());
|
||||
assertEquals(3, cursor2.getNextPage());
|
||||
assertEquals(1, cursor2.getStartRow());
|
||||
assertEquals(1, cursor2.getEndRow());
|
||||
assertEquals(1, cursor2.getRowCount());
|
||||
Cursor cursor3 = paging.createCursor(10, paging.createPage(1, 10));
|
||||
assertEquals(1, cursor3.getCurrentPage());
|
||||
assertEquals(1, cursor3.getFirstPage());
|
||||
assertEquals(1, cursor3.getLastPage());
|
||||
assertEquals(-1, cursor3.getPrevPage());
|
||||
assertEquals(-1, cursor3.getNextPage());
|
||||
assertEquals(0, cursor3.getStartRow());
|
||||
assertEquals(9, cursor3.getEndRow());
|
||||
assertEquals(10, cursor3.getRowCount());
|
||||
Cursor cursor4 = paging.createCursor(9, paging.createPage(1, 10));
|
||||
assertEquals(1, cursor4.getCurrentPage());
|
||||
assertEquals(1, cursor4.getFirstPage());
|
||||
assertEquals(1, cursor4.getLastPage());
|
||||
assertEquals(-1, cursor4.getPrevPage());
|
||||
assertEquals(-1, cursor4.getNextPage());
|
||||
assertEquals(0, cursor4.getStartRow());
|
||||
assertEquals(8, cursor4.getEndRow());
|
||||
assertEquals(9, cursor4.getRowCount());
|
||||
Cursor cursor5 = paging.createCursor(11, paging.createPage(1, 10));
|
||||
assertEquals(1, cursor5.getCurrentPage());
|
||||
assertEquals(1, cursor5.getFirstPage());
|
||||
assertEquals(2, cursor5.getLastPage());
|
||||
assertEquals(-1, cursor5.getPrevPage());
|
||||
assertEquals(2, cursor5.getNextPage());
|
||||
assertEquals(0, cursor5.getStartRow());
|
||||
assertEquals(9, cursor5.getEndRow());
|
||||
assertEquals(10, cursor5.getRowCount());
|
||||
Cursor cursor6 = paging.createCursor(20, paging.createPage(1, 10));
|
||||
assertEquals(1, cursor6.getCurrentPage());
|
||||
assertEquals(1, cursor6.getFirstPage());
|
||||
assertEquals(2, cursor6.getLastPage());
|
||||
assertEquals(-1, cursor6.getPrevPage());
|
||||
assertEquals(2, cursor6.getNextPage());
|
||||
assertEquals(0, cursor6.getStartRow());
|
||||
assertEquals(9, cursor6.getEndRow());
|
||||
assertEquals(10, cursor6.getRowCount());
|
||||
Cursor cursor7 = paging.createCursor(20, paging.createPage(2, 10));
|
||||
assertEquals(2, cursor7.getCurrentPage());
|
||||
assertEquals(1, cursor7.getFirstPage());
|
||||
assertEquals(2, cursor7.getLastPage());
|
||||
assertEquals(1, cursor7.getPrevPage());
|
||||
assertEquals(-1, cursor7.getNextPage());
|
||||
assertEquals(10, cursor7.getStartRow());
|
||||
assertEquals(19, cursor7.getEndRow());
|
||||
assertEquals(10, cursor7.getRowCount());
|
||||
Cursor cursor8 = paging.createCursor(11, paging.createPage(2, 10));
|
||||
assertEquals(2, cursor8.getCurrentPage());
|
||||
assertEquals(1, cursor8.getFirstPage());
|
||||
assertEquals(2, cursor8.getLastPage());
|
||||
assertEquals(1, cursor8.getPrevPage());
|
||||
assertEquals(-1, cursor8.getNextPage());
|
||||
assertEquals(10, cursor8.getStartRow());
|
||||
assertEquals(10, cursor8.getEndRow());
|
||||
assertEquals(1, cursor8.getRowCount());
|
||||
}
|
||||
|
||||
public void testUnlimitedPage()
|
||||
{
|
||||
Cursor cursor1 = paging.createCursor(100, paging.createPage(1, 0));
|
||||
assertTrue(cursor1.isInRange());
|
||||
assertEquals(1, cursor1.getCurrentPage());
|
||||
assertEquals(1, cursor1.getFirstPage());
|
||||
assertEquals(1, cursor1.getLastPage());
|
||||
assertEquals(-1, cursor1.getPrevPage());
|
||||
assertEquals(-1, cursor1.getNextPage());
|
||||
assertEquals(0, cursor1.getStartRow());
|
||||
assertEquals(99, cursor1.getEndRow());
|
||||
Cursor cursor2 = paging.createCursor(100, paging.createPage(2, 0));
|
||||
assertFalse(cursor2.isInRange());
|
||||
}
|
||||
|
||||
public void testScrollPage()
|
||||
{
|
||||
int count = 0;
|
||||
long[] coll = new long[100];
|
||||
|
||||
Cursor cursor = paging.createCursor(coll.length, paging.createPage(1, 10));
|
||||
while (cursor.isInRange())
|
||||
{
|
||||
for (long i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
|
||||
{
|
||||
coll[(int)i] = i;
|
||||
count++;
|
||||
}
|
||||
cursor = paging.createCursor(coll.length, paging.createPage(cursor.getNextPage(), cursor.getPageSize()));
|
||||
}
|
||||
|
||||
assertEquals(100, count);
|
||||
for (int test = 0; test < count; test++)
|
||||
{
|
||||
assertEquals(test, coll[test]);
|
||||
}
|
||||
}
|
||||
|
||||
public void testZeroRowsWindow()
|
||||
{
|
||||
Cursor rows = paging.createCursor(0, paging.createWindow(0, 10));
|
||||
assertNotNull(rows);
|
||||
assertEquals(0, rows.getTotalRows());
|
||||
assertFalse(rows.isInRange());
|
||||
assertEquals(10, rows.getPageSize());
|
||||
assertEquals(0, rows.getStartRow());
|
||||
assertEquals(-1, rows.getEndRow());
|
||||
assertEquals(0, rows.getRowCount());
|
||||
assertEquals(-1, rows.getNextPage());
|
||||
}
|
||||
|
||||
public void testOutOfBoundsWindow()
|
||||
{
|
||||
Cursor cursor1 = paging.createCursor(1, paging.createWindow(0, 1));
|
||||
assertNotNull(cursor1);
|
||||
assertTrue(cursor1.isInRange());
|
||||
Cursor cursor2 = paging.createCursor(1, paging.createWindow(1, 1));
|
||||
assertNotNull(cursor2);
|
||||
assertFalse(cursor2.isInRange());
|
||||
Cursor cursor3 = paging.createCursor(1, paging.createWindow(0, -1));
|
||||
assertNotNull(cursor3);
|
||||
assertTrue(cursor3.isInRange());
|
||||
}
|
||||
|
||||
public void testTotalWindow()
|
||||
{
|
||||
Cursor cursor1 = paging.createCursor(10, paging.createWindow(1, 1));
|
||||
assertEquals(10, cursor1.getTotalRows());
|
||||
}
|
||||
|
||||
public void testCursorWindow()
|
||||
{
|
||||
Cursor cursor1 = paging.createCursor(10, paging.createWindow(0, 1));
|
||||
assertEquals(0, cursor1.getStartRow());
|
||||
assertEquals(0, cursor1.getEndRow());
|
||||
assertEquals(1, cursor1.getRowCount());
|
||||
assertEquals(1, cursor1.getNextPage());
|
||||
Cursor cursor2 = paging.createCursor(10, paging.createWindow(0, 7));
|
||||
assertEquals(0, cursor2.getStartRow());
|
||||
assertEquals(6, cursor2.getEndRow());
|
||||
assertEquals(7, cursor2.getRowCount());
|
||||
assertEquals(7, cursor2.getNextPage());
|
||||
Cursor cursor3 = paging.createCursor(10, paging.createWindow(7, 7));
|
||||
assertEquals(7, cursor3.getStartRow());
|
||||
assertEquals(9, cursor3.getEndRow());
|
||||
assertEquals(3, cursor3.getRowCount());
|
||||
assertEquals(-1, cursor3.getNextPage());
|
||||
Cursor cursor4 = paging.createCursor(10, paging.createWindow(0, 10));
|
||||
assertEquals(0, cursor4.getStartRow());
|
||||
assertEquals(9, cursor4.getEndRow());
|
||||
assertEquals(10, cursor4.getRowCount());
|
||||
assertEquals(-1, cursor4.getNextPage());
|
||||
Cursor cursor5 = paging.createCursor(10, paging.createWindow(0, 11));
|
||||
assertEquals(0, cursor5.getStartRow());
|
||||
assertEquals(9, cursor5.getEndRow());
|
||||
assertEquals(10, cursor5.getRowCount());
|
||||
assertEquals(-1, cursor5.getNextPage());
|
||||
}
|
||||
|
||||
public void testUnlimitedWindow()
|
||||
{
|
||||
Cursor cursor1 = paging.createCursor(100, paging.createWindow(0, 0));
|
||||
assertTrue(cursor1.isInRange());
|
||||
assertEquals(0, cursor1.getStartRow());
|
||||
assertEquals(99, cursor1.getEndRow());
|
||||
assertEquals(100, cursor1.getRowCount());
|
||||
assertEquals(-1, cursor1.getNextPage());
|
||||
}
|
||||
|
||||
public void testScrollWindow()
|
||||
{
|
||||
int count = 0;
|
||||
long[] coll = new long[100];
|
||||
|
||||
Cursor cursor = paging.createCursor(coll.length, paging.createWindow(0, 10));
|
||||
while (cursor.isInRange())
|
||||
{
|
||||
for (long i = cursor.getStartRow(); i <= cursor.getEndRow(); i++)
|
||||
{
|
||||
coll[(int)i] = i;
|
||||
count++;
|
||||
}
|
||||
cursor = paging.createCursor(coll.length, paging.createWindow(cursor.getNextPage(), cursor.getPageSize()));
|
||||
}
|
||||
|
||||
assertEquals(100, count);
|
||||
for (int test = 0; test < count; test++)
|
||||
{
|
||||
assertEquals(test, coll[test]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2007 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have recieved a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.web.util.paging;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.alfresco.repo.web.util.paging.Paging.PageType;
|
||||
|
||||
|
||||
/**
|
||||
* Cursor implementation based on notion of a Window.
|
||||
*
|
||||
* @author davidc
|
||||
*/
|
||||
public class WindowedCursor implements Cursor, Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 521131539938276413L;
|
||||
|
||||
private boolean zeroBasedRow;
|
||||
private int totalRows;
|
||||
private int skipRows;
|
||||
private int maxRows;
|
||||
private int rowsPerPage;
|
||||
|
||||
/**
|
||||
* Construct
|
||||
*
|
||||
* @param zeroBasedRow true => 0 based, false => 1 based
|
||||
* @param totalRows total rows in collection
|
||||
* @param skipRows number of rows to skip (0 - none)
|
||||
* @param maxRows maximum number of rows in window
|
||||
*/
|
||||
WindowedCursor(boolean zeroBasedRow, int totalRows, int skipRows, int maxRows)
|
||||
{
|
||||
this.zeroBasedRow = zeroBasedRow;
|
||||
this.totalRows = totalRows;
|
||||
this.skipRows = skipRows;
|
||||
this.maxRows = maxRows;
|
||||
this.rowsPerPage = (maxRows <= 0) ? totalRows - skipRows : maxRows;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getPageType()
|
||||
*/
|
||||
public String getPageType()
|
||||
{
|
||||
return PageType.WINDOW.toString();
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getPageSize()
|
||||
*/
|
||||
public int getPageSize()
|
||||
{
|
||||
return maxRows;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getTotalPages()
|
||||
*/
|
||||
public int getTotalPages()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getTotalRows()
|
||||
*/
|
||||
public int getTotalRows()
|
||||
{
|
||||
return totalRows;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getCurrentPage()
|
||||
*/
|
||||
public int getCurrentPage()
|
||||
{
|
||||
return skipRows;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getFirstPage()
|
||||
*/
|
||||
public int getFirstPage()
|
||||
{
|
||||
if (totalRows <=0)
|
||||
return -1;
|
||||
|
||||
return zeroBasedRow ? 0 : 1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getLastPage()
|
||||
*/
|
||||
public int getLastPage()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getNextPage()
|
||||
*/
|
||||
public int getNextPage()
|
||||
{
|
||||
return (skipRows + rowsPerPage < totalRows) ? skipRows + maxRows : -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getPrevPage()
|
||||
*/
|
||||
public int getPrevPage()
|
||||
{
|
||||
return (skipRows > 0) ? Math.max(0, skipRows - maxRows) : -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#isInRange()
|
||||
*/
|
||||
public boolean isInRange()
|
||||
{
|
||||
return skipRows >= 0 && skipRows < totalRows;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#hasFirstPage()
|
||||
*/
|
||||
public boolean getHasFirstPage()
|
||||
{
|
||||
return getFirstPage() != -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#hasLastPage()
|
||||
*/
|
||||
public boolean getHasLastPage()
|
||||
{
|
||||
return getLastPage() != -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#hasNextPage()
|
||||
*/
|
||||
public boolean getHasNextPage()
|
||||
{
|
||||
return getNextPage() != -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#hasPrevPage()
|
||||
*/
|
||||
public boolean getHasPrevPage()
|
||||
{
|
||||
return getPrevPage() != -1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getStartRow()
|
||||
*/
|
||||
public int getStartRow()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return 0;
|
||||
|
||||
return skipRows + (zeroBasedRow ? 0 : 1);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getEndRow()
|
||||
*/
|
||||
public int getEndRow()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return -1;
|
||||
|
||||
return getStartRow() + Math.min(rowsPerPage, totalRows - skipRows) - 1;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.web.util.paging.Cursor#getRowCount()
|
||||
*/
|
||||
public int getRowCount()
|
||||
{
|
||||
if (totalRows <= 0)
|
||||
return 0;
|
||||
|
||||
return getEndRow() - getStartRow() + 1;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user