Update of /cvsroot/displaytag/displaytag/src/org/apache/taglibs/display
In directory sc8-pr-cvs1:/tmp/cvs-serv4301/src/org/apache/taglibs/display

Modified Files:
        BeanSorter.java ColumnDecorator.java ColumnTag.java 
        Decorator.java SetPropertyTag.java SmartListHelper.java 
        StringUtil.java TableDecorator.java TableTag.java 
        TableTagExtraInfo.java TemplateTag.java 
Log Message:
Reformatted the sources. Fixed some type casts that are not needed. Tabletag now calls 
reset just before returning from doEndTag.

Index: BeanSorter.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/BeanSorter.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** BeanSorter.java     23 Mar 2003 20:54:47 -0000      1.2
--- BeanSorter.java     12 Jun 2003 17:22:15 -0000      1.3
***************
*** 1,12 ****
! /**
   * $Id$
   *
-  * Status: Under Development
-  *
   * Todo
   *   - implementation
   *   - documentation (javadoc, examples, etc...)
   *   - junit test cases
!  **/
  
  package org.apache.taglibs.display;
--- 1,10 ----
! /*
   * $Id$
   *
   * Todo
   *   - implementation
   *   - documentation (javadoc, examples, etc...)
   *   - junit test cases
!  */
  
  package org.apache.taglibs.display;
