Save This Page
Home » displaytag-1.1.1-src » org » displaytag » pagination » [javadoc | source]
    1   /**
    2    * Licensed under the Artistic License; you may not use this file
    3    * except in compliance with the License.
    4    * You may obtain a copy of the License at
    5    *
    6    *      http://displaytag.sourceforge.net/license.html
    7    *
    8    * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
    9    * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
   10    * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
   11    */
   12   package org.displaytag.pagination;
   13   
   14   import java.text.MessageFormat;
   15   import java.util.List;
   16   
   17   import org.apache.commons.lang.builder.ToStringBuilder;
   18   import org.apache.commons.lang.builder.ToStringStyle;
   19   import org.apache.commons.logging.Log;
   20   import org.apache.commons.logging.LogFactory;
   21   import org.displaytag.Messages;
   22   import org.displaytag.properties.TableProperties;
   23   import org.displaytag.util.Href;
   24   
   25   
   26   /**
   27    * <p>
   28    * Utility class that chops up a List of objects into small bite size pieces that are more suitable for display.
   29    * </p>
   30    * <p>
   31    * This class is a stripped down version of the WebListHelper from Tim Dawson (tdawson@is.com)
   32    * </p>
   33    * @author epesh
   34    * @author Fabrizio Giustina
   35    * @version $Revision: 1109 $ ($Author: fgiust $)
   36    */
   37   public class SmartListHelper
   38   {
   39   
   40       /**
   41        * logger.
   42        */
   43       private static Log log = LogFactory.getLog(SmartListHelper.class);
   44   
   45       /**
   46        * full list.
   47        */
   48       private List fullList;
   49   
   50       /**
   51        * sixe of the full list.
   52        */
   53       private int fullListSize;
   54   
   55       /**
   56        * number of items in a page.
   57        */
   58       private int pageSize;
   59   
   60       /**
   61        * number of pages.
   62        */
   63       private int pageCount;
   64   
   65       /**
   66        * the list we hold is only part of the full dataset
   67        */
   68       private boolean partialList;
   69   
   70       /**
   71        * index of current page.
   72        */
   73       private int currentPage;
   74   
   75       /**
   76        * TableProperties.
   77        */
   78       private TableProperties properties;
   79   
   80       /**
   81        * Creates a SmarListHelper instance that will help you chop up a list into bite size pieces that are suitable for
   82        * display.
   83        * @param list List
   84        * @param fullSize size of the full list
   85        * @param itemsInPage number of items in a page (int > 0)
   86        * @param tableProperties TableProperties
   87        */
   88       public SmartListHelper(
   89           List list,
   90           int fullSize,
   91           int itemsInPage,
   92           TableProperties tableProperties,
   93           boolean partialList)
   94       {
   95           if (log.isDebugEnabled())
   96           {
   97               log.debug(Messages.getString("SmartListHelper.debug.instantiated", //$NON-NLS-1$
   98                   new Object[]{new Integer(list.size()), new Integer(itemsInPage), new Integer(fullSize)}));
   99           }
  100   
  101           this.properties = tableProperties;
  102           this.pageSize = itemsInPage;
  103           this.fullList = list;
  104           this.fullListSize = fullSize;
  105           this.pageCount = computedPageCount();
  106           this.currentPage = 1;
  107           this.partialList = partialList;
  108       }
  109   
  110       /**
  111        * Constructor that can be used by subclasses. Subclasses that use this constructor must also override all the
  112        * public methods, since this constructor does nothing.
  113        */
  114       protected SmartListHelper()
  115       {
  116       }
  117   
  118       /**
  119        * Returns the computed number of pages it would take to show all the elements in the list given the pageSize we are
  120        * working with.
  121        * @return int computed number of pages
  122        */
  123       protected int computedPageCount()
  124       {
  125           int size = this.fullListSize;
  126           int div = size / this.pageSize;
  127           int result = (size % this.pageSize == 0) ? div : div + 1;
  128   
  129           return result;
  130       }
  131   
  132       /**
  133        * Returns the index into the master list of the first object that should appear on the current page that the user
  134        * is viewing.
  135        * @return int index of the first object that should appear on the current page
  136        */
  137       public int getFirstIndexForCurrentPage()
  138       {
  139           return getFirstIndexForPage(this.currentPage);
  140       }
  141   
  142       /**
  143        * Returns the index into the master list of the last object that should appear on the current page that the user is
  144        * viewing.
  145        * @return int
  146        */
  147       protected int getLastIndexForCurrentPage()
  148       {
  149   
  150           return getLastIndexForPage(this.currentPage);
  151       }
  152   
  153       /**
  154        * Returns the index into the master list of the first object that should appear on the given page.
  155        * @param pageNumber page number
  156        * @return int index of the first object that should appear on the given page
  157        */
  158       protected int getFirstIndexForPage(int pageNumber)
  159       {
  160           if (this.partialList)
  161           {
  162               return 0;
  163           }
  164           else
  165           {
  166               int retval = (pageNumber - 1) * this.pageSize;
  167               return retval >= 0 ? retval : 0;
  168           }
  169       }
  170   
  171       /**
  172        * Returns the index into the master list of the last object that should appear on the given page.
  173        * @param pageNumber page number
  174        * @return int index of the last object that should appear on the given page
  175        */
  176       protected int getLastIndexForPage(int pageNumber)
  177       {
  178           if (this.partialList)
  179           {
  180               // return the min of pageSize or list size on the off chance they gave us more data than pageSize allows
  181               return Math.min(this.pageSize - 1, this.fullList.size() - 1);
  182           }
  183           else
  184           {
  185               int firstIndex = getFirstIndexForPage(pageNumber);
  186               int pageIndex = this.pageSize - 1;
  187               int lastIndex = this.fullListSize - 1;
  188   
  189               return Math.min(firstIndex + pageIndex, lastIndex);
  190           }
  191       }
  192   
  193       /**
  194        * Returns a subsection of the list that contains just the elements that are supposed to be shown on the current
  195        * page the user is viewing.
  196        * @return List subsection of the list that contains the elements that are supposed to be shown on the current page
  197        */
  198       public List getListForCurrentPage()
  199       {
  200   
  201           return getListForPage(this.currentPage);
  202       }
  203   
  204       /**
  205        * Returns a subsection of the list that contains just the elements that are supposed to be shown on the given page.
  206        * @param pageNumber page number
  207        * @return List subsection of the list that contains just the elements that are supposed to be shown on the given
  208        * page
  209        */
  210       protected List getListForPage(int pageNumber)
  211       {
  212           if (log.isDebugEnabled())
  213           {
  214               log.debug(Messages.getString("SmartListHelper.debug.sublist", //$NON-NLS-1$
  215                   new Object[]{new Integer(pageNumber)}));
  216           }
  217   
  218           int firstIndex = getFirstIndexForPage(pageNumber);
  219           int lastIndex = getLastIndexForPage(pageNumber);
  220           return this.fullList.subList(firstIndex, lastIndex + 1);
  221       }
  222   
  223       /**
  224        * Set's the page number that the user is viewing.
  225        * @param pageNumber page number
  226        */
  227       public void setCurrentPage(int pageNumber)
  228       {
  229           if (log.isDebugEnabled())
  230           {
  231               log.debug(Messages.getString("SmartListHelper.debug.currentpage", //$NON-NLS-1$
  232                   new Object[]{new Integer(pageNumber), new Integer(this.pageCount)}));
  233           }
  234   
  235           if (pageNumber < 1)
  236           {
  237               // invalid page: better don't throw an exception, since this could easily happen
  238               // (list changed, user bookmarked the page)
  239               this.currentPage = 1;
  240           }
  241           else if (pageNumber != 1 && pageNumber > this.pageCount)
  242           {
  243               // invalid page: set to last page
  244               this.currentPage = this.pageCount;
  245           }
  246           else
  247           {
  248               this.currentPage = pageNumber;
  249           }
  250       }
  251   
  252       /**
  253        * Return the little summary message that lets the user know how many objects are in the list they are viewing, and
  254        * where in the list they are currently positioned. The message looks like: nnn [item(s)] found, displaying nnn to
  255        * nnn. [item(s)] is replaced by either itemName or itemNames depending on if it should be signular or plural.
  256        * @return String
  257        */
  258       public String getSearchResultsSummary()
  259       {
  260   
  261           Object[] objs;
  262           String message;
  263   
  264           if (this.fullListSize == 0)
  265           {
  266               objs = new Object[]{this.properties.getPagingItemsName()};
  267               message = this.properties.getPagingFoundNoItems();
  268   
  269           }
  270           else if (this.fullListSize == 1)
  271           {
  272               objs = new Object[]{this.properties.getPagingItemName()};
  273               message = this.properties.getPagingFoundOneItem();
  274           }
  275           else if (computedPageCount() == 1)
  276           {
  277               objs = new Object[]{
  278                   new Integer(this.fullListSize),
  279                   this.properties.getPagingItemsName(),
  280                   this.properties.getPagingItemsName()};
  281               message = this.properties.getPagingFoundAllItems();
  282           }
  283           else
  284           {
  285               objs = new Object[]{
  286                   new Integer(this.fullListSize),
  287                   this.properties.getPagingItemsName(),
  288                   new Integer(getFirstIndexForCurrentPage() + 1),
  289                   new Integer(getLastIndexForCurrentPage() + 1),
  290                   new Integer(this.currentPage),
  291                   new Integer(this.pageCount)};
  292               message = this.properties.getPagingFoundSomeItems();
  293           }
  294   
  295           return MessageFormat.format(message, objs);
  296       }
  297   
  298       /**
  299        * Returns a string containing the nagivation bar that allows the user to move between pages within the list. The
  300        * urlFormatString should be a URL that looks like the following: somepage.page?page={0}
  301        * @param baseHref Href used for links
  302        * @param pageParameter name for the page parameter
  303        * @return String
  304        */
  305       public String getPageNavigationBar(Href baseHref, String pageParameter)
  306       {
  307   
  308           int groupSize = this.properties.getPagingGroupSize();
  309           int startPage;
  310           int endPage;
  311   
  312           Pagination pagination = new Pagination(baseHref, pageParameter);
  313           pagination.setCurrent(new Integer(this.currentPage));
  314   
  315           // if no items are found still add pagination?
  316           if (this.pageCount == 0)
  317           {
  318               pagination.addPage(1, true);
  319           }
  320   
  321           // center the selected page, but only if there are {groupSize} pages available after it, and check that the
  322           // result is not < 1
  323           startPage = Math.max(Math.min(this.currentPage - groupSize / 2, this.pageCount - (groupSize - 1)), 1);
  324           endPage = Math.min(startPage + groupSize - 1, this.pageCount);
  325   
  326           if (log.isDebugEnabled())
  327           {
  328               log.debug("Displaying pages from " + startPage + " to " + endPage);
  329           }
  330   
  331           if (this.currentPage != 1)
  332           {
  333               pagination.setFirst(new Integer(1));
  334               pagination.setPrevious(new Integer(this.currentPage - 1));
  335           }
  336   
  337           for (int j = startPage; j <= endPage; j++)
  338           {
  339               if (log.isDebugEnabled())
  340               {
  341                   log.debug("adding page " + j); //$NON-NLS-1$
  342               }
  343               pagination.addPage(j, (j == this.currentPage));
  344           }
  345   
  346           if (this.currentPage != this.pageCount)
  347           {
  348               pagination.setNext(new Integer(this.currentPage + 1));
  349               pagination.setLast(new Integer(this.pageCount));
  350           }
  351   
  352           // format for previous/next banner
  353           String bannerFormat;
  354   
  355           if (pagination.isOnePage())
  356           {
  357               bannerFormat = this.properties.getPagingBannerOnePage();
  358           }
  359           else if (pagination.isFirst())
  360           {
  361               bannerFormat = this.properties.getPagingBannerFirst();
  362           }
  363           else if (pagination.isLast())
  364           {
  365               bannerFormat = this.properties.getPagingBannerLast();
  366           }
  367           else
  368           {
  369               bannerFormat = this.properties.getPagingBannerFull();
  370           }
  371   
  372           return pagination.getFormattedBanner(this.properties.getPagingPageLink(), this.properties
  373               .getPagingPageSelected(), this.properties.getPagingPageSeparator(), bannerFormat);
  374       }
  375   
  376       /**
  377        * @see java.lang.Object#toString()
  378        */
  379       public String toString()
  380       {
  381           return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) //
  382               .append("fullList", this.fullList) //$NON-NLS-1$
  383               .append("fullListSize", this.fullListSize) //$NON-NLS-1$
  384               .append("pageSize", this.pageSize) //$NON-NLS-1$
  385               .append("pageCount", this.pageCount) //$NON-NLS-1$
  386               .append("properties", this.properties) //$NON-NLS-1$
  387               .append("currentPage", this.currentPage) //$NON-NLS-1$
  388               .append("partialList", this.partialList) //$NON-NLS-1$
  389               .toString();
  390       }
  391   }

Save This Page
Home » displaytag-1.1.1-src » org » displaytag » pagination » [javadoc | source]