home *** CD-ROM | disk | FTP | other *** search
/ Java 1.2 How-To / JavaHowTo.iso / 3rdParty / jbuilder / unsupported / JDK1.2beta3 / SOURCE / SRC.ZIP / java / text / Collator.java < prev    next >
Encoding:
Java Source  |  1998-03-20  |  19.1 KB  |  483 lines

  1. /*
  2.  * @(#)Collator.java    1.14 98/03/18
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1997, 1998 Sun Microsystems, Inc. All Rights Reserved.
  8.  *
  9.  *   The original version of this source code and documentation is copyrighted
  10.  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  11.  * materials are provided under terms of a License Agreement between Taligent
  12.  * and Sun. This technology is protected by multiple US and International
  13.  * patents. This notice and attribution to Taligent may not be removed.
  14.  *   Taligent is a registered trademark of Taligent, Inc.
  15.  *
  16.  * Permission to use, copy, modify, and distribute this software
  17.  * and its documentation for NON-COMMERCIAL purposes and without
  18.  * fee is hereby granted provided that this copyright notice
  19.  * appears in all copies. Please refer to the file "copyright.html"
  20.  * for further important copyright and licensing information.
  21.  *
  22.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  23.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  24.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  25.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  26.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  27.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  28.  *
  29.  */
  30.  
  31. package java.text;
  32.  
  33. import java.io.Serializable;
  34. import java.util.Locale;
  35. import java.util.MissingResourceException;
  36. import java.util.ResourceBundle;
  37. import java.text.resources.*;
  38. import java.util.Hashtable;
  39.  
  40.  
  41. /**
  42.  * The <code>Collator</code> class performs locale-sensitive
  43.  * <code>String</code> comparison. You use this class to build
  44.  * searching and sorting routines for natural language text.
  45.  *
  46.  * <p>
  47.  * <code>Collator</code> is an abstract base class. Subclasses
  48.  * implement specific collation strategies. One subclass,
  49.  * <code>RuleBasedCollator</code>, is currently provided with
  50.  * the JDK and is applicable to a wide set of languages. Other
  51.  * subclasses may be created to handle more specialized needs.
  52.  *
  53.  * <p>
  54.  * Like other locale-sensitive classes, you can use the static
  55.  * factory method, <code>getInstance</code>, to obtain the appropriate
  56.  * <code>Collator</code> object for a given locale. You will only need
  57.  * to look at the subclasses of <code>Collator</code> if you need
  58.  * to understand the details of a particular collation strategy or
  59.  * if you need to modify that strategy.
  60.  *
  61.  * <p>
  62.  * The following example shows how to compare two strings using
  63.  * the <code>Collator</code> for the default locale.
  64.  * <blockquote>
  65.  * <pre>
  66.  * // Compare two strings in the default locale
  67.  * Collator myCollator = Collator.getInstance();
  68.  * if( myCollator.compare("abc", "ABC") < 0 )
  69.  *     System.out.println("abc is less than ABC");
  70.  * else
  71.  *     System.out.println("abc is greater than or equal to ABC");
  72.  * </pre>
  73.  * </blockquote>
  74.  *
  75.  * <p>
  76.  * You can set a <code>Collator</code>'s <em>strength</em> property
  77.  * to determine the level of difference considered significant in
  78.  * comparisons. Four strengths are provided: <code>PRIMARY</code>,
  79.  * <code>SECONDARY</code>, <code>TERTIARY</code>, and <code>IDENTICAL</code>.
  80.  * The exact assignment of strengths to language features is
  81.  * locale dependant.  For example, in Czech, "e" and "f" are considered
  82.  * primary differences, while "e" and "\u00EA" are secondary differences,
  83.  * "e" and "E" are tertiary differences and "e" and "e" are identical.
  84.  * The following shows how both case and accents could be ignored for
  85.  * US English.
  86.  * <blockquote>
  87.  * <pre>
  88.  * //Get the Collator for US English and set its strength to PRIMARY
  89.  * Collator usCollator = Collator.getInstance(Locale.US);
  90.  * usCollator.setStrength(Collator.PRIMARY);
  91.  * if( usCollator.compare("abc", "ABC") == 0 ) {
  92.  *     System.out.println("Strings are equivalent");
  93.  * }
  94.  * </pre>
  95.  * </blockquote>
  96.  * <p>
  97.  * For comparing <code>String</code>s exactly once, the <code>compare</code>
  98.  * method provides the best performance. When sorting a list of
  99.  * <code>String</code>s however, it is generally necessary to compare each
  100.  * <code>String</code> multiple times. In this case, <code>CollationKey</code>s
  101.  * provide better performance. The <code>CollationKey</code> class converts
  102.  * a <code>String</code> to a series of bits that can be compared bitwise
  103.  * against other <code>CollationKey</code>s. A <code>CollationKey</code> is
  104.  * created by a <code>Collator</code> object for a given <code>String</code>.
  105.  * <br>
  106.  * <strong>Note:</strong> <code>CollationKey</code>s from different
  107.  * <code>Collator</code>s can not be compared. See the class description
  108.  * for <a href="java.test.CollationKey.html"><code>CollationKey</code></a>
  109.  * for an example using <code>CollationKey</code>s.
  110.  *
  111.  * @see         RuleBasedCollator
  112.  * @see         CollationKey
  113.  * @see         CollationElementIterator
  114.  * @see         Locale
  115.  * @version     1.14 03/18/98
  116.  * @author      Helena Shih
  117.  */
  118.  
  119. public abstract class Collator implements java.util.Comparator, Cloneable,
  120.                       Serializable {
  121.     /**
  122.      * Collator strength value.  When set, only PRIMARY differences are
  123.      * considered significant during comparison. The assignment of strengths
  124.      * to language features is locale dependant. A common example is for
  125.      * different base letters ("a" vs "b") to be considered a PRIMARY difference.
  126.      * @see java.text.Collator#setStrength
  127.      * @see java.text.Collator#getStrength
  128.      */
  129.     public final static int PRIMARY = 0;
  130.     /**
  131.      * Collator strength value.  When set, only SECONDARY and above differences are
  132.      * considered significant during comparison. The assignment of strengths
  133.      * to language features is locale dependant. A common example is for
  134.      * different accented forms of the same base letter ("a" vs "\u00E4") to be
  135.      * considered a SECONDARY difference.
  136.      * @see java.text.Collator#setStrength
  137.      * @see java.text.Collator#getStrength
  138.      */
  139.     public final static int SECONDARY = 1;
  140.     /**
  141.      * Collator strength value.  When set, only TERTIARY and above differences are
  142.      * considered significant during comparison. The assignment of strengths
  143.      * to language features is locale dependant. A common example is for
  144.      * case differences ("a" vs "A") to be considered a TERTIARY difference.
  145.      * @see java.text.Collator#setStrength
  146.      * @see java.text.Collator#getStrength
  147.      */
  148.     public final static int TERTIARY = 2;
  149.  
  150.     /**
  151.      * Collator strength value.  When set, all differences are
  152.      * considered significant during comparison. The assignment of strengths
  153.      * to language features is locale dependant. A common example is for control
  154.      * characters ("\u0001" vs "\u0002") to be considered equal at the
  155.      * PRIMARY, SECONDARY, and TERTIARY levels but different at the IDENTICAL
  156.      * level.  Additionally, differences between pre-composed accents such as
  157.      * "\u00C0" (A-grave) and combining accents such as "A\u0300"
  158.      * (A, combining-grave) will be considered significant at the tertiary
  159.      * level if decomposition is set to NO_DECOMPOSITION.
  160.      */
  161.     public final static int IDENTICAL = 3;
  162.  
  163.     /**
  164.      * Decomposition mode value. With NO_DECOMPOSITION
  165.      * set, accented characters will not be decomposed for collation. This
  166.      * provides the fastest collation but will only produce correct results
  167.      * for languages that do not use accents.
  168.      * @see java.text.Collator#getDecomposition
  169.      * @see java.text.Collator#setDecomposition
  170.      */
  171.     public final static int NO_DECOMPOSITION = 0;
  172.  
  173.     /**
  174.      * Decomposition mode value. With CANONICAL_DECOMPOSITION
  175.      * set, characters that are canonical variants according to Unicode 2.0
  176.      * will be decomposed for collation. This is the default setting and
  177.      * should be used to get correct collation of accented characters.
  178.      * @see java.text.Collator#getDecomposition
  179.      * @see java.text.Collator#setDecomposition
  180.      */
  181.     public final static int CANONICAL_DECOMPOSITION = 1;
  182.  
  183.     /**
  184.      * Decomposition mode value. With FULL_DECOMPOSITION
  185.      * set, both Unicode canonical variants and Unicode compatibility variants
  186.      * will be decomposed for collation.  This causes not only accented
  187.      * characters to be collated, but also characters that have special formats
  188.      * to be collated with their norminal form. For example, the half-width and
  189.      * full-width ASCII and Katakana characters are then collated together.
  190.      * FULL_DECOMPOSITION is the most complete and therefore the slowest
  191.      * decomposition mode.
  192.      * @see java.text.Collator#getDecomposition
  193.      * @see java.text.Collator#setDecomposition
  194.      */
  195.     public final static int FULL_DECOMPOSITION = 2;
  196.  
  197.     /**
  198.      * Gets the Collator for the current default locale.
  199.      * The default locale is determined by java.util.Locale.getDefault.
  200.      * @return the Collator for the default locale.(for example, en_US)
  201.      * @see java.util.Locale#getDefault
  202.      */
  203.     public static synchronized Collator getInstance() {
  204.         return getInstance(Locale.getDefault());
  205.     }
  206.  
  207.     /**
  208.      * Gets the Collator for the desired locale.
  209.      * @param desiredLocale the desired locale.
  210.      * @return the Collator for the desired locale.
  211.      * @see java.util.Locale
  212.      * @see java.util.ResourceBundle
  213.      */
  214.     public static synchronized
  215.     Collator getInstance(Locale desiredLocale)
  216.     {
  217.         RuleBasedCollator result = null;
  218.         result = (RuleBasedCollator) cache.get(desiredLocale);
  219.         if (result != null) {
  220.             return (Collator)result.clone();  // make the world safe
  221.         }
  222.  
  223.         // Load the resource of the desired locale from resource
  224.         // manager.
  225.         String colString;
  226.         try {
  227.             ResourceBundle resource = ResourceBundle.getBundle
  228.                                       ("java.text.resources.LocaleElements",
  229.                                        desiredLocale);
  230.  
  231.             colString = resource.getString("CollationElements");
  232.         } catch (MissingResourceException e) {
  233.             // return default US collation
  234.             colString = "";
  235.         }
  236.         try
  237.         {
  238.             result = new RuleBasedCollator( CollationRules.DEFAULTRULES +
  239.                                             colString );
  240.         }
  241.         catch(ParseException foo)
  242.         {
  243.             // predefined tables should contain correct grammar
  244.             try {
  245.                 result = new RuleBasedCollator( CollationRules.DEFAULTRULES );
  246.             } catch (ParseException bar) {
  247.                 // do nothing
  248.             }
  249.         }
  250.         cache.put(desiredLocale,result);
  251.         return (Collator)result.clone();
  252.     }
  253.  
  254.     /**
  255.      * Compares the source string to the target string according to the
  256.      * collation rules for this Collator.  Returns an integer less than,
  257.      * equal to or greater than zero depending on whether the source String is
  258.      * less than, equal to or greater than the target string.  See the Collator
  259.      * class description for an example of use.
  260.      * <p>
  261.      * For a one time comparison, this method has the best performance. If a
  262.      * given String will be involved in multiple comparisons, CollationKey.compareTo
  263.      * has the best performance. See the Collator class description for an example
  264.      * using CollationKeys.
  265.      * @param source the source string.
  266.      * @param target the target string.
  267.      * @return Returns an integer value. Value is less than zero if source is less than
  268.      * target, value is zero if source and target are equal, value is greater than zero
  269.      * if source is greater than target.
  270.      * @see java.text.CollationKey
  271.      * @see java.text.Collator#getCollationKey
  272.      */
  273.     public abstract int compare(String source, String target);
  274.  
  275.     /**
  276.      * Compares its two arguments for order.  Returns a negative integer,
  277.      * zero, or a positive integer as the first argument is less than, equal
  278.      * to, or greater than the second.
  279.      * <p>
  280.      * This implementation merely returns
  281.      *     <code> compare((String)o1, (String)o2) </code>.
  282.      * 
  283.      * @return a negative integer, zero, or a positive integer as the
  284.      *            first argument is less than, equal to, or greater than the
  285.      *           second. 
  286.      * @exception ClassCastException the arguments cannot be cast to Strings.
  287.      * @see    Comparator
  288.      * @since   JDK1.2
  289.      */
  290.     public int compare(Object o1, Object o2) {
  291.     return compare((String)o1, (String)o2);
  292.     }
  293.  
  294.     /**
  295.      * Transforms the String into a series of bits that can be compared bitwise
  296.      * to other CollationKeys. CollationKeys provide better performance than
  297.      * Collator.compare when Strings are involved in multiple comparisons.
  298.      * See the Collator class description for an example using CollationKeys.
  299.      * @param source the string to be transformed into a collation key.
  300.      * @return the CollationKey for the given String based on this Collator's collation
  301.      * rules. If the source String is null, a null CollationKey is returned.
  302.      * @see java.text.CollationKey
  303.      * @see java.text.Collator#compare
  304.      */
  305.     public abstract CollationKey getCollationKey(String source);
  306.  
  307.     /**
  308.      * Convenience method for comparing the equality of two strings based on
  309.      * this Collator's collation rules.
  310.      * @param source the source string to be compared with.
  311.      * @param target the target string to be compared with.
  312.      * @return true if the strings are equal according to the collation
  313.      * rules.  false, otherwise.
  314.      * @see java.text.Collator#compare
  315.      */
  316.     public boolean equals(String source, String target)
  317.     {
  318.         return (compare(source, target) == Collator.EQUAL);
  319.     }
  320.  
  321.     /**
  322.      * Returns this Collator's strength property.  The strength property determines
  323.      * the minimum level of difference considered significant during comparison.
  324.      * See the Collator class description for an example of use.
  325.      * @return this Collator's current strength property.
  326.      * @see java.text.Collator#setStrength
  327.      * @see java.text.Collator#PRIMARY
  328.      * @see java.text.Collator#SECONDARY
  329.      * @see java.text.Collator#TERTIARY
  330.      * @see java.text.Collator#IDENTICAL
  331.      */
  332.     public synchronized int getStrength()
  333.     {
  334.         return strength;
  335.     }
  336.  
  337.     /**
  338.      * Sets this Collator's strength property.  The strength property determines
  339.      * the minimum level of difference considered significant during comparison.
  340.      * See the Collator class description for an example of use.
  341.      * @param the new strength value.
  342.      * @see java.text.Collator#getStrength
  343.      * @see java.text.Collator#PRIMARY
  344.      * @see java.text.Collator#SECONDARY
  345.      * @see java.text.Collator#TERTIARY
  346.      * @see java.text.Collator#IDENTICAL
  347.      * @exception  IllegalArgumentException If the new strength value is not one of
  348.      * PRIMARY, SECONDARY, TERTIARY or IDENTICAL.
  349.      */
  350.     public synchronized void setStrength(int newStrength) {
  351.         if ((newStrength != PRIMARY) &&
  352.             (newStrength != SECONDARY) &&
  353.             (newStrength != TERTIARY) &&
  354.             (newStrength != IDENTICAL))
  355.             throw new IllegalArgumentException("Incorrect comparison level.");
  356.         strength = newStrength;
  357.     }
  358.  
  359.     /**
  360.      * Get the decomposition mode of this Collator. Decomposition mode
  361.      * determines how Unicode composed characters are handled. Adjusting
  362.      * decomposition mode allows the user to select between faster and more
  363.      * complete collation behavior.
  364.      * <p>The three values for decomposition mode are:
  365.      * <UL>
  366.      * <LI>NO_DECOMPOSITION,
  367.      * <LI>CANONICAL_DECOMPOSITION
  368.      * <LI>FULL_DECOMPOSITION.
  369.      * </UL>
  370.      * See the documentation for these three constants for a description
  371.      * of their meaning.
  372.      * @return the decomposition mode
  373.      * @see java.text.Collator#setDecomposition
  374.      * @see java.text.Collator#NO_DECOMPOSITION
  375.      * @see java.text.Collator#CANONICAL_DECOMPOSITION
  376.      * @see java.text.Collator#FULL_DECOMPOSITION
  377.      */
  378.     public synchronized int getDecomposition()
  379.     {
  380.         return decmp;
  381.     }
  382.     /**
  383.      * Set the decomposition mode of this Collator. See getDecomposition
  384.      * for a description of decomposition mode.
  385.      * @param the new decomposition mode
  386.      * @see java.text.Collator#getDecomposition
  387.      * @see java.text.Collator#NO_DECOMPOSITION
  388.      * @see java.text.Collator#CANONICAL_DECOMPOSITION
  389.      * @see java.text.Collator#FULL_DECOMPOSITION
  390.      * @exception IllegalArgumentException If the given value is not a valid decomposition
  391.      * mode.
  392.      */
  393.     public synchronized void setDecomposition(int decompositionMode) {
  394.         if ((decompositionMode != NO_DECOMPOSITION) &&
  395.             (decompositionMode != CANONICAL_DECOMPOSITION) &&
  396.             (decompositionMode != FULL_DECOMPOSITION))
  397.             throw new IllegalArgumentException("Wrong decomposition mode.");
  398.         decmp = decompositionMode;
  399.     }
  400.  
  401.     /**
  402.      * Get the set of Locales for which Collators are installed.
  403.      * @return the list of available locales which collators are installed.
  404.      */
  405.     public static synchronized Locale[] getAvailableLocales() {
  406.         return LocaleData.getAvailableLocales("CollationElements");
  407.     }
  408.  
  409.     /**
  410.      * Overrides Cloneable
  411.      */
  412.     public Object clone()
  413.     {
  414.         try {
  415.             return (Collator)super.clone();
  416.         } catch (CloneNotSupportedException e) {
  417.             throw new InternalError();
  418.         }
  419.     }
  420.  
  421.     /**
  422.      * Compares the equality of two Collators.
  423.      * @param that the Collator to be compared with this.
  424.      * @return true if this Collator is the same as that Collator;
  425.      * false otherwise.
  426.      */
  427.     public boolean equals(Object that)
  428.     {
  429.         if (this == that) return true;
  430.         if (that == null) return false;
  431.         if (getClass() != that.getClass()) return false;
  432.         Collator other = (Collator) that;
  433.         return ((strength == other.strength) &&
  434.                 (decmp == other.decmp));
  435.     }
  436.  
  437.     /**
  438.      * Generates the hash code for this Collator.
  439.      */
  440.     abstract public int hashCode();
  441.  
  442.     /**
  443.      * Default constructor.  This constructor is
  444.      * protected so subclasses can get access to it. Users typically create
  445.      * a Collator sub-class by calling the factory method getInstance.
  446.      * @see java.text.Collator#getInstance
  447.      */
  448.     protected Collator()
  449.     {
  450.         strength = TERTIARY;
  451.         decmp = CANONICAL_DECOMPOSITION;
  452.     }
  453.  
  454.     private int strength = 0;
  455.     private int decmp = 0;
  456.     private static Hashtable cache = new Hashtable();
  457.  
  458.     //
  459.     // FIXME: These three constants should be removed.
  460.     //
  461.     /**
  462.      * LESS is returned if source string is compared to be less than target
  463.      * string in the compare() method.
  464.      * @see java.text.Collator#compare
  465.      */
  466.     final static int LESS = -1;
  467.     /**
  468.      * EQUAL is returned if source string is compared to be equal to target
  469.      * string in the compare() method.
  470.      * @see java.text.Collator#compare
  471.      */
  472.     final static int EQUAL = 0;
  473.     /**
  474.      * GREATER is returned if source string is compared to be greater than
  475.      * target string in the compare() method.
  476.      * @see java.text.Collator#compare
  477.      */
  478.     final static int GREATER = 1;
  479.  
  480.     // Proclaims serialization compatibility to 1.1.
  481.     static final long serialVersionUID = -7718728969026499504L;
  482.  }
  483.