View Javadoc

1   /*
2    * Copyright (c) 1998, 2005 Gargoyle Software Inc. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, are permitted provided that the following conditions are met:
6    *
7    * 1. Redistributions of source code must retain the above copyright notice,
8    *    this list of conditions and the following disclaimer.
9    * 2. Redistributions in binary form must reproduce the above copyright notice,
10   *    this list of conditions and the following disclaimer in the documentation
11   *    and/or other materials provided with the distribution.
12   * 3. The end-user documentation included with the redistribution, if any, must
13   *    include the following acknowledgment:
14   *
15   *       "This product includes software developed by Gargoyle Software Inc.
16   *        (http://www.GargoyleSoftware.com/)."
17   *
18   *    Alternately, this acknowledgment may appear in the software itself, if
19   *    and wherever such third-party acknowledgments normally appear.
20   * 4. The name "Gargoyle Software" must not be used to endorse or promote
21   *    products derived from this software without prior written permission.
22   *    For written permission, please contact info@GargoyleSoftware.com.
23   * 5. Products derived from this software may not be called "GSBase", nor may
24   *    "GSBase" appear in their name, without prior written permission of
25   *    Gargoyle Software Inc.
26   *
27   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
28   * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
29   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GARGOYLE
30   * SOFTWARE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
33   * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34   * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35   * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
36   * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37   */
38  package com.gargoylesoftware.base.collections;
39  
40  import java.text.Collator;
41  import java.util.Comparator;
42  import java.util.Locale;
43  
44  /***
45   * A concrete implementation of Comparator that compares two strings.  If a locale
46   * is specified then the comparison will be performed using the locale specific
47   * collating sequences.  If the locale is not specified then a binary comparison
48   * will be performed.
49   *
50   * @version $Revision: 1.4 $
51   * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a>
52   */
53  public class StringComparator
54  implements
55  Comparator {
56  
57      private final Locale locale_;
58      private final Collator collator_;
59      private final boolean isAscending_;
60  
61      /***
62       * Create a locale specific comparator.
63       *
64       * @param locale The locale to be used when determining sorting order.
65       *        If locale is null then a binary comparison is performed.
66       * @param collatorStrength The strength value to be used by the
67       *        Collator.  If locale is null then this value is ignored.
68       * @param isAscending True if we are sorting in ascending order, false
69       *        otherwise.
70       */
71      public StringComparator(
72                             final Locale locale,
73                             final int collatorStrength,
74                             final boolean isAscending ) {
75  
76          locale_ = locale;
77          if( locale_ == null ) {
78              collator_ = null;
79          }
80          else {
81              collator_ = Collator.getInstance(locale_);
82              collator_.setStrength( collatorStrength );
83          }
84          isAscending_ = isAscending;
85      }
86  
87      /***
88       * Create a locale specific comparator.
89       *
90       * @param locale The locale to be used when determining sorting order.
91       *        If locale is null then a binary comparison is performed.
92       */
93      public StringComparator( final Locale locale ) {
94          this( locale, Collator.PRIMARY, true );
95      }
96  
97      /***
98       * Compare the two strings.
99       * @param object1 The first string.
100      * @param object2 The second string.
101      * @return a negative integer, zero, or a positive integer as the first
102      * argument is less than, equal to, or greater than the second.
103      */
104     public int compare( final Object object1, final Object object2 ) {
105         int rc;
106 
107         final String string1 = object1.toString();
108         final String string2 = object2.toString();
109 
110         if( locale_ == null ) {
111             // Perform a binary compare.  Individual characters are sorted
112             //by their unicode values.
113             rc = string1.compareTo(string2);
114         }
115         else {
116             // Perform a locale specific compare.
117             rc = collator_.compare( string1, string2 );
118         }
119 
120         // If we're sorting in descending order then flip the result now.
121         if( isAscending_ == false ) {
122             rc *= -1;
123         }
124 
125         return rc;
126     }
127 }
128