import org.apache.log4j.Logger;
import java.util.List;
/**
* @author Pietro Polsinelli [email protected]
*/
public interface Page {
boolean isFirstPage();
boolean isLastPage();
boolean hasNextPage();
boolean hasPreviousPage();
int getLastPageNumber();
List getThisPageElements();
Logger getLogger();
int getTotalNumberOfElements();
int getThisPageFirstElementNumber();
int getThisPageLastElementNumber();
int getNextPageNumber();
int getPreviousPageNumber();
int getPageSize();
int getPageNumber();
}
import net.sf.hibernate.*;
import net.sf.hibernate.impl.SQLQueryImpl;
import net.sf.hibernate.persister.EntityPersister;
import org.apache.log4j.Logger;
import org.jblooming.PlatformRuntimeException;
import org.jblooming.persistence.hibernate.HibernateFactory;
import org.jblooming.tracer.Tracer;
import org.jblooming.waf.settings.ApplicationState;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.ResultSet;
/**
* @author Pietro Polsinelli [email protected]
*/
public class HibernatePage implements Page {
protected List elements;
protected int pageSize;
protected int pageNumber;
protected int totalElements = 0;
public static Set jdbcClassesSupportingScrollCursors = new HashSet();
private ScrollableResults scrollableResults;
private HibernatePage(int pageNumber, int pageSize) {
this.pageNumber = pageNumber;
this.pageSize = pageSize;
}
public boolean isFirstPage() {
return getPageNumber() == 0;
}
public boolean isLastPage() {
return getPageNumber() >= getLastPageNumber();
}
public boolean hasNextPage() {
return elements.size() > getPageSize();
}
public boolean hasPreviousPage() {
return getPageNumber() > 0;
}
public int getLastPageNumber() {
double totalResults =
new Integer(getTotalNumberOfElements()).doubleValue();
return new Double(Math.floor(totalResults / getPageSize())).intValue();
}
public List getThisPageElements() {
/*
* Since we retrieved one more than the specified pageSize when the
* class was constructed, we now trim it down to the pageSize if a next
* page exists.
*/
return hasNextPage() ? elements.subList(0, getPageSize()) : elements;
}
public Logger getLogger() {
return Tracer.hibernateLogger;
}
public int getTotalNumberOfElements() {
return totalElements;
}
public int getThisPageFirstElementNumber() {
return getPageNumber() * getPageSize() + 1;
}
public int getThisPageLastElementNumber() {
int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
return getTotalNumberOfElements() < fullPage ?
getTotalNumberOfElements() :
fullPage;
}
public int getNextPageNumber() {
return getPageNumber() + 1;
}
public int getPreviousPageNumber() {
return getPageNumber() - 1;
}
public int getPageSize() {
return pageSize;
}
public int getPageNumber() {
return pageNumber;
}
public static HibernatePage getHibernatePageInstance(Query query, int pageNumber, int pageSize) {
return getHibernatePageInstance(query, pageNumber, pageSize, ApplicationState.platformConfiguration.driver_class);
}
public static HibernatePage getHibernatePageInstance(Query query,
int pageNumber,
int pageSize,
String driverClass) {
if (jdbcClassesSupportingScrollCursors.contains(driverClass))
return HibernatePage.getScrollPageInstanceWithTotalByScroll(query, pageNumber, pageSize);
else
return HibernatePage.getScrollPageInstanceWithTotalByList(query, pageNumber, pageSize);
}
/**
* Construct a new HibernatePage. HibernatePage numbers are zero-based so the
* first page is page 0.
*
* @param query the Hibernate Query
* @param pageNumber the page number (zero-based);
* if Integer.MAX_VALUE will return the last page for the query
* @param pageSize the number of results to display on the page
*/
protected static HibernatePage getScrollPageInstanceWithTotalByScroll(Query query, int pageNumber, int pageSize) {
HibernatePage sp = new HibernatePage(pageNumber, pageSize);
try {
sp.scrollableResults = query.scroll(ScrollMode.SCROLL_SENSITIVE);
sp.scrollableResults.last();
sp.totalElements = sp.scrollableResults.getRowNumber();
sp.determineElements(query);
} catch (HibernateException e) {
sp.getLogger().error("Failed to create ScrollPage by getScrollPageInstanceWithTotalByScroll: " + e.getMessage());
throw new PlatformRuntimeException(e);
}
return sp;
}
/**
* Construct a new HibernatePage. HibernatePage numbers are zero-based so the
* first page is page 0.
*
* @param query the Hibernate Query
* @param pageNumber the page number (zero-based);
* if Integer.MAX_VALUE will return the last page for the query
* @param pageSize the number of results to display on the page
*/
protected static HibernatePage getScrollPageInstanceWithTotalByList(Query query, int pageNumber, int pageSize) {
HibernatePage sp = new HibernatePage(pageNumber, pageSize);
try {
sp.scrollableResults = query.scroll(ScrollMode.FORWARD_ONLY);
sp.totalElements = sp.calculateTotalElementsByList(query);
sp.determineElements(query);
} catch (HibernateException e) {
sp.getLogger().error("Failed to create ScrollPage by getScrollPageInstanceWithTotalByQuery: " + e.getMessage());
throw new PlatformRuntimeException(e);
}
return sp;
}
private void determineElements(Query query) throws HibernateException {
if (Integer.MAX_VALUE == this.pageNumber)
this.pageNumber = (getTotalNumberOfElements() / this.pageSize);
/**
* todo: this no more makes sense, as we know the total number of elements
*
* We set the max results to one more than the specfied pageSize to
* determine if any more results exist (i.e. if there is a next page
* to display). The result set is trimmed down to just the pageSize
* before being displayed later (in getThisPageElements()).
*/
elements = query.setFirstResult(this.pageNumber * this.pageSize).setMaxResults(this.pageSize + 1).list();
}
private int calculateTotalElementsByList(Query query) throws HibernateException {
return query.list().size();
}
}
package org.jblooming.page;
import org.apache.log4j.Logger;
import org.jblooming.tracer.Tracer;
import java.util.List;
/**
* @author Pietro Polsinelli [email protected]
*/
public class ListPage implements Page {
private List elements;
private int pageSize;
private int pageNumber;
/**
* Construct a new ListPage. ListPage numbers are zero-based, so the
* first page is page 0.
*
* @param pageNumber the page number (zero-based);
* if Integer.MAX_VALUE will return the last page for the query
* @param pageSize the number of results to display on the page
*/
public ListPage(List elements, int pageNumber, int pageSize) {
this.elements = elements;
this.pageSize = pageSize;
this.pageNumber = pageNumber;
if (Integer.MAX_VALUE == this.pageNumber)
this.pageNumber = (getTotalNumberOfElements() / this.pageSize);
}
public boolean isFirstPage() {
return getPageNumber() == 0;
}
public boolean isLastPage() {
return getPageNumber() >= getLastPageNumber();
}
public boolean hasNextPage() {
return ((getPageNumber() + 1) * getPageSize()) <
(getTotalNumberOfElements() + 1);
}
public boolean hasPreviousPage() {
return getPageNumber() > 0;
}
public int getLastPageNumber() {
/*
* We use the Math.floor() method because page numbers are zero-based
* (i.e. the first page is page 0).
*/
double totalResults = new Integer(getTotalNumberOfElements()).doubleValue();
return new Double(Math.floor(totalResults / getPageSize())).intValue();
}
public List getThisPageElements() {
/*
* Since we retrieved one more than the specified pageSize when the
* class was constructed, we now trim it down to the pageSize if a next
* page exists.
*/
final int start = getPageNumber() * getPageSize();
return elements.subList(Math.min(start, getTotalNumberOfElements() + 1),
Math.min(start + getPageSize(), getTotalNumberOfElements() + 1));
}
public Logger getLogger() {
return Tracer.hibernateLogger;
}
/**
* this is 0-based, differently from list.size();
*/
public int getTotalNumberOfElements() {
return elements.size() - 1;
}
public int getThisPageFirstElementNumber() {
return getPageNumber() * getPageSize() + 1;
}
public int getThisPageLastElementNumber() {
int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
return getTotalNumberOfElements() < fullPage ?
getTotalNumberOfElements() :
fullPage;
}
public int getNextPageNumber() {
return getPageNumber() + 1;
}
public int getPreviousPageNumber() {
return getPageNumber() - 1;
}
public int getPageSize() {
return pageSize;
}
public int getPageNumber() {
return pageNumber;
}
}