You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by nb...@apache.org on 2004/11/11 04:46:44 UTC

cvs commit: jakarta-velocity-tools/src/java/org/apache/velocity/tools/view/tools AbstractSearchTool.java

nbubna      2004/11/10 19:46:44

  Modified:    src/java/org/apache/velocity/tools/view/tools
                        AbstractSearchTool.java
  Log:
  factor out basic paging functionality into new AbstractPagerTool
  
  Revision  Changes    Path
  1.8       +40 -367   jakarta-velocity-tools/src/java/org/apache/velocity/tools/view/tools/AbstractSearchTool.java
  
  Index: AbstractSearchTool.java
  ===================================================================
  RCS file: /home/cvs/jakarta-velocity-tools/src/java/org/apache/velocity/tools/view/tools/AbstractSearchTool.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- AbstractSearchTool.java	12 Mar 2004 20:30:32 -0000	1.7
  +++ AbstractSearchTool.java	11 Nov 2004 03:46:44 -0000	1.8
  @@ -1,5 +1,5 @@
   /*
  - * Copyright 2003 The Apache Software Foundation.
  + * Copyright 2003-2004 The Apache Software Foundation.
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
  @@ -79,28 +79,28 @@
    *     <input type="text"name="find" value="$!search.criteria">
    *     <input type="submit" value="Find">
    *   </form>
  - *   #if( $search.hasResults() )
  + *   #if( $search.hasItems() )
    *   Showing $!search.pageDescription<br>
    *     #set( $i = $search.index )
  - *     #foreach( $result in $search.page )
  - *       ${i}. $!result <br>
  + *     #foreach( $item in $search.page )
  + *       ${i}. $!item <br>
    *       #set( $i = $i + 1 )
    *     #end
    *     <br>
    *     #if ( $search.pagesAvailable > 1 )
  - *       #set( $searchlink = $link.setRelative('search.vm').addQueryData("find",$!search.criteria).addQueryData("show",$!search.itemsPerPage) )
  + *       #set( $pagelink = $link.setRelative('search.vm').addQueryData("find",$!search.criteria).addQueryData("show",$!search.itemsPerPage) )
    *       #if( $search.prevIndex )
  - *           <a href="$searchlink.addQueryData('index',$!search.prevIndex)">Prev</a>
  + *           <a href="$pagelink.addQueryData('index',$!search.prevIndex)">Prev</a>
    *       #end
    *       #foreach( $index in $search.slip )
    *         #if( $index == $search.index )
    *           <b>$search.pageNumber</b>
    *         #else
  - *           <a href="$searchlink.addQueryData('index',$!index)">$!search.getPageNumber($index)</a>
  + *           <a href="$pagelink.addQueryData('index',$!index)">$!search.getPageNumber($index)</a>
    *         #end
    *       #end
    *       #if( $search.nextIndex )
  - *           <a href="$searchlink.addQueryData('index',$!search.nextIndex)">Next</a>
  + *           <a href="$pagelink.addQueryData('index',$!search.nextIndex)">Next</a>
    *       #end
    *     #end
    *   #elseif( $search.criteria )
  @@ -128,7 +128,7 @@
    * <pre>&lt;tool&gt;
    *   &lt;key&gt;search&lt;/key&gt;
    *   &lt;scope&gt;request&lt;/scope&gt;
  - *   &lt;class&gt;com.foo.tools.MyAbstractSearchTool&lt;/class&gt;
  + *   &lt;class&gt;com.foo.tools.MySearchTool&lt;/class&gt;
    * &lt;/tool&gt;
    * </pre>
    * </p>
  @@ -137,146 +137,41 @@
    * @since VelocityTools 1.0
    * @version $Revision$ $Date$
    */
  -public abstract class AbstractSearchTool implements ViewTool
  +public abstract class AbstractSearchTool extends AbstractPagerTool
   {
  -
  -
  -    /** the default number of results shown per page */
  -    public static final int DEFAULT_ITEMS_PER_PAGE = 10;
  -
  -    /** the default max number of result page indices to list */
  -    public static final int DEFAULT_SLIP_SIZE = 20;
  -
       /** the key under which StoredResults are kept in session */
       protected static final String STORED_RESULTS_KEY = 
           StoredResults.class.getName();
   
  -    private List results;
       private Object criteria;
  -    private int index = 0;
  -    private int slipSize = DEFAULT_SLIP_SIZE;
  -    private int itemsPerPage = DEFAULT_ITEMS_PER_PAGE;
  -
  -    protected HttpSession session;
  -
  -
  -    /**
  -     * Initializes this instance by grabbing the request
  -     * and session objects from the current ViewContext.
  -     *
  -     * @param obj the current ViewContext
  -     * @throws ClassCastException if the param is not a ViewContext
  -     */
  -    public void init(Object obj)
  -    {
  -        ViewContext context = (ViewContext)obj;
  -        HttpServletRequest request = context.getRequest();
  -        session = request.getSession(false);
  -        setup(request);
  -    }
  -
  -
  -    /**
  -     * Abstract method to make it as obvious as possible just
  -     * where implementing classes should be retrieving and configuring
  -     * search/display parameters. 
  -     * <p>A simple implementation would be:
  -     * <pre>
  -     * public void setup(HttpServletRequest req)
  -     * {
  -     *     ParameterParser pp = new ParameterParser(req);
  -     *     setCriteria(pp.getString("find"));
  -     *     setIndex(pp.getInt("index", 0));
  -     *     setItemsPerPage(pp.getInt("show", DEFAULT_ITEMS_PER_PAGE));
  -     * }
  -     * </pre>
  -     *
  -     * @param request the current HttpServletRequest
  -     */
  -    public abstract void setup(HttpServletRequest request);
   
   
       /*  ---------------------- mutators -----------------------------  */
   
  -
       /**
        * Sets the criteria and results to null, page index to zero, and
        * items per page to the default.
        */
       public void reset()
       {
  -        results = null;
  +        super.reset();
           criteria = null;
  -        index = 0;
  -        itemsPerPage = DEFAULT_ITEMS_PER_PAGE;
       }
   
   
       /**
  -     * Sets the criteria for this search and clears existing results.
  +     * Sets the criteria for this search.
        *
        * @param criteria - the criteria used for this search
        */
       public void setCriteria(Object criteria)
       {
           this.criteria = criteria;
  -        this.results = null;
  -    }
  -
  -
  -    /**
  -     * Sets the index of the first result in the current page
  -     *
  -     * @param index the result index to start the current page with
  -     */
  -    public void setIndex(int index)
  -    {
  -        if (index < 0)
  -        {
  -            /* quietly override to a reasonable value */
  -            index = 0;
  -        }
  -        this.index = index;
  -    }
  -
  -
  -    /**
  -     * Sets the number of items returned in a page of results
  -     *
  -     * @param itemsPerPage the number of items to be returned per page
  -     */
  -    public void setItemsPerPage(int itemsPerPage)
  -    {
  -        if (itemsPerPage < 1)
  -        {
  -            /* quietly override to a reasonable value */
  -            itemsPerPage = DEFAULT_ITEMS_PER_PAGE;
  -        }
  -        this.itemsPerPage = itemsPerPage;
  -    }
  -
  -
  -    /**
  -     * Sets the number of result page indices for {@link #getSlip} to list.
  -     * (for google-ish result page links).
  -     *
  -     * @see #getSlip
  -     * @param slipSize - the number of result page indices to list
  -     */
  -    public void setSlipSize(int slipSize)
  -    {
  -        if (slipSize < 2)
  -        {
  -            /* quietly override to a reasonable value */
  -            slipSize = DEFAULT_SLIP_SIZE;
  -        }
  -        this.slipSize = slipSize;
       }
   
   
       /*  ---------------------- accessors -----------------------------  */
   
  -
       /**
        * Return the criteria object for this request.
        * (for a simple search mechanism, this will typically be
  @@ -291,272 +186,58 @@
   
   
       /**
  -     * Return the set number of items to be displayed per page of results
  -     *
  -     * @return current number of results shown per page
  -     */
  -    public int getItemsPerPage()
  -    {
  -        return itemsPerPage;
  -    }
  -
  -
  -    /**
  -     * Returns the number of result page indices {@link #getSlip} 
  -     * will return per request (if available).
  -     *
  -     * @return the number of result page indices {@link #getSlip} 
  -     *         will try to return
  -     */
  -    public int getSlipSize()
  -    {
  -        return slipSize;
  -    }
  -
  -
  -    /**
  -     * Return the current search result index.
  -     *
  -     * @return the index for the beginning of the current page
  -     */
  -    public int getIndex()
  -    {
  -        return index;
  -    }
  -
  -
  -    /**
  -     * Checks whether or not the result list is empty.
  -     *
  -     * @return <code>true</code> if the result list is not empty.
  +     * @deprecated Use {@link AbstractPagerTool#hasItems()}
        */
       public boolean hasResults()
       {
  -        return !getResults().isEmpty();
  +        return hasItems();
       }
   
   
       /**
  -     * Return the results for the given criteria.  This is guaranteed
  -     * to never return <code>null</code>.
  -     *
  -     * @return {@link List} of all results for the criteria
  +     * @deprecated Use {@link AbstractPagerTool#getItems()}.
        */
       public List getResults()
       {
  -        if (results == null)
  -        {
  -            results = retrieveResults();
  -        }
  -        return results;
  -    }
  -
  -
  -    /**
  -     * Return the index for the next page of results
  -     * (as determined by the current index, items per page, and 
  -     * the number of results).  If no "next page" exists, then null is
  -     * returned.
  -     *
  -     * @return index for the next page or <code>null</code> if none exists
  -     */
  -    public Integer getNextIndex()
  -    {
  -        int next = index + itemsPerPage;
  -        if (next < getResults().size())
  -        {
  -            return new Integer(next);
  -        }
  -        return null;
  -    }
  -
  -
  -    /**
  -     * Return the index for the previous page of results
  -     * (as determined by the current index, items per page, and 
  -     * the number of results).  If no "next page" exists, then null is
  -     * returned.
  -     *
  -     * @return index for the previous page or <code>null</code> if none exists
  -     */
  -    public Integer getPrevIndex()
  -    {
  -        int prev = Math.min(index, getResults().size()) - itemsPerPage;
  -        if (index > 0)
  -        {
  -            return new Integer(Math.max(0, prev));
  -        }
  -        return null;
  -    }
  -
  -
  -    /**
  -     * Return the number of pages that can be made from this list
  -     * given the set number of items per page.
  -     */
  -    public int getPagesAvailable()
  -    {
  -        return (int)Math.ceil(getResults().size() / (double)itemsPerPage);
  -    }
  -
  -
  -    /**
  -     * Return the current "page" of search results.
  -     *
  -     * @return a {@link List} of results for the "current page"
  -     */
  -    public List getPage()
  -    {
  -        /* return null if we have no results */
  -        if (!hasResults())
  -        {
  -            return null;
  -        }
  -        /* quietly keep the page indices to legal values for robustness' sake */
  -        int start = Math.min(getResults().size() - 1, index);
  -        int end = Math.min(getResults().size(), index + itemsPerPage);
  -        return getResults().subList(start, end);
  -    }
  -
  -
  -    /**
  -     * Returns the "page number" for the specified index.  Because the page
  -     * number is used for the user interface, the page numbers are 1-based.
  -     *
  -     * @param i the index that you want the page number for
  -     * @return the approximate "page number" for the specified index or 
  -     *         <code>null</code> if there are no results
  -     */
  -    public Integer getPageNumber(int i)
  -    {
  -        if (!hasResults())
  -        {
  -            return null;
  -        }
  -        return new Integer(1 + i / itemsPerPage);
  -    }
  -
  -
  -    /**
  -     * Returns the "page number" for the current index.  Because the page
  -     * number is used for the user interface, the page numbers are 1-based.
  -     *
  -     * @return the approximate "page number" for the current index or 
  -     *         <code>null</code> if there are no results
  -     */
  -    public Integer getPageNumber()
  -    {
  -        return getPageNumber(index);
  +        return getItems();
       }
   
   
       /**
  -     * <p>Returns a description of the current page.  This implementation
  -     * displays a 1-based range of result indices and the total number 
  -     * of results.  (e.g. "1 - 10 of 42" or "7 of 7")</p>
  -     *
  -     * <p>Sub-classes may override this to provide a customized 
  -     * description (such as one in another language).</p>
  -     *
  -     * @return a description of the current page
  -     */
  -    public String getPageDescription()
  -    {
  -        StringBuffer out = new StringBuffer();
  -        int first = index + 1;
  -        int total = getResults().size();
  -        if (first >= total)
  -        {
  -            out.append(total);
  -            out.append(" of ");
  -            out.append(total);
  -        }
  -        else
  -        {
  -            int last = Math.min(index + itemsPerPage, total);
  -            out.append(first);
  -            out.append(" - ");
  -            out.append(last);
  -            out.append(" of ");
  -            out.append(total);
  -        }
  -        return out.toString();
  -    }
  -
  -
  -    /**
  -     * Return a <b>S</b>liding <b>L</b>ist of <b>I</b>ndices for <b>P</b>ages
  -     * of search results.
  -     *
  -     * <p>Essentially, this returns a list of result indices that correspond
  -     * to available pages of search results (as based on the set 
  -     * items-per-page). This makes it relativly easy to do a google-ish set 
  -     * of links to result pages.</p>
  -     *
  -     * <p>Note that this list of Integers is 0-based to correspond with the
  -     * underlying result indices and not the displayed page numbers (see
  -     * {@link #getPageNumber}).</p>
  +     * Gets the results for the given criteria either in memory
  +     * or by performing a new query for them.  If the criteria
  +     * is null, an empty list will be returned.
        *
  -     * @return {@link List} of Integers representing the indices of result 
  -     *         pages or empty list if there's one or less pages available
  +     * @return {@link List} of all items for the criteria
        */
  -    public List getSlip()
  +    public List getItems()
       {
  -        /* return an empty list if there's no pages to list */
  -        int totalPgs = getPagesAvailable();
  -        if (totalPgs <= 1)
  +        /* return empty list if we have no criteria */
  +        if (criteria == null)
           {
               return Collections.EMPTY_LIST;
           }
   
  -        /* page number is 1-based so decrement it */
  -        int curPg = getPageNumber().intValue() - 1;
  -
  -        /* don't include current page in slip size calcs */
  -        int adjSlipSize = slipSize - 1;
  +        /* get the current list */
  +        List list = super.getItems();
   
  -        /* start at zero or just under half of max slip size 
  -         * this keeps "forward" and "back" pages about even
  -         * but gives preference to "forward" pages */
  -        int slipStart = Math.max(0, (curPg - (adjSlipSize / 2)));
  -
  -        /* push slip end as far as possible */
  -        int slipEnd = Math.min(totalPgs, (slipStart + adjSlipSize));
  -
  -        /* if we're out of "forward" pages, then push the 
  -         * slip start toward zero to maintain slip size */
  -        if (slipEnd - slipStart < adjSlipSize)
  +        /* if empty, execute a query for the criteria */
  +        if (list.isEmpty())
           {
  -            slipStart = Math.max(0, slipEnd - adjSlipSize);
  -        }
  +            /* perform a new query */
  +            list = executeQuery(criteria);
   
  -        /* convert 0-based page numbers to indices and create list */
  -        List slip = new ArrayList((slipEnd - slipStart) + 1);
  -        for (int i=slipStart; i < slipEnd; i++)
  -        {
  -            slip.add(new Integer(i * itemsPerPage));
  +            /* save the new results */
  +            setItems(list);
           }
  -        return slip;
  +        return list;
       }
   
   
  -    /*  ---------------------- private methods -----------------------------  */
  -
  +    /*  ---------------------- protected methods -----------------------------  */
   
  -    /**
  -     * Gets the results for the given criteria either in memory
  -     * or by performing a new query for them.  This is guaranteed to
  -     * NOT return null.
  -     */
  -    private List retrieveResults()
  +    protected List getStoredItems()
       {
  -        /* return empty list if we have no criteria */
  -        if (criteria == null)
  -        {
  -            return Collections.EMPTY_LIST;
  -        }
  -
  -        /* get any stored results */
           StoredResults sr = getStoredResults();
   
           /* if the criteria equals that of the stored results, 
  @@ -565,21 +246,14 @@
           {
               return sr.getList();
           }
  -
  -        /* perform a new query and make sure we don't end up with a null list */
  -        List list = executeQuery(criteria);
  -        if (list == null)
  -        {
  -            list = Collections.EMPTY_LIST;
  -        }
  -
  -        /* save the new results */
  -        setStoredResults(new StoredResults(criteria, list));
  -        return list;
  +        return null;
       }
   
   
  -    /*  ---------------------- protected methods -----------------------------  */
  +    protected void setStoredItems(List items)
  +    {
  +        setStoredResults(new StoredResults(criteria, items));
  +    }
   
   
       /**
  @@ -635,7 +309,6 @@
   
   
       /*  ---------------------- utility class -----------------------------  */
  -
   
       /**
        * Simple utility class to hold a criterion and its result list.
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org