Pager.java

package info.textgrid.rep.shared;

public class Pager {

  private int hits, limit, start, end, currentPage, totalPages;

  private int maxHits = 99950; // Default to 50 hits less than elasticsearch default max_result_window
  private int pageRange = 8; // Default page range (max amount of page links to be displayed at once).
  private Integer[] pages;

  private boolean truncated;

  public void calculatePages() {

    int calcHits = hits;

    // we want to only calculate pages which are allowed
    if(calcHits > maxHits) {
      truncated = true;
      calcHits = maxHits;
    }

    // Set currentPage, totalPages and pages.
    currentPage = (calcHits / limit) - ((calcHits - start) / limit) + 1;
    totalPages = (calcHits / limit) + ((calcHits % limit != 0) ? 1 : 0);
    int pagesLength = Math.min(pageRange, totalPages);
    pages = new Integer[pagesLength];

    if(start + limit <= calcHits) {
      end = start + limit;
    } else {
      end = calcHits;
    }

    // firstPage must be greater than 0 and lesser than totalPages-pageLength.
    int firstPage = Math.min(Math.max(0, currentPage - (pageRange / 2)), totalPages - pagesLength);

    // Create pages (page numbers for page links).
    for (int i = 0; i < pagesLength; i++) {
      pages[i] = ++firstPage;
    }

  }

  public int getLimit() {
    return limit;
  }

  public Pager setLimit(int limit) {
    this.limit = limit;
    return this;
  }

  public int getStart() {
    return start;
  }

  public Pager setStart(int start) {
    this.start = start;
    return this;
  }

  public int getHits() {
    return hits;
  }

  public Pager setHits(int hits) {
    this.hits = hits;
    return this;
  }

  public Integer[] getPages() {
    return pages;
  }

  public int getTotalPages() {
    return totalPages;
  }

  public int getEnd() {
    return end;
  }

  public Pager setMaxHits(int maxhits) {
    this.maxHits = maxhits;
    return this;
  }

  public int getMaxHits() {
    return maxHits;
  }

  /**
   * Check wether we are on the last page of a result list where there are more hits
   * available. this is useful to show a message stating this
   *
   * @return true if last page, but more results available
   */
  public boolean getIsLastPageButHasMoreHits() {
    return truncated && currentPage >= totalPages;
  }

  /**
   * Calculate the start position for a given page number.
   *
   * @param page the page number (1-based)
   * @return the start position for that page
   */
  public int getStartForPage(int page) {
    return (page - 1) * limit;
  }

  /**
   * Calculate the next start position.
   *
   * @return the next start position
   */
  public int getNextStart() {
    return start + limit;
  }

  /**
   * Calculate the previous start position.
   *
   * @return the previous start position (0 if start < limit)
   */
  public int getPreviousStart() {
    return start < limit ? 0 : start - limit;
  }

  /**
   * Check if there are more results after the current page.
   *
   * @return true if there are more results
   */
  public boolean getHasMoreResults() {
    return (start + limit) < hits && !getIsLastPageButHasMoreHits();
  }

}