Add setComparator to allow custom sorting of candidates from search.

Fixes issues 4373, 5920

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

Review by: skybrian@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11230 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/MultiWordSuggestOracle.java b/user/src/com/google/gwt/user/client/ui/MultiWordSuggestOracle.java
index a328ac6..e2584c4 100644
--- a/user/src/com/google/gwt/user/client/ui/MultiWordSuggestOracle.java
+++ b/user/src/com/google/gwt/user/client/ui/MultiWordSuggestOracle.java
@@ -22,6 +22,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -153,6 +154,11 @@
 
   private Response defaultResponse;
 
+  /*
+   * Comparator used for sorting candidates from search.
+   */
+  private Comparator<String> comparator = null;
+
   /**
    * Constructor for <code>MultiWordSuggestOracle</code>. This uses a space as
    * the whitespace character.
@@ -266,6 +272,15 @@
   }
 
   /**
+   * Sets the comparator used for sorting candidates from search.
+   *
+   * @param comparator the comparator to use.
+   */
+  public void setComparator(Comparator<String> comparator) {
+    this.comparator = comparator;
+  }
+
+  /**
    * Sets the default suggestion collection.
    *
    * @param suggestionList the default list of suggestions
@@ -398,7 +413,7 @@
     }
     if (candidateSet != null) {
       candidates.addAll(candidateSet);
-      Collections.sort(candidates);
+      Collections.sort(candidates, comparator);
     }
     return candidates;
   }
diff --git a/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java b/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java
index 6492f18..503c96e 100644
--- a/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java
+++ b/user/test/com/google/gwt/user/client/ui/SuggestBoxTest.java
@@ -1,12 +1,12 @@
 /*
  * Copyright 2009 Google Inc.
- * 
+ *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
  * the License at
- * 
+ *
  * http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -26,6 +26,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -66,7 +67,7 @@
 
     /**
      * Get the suggestion at the specified index.
-     * 
+     *
      * @param index the index
      * @return the {@link Suggestion} at the index
      */
@@ -77,7 +78,7 @@
     /**
      * Get the number of suggestions that are currently showing. Used for
      * testing.
-     * 
+     *
      * @return the number of suggestions currently showing, 0 if there are none
      */
     public int getSuggestionCount() {
@@ -172,7 +173,7 @@
     box.showSuggestionList();
     assertTrue(display.isSuggestionListShowing());
     assertEquals(3, display.getSuggestionCount());
-    assertEquals("<strong>Hark</strong>, Shark and <strong>Herald</strong>", 
+    assertEquals("<strong>Hark</strong>, Shark and <strong>Herald</strong>",
         display.getSuggestion(0).getDisplayString());
     assertEquals("<strong>Hark</strong>! The <strong>Herald</strong> Angels Sing",
         display.getSuggestion(1).getDisplayString());
@@ -180,6 +181,29 @@
         display.getSuggestion(2).getDisplayString());
   }
 
+  public void testMatchCustomSort() {
+    MultiWordSuggestOracle oracle = new MultiWordSuggestOracle(",! ");
+    oracle.add("Hark, Shark and Herald");
+    oracle.add("Hark! The Herald Angels Sing");
+    oracle.add("Heraldings and Harkings");
+    oracle.add("Send my regards to Herald");
+    oracle.setComparator(Collections.<String>reverseOrder());
+
+    TestSuggestionDisplay display = new TestSuggestionDisplay();
+    SuggestBox box = new SuggestBox(oracle, new TextBox(), display);
+    RootPanel.get().add(box);
+    box.setText("Herald! Hark");
+    box.showSuggestionList();
+    assertTrue(display.isSuggestionListShowing());
+    assertEquals(3, display.getSuggestionCount());
+    assertEquals("<strong>Herald</strong>ings and <strong>Hark</strong>ings",
+        display.getSuggestion(0).getDisplayString());
+    assertEquals("<strong>Hark</strong>! The <strong>Herald</strong> Angels Sing",
+        display.getSuggestion(1).getDisplayString());
+    assertEquals("<strong>Hark</strong>, Shark and <strong>Herald</strong>",
+        display.getSuggestion(2).getDisplayString());
+  }
+
   @SuppressWarnings("deprecation")
   public void testShowAndHide() {
     SuggestBox box = createSuggestBox();
@@ -275,7 +299,7 @@
     assertEquals("A", display.getSuggestion(0).getReplacementString());
     assertEquals("B", display.getSuggestion(1).getReplacementString());
   }
-  
+
   public void testSuggestionSelection() {
     MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
     oracle.setDefaultSuggestionsFromText(Arrays.asList("A", "B"));
@@ -289,7 +313,7 @@
     assertNull(display.getCurrentSelection());
     display.moveSelectionDown();
     assertEquals("A", display.getCurrentSelection().getReplacementString());
-    
+
     // Once something is selected, selections are made as expected, but we do
     // not move outside the box
     display.moveSelectionDown();
@@ -300,12 +324,12 @@
     assertEquals("A", display.getCurrentSelection().getReplacementString());
     display.moveSelectionUp();
     assertEquals("A", display.getCurrentSelection().getReplacementString());
-    
+
     // Reset the suggestions so that nothing is selected again
     display.hideSuggestions();
     box.showSuggestionList();
     assertNull(display.getCurrentSelection());
-    
+
     // If nothing is selected, moving up will select the last item
     display.moveSelectionUp();
     assertEquals("B", display.getCurrentSelection().getReplacementString());