***************
*** 19,137 ****
  /**
   * This utility class is used to sort the list that the table is viewing
!  * based on arbitrary properties of objects contained in that list.  The
!  * only assumption made is that the object returned by the property is
!  * either a native type, or implements the Comparable interface.
   *
!  * If the property does not implement Comparable, then this little sorter
   * object will just assume that all objects are the same, and quietly do
   * nothing (so you should check for Comparable objecttypes elsewhere as
!  * this object won't complain).
!  **/
! 
! class BeanSorter extends Object implements Comparator
! {
!    private String property;
!    private Decorator dec;
! 
! 
!    /**
!     * BeanSorter is a decorator of sorts, you need to initialize it with
!     * the property name of the object that is to be sorted (getXXX method
!     * name).  This property should return a Comparable object.
!     */
! 
!    protected BeanSorter( String property, Decorator dec )
!    {
!       this.property = property;
!       this.dec = dec;
!    }
! 
! 
!    /**
!     * Compares two objects by first fetching a property from each object
!     * and then comparing that value.  If there are any errors produced while
!     * trying to compare these objects then a RunTimeException will be
!     * thrown as any error found here will most likely be a programming
!     * error that needs to be quickly addressed (like trying to compare
!     * objects that are not comparable, or trying to read a property from a
!     * bean that is invalid, etc...)
!     *
!     * @throws RuntimeException if there are any problems making a comparison
!     *    of the object properties.
!     */
  
!    public int compare( Object o1, Object o2 )
!       throws RuntimeException
!    {
!       if( property == null ) {
!          throw new NullPointerException( "Null property provided which " +
!             "prevents BeanSorter sort" );
!       }
  
!       try {
!          Object p1 = null;
!          Object p2 = null;
  
!          // If they have supplied a decorator, then make sure and use it for
!          // the sorting as well... TODO - Major hack....
  
!          if( this.dec != null ) {
!             try {
!                dec.initRow( o1, -1, -1 );
!                p1 = PropertyUtils.getProperty( dec, property );
  
!                dec.initRow( o2, -1, -1 );
!                p2 = PropertyUtils.getProperty( dec, property );
!             } catch( Exception e ) {
!                // If there were any problems, then assume that the decorator
!                // does not implement that method, and instead fall down to
!                // the original object...
  
!                p1 = PropertyUtils.getProperty( o1, property );
!                p2 = PropertyUtils.getProperty( o2, property );
              }
-          } else {
-             p1 = PropertyUtils.getProperty( o1, property );
-             p2 = PropertyUtils.getProperty( o2, property );
-          }
- 
-          if( p1 instanceof Comparable && p2 instanceof Comparable ) {
-             Comparable c1 = (Comparable)p1;
-             Comparable c2 = (Comparable)p2;
-             return c1.compareTo( c2 );
-          } else {
-             throw new RuntimeException( "Object returned by property \"" +
-                property + "\" is not a Comparable object" );
-          }
-       } catch( IllegalAccessException e ) {
-          throw new RuntimeException( "IllegalAccessException thrown while " +
-             "trying to fetch property \"" + property + "\" during sort" );
-       } catch( InvocationTargetException e ) {
-          throw new RuntimeException( "InvocationTargetException thrown while " +
-             "trying to fetch property \"" + property + "\" during sort" );
-       } catch( NoSuchMethodException e ) {
-          throw new RuntimeException( "NoSuchMethodException thrown while " +
-             "trying to fetch property \"" + property + "\" during sort" );
-       }
-    }
  
  
-    /**
-     * Is this Comparator the same as another one...
-     */
  
!    public boolean equals( Object obj )
!    {
!       if( obj == this ) return true;
  
!       if( obj instanceof BeanSorter ) {
!          if( this.property != null ) {
!             return this.property.equals( ( (BeanSorter)obj ).property );
!          } else {
              return false;
!          }
!       } else {
!          return false;
!       }
!    }
! }
--- 17,135 ----
  /**
   * This utility class is used to sort the list that the table is viewing
!  * based on arbitrary properties of objects contained in that list.
   *
!  * <p>The only assumption made is that the object returned by the property is
!  * either a native type, or implements the Comparable interface.</p>
!  *
!  * <p>If the property does not implement Comparable, then this little sorter
   * object will just assume that all objects are the same, and quietly do
   * nothing (so you should check for Comparable objecttypes elsewhere as
!  * this object won't complain).</p>
!  *
!  * @version $Revision$
!  */
! class BeanSorter extends Object implements Comparator {
!     private String property;
!     private Decorator dec;
  
!     /**
!      * BeanSorter is a decorator of sorts, you need to initialize it with
!      * the property name of the object that is to be sorted (getXXX method
!      * name).  This property should return a Comparable object.
!      */
!     protected BeanSorter(String property, Decorator dec) {
!         this.property = property;
!         this.dec = dec;
!     }
  
!     /**
!      * Compares two objects by first fetching a property from each object
!      * and then comparing that value.  If there are any errors produced while
!      * trying to compare these objects then a RunTimeException will be
!      * thrown as any error found here will most likely be a programming
!      * error that needs to be quickly addressed (like trying to compare
!      * objects that are not comparable, or trying to read a property from a
!      * bean that is invalid, etc...)
!      *
!      * @throws RuntimeException if there are any problems making a comparison
!      *    of the object properties.
!      */
!     public int compare(Object o1, Object o2)
!             throws RuntimeException {
!         if (property == null) {
!             throw new NullPointerException("Null property provided which " +
!                                            "prevents BeanSorter sort");
!         }
  
!         try {
!             Object p1 = null;
!             Object p2 = null;
  
!             // If they have supplied a decorator, then make sure and use it for
!             // the sorting as well... TODO - Major hack....
  
!             if (this.dec != null) {
!                 try {
!                     dec.initRow(o1, -1, -1);
!                     p1 = PropertyUtils.getProperty(dec, property);
  
!                     dec.initRow(o2, -1, -1);
!                     p2 = PropertyUtils.getProperty(dec, property);
!                 }
!                 catch (Exception e) {
!                     // If there were any problems, then assume that the decorator
!                     // does not implement that method, and instead fall down to
!                     // the original object...
!                     p1 = PropertyUtils.getProperty(o1, property);
!                     p2 = PropertyUtils.getProperty(o2, property);
!                 }
!             }
!             else {
!                 p1 = PropertyUtils.getProperty(o1, property);
!                 p2 = PropertyUtils.getProperty(o2, property);
              }
  
+             if (p1 instanceof Comparable && p2 instanceof Comparable) {
+                 Comparable c1 = (Comparable) p1;
+                 Comparable c2 = (Comparable) p2;
+                 return c1.compareTo(c2);
+             }
+             else {
+                 throw new RuntimeException("Object returned by property \"" +
+                                            property + "\" is not a Comparable 
object");
+             }
+         }
+         catch (IllegalAccessException e) {
+             throw new RuntimeException("IllegalAccessException thrown while " +
+                                        "trying to fetch property \"" + property + 
"\" during sort");
+         }
+         catch (InvocationTargetException e) {
+             throw new RuntimeException("InvocationTargetException thrown while " +
+                                        "trying to fetch property \"" + property + 
"\" during sort");
+         }
+         catch (NoSuchMethodException e) {
+             throw new RuntimeException("NoSuchMethodException thrown while " +
+                                        "trying to fetch property \"" + property + 
"\" during sort");
+         }
+     }
  
  
!     /**
!      * Checks if this Comparator the same as another one.
!      */
!     public boolean equals(Object obj) {
!         if (obj == this) return true;
  
!         if (obj instanceof BeanSorter) {
!             if (this.property != null) {
!                 return this.property.equals(((BeanSorter) obj).property);
!             }
!             else {
!                 return false;
!             }
!         }
!         else {
              return false;
!         }
!     }
! }
\ No newline at end of file

Index: ColumnDecorator.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/ColumnDecorator.java,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** ColumnDecorator.java        4 Feb 2003 01:35:34 -0000       1.1.1.1
--- ColumnDecorator.java        12 Jun 2003 17:22:15 -0000      1.2
***************
*** 1,18 ****
! /**
   * $Id$
!  *
!  * Status: Ok
!  **/
  
  package org.apache.taglibs.display;
  
! public abstract class ColumnDecorator extends Decorator
! {
!    public ColumnDecorator()
!    {
!       super();
!    }
! 
!    public abstract String decorate( Object columnValue );
! }
  
--- 1,16 ----
! /*
   * $Id$
!  */
  
  package org.apache.taglibs.display;
  
! /**
!  * @version $Revision$
!  */
! public abstract class ColumnDecorator extends Decorator {
!     public ColumnDecorator() {
!         super();
!     }
  
+     public abstract String decorate(Object columnValue);
+ }
\ No newline at end of file

Index: ColumnTag.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/ColumnTag.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** ColumnTag.java      23 Mar 2003 20:54:47 -0000      1.4
--- ColumnTag.java      12 Jun 2003 17:22:16 -0000      1.5
***************
*** 19,23 ****
  
  /**
!  * This tag works hand in hand with the SmartListTag to display a list of 
   * objects.  This describes a column of data in the SmartListTag.  There can
   * be any (reasonable) number of columns that make up the list.
--- 19,23 ----
  
  /**
!  * This tag works hand in hand with the SmartListTag to display a list of
   * objects.  This describes a column of data in the SmartListTag.  There can
   * be any (reasonable) number of columns that make up the list.
***************
*** 36,40 ****
   * Attributes:<pre>
   *
!  *   property       - the property method that is called to retrieve the 
   *                    information to be displayed in this column.  This method
   *                    is called on the current object in the iteration for
--- 36,40 ----
   * Attributes:<pre>
   *
!  *   property       - the property method that is called to retrieve the
   *                    information to be displayed in this column.  This method
   *                    is called on the current object in the iteration for
***************
*** 47,51 ****
   *
   *   nulls          - by default, null values don't appear in the list, by
!  *                    setting viewNulls to 'true', then null values will 
   *                    appear as "null" in the list (mostly useful for debugging)
   *                    (optional)
--- 47,51 ----
   *
   *   nulls          - by default, null values don't appear in the list, by
!  *                    setting viewNulls to 'true', then null values will
   *                    appear as "null" in the list (mostly useful for debugging)
   *                    (optional)
***************
*** 71,77 ****
   *                    into a hypertext link.
   *
!  *   href           - if this attribute is provided, then the data that is 
   *                    shown for this column is wrapped inside a &lt;a href&gt;
!  *                    tag with the url provided through this attribute.  
   *                    Typically you would use this attribute along with one
   *                    of the struts-like param attributes below to create
--- 71,77 ----
   *                    into a hypertext link.
   *
!  *   href           - if this attribute is provided, then the data that is
   *                    shown for this column is wrapped inside a &lt;a href&gt;
!  *                    tag with the url provided through this attribute.
   *                    Typically you would use this attribute along with one
   *                    of the struts-like param attributes below to create
***************
*** 80,107 ****
   *
   *   paramId        - The name of the request parameter that will be dynamically
!  *                    added to the generated href URL. The corresponding value 
!  *                    is defined by the paramProperty and (optional) paramName 
   *                    attributes, optionally scoped by the paramScope attribute.
   *                    (optional)
   *
!  *   paramName      - The name of a JSP bean that is a String containing the 
!  *                    value for the request parameter named by paramId (if 
!  *                    paramProperty is not specified), or a JSP bean whose 
!  *                    property getter is called to return a String (if 
!  *                    paramProperty is specified). The JSP bean is constrained 
!  *                    to the bean scope specified by the paramScope property, 
   *                    if it is specified.  If paramName is omitted, then it is
   *                    assumed that the current object being iterated on is the
   *                    target bean. (optional)
   *
!  *   paramProperty  - The name of a property of the bean specified by the 
   *                    paramName attribute (or the current object being iterated
!  *                    on if paramName is not provided), whose return value must 
!  *                    be a String containing the value of the request parameter 
!  *                    (named by the paramId attribute) that will be dynamically 
   *                    added to this href URL. (optional)
   *
   *   paramScope     - The scope within which to search for the bean specified by
!  *                    the paramName attribute. If not specified, all scopes are 
   *                    searched.  If paramName is not provided, then the current
   *                    object being iterated on is assumed to be the target bean.
--- 80,107 ----
   *
   *   paramId        - The name of the request parameter that will be dynamically
!  *                    added to the generated href URL. The corresponding value
!  *                    is defined by the paramProperty and (optional) paramName
   *                    attributes, optionally scoped by the paramScope attribute.
   *                    (optional)
   *
!  *   paramName      - The name of a JSP bean that is a String containing the
!  *                    value for the request parameter named by paramId (if
!  *                    paramProperty is not specified), or a JSP bean whose
!  *                    property getter is called to return a String (if
!  *                    paramProperty is specified). The JSP bean is constrained
!  *                    to the bean scope specified by the paramScope property,
   *                    if it is specified.  If paramName is omitted, then it is
   *                    assumed that the current object being iterated on is the
   *                    target bean. (optional)
   *
!  *   paramProperty  - The name of a property of the bean specified by the
   *                    paramName attribute (or the current object being iterated
!  *                    on if paramName is not provided), whose return value must
!  *                    be a String containing the value of the request parameter
!  *                    (named by the paramId attribute) that will be dynamically
   *                    added to this href URL. (optional)
   *
   *   paramScope     - The scope within which to search for the bean specified by
!  *                    the paramName attribute. If not specified, all scopes are
   *                    searched.  If paramName is not provided, then the current
   *                    object being iterated on is assumed to be the target bean.
***************
*** 122,355 ****
   */
  public class ColumnTag extends BodyTagSupport implements Cloneable {
!    
!    private String property;
!    private String title;
!    private String nulls;
!    private String sort;
!    private String autolink;
!    private String group; /* If this property is set then the values have to be 
grouped */
!    
!    private String href;
!    private String paramId;
!    private String paramName;
!    private String paramProperty;
!    private String paramScope;
!    private int maxLength;
!    private int maxWords;
  
!    private String width;
!    private String align;
!    private String background;
!    private String bgcolor;
!    private String height;
!    private String nowrap;
!    private String valign;
!    private String clazz;
!    private String headerClazz;
  
!    private String value;
  
!    private String doubleQuote ;
  
!    private String decorator;
  
!    // -------------------------------------------------------- Accessor methods
  
!    public void setProperty( String v ) { this.property = v; }
!    public void setTitle( String v ) { this.title = v; }
!    public void setNulls( String v ) { this.nulls = v; }
!    public void setSort( String v ) { this.sort = v; }
!    public void setAutolink( String v ) { this.autolink = v; }
!    public void setGroup( String v ) { this.group = v; }
  
  
!    public void setHref( String v ) { this.href = v; }
!    public void setParamId( String v ) { this.paramId = v; }
!    public void setParamName( String v ) { this.paramName = v; }
!    public void setParamProperty( String v ) { this.paramProperty = v; }
!    public void setParamScope( String v ) { this.paramScope = v; }
  
!    public void setMaxLength( int v ) { this.maxLength = v; }
!    public void setMaxWords( int v ) { this.maxWords = v; }
  
  
!    public void setWidth( String v ) { this.width = v; }
!    public void setAlign( String v ) { this.align = v; }
!    public void setBackground( String v ) { this.background = v; }
!    public void setBgcolor( String v ) { this.bgcolor = v; }
!    public void setHeight( String v ) { this.height = v; }
!    public void setNowrap( String v ) { this.nowrap = v; }
!    public void setValign( String v ) { this.valign = v; }
!    public void setStyleClass( String v ) { this.clazz = v; }
!    public void setHeaderStyleClass( String v ) { this.headerClazz = v; }
  
!    public void setValue( String v ) { this.value = v; }
  
-    public void setDoubleQuote ( String v ) { this.doubleQuote = v ; }
-    public void setDecorator(String v) {this.decorator = v; }
  
  
!    public String getProperty() { return this.property; }
!    public String getTitle() { return this.title; }
!    public String getNulls() { return this.nulls; }
!    public String getSort() { return this.sort; }
!    public String getAutolink() { return this.autolink; }
!    public String getGroup() { return this.group; }
!               
!    public String getHref() { return this.href; }
!    public String getParamId() { return this.paramId; }
!    public String getParamName() { return this.paramName; }
!    public String getParamProperty() { return this.paramProperty; }
!    public String getParamScope() { return this.paramScope; }
  
!    public int getMaxLength() { return this.maxLength; }
!    public int getMaxWords() { return this.maxWords; }
  
!    public String getWidth() { return this.width; }
!    public String getAlign() { return this.align; }
!    public String getBackground() { return this.background; }
!    public String getBgcolor() { return this.bgcolor; }
!    public String getHeight() { return this.height; }
!    public String getNowrap() { return this.nowrap; }
!    public String getValign() { return this.valign; }
!    public String getStyleClass() { return this.clazz; }
!    public String getHeaderStyleClass() { return this.headerClazz; }
  
!    public String getValue() { return this.value; }
  
!    public String getDoubleQuote () { return this.doubleQuote ; }
!    public String getDecorator() { return this.decorator ;}
  
!    // --------------------------------------------------------- Tag API methods
!    
!    /**
!     * Passes attribute information up to the parent TableTag.
!     *
!     * <p>When we hit the end of the tag, we simply let our parent (which better
!     * be a TableTag) know what the user wants to do with this column.
!     * We do that by simple registering this tag with the parent.  This tag's
!     * only job is to hold the configuration information to describe this 
!     * particular column.  The TableTag does all the work.</p>
!     *
!     * @throws JspException if this tag is being used outside of a 
!     *    &lt;display:list...&gt; tag.
!     **/
  
-    public int doEndTag() throws JspException {
-       Object parent = this.getParent();
  
!       boolean foundTableTag = false;
  
!       while (!foundTableTag) {
!         if( parent == null ) {
!             throw new JspException( "Can not use column tag outside of a TableTag." 
);
!         }
  
!         if( !( parent instanceof TableTag ) ) {
!             if (parent instanceof TagSupport)
!                 parent = ((TagSupport) parent).getParent ();
!             else 
!                 throw new JspException( "Can not use column tag outside of a 
TableTag." );
!         } else
!             foundTableTag = true;
!       }
  
!       // Need to clone the ColumnTag before passing it to the TableTag as
!       // the ColumnTags can be reused by some containers, and since we are
!       // using the ColumnTags as basically containers of data, we need to
!       // save the original values, and not the values that are being changed
!       // as the tag is being reused...
  
!       ColumnTag copy = this;
!       try {
!          copy = (ColumnTag)this.clone();
!       } catch( CloneNotSupportedException e ) {} // shouldn't happen...
  
!       ((TableTag)parent).addColumn( copy );
  
!       return super.doEndTag();
!    }
  
  
!    /**
!     * Takes all the column pass-through arguments and bundles them up as a
!     * string that gets tacked on to the end of the td tag declaration.<p>
!     **/
  
!    protected String getCellAttributes()
!    {
!       StringBuffer results = new StringBuffer();
  
!       if( this.clazz != null ) {
!           results.append( " class=\"" );
!           results.append( this.clazz );
!           results.append( "\"" );
!       } else {
!           results.append( " class=\"tableCell\"" );
!       }
  
!       if( this.width != null ) {
!          results.append( " width=\"" );
!          results.append( this.width );
!          results.append( "\"" );
!       }
  
-       if( this.align != null ) {
-          results.append( " align=\"" );
-          results.append( this.align );
-          results.append( "\"" );
-       } else {
-           results.append( " align=\"left\"" );
-       }
  
!       if( this.background != null ) {
!          results.append( " background=\"" );
!          results.append( this.background );
!          results.append( "\"" );
!       }
  
!       if( this.bgcolor != null ) {
!          results.append( " bgcolor=\"" );
!          results.append( this.bgcolor );
!          results.append( "\"" );
!       }
  
!       if( this.height != null ) {
!          results.append( " height=\"" );
!          results.append( this.height );
!          results.append( "\"" );
!       }
  
!       if( this.nowrap != null ) {
!          results.append( " nowrap" );
!       }
  
!       if( this.valign != null ) {
!          results.append( " valign=\"" );
!          results.append( this.valign );
!          results.append( "\"" );
!       } else {
!           results.append( " valign=\"top\"" );
!       }
  
!       return results.toString();
!    }
  
  
!    /**
!     * Returns a String representation of this Tag that is suitable for
!     * printing while debugging.  The format of the string is subject to change
!     * but it currently:
!     *
!     * <p><code>SmartColumnTag([title],[property],[href])</code></p>
!     *
!     * <p>Where the placeholders in brackets are replaced with their appropriate
!     * instance variables.</p>
!     **/
!    
!    public String toString() {
!       return "SmartColumnTag(" + title + "," + property + "," + href + ")";
!    }
  
! }
  
--- 122,491 ----
   */
  public class ColumnTag extends BodyTagSupport implements Cloneable {
!     private String property;
!     private String title;
!     private String nulls;
!     private String sort;
!     private String autolink;
!     private String group; /* If this property is set then the values have to be 
grouped */
  
!     private String href;
!     private String paramId;
!     private String paramName;
!     private String paramProperty;
!     private String paramScope;
!     private int maxLength;
!     private int maxWords;
  
!     private String width;
!     private String align;
!     private String background;
!     private String bgcolor;
!     private String height;
!     private String nowrap;
!     private String valign;
!     private String clazz;
!     private String headerClazz;
  
!     private String value;
  
!     private String doubleQuote;
  
!     private String decorator;
  
!     // -------------------------------------------------------- Accessor methods
  
+     public void setProperty(String v) {
+         this.property = v;
+     }
  
!     public void setTitle(String v) {
!         this.title = v;
!     }
  
!     public void setNulls(String v) {
!         this.nulls = v;
!     }
  
+     public void setSort(String v) {
+         this.sort = v;
+     }
  
!     public void setAutolink(String v) {
!         this.autolink = v;
!     }
  
!     public void setGroup(String v) {
!         this.group = v;
!     }
  
  
+     public void setHref(String v) {
+         this.href = v;
+     }
  
!     public void setParamId(String v) {
!         this.paramId = v;
!     }
  
!     public void setParamName(String v) {
!         this.paramName = v;
!     }
  
!     public void setParamProperty(String v) {
!         this.paramProperty = v;
!     }
  
!     public void setParamScope(String v) {
!         this.paramScope = v;
!     }
  
!     public void setMaxLength(int v) {
!         this.maxLength = v;
!     }
  
!     public void setMaxWords(int v) {
!         this.maxWords = v;
!     }
  
  
!     public void setWidth(String v) {
!         this.width = v;
!     }
  
!     public void setAlign(String v) {
!         this.align = v;
!     }
  
!     public void setBackground(String v) {
!         this.background = v;
!     }
  
!     public void setBgcolor(String v) {
!         this.bgcolor = v;
!     }
  
!     public void setHeight(String v) {
!         this.height = v;
!     }
  
!     public void setNowrap(String v) {
!         this.nowrap = v;
!     }
  
!     public void setValign(String v) {
!         this.valign = v;
!     }
  
+     public void setStyleClass(String v) {
+         this.clazz = v;
+     }
  
!     public void setHeaderStyleClass(String v) {
!         this.headerClazz = v;
!     }
  
!     public void setValue(String v) {
!         this.value = v;
!     }
  
!     public void setDoubleQuote(String v) {
!         this.doubleQuote = v;
!     }
  
!     public void setDecorator(String v) {
!         this.decorator = v;
!     }
  
  
!     public String getProperty() {
!         return this.property;
!     }
  
!     public String getTitle() {
!         return this.title;
!     }
  
!     public String getNulls() {
!         return this.nulls;
!     }
  
!     public String getSort() {
!         return this.sort;
!     }
  
!     public String getAutolink() {
!         return this.autolink;
!     }
  
!     public String getGroup() {
!         return this.group;
!     }
  
+     public String getHref() {
+         return this.href;
+     }
  
!     public String getParamId() {
!         return this.paramId;
!     }
  
!     public String getParamName() {
!         return this.paramName;
!     }
! 
!     public String getParamProperty() {
!         return this.paramProperty;
!     }
! 
!     public String getParamScope() {
!         return this.paramScope;
!     }
! 
!     public int getMaxLength() {
!         return this.maxLength;
!     }
! 
!     public int getMaxWords() {
!         return this.maxWords;
!     }
! 
!     public String getWidth() {
!         return this.width;
!     }
! 
!     public String getAlign() {
!         return this.align;
!     }
! 
!     public String getBackground() {
!         return this.background;
!     }
! 
!     public String getBgcolor() {
!         return this.bgcolor;
!     }
! 
!     public String getHeight() {
!         return this.height;
!     }
! 
!     public String getNowrap() {
!         return this.nowrap;
!     }
! 
!     public String getValign() {
!         return this.valign;
!     }
! 
!     public String getStyleClass() {
!         return this.clazz;
!     }
! 
!     public String getHeaderStyleClass() {
!         return this.headerClazz;
!     }
! 
!     public String getValue() {
!         return this.value;
!     }
! 
!     public String getDoubleQuote() {
!         return this.doubleQuote;
!     }
! 
!     public String getDecorator() {
!         return this.decorator;
!     }
  
+     // --------------------------------------------------------- Tag API methods
+ 
+     /**
+      * Passes attribute information up to the parent TableTag.
+      *
+      * <p>When we hit the end of the tag, we simply let our parent (which better
+      * be a TableTag) know what the user wants to do with this column.
+      * We do that by simple registering this tag with the parent.  This tag's
+      * only job is to hold the configuration information to describe this
+      * particular column.  The TableTag does all the work.</p>
+      *
+      * @throws JspException if this tag is being used outside of a
+      *    &lt;display:list...&gt; tag.
+      */
+     public int doEndTag() throws JspException {
+         Object parent = this.getParent();
+ 
+         boolean foundTableTag = false;
+ 
+         while (!foundTableTag) {
+             if (parent == null) {
+                 throw new JspException("Can not use column tag outside of a 
TableTag.");
+             }
+ 
+             if (!(parent instanceof TableTag)) {
+                 if (parent instanceof TagSupport)
+                     parent = ((TagSupport) parent).getParent();
+                 else
+                     throw new JspException("Can not use column tag outside of a 
TableTag.");
+             }
+             else
+                 foundTableTag = true;
+         }
+ 
+         // Need to clone the ColumnTag before passing it to the TableTag as
+         // the ColumnTags can be reused by some containers, and since we are
+         // using the ColumnTags as basically containers of data, we need to
+         // save the original values, and not the values that are being changed
+         // as the tag is being reused...
+ 
+         ColumnTag copy = this;
+         try {
+             copy = (ColumnTag) this.clone();
+         }
+         catch (CloneNotSupportedException e) {
+         } // shouldn't happen...
+ 
+         ((TableTag) parent).addColumn(copy);
+ 
+         return super.doEndTag();
+     }
+ 
+ 
+     /**
+      * Takes all the column pass-through arguments and bundles them up as a
+      * string that gets tacked on to the end of the td tag declaration.
+      */
+     protected String getCellAttributes() {
+         StringBuffer results = new StringBuffer();
+ 
+         if (this.clazz != null) {
+             results.append(" class=\"");
+             results.append(this.clazz);
+             results.append("\"");
+         }
+         else {
+             results.append(" class=\"tableCell\"");
+         }
+ 
+         if (this.width != null) {
+             results.append(" width=\"");
+             results.append(this.width);
+             results.append("\"");
+         }
+ 
+         if (this.align != null) {
+             results.append(" align=\"");
+             results.append(this.align);
+             results.append("\"");
+         }
+         else {
+             results.append(" align=\"left\"");
+         }
+ 
+         if (this.background != null) {
+             results.append(" background=\"");
+             results.append(this.background);
+             results.append("\"");
+         }
+ 
+         if (this.bgcolor != null) {
+             results.append(" bgcolor=\"");
+             results.append(this.bgcolor);
+             results.append("\"");
+         }
+ 
+         if (this.height != null) {
+             results.append(" height=\"");
+             results.append(this.height);
+             results.append("\"");
+         }
+ 
+         if (this.nowrap != null) {
+             results.append(" nowrap");
+         }
+ 
+         if (this.valign != null) {
+             results.append(" valign=\"");
+             results.append(this.valign);
+             results.append("\"");
+         }
+         else {
+             results.append(" valign=\"top\"");
+         }
+ 
+         return results.toString();
+     }
+ 
+     /**
+      * Returns a String representation of this Tag that is suitable for
+      * printing while debugging.  The format of the string is subject to change
+      * but it currently:
+      *
+      * <p><code>SmartColumnTag([title],[property],[href])</code></p>
+      *
+      * <p>Where the placeholders in brackets are replaced with their appropriate
+      * instance variables.</p>
+      */
+     public String toString() {
+         return "SmartColumnTag(" + title + "," + property + "," + href + ")";
+     }
+ }
\ No newline at end of file

Index: Decorator.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/Decorator.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** Decorator.java      23 Mar 2003 20:54:47 -0000      1.4
--- Decorator.java      12 Jun 2003 17:22:16 -0000      1.5
***************
*** 1,10 ****
! /**
   * $Id$
   *
-  * Status: Ok
-  *
   * Todo
   *   - push the appropriate stuff down into TableDecorator
!  **/
  
  package org.apache.taglibs.display;
--- 1,8 ----
! /*
   * $Id$
   *
   * Todo
   *   - push the appropriate stuff down into TableDecorator
!  */
  
  package org.apache.taglibs.display;
***************
*** 16,77 ****
  
  /**
!  * This class provides some basic functionality for all objects which serve
!  * as decorators for the objects in the List being displayed.
!  **/
! 
! public abstract class Decorator extends Object
! {
!    private PageContext ctx = null;
!    private Object collection = null;
!     
!    private Object obj = null;
!    private int viewIndex = -1;
!    private int listIndex = -1;
  
  
!    public Decorator() {
  
!    }
  
!    public void init( PageContext ctx, Object list ) {
!       this.ctx = ctx;
!       this.collection = list;
!    }
  
!    public String initRow( Object obj, int viewIndex, int listIndex ) {
!       this.obj = obj;
!       this.viewIndex = viewIndex;
!       this.listIndex = listIndex;
!       return "";
!    }
  
!    public String startRow() {
!       return "";
!    }
  
!    public String finishRow() {
!       return "";
!    }
  
!    public void finish() {
!    
!    }
  
!    public PageContext getPageContext() { return this.ctx; }
  
      public List getList() {
!       if (this.collection instanceof List) 
!         return (List)this.collection;
!       else throw new RuntimeException ("This function is only supported if the given 
collection is a java.util.List.");
      }
  
!     public Collection getCollection () {
!       if (this instanceof Collection)
!           return (Collection) this.collection;
!       else throw new RuntimeException ("This function is only supported if the given 
collection is a java.util.Collection.");
      }
!     
!    public Object getObject() { return this.obj; }
!    public int getViewIndex() { return this.viewIndex; }
!    public int getListIndex() { return this.listIndex; }
! }
--- 14,85 ----
  
  /**
!  * This class provides some basic functionality for all objects which
!  * serve as decorators for the objects in the List being displayed.
!  *
!  * @version $Revision$
!  */
! public abstract class Decorator extends Object {
!     private PageContext ctx = null;
!     private Object collection = null;
  
+     private Object obj = null;
+     private int viewIndex = -1;
+     private int listIndex = -1;
  
!     public Decorator() {
!     }
  
!     public void init(PageContext ctx, Object list) {
!         this.ctx = ctx;
!         this.collection = list;
!     }
  
!     public String initRow(Object obj, int viewIndex, int listIndex) {
!         this.obj = obj;
!         this.viewIndex = viewIndex;
!         this.listIndex = listIndex;
!         return "";
!     }
  
!     public String startRow() {
!         return "";
!     }
  
!     public String finishRow() {
!         return "";
!     }
  
!     public void finish() {
  
!     }
  
!     public PageContext getPageContext() {
!         return this.ctx;
!     }
  
      public List getList() {
!         if (this.collection instanceof List)
!             return (List) this.collection;
!         else
!             throw new RuntimeException("This function is only supported if the given 
collection is a java.util.List.");
      }
  
!     public Collection getCollection() {
!         if (this instanceof Collection)
!             return (Collection) this.collection;
!         else
!             throw new RuntimeException("This function is only supported if the given 
collection is a java.util.Collection.");
      }
! 
!     public Object getObject() {
!         return this.obj;
!     }
! 
!     public int getViewIndex() {
!         return this.viewIndex;
!     }
! 
!     public int getListIndex() {
!         return this.listIndex;
!     }
! }
\ No newline at end of file

Index: SetPropertyTag.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/SetPropertyTag.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** SetPropertyTag.java 23 Mar 2003 20:54:47 -0000      1.2
--- SetPropertyTag.java 12 Jun 2003 17:22:16 -0000      1.3
***************
*** 1,12 ****
! /**
   * $Id$
   *
-  * Status: Under Development
-  *
   * Todo
   *   - implementation
   *   - documentation (javadoc, examples, etc...)
   *   - junit test cases
!  **/
  
  package org.apache.taglibs.display;
--- 1,10 ----
! /*
   * $Id$
   *
   * Todo
   *   - implementation
   *   - documentation (javadoc, examples, etc...)
   *   - junit test cases
!  */
  
  package org.apache.taglibs.display;
***************
*** 19,66 ****
   *
   * More detailed class description, including examples of usage if applicable.
!  **/
! 
! public class SetPropertyTag extends BodyTagSupport implements Cloneable
! {
!    private String name;
!    private String value;
  
!    public void setName( String v ) { this.name = v; }
!    public void setValue( String v ) { this.value = v; }
  
!    public String getName() { return this.name; }
!    public String getValue() { return this.value; }
  
!    // --------------------------------------------------------- Tag API methods
  
!    /**
!     * Passes attribute information up to the parent TableTag.<p>
!     *
!     * When we hit the end of the tag, we simply let our parent (which better
!     * be a TableTag) know what the user wants to change a property value, and
!     * we pass the name/value pair that the user gave us, up to the parent
!     *
!     * @throws javax.servlet.jsp.JspException if this tag is being used outside of a
!     *    <display:list...> tag.
!     **/
  
!    public int doEndTag() throws JspException {
!       Object parent = this.getParent();
  
!       if( parent == null ) {
!          throw new JspException( "Can not use column tag outside of a " +
!                                  "TableTag. Invalid parent = null" );
!       }
  
!       if( !( parent instanceof TableTag ) ) {
!          throw new JspException( "Can not use column tag outside of a " +
!                                  "TableTag. Invalid parent = " +
!                                  parent.getClass().getName() );
!       }
  
!       ((TableTag)parent).setProperty( this.name, this.value );
  
!       return super.doEndTag();
!    }
  
! }
--- 17,70 ----
   *
   * More detailed class description, including examples of usage if applicable.
!  */
! public class SetPropertyTag extends BodyTagSupport implements Cloneable {
!     private String name;
!     private String value;
  
!     public void setName(String v) {
!         this.name = v;
!     }
  
!     public void setValue(String v) {
!         this.value = v;
!     }
  
!     public String getName() {
!         return this.name;
!     }
  
!     public String getValue() {
!         return this.value;
!     }
  
!     // --------------------------------------------------------- Tag API methods
  
!     /**
!      * Passes attribute information up to the parent TableTag.<p>
!      *
!      * When we hit the end of the tag, we simply let our parent (which better
!      * be a TableTag) know what the user wants to change a property value, and
!      * we pass the name/value pair that the user gave us, up to the parent
!      *
!      * @throws javax.servlet.jsp.JspException if this tag is being used outside of a
!      *    <display:list...> tag.
!      */
!     public int doEndTag() throws JspException {
!         Object parent = this.getParent();
  
!         if (parent == null) {
!             throw new JspException("Can not use column tag outside of a " +
!                                    "TableTag. Invalid parent = null");
!         }
  
!         if (!(parent instanceof TableTag)) {
!             throw new JspException("Can not use column tag outside of a " +
!                                    "TableTag. Invalid parent = " +
!                                    parent.getClass().getName());
!         }
  
!         ((TableTag) parent).setProperty(this.name, this.value);
  
!         return super.doEndTag();
!     }
! }
\ No newline at end of file

Index: SmartListHelper.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/SmartListHelper.java,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** SmartListHelper.java        4 Feb 2003 01:35:36 -0000       1.1.1.1
--- SmartListHelper.java        12 Jun 2003 17:22:16 -0000      1.2
***************
*** 1,7 ****
! /**
   * $Id$
!  *
!  * Status: Under Development
!  **/
  
  package org.apache.taglibs.display;
--- 1,5 ----
! /*
   * $Id$
!  */
  
  package org.apache.taglibs.display;
***************
*** 17,322 ****
   * display.
   *
!  * This class is a stripped down version of the WebListHelper that we got
!  * from Tim Dawson ([EMAIL PROTECTED])
   */
  
! class SmartListHelper extends Object
! {
!    private List masterList;
!    private int pageSize;
!    private int pageCount;
!    private int currentPage;
! 
!    private Properties prop = null;
! 
! 
!    /**
!     * Creates a SmarListHelper instance that will help you chop up a list
!     * into bite size pieces that are suitable for display.
!     */
! 
!    protected SmartListHelper( List list, int pageSize, Properties prop )
!    {
!       super();
! 
!       if( list == null || pageSize < 1 ) {
!          throw new IllegalArgumentException( "Bad arguments passed into " +
!             "SmartListHelper() constructor" );
!       }
! 
!       this.prop = prop;
!       this.pageSize = pageSize;
!       this.masterList = list;
!       this.pageCount = this.computedPageCount();
!       this.currentPage = 1;
!    }
! 
! 
!    /**
!     * Returns the computed number of pages it would take to show all the
!     * elements in the list given the pageSize we are working with.
!     */
! 
!    protected int computedPageCount()
!    {
! 
!       int result = 0;
! 
!       if( ( this.masterList != null ) && ( this.pageSize > 0 ) ) {
!          int size = this.masterList.size();
!          int div = size / this.pageSize;
!          int mod = size % this.pageSize;
!          result = ( mod == 0 ) ? div : div + 1;
!       }
! 
!       return result;
! 
!    }
! 
! 
!    /**
!     * Returns the index into the master list of the first object that
!     * should appear on the current page that the user is viewing.
!     */
! 
!    protected int getFirstIndexForCurrentPage()
!    {
!       return this.getFirstIndexForPage( this.currentPage );
!    }
! 
!    /**
!     * Returns the index into the master list of the last object that should
!     * appear on the current page that the user is viewing.
!     */
! 
!    protected int getLastIndexForCurrentPage()
!    {
!       return this.getLastIndexForPage( this.currentPage );
!    }
! 
! 
!    /**
!     * Returns the index into the master list of the first object that
!     * should appear on the given page.
!     */
! 
!    protected int getFirstIndexForPage( int page )
!    {
!       return ( ( page - 1 ) * this.pageSize );
!    }
! 
! 
!    /**
!     * Returns the index into the master list of the last object that should
!     * appear on the given page.
!     */
! 
!    protected int getLastIndexForPage( int page )
!    {
!       int firstIndex = this.getFirstIndexForPage( page );
!       int pageIndex = this.pageSize - 1;
!       int lastIndex = this.masterList.size() - 1;
! 
!       return Math.min( firstIndex + pageIndex, lastIndex );
!    }
  
  
!    /**
!     * Returns a subsection of the list that contains just the elements that
!     * are supposed to be shown on the current page the user is viewing.
!     */
  
!    protected List getListForCurrentPage()
!    {
!       return this.getListForPage( this.currentPage );
!    }
  
  
!    /**
!     * Returns a subsection of the list that contains just the elements that
!     * are supposed to be shown on the given page.
!     */
  
!    protected List getListForPage( int page )
!    {
!       List list = new ArrayList( this.pageSize + 1 );
  
!       int firstIndex = this.getFirstIndexForPage( page );
!       int lastIndex = this.getLastIndexForPage( page );
  
!       for( int i = firstIndex; i <= lastIndex; i++ ) {
!          list.add( this.masterList.get( i ) );
!       }
  
!       return list;
!    }
  
  
!    /**
!     * Set's the page number that the user is viewing.
!     *
!     * @throws IllegalArgumentException if the page provided is invalid.
!     */
  
!    protected void setCurrentPage( int page )
!    {
!       if( page < 1 || page > this.pageCount ) {
!          Object[] objs = {new Integer( page ), new Integer( pageCount )};
!          throw new IllegalArgumentException(
!             MessageFormat.format( prop.getProperty( "error.msg.invalid_page" ), objs 
) );
!       }
  
!       this.currentPage = page;
!    }
  
  
!    /**
!     * Return the little summary message that lets the user know how many
!     * objects are in the list they are viewing, and where in the list they
!     * are currently positioned.  The message looks like:
!     *
!     *   nnn <item(s)> found, displaying nnn to nnn.
!     *
!     * <item(s)> is replaced by either itemName or itemNames depending on if
!     * it should be signular or plurel.
!     */
  
!    protected String getSearchResultsSummary()
!    {
  
!       if( this.masterList.size() == 0 ) {
!          Object[] objs = {prop.getProperty( "paging.banner.items_name" )};
!          return MessageFormat.format(
!             prop.getProperty( "paging.banner.no_items_found" ), objs );
!       } else if( this.masterList.size() == 1 ) {
!          Object[] objs = {prop.getProperty( "paging.banner.item_name" )};
!          return MessageFormat.format(
!             prop.getProperty( "paging.banner.one_item_found" ), objs );
!       } else if( this.getFirstIndexForCurrentPage() == 
this.getLastIndexForCurrentPage() ) {
!          Object[] objs = {new Integer( this.masterList.size() ),
!                           prop.getProperty( "paging.banner.items_name" ),
!                           prop.getProperty( "paging.banner.items_name" )};
  
!          return MessageFormat.format(
!             prop.getProperty( "paging.banner.all_items_found" ), objs );
!       } else {
!          Object[] objs = {new Integer( this.masterList.size() ),
!                           prop.getProperty( "paging.banner.items_name" ),
!                           new Integer( this.getFirstIndexForCurrentPage() + 1 ),
!                           new Integer( this.getLastIndexForCurrentPage() + 1 )};
  
!          return MessageFormat.format(
!             prop.getProperty( "paging.banner.some_items_found" ), objs );
!       }
!    }
  
  
!    /**
!     * Returns a string containing the nagivation bar that allows the user
!     * to move between pages within the list.
!     *
!     * The urlFormatString should be a URL that looks like the following:
!     *
!     * http://.../somepage.page?page={0}
!     */
  
!    protected String getPageNavigationBar( String urlFormatString )
!    {
!       MessageFormat form = new MessageFormat( urlFormatString );
  
!       int maxPages = 8;
  
!       try {
!          maxPages = Integer.parseInt( prop.getProperty( "paging.banner.group_size" ) 
);
!       } catch( NumberFormatException e ) {
!          // Don't care, we will just default to 8.
!       }
  
!       int currentPage = this.currentPage;
!       int pageCount = this.pageCount;
!       int startPage = 1;
!       int endPage = maxPages;
  
!       if( pageCount == 1 || pageCount == 0 ) {
!          return "<b>1</b>";
!       }
  
!       if( currentPage < maxPages ) {
!          startPage = 1;
!          endPage = maxPages;
!          if( pageCount < endPage ) {
!             endPage = pageCount;
!          }
!       } else {
!          startPage = currentPage;
!          while( startPage + maxPages > ( pageCount + 1 ) ) {
!             startPage--;
!          }
  
!          endPage = startPage + ( maxPages - 1 );
!       }
  
!       boolean includeFirstLast = prop.getProperty( 
"paging.banner.include_first_last" ).equals( "true" );
  
!       String msg = "";
!       if( currentPage == 1 ) {
!          if( includeFirstLast ) {
!             msg += "[" + prop.getProperty( "paging.banner.first_label" ) +
!                "/" + prop.getProperty( "paging.banner.prev_label" ) + "] ";
!          } else {
!             msg += "[" + prop.getProperty( "paging.banner.prev_label" ) + "] ";
!          }
!       } else {
!          Object[] objs = {new Integer( currentPage - 1 )};
!          Object[] v1 = {new Integer( 1 )};
!          if( includeFirstLast ) {
!             msg += "[<a href=\"" + form.format( v1 ) + "\">" +
!                prop.getProperty( "paging.banner.first_label" ) + "</a>/<a href=\"" +
!                form.format( objs ) + "\">" +
!                prop.getProperty( "paging.banner.prev_label" ) + "</a>] ";
!          } else {
!             msg += "[<a href=\"" + form.format( objs ) + "\">" +
!                prop.getProperty( "paging.banner.prev_label" ) + "</a>] ";
!          }
!       }
  
!       for( int i = startPage; i <= endPage; i++ ) {
!          if( i == currentPage ) {
!             msg += "<b>" + i + "</b>";
!          } else {
!             Object[] v = {new Integer( i )};
  
!             msg += "<a href=\"" + form.format( v ) + "\">" + i + "</a>";
!          }
  
!          if( i != endPage ) {
!             msg += ", ";
!          } else {
!             msg += " ";
!          }
!       }
  
!       if( currentPage == pageCount ) {
!       if( includeFirstLast ) {
!             msg += "[" + prop.getProperty( "paging.banner.next_label" ) +
!                "/" + prop.getProperty( "paging.banner.last_label" ) + "] ";
!          } else {
!             msg += "[" + prop.getProperty( "paging.banner.next_label" ) + "] ";
!          }
!       } else {
!          Object[] objs = {new Integer( currentPage + 1 )};
!          Object[] v1 = {new Integer( pageCount )};
!          if( includeFirstLast ) {
!             msg += "[<a href=\"" + form.format( objs ) + "\">" +
!                prop.getProperty( "paging.banner.next_label" ) + "</a>/<a href=\"" +
!                form.format( v1 ) + "\">" +
!                prop.getProperty( "paging.banner.last_label" ) + "</a>] ";
!          } else {
!             msg += "[<a href=\"" + form.format( objs ) + "\">" +
!                prop.getProperty( "paging.banner.next_label" ) + "</a>] ";
!          }
!       }
  
!       return msg;
!    }
! }
--- 15,298 ----
   * display.
   *
!  * <p>This class is a stripped down version of the WebListHelper that we got
!  * from Tim Dawson ([EMAIL PROTECTED])</p>
!  *
!  * @version $Revision$
   */
+ class SmartListHelper extends Object {
+     private List masterList;
+     private int pageSize;
+     private int pageCount;
+     private int currentPage;
  
!     private Properties prop = null;
  
+     /**
+      * Creates a SmarListHelper instance that will help you chop up a list
+      * into bite size pieces that are suitable for display.
+      */
+     protected SmartListHelper(List list, int pageSize, Properties prop) {
+         super();
  
!         if (list == null || pageSize < 1) {
!             throw new IllegalArgumentException("Bad arguments passed into " +
!                                                "SmartListHelper() constructor");
!         }
  
!         this.prop = prop;
!         this.pageSize = pageSize;
!         this.masterList = list;
!         this.pageCount = this.computedPageCount();
!         this.currentPage = 1;
!     }
  
+     /**
+      * Returns the computed number of pages it would take to show all the
+      * elements in the list given the pageSize we are working with.
+      */
+     protected int computedPageCount() {
+         int result = 0;
  
!         if ((this.masterList != null) && (this.pageSize > 0)) {
!             int size = this.masterList.size();
!             int div = size / this.pageSize;
!             int mod = size % this.pageSize;
!             result = (mod == 0) ? div : div + 1;
!         }
  
!         return result;
!     }
  
!     /**
!      * Returns the index into the master list of the first object that
!      * should appear on the current page that the user is viewing.
!      */
!     protected int getFirstIndexForCurrentPage() {
!         return this.getFirstIndexForPage(this.currentPage);
!     }
  
!     /**
!      * Returns the index into the master list of the last object that should
!      * appear on the current page that the user is viewing.
!      */
!     protected int getLastIndexForCurrentPage() {
!         return this.getLastIndexForPage(this.currentPage);
!     }
  
!     /**
!      * Returns the index into the master list of the first object that
!      * should appear on the given page.
!      */
!     protected int getFirstIndexForPage(int page) {
!         return ((page - 1) * this.pageSize);
!     }
  
+     /**
+      * Returns the index into the master list of the last object that should
+      * appear on the given page.
+      */
+     protected int getLastIndexForPage(int page) {
+         int firstIndex = this.getFirstIndexForPage(page);
+         int pageIndex = this.pageSize - 1;
+         int lastIndex = this.masterList.size() - 1;
  
!         return Math.min(firstIndex + pageIndex, lastIndex);
!     }
  
!     /**
!      * Returns a subsection of the list that contains just the elements that
!      * are supposed to be shown on the current page the user is viewing.
!      */
!     protected List getListForCurrentPage() {
!         return this.getListForPage(this.currentPage);
!     }
  
!     /**
!      * Returns a subsection of the list that contains just the elements that
!      * are supposed to be shown on the given page.
!      */
!     protected List getListForPage(int page) {
!         List list = new ArrayList(this.pageSize + 1);
  
+         int firstIndex = this.getFirstIndexForPage(page);
+         int lastIndex = this.getLastIndexForPage(page);
  
!         for (int i = firstIndex; i <= lastIndex; i++) {
!             list.add(this.masterList.get(i));
!         }
  
!         return list;
!     }
  
!     /**
!      * Set's the page number that the user is viewing.
!      *
!      * @throws IllegalArgumentException if the page provided is invalid.
!      */
!     protected void setCurrentPage(int page) {
!         if (page < 1 || page > this.pageCount) {
!             Object[] objs = {new Integer(page), new Integer(pageCount)};
!             throw new IllegalArgumentException(
!                     MessageFormat.format(prop.getProperty("error.msg.invalid_page"), 
objs));
!         }
  
!         this.currentPage = page;
!     }
  
!     /**
!      * Return the little summary message that lets the user know how many
!      * objects are in the list they are viewing, and where in the list they
!      * are currently positioned.  The message looks like:
!      *
!      * <p>nnn item(s) found, displaying nnn to nnn.</p>
!      *
!      * <p><code>item(s)</code> is replaced by either itemName or itemNames depending 
on if
!      * it should be signular or plurel.</p>
!      */
!     protected String getSearchResultsSummary() {
!         if (this.masterList.size() == 0) {
!             Object[] objs = {prop.getProperty("paging.banner.items_name")};
!             return MessageFormat.format(
!                     prop.getProperty("paging.banner.no_items_found"), objs);
!         }
!         else if (this.masterList.size() == 1) {
!             Object[] objs = {prop.getProperty("paging.banner.item_name")};
!             return MessageFormat.format(
!                     prop.getProperty("paging.banner.one_item_found"), objs);
!         }
!         else if (this.getFirstIndexForCurrentPage() == 
this.getLastIndexForCurrentPage()) {
!             Object[] objs = {new Integer(this.masterList.size()),
!                              prop.getProperty("paging.banner.items_name"),
!                              prop.getProperty("paging.banner.items_name")};
  
+             return MessageFormat.format(
+                     prop.getProperty("paging.banner.all_items_found"), objs);
+         }
+         else {
+             Object[] objs = {new Integer(this.masterList.size()),
+                              prop.getProperty("paging.banner.items_name"),
+                              new Integer(this.getFirstIndexForCurrentPage() + 1),
+                              new Integer(this.getLastIndexForCurrentPage() + 1)};
  
!             return MessageFormat.format(
!                     prop.getProperty("paging.banner.some_items_found"), objs);
!         }
!     }
  
!     /**
!      * Returns a string containing the nagivation bar that allows the user
!      * to move between pages within the list.
!      *
!      * <p>The urlFormatString should be a URL that looks like the following:</p>
!      *
!      * <p>http://.../somepage.page?page={0}</p>
!      */
!     protected String getPageNavigationBar(String urlFormatString) {
!         MessageFormat form = new MessageFormat(urlFormatString);
  
!         int maxPages = 8;
  
!         try {
!             maxPages = 
Integer.parseInt(prop.getProperty("paging.banner.group_size"));
!         }
!         catch (NumberFormatException e) {
!             // Don't care, we will just default to 8.
!         }
  
!         int currentPage = this.currentPage;
!         int pageCount = this.pageCount;
!         int startPage = 1;
!         int endPage = maxPages;
  
!         if (pageCount == 1 || pageCount == 0) {
!             return "<b>1</b>";
!         }
  
!         if (currentPage < maxPages) {
!             startPage = 1;
!             endPage = maxPages;
!             if (pageCount < endPage) {
!                 endPage = pageCount;
!             }
!         }
!         else {
!             startPage = currentPage;
!             while (startPage + maxPages > (pageCount + 1)) {
!                 startPage--;
!             }
  
!             endPage = startPage + (maxPages - 1);
!         }
  
!         boolean includeFirstLast = 
prop.getProperty("paging.banner.include_first_last").equals("true");
  
!         String msg = "";
!         if (currentPage == 1) {
!             if (includeFirstLast) {
!                 msg += "[" + prop.getProperty("paging.banner.first_label") +
!                         "/" + prop.getProperty("paging.banner.prev_label") + "] ";
!             }
!             else {
!                 msg += "[" + prop.getProperty("paging.banner.prev_label") + "] ";
!             }
!         }
!         else {
!             Object[] objs = {new Integer(currentPage - 1)};
!             Object[] v1 = {new Integer(1)};
!             if (includeFirstLast) {
!                 msg += "[<a href=\"" + form.format(v1) + "\">" +
!                         prop.getProperty("paging.banner.first_label") + "</a>/<a 
href=\"" +
!                         form.format(objs) + "\">" +
!                         prop.getProperty("paging.banner.prev_label") + "</a>] ";
!             }
!             else {
!                 msg += "[<a href=\"" + form.format(objs) + "\">" +
!                         prop.getProperty("paging.banner.prev_label") + "</a>] ";
!             }
!         }
  
!         for (int i = startPage; i <= endPage; i++) {
!             if (i == currentPage) {
!                 msg += "<b>" + i + "</b>";
!             }
!             else {
!                 Object[] v = {new Integer(i)};
  
!                 msg += "<a href=\"" + form.format(v) + "\">" + i + "</a>";
!             }
  
!             if (i != endPage) {
!                 msg += ", ";
!             }
!             else {
!                 msg += " ";
!             }
!         }
  
!         if (currentPage == pageCount) {
!             if (includeFirstLast) {
!                 msg += "[" + prop.getProperty("paging.banner.next_label") +
!                         "/" + prop.getProperty("paging.banner.last_label") + "] ";
!             }
!             else {
!                 msg += "[" + prop.getProperty("paging.banner.next_label") + "] ";
!             }
!         }
!         else {
!             Object[] objs = {new Integer(currentPage + 1)};
!             Object[] v1 = {new Integer(pageCount)};
!             if (includeFirstLast) {
!                 msg += "[<a href=\"" + form.format(objs) + "\">" +
!                         prop.getProperty("paging.banner.next_label") + "</a>/<a 
href=\"" +
!                         form.format(v1) + "\">" +
!                         prop.getProperty("paging.banner.last_label") + "</a>] ";
!             }
!             else {
!                 msg += "[<a href=\"" + form.format(objs) + "\">" +
!                         prop.getProperty("paging.banner.next_label") + "</a>] ";
!             }
!         }
  
!         return msg;
!     }
! }
\ No newline at end of file

Index: StringUtil.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/StringUtil.java,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** StringUtil.java     4 Feb 2003 01:35:36 -0000       1.1.1.1
--- StringUtil.java     12 Jun 2003 17:22:16 -0000      1.2
***************
*** 13,59 ****
  
  /**
!  * One line description of what this class does.
   *
!  * More detailed class description, including examples of usage if applicable.
!  **/
! 
! public class StringUtil extends Object
! {
!    /**
!     * Replace character at given index with the same character to upper case
!     *
!     * @param       oldString old string
!     * @param       index of replacement
!     * @return      String new string
!     * @exception   StringIndexOutOfBoundsException &nbsp;
!     *
!     **/
!    public static String toUpperCaseAt( String oldString, int index )
!       throws NullPointerException, StringIndexOutOfBoundsException
!    {
!       int length = oldString.length();
!       String newString = "";
! 
!       if( index >= length || index < 0 ) {
!          throw new StringIndexOutOfBoundsException(
!             "Index " + index
!             + " is out of bounds for string length " + length );
!       }
  
!       //get upper case replacement
!       String upper = String.valueOf( oldString.charAt( index ) ).toUpperCase();
  
!       //avoid index out of bounds
!       String paddedString = oldString + " ";
  
!       //get reusable parts
!       String beforeIndex = paddedString.substring( 0, index );
!       String afterIndex = paddedString.substring( index + 1 );
  
!       //generate new String - remove padding spaces
!       newString = ( beforeIndex + upper + afterIndex ).substring( 0, length );
  
!       return newString;
!    }
  
! }
--- 13,52 ----
  
  /**
!  * Document me!
   *
!  * @version $Revision$
!  */
! public class StringUtil extends Object {
!     /**
!      * Replace character at given index with the same character to upper case.
!      *
!      * @param       oldString old string
!      * @param       index of replacement
!      * @return      String new string
!      * @exception   StringIndexOutOfBoundsException &nbsp;
!      */
!     public static String toUpperCaseAt(String oldString, int index) {
!         int length = oldString.length();
!         String newString = "";
  
!         if (index >= length || index < 0) {
!             throw new StringIndexOutOfBoundsException(
!                     "Index " + index + " is out of bounds for string length " + 
length);
!         }
  
!         // get upper case replacement
!         String upper = String.valueOf(oldString.charAt(index)).toUpperCase();
  
!         // avoid index out of bounds
!         String paddedString = oldString + " ";
  
!         // get reusable parts
!         String beforeIndex = paddedString.substring(0, index);
!         String afterIndex = paddedString.substring(index + 1);
  
!         //generate new String - remove padding spaces
!         newString = (beforeIndex + upper + afterIndex).substring(0, length);
  
!         return newString;
!     }
! }
\ No newline at end of file

Index: TableDecorator.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/TableDecorator.java,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -C2 -d -r1.1.1.1 -r1.2
*** TableDecorator.java 4 Feb 2003 01:35:36 -0000       1.1.1.1
--- TableDecorator.java 12 Jun 2003 17:22:16 -0000      1.2
***************
*** 1,18 ****
! /**
   * $Id$
   *
-  * Status: Ok
-  *
   * Todo:
   *   - setup the correct deprecation rules, so that people know to extend
   *     this class, rather then the Decorator class.
!  **/
  
  package org.apache.taglibs.display;
  
! public class TableDecorator extends Decorator
! {
!    public TableDecorator() {
!       super();
!    }
  }
--- 1,15 ----
! /*
   * $Id$
   *
   * Todo:
   *   - setup the correct deprecation rules, so that people know to extend
   *     this class, rather then the Decorator class.
!  */
  
  package org.apache.taglibs.display;
  
! public class TableDecorator extends Decorator {
!     public TableDecorator() {
!         super();
!     }
  }

Index: TableTag.java
===================================================================
RCS file: /cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/TableTag.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** TableTag.java       12 Jun 2003 16:35:54 -0000      1.7
--- TableTag.java       12 Jun 2003 17:22:16 -0000      1.8
***************
*** 37,48 ****
  import org.apache.commons.beanutils.PropertyUtils;
  
- /* This would allow certain kinds of stuctures to be used (rather than
-  * java.util.Collections), but I did not want to introduce a dependency
-  * on struts for compilation...
-  *
-  * import org.apache.struts.util.*;
-  *
-  */
- 
[...4000 lines suppressed...]
+         prop.setProperty("paging.banner.all_items_found", "{0} {1} found, showing 
all {2}");
+         prop.setProperty("paging.banner.some_items_found", "{0} {1} found, 
displaying {2} to {3}");
+         prop.setProperty("paging.banner.include_first_last", "false");
+         prop.setProperty("paging.banner.first_label", "First");
+         prop.setProperty("paging.banner.last_label", "Last");
+         prop.setProperty("paging.banner.prev_label", "Prev");
+         prop.setProperty("paging.banner.next_label", "Next");
+         prop.setProperty("paging.banner.group_size", "8");
  
!         prop.setProperty("error.msg.cant_find_bean", "Could not find bean {0} in 
scope {1}");
!         prop.setProperty("error.msg.invalid_bean", "The bean that you gave me is not 
a Collection I understand: {0}");
!         prop.setProperty("error.msg.no_column_tags", "Please provide column tags.");
!         prop.setProperty("error.msg.illegal_access_exception", 
"IllegalAccessException trying to fetch property {0} on bean {1}");
!         prop.setProperty("error.msg.invocation_target_exception", 
"InvocationTargetException trying to fetch property {0} on bean {1}");
!         prop.setProperty("error.msg.nosuchmethod_exception", "NoSuchMethodException 
trying to fetch property {0} on bean {1}");
!         prop.setProperty("error.msg.invalid_decorator", "Decorator class is not a 
subclass of TableDecorator");
!         prop.setProperty("error.msg.invalid_page", "Invalid page ({0}) provided, 
value should be between 1 and {1}");
!     }
  }
  

Index: TableTagExtraInfo.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/TableTagExtraInfo.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** TableTagExtraInfo.java      23 Mar 2003 20:54:47 -0000      1.2
--- TableTagExtraInfo.java      12 Jun 2003 17:22:16 -0000      1.3
***************
*** 1,12 ****
! /**
   * $Id$
   *
-  * Status: Under Development
-  *
   * Todo
   *   - impementation
   *   - documentation (javadoc, examples, etc...)
   *   - junit test cases
!  **/
  
  package org.apache.taglibs.display;
--- 1,10 ----
! /*
   * $Id$
   *
   * Todo
   *   - impementation
   *   - documentation (javadoc, examples, etc...)
   *   - junit test cases
!  */
  
  package org.apache.taglibs.display;
***************
*** 17,40 ****
  
  /**
!  * One line description of what this class does.
   *
!  * More detailed class description, including examples of usage if applicable.
!  **/
! 
! public class TableTagExtraInfo extends TagExtraInfo
! {
!    public VariableInfo[] getVariableInfo( TagData data ) {
!       return new VariableInfo[] {
!          new VariableInfo( "table_index",
!                            "java.lang.Integer",
!                            true,
!                            VariableInfo.NESTED ),
  
!          new VariableInfo( "table_item",
!                            "java.lang.Object",
!                            true,
!                            VariableInfo.NESTED ),
  
!       };
!    }
  }
--- 15,36 ----
  
  /**
!  * Document me!
   *
!  * @version $Revision$
!  */
! public class TableTagExtraInfo extends TagExtraInfo {
!     public VariableInfo[] getVariableInfo(TagData data) {
!         return new VariableInfo[]{
!             new VariableInfo("table_index",
!                              "java.lang.Integer",
!                              true,
!                              VariableInfo.NESTED),
  
!             new VariableInfo("table_item",
!                              "java.lang.Object",
!                              true,
!                              VariableInfo.NESTED),
  
!         };
!     }
  }

Index: TemplateTag.java
===================================================================
RCS file: 
/cvsroot/displaytag/displaytag/src/org/apache/taglibs/display/TemplateTag.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** TemplateTag.java    5 Feb 2003 04:04:10 -0000       1.3
--- TemplateTag.java    12 Jun 2003 17:22:16 -0000      1.4
***************
*** 1,2 ****
--- 1,9 ----
+ package org.apache.taglibs.display;
+ 
+ import javax.servlet.jsp.JspTagException;
+ import javax.servlet.jsp.tagext.BodyTagSupport;
+ import java.io.IOException;
+ import java.io.Writer;
+ 
  /**
   * This is an abstract class that most tags should inherit from, it provides a
***************
*** 4,38 ****
   * template files from the web/templates directory, and use those templates as
   * flexible StringBuffers that reread themselves when their matching file
!  * changes, etc...
   *
!  * $Id$
!  **/
! 
! package org.apache.taglibs.display;
! 
! import java.io.IOException;
! 
! import javax.servlet.jsp.JspTagException;
! import javax.servlet.jsp.JspWriter;
! import javax.servlet.jsp.tagext.BodyTagSupport;
! 
! abstract public class TemplateTag extends BodyTagSupport
! {
! 
!    public void write( String val ) throws JspTagException
!    {
!       try {
!          JspWriter out = pageContext.getOut();
!          out.write( val );
!       } catch( IOException e ) {
!          throw new JspTagException( "Writer Exception: " + e );
!       }
!    }
! 
!    public void write( StringBuffer val ) throws JspTagException
!    {
!       this.write( val.toString() );
!    }
  
  }
  
--- 11,32 ----
   * template files from the web/templates directory, and use those templates as
   * flexible StringBuffers that reread themselves when their matching file
!  * changes, etc.
   *
!  * @version $Revision$
!  */
! abstract public class TemplateTag extends BodyTagSupport {
!     public void write(String value) throws JspTagException {
!         try {
!             Writer out = pageContext.getOut();
!             out.write(value);
!         }
!         catch (IOException e) {
!             throw new JspTagException("IOException writing to out: " + 
e.getMessage());
!         }
!     }
  
+     public void write(StringBuffer val) throws JspTagException {
+         this.write(val.toString());
+     }
  }
  




-------------------------------------------------------
This SF.NET email is sponsored by: eBay
Great deals on office technology -- on eBay now! Click here:
http://adfarm.mediaplex.com/ad/ck/711-11697-6916-5
_______________________________________________
displaytag-devel mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/displaytag-devel

Reply via email to