/*<license>
  Copyright 2004, PeopleWare n.v.
  NO RIGHTS ARE GRANTED FOR THE USE OF THIS SOFTWARE, EXCEPT, IN WRITING,
  TO SELECTED PARTIES.
</license>*/
package be.peopleware.persistence_II.hibernate;


import java.util.ConcurrentModificationException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.ppwcode.vernacular.exception_N.TechnicalException;

import be.peopleware.persistence_II.dao.PagingList;


/**
 * A list of lists, that contains the result of a Hibernate query
 * using paging. Each page, except for the last,
 * has size {@link #getPageSize()}.
 * When the virtual resultset on the DB changes during iteration,
 * we throw a {@link ConcurrentModificationException} when the next
 * page is requested.
 *
 * @author Jan Dockx
 * @author Peopleware n.v.
 *
 * @invar getPageSize() > 0;
 */
public final class HibernatePagingList extends PagingList {

  /*<section name="Meta Information">*/
  //------------------------------------------------------------------
  /** {@value} */
  public static final String CVS_REVISION = "$Revision$";
  /** {@value} */
  public static final String CVS_DATE = "$Date$";
  /** {@value} */
  public static final String CVS_STATE = "$State$";
  /** {@value} */
  public static final String CVS_TAG = "$Name$";
  /*</section>*/


  private static final Log LOG = LogFactory.getLog(HibernatePagingList.class);


  /*<construction>*/
  //------------------------------------------------------------------

  /**
   * @pre query != null;
   * @pre countQuery != null;
   * @pre pageSize > 0;
   * @post new.getQuery() == query;
   * @post new.getCountQuery() == countQuery;
   * @post new.getPageSize() == pageSize;
   * @throws TechnicalException
   */
  public HibernatePagingList(Query query, Query countQuery, int pageSize) throws TechnicalException {
    super(pageSize, retrieveRecordCount(countQuery));
    assert query != null;
    assert countQuery != null;
    $query = query;
    $countQuery = countQuery;
  }

  /**
   * @pre criteria != null;
   * @pre countCriteria != null;
   * @pre pageSize > 0;
   * @post new.getQuery() == query;
   * @post new.getCountQuery() == countQuery;
   * @post new.getPageSize() == pageSize;
   * @throws TechnicalException
   */
  public HibernatePagingList(Criteria criteria, Query countQuery, int pageSize) throws TechnicalException {
    super(pageSize, retrieveRecordCount(countQuery));
    assert criteria != null;
    assert countQuery != null;
    $criteria = criteria;
    $countQuery = countQuery;
  }

  /*</construction>*/



  /*<property name="query">*/
  //------------------------------------------------------------------

  /**
   * @basic
   */
  public final Query getQuery() {
    return $query;
  }

  /**
   * @invar $query != null;
   */
  private Query $query;

  /*</property>*/



  /*<property name="criteria">*/
  //------------------------------------------------------------------

  /**
   * @basic
   */
  public final Criteria getCriteria() {
    return $criteria;
  }

  /**
   * @invar $criteria != null;
   */
  private Criteria $criteria;

  /*</property>*/



  /*<property name="countQuery">*/
  //------------------------------------------------------------------

  /**
   * @basic
   */
  public final Query getCountQuery() {
    return $countQuery;
  }

  private static int retrieveRecordCount(Query countQuery) throws TechnicalException {
    try {
      LOG.debug("retrieving record count");
      int result = ((Integer)countQuery.uniqueResult()).intValue();
      LOG.debug("record count is " + result);
      return result;
    }
    catch (HibernateException e) {
      throw new TechnicalException("cannot retrieve count", e);
    }
  }

  protected final int retrieveRecordCount() throws TechnicalException {
      return retrieveRecordCount(getCountQuery());
  }

  /**
   * @invar $countQuery != null;
   */
  private Query $countQuery;

  /*</property>*/



  protected final List retrievePage(int retrieveSize, int startOfPage) throws TechnicalException {
    try {
      List page = null;
      if ($criteria != null) {
        page = retrievePageCriteria(retrieveSize, startOfPage);
      }
      else if ($query !=  null) {
        page = retrievePageQuery(retrieveSize, startOfPage);
      }
      else {
        assert false : "Cannot happen";
      }
      LOG.debug("page retrieved successfully");
      return page;
    }
    catch (HibernateException hExc) {
      throw new TechnicalException("cannot retrieve page", hExc);
    }
  }

  private List retrievePageCriteria(int retrieveSize, int startOfPage) throws HibernateException {
    $criteria.setMaxResults(retrieveSize); // first and last record is for check only (depending on booleans)
    $criteria.setFirstResult(startOfPage);
    List page = $criteria.list();
    return page;
  }

  private List retrievePageQuery(int retrieveSize, int startOfPage) throws HibernateException {
    $query.setMaxResults(retrieveSize); // first and last record is for check only (depending on booleans)
    $query.setFirstResult(startOfPage);
    List page = $query.list();
    return page;
  }

}

@@ -284,96 +284,14 @@
 ort 
-org.apache.commons.logging.Log;%0Aimport org.apache.commons.logging.LogFactory;%0Aimport org
+net.sf
 .hib
@@ -306,35 +306,38 @@
 riteria;%0Aimport 
-org
+net.sf
 .hibernate.Hiber
@@ -358,19 +358,22 @@
 %0Aimport 
-org
+net.sf
 .hiberna
@@ -382,16 +382,17 @@
 .Query;%0A
+%0A
 import o
@@ -398,26 +398,103 @@
 org.
-ppwcode.vernacul
+apache.commons.logging.Log;%0Aimport org.apache.commons.logging.LogFactory;%0A%0Aimport be.peoplew
 ar
+e
 .exc
@@ -500,17 +500,17 @@
 ception_
-N
+I
 .Technic
@@ -522,17 +522,16 @@
 eption;%0A
-%0A
 import b

Revert to r875