ColumnSortList can grow indefintely, but some users would like to have only a
limited number of entries within it (usually just one). In such cases it will
reduce the need to call clear() before push(...), reducing the number of header
refresh calls. Adding a new limit field and maintaining the list size according
the limit solves this issue with little overhead.

Review at http://gwt-code-reviews.appspot.com/1625803

Review by: jlabanca@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@10826 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/cellview/client/ColumnSortList.java b/user/src/com/google/gwt/user/cellview/client/ColumnSortList.java
index 591eddd..ad66230 100644
--- a/user/src/com/google/gwt/user/cellview/client/ColumnSortList.java
+++ b/user/src/com/google/gwt/user/cellview/client/ColumnSortList.java
@@ -121,6 +121,12 @@
   private final List<ColumnSortInfo> infos = new ArrayList<ColumnSortInfo>();
 
   /**
+   * This limit prevents the infos list to grow over a given size. The default value (0) means
+   * that the size can grow indefinitely.
+   */
+  private int limit = 0;
+
+  /**
    * Construct a new {@link ColumnSortList} without a {@link Delegate}.
    */
   public ColumnSortList() {
@@ -172,6 +178,15 @@
     return infos.get(index);
   }
 
+  /**
+   * Get the actual limit value
+   * 
+   * @return the actual limit value
+   */
+  public int getLimit() {
+    return limit;
+  }
+
   @Override
   public int hashCode() {
     return 31 * infos.hashCode() + 13;
@@ -201,6 +216,17 @@
         i--;
       }
     }
+    
+    if (limit > 0) {
+      // at this point, infos.size() must not exceed the limit, a simple condition check is enough
+      if (limit == infos.size()) {
+        infos.remove(infos.size() - 1);
+      }
+      // by the contract of the limit, inserting after the limit must not be allowed
+      if (index >= limit) {
+        throw new IndexOutOfBoundsException("Index: " + index + ", Limit: " + limit);
+      }
+    }
 
     // Insert the new sort info
     infos.add(index, sortInfo);
@@ -253,6 +279,31 @@
   }
 
   /**
+   * Set the limit to a positive value to prevent the growth of the infos list over the given size.
+   * This method will check if the actual infos list is over the limit, and it will fire the
+   * delegate in the case it should remove items from the list.
+   * 
+   * The default value (0) means the size can grow indefinitely. 
+   * 
+   * @param limit the new limit value
+   */
+  public void setLimit(int limit) {
+    this.limit = limit;
+    
+    if (limit > 0) {
+      // checking the list size, as it might have been populated over the limit
+      boolean modified = false;
+      while (limit < infos.size()) {
+        infos.remove(infos.size() - 1);
+        modified = true;
+      }
+      if (modified) {
+        fireDelegate();
+      }
+    }
+  }
+
+  /**
    * Get the size of the list.
    * 
    * @return the number of {@link ColumnSortInfo} in the list