home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1998 February / VPR9802A.ISO / APP_DEMO / VC / MAIN.BIN / Collator.java < prev    next >
Text File  |  1997-10-27  |  18KB  |  457 lines

  1. /*
  2.  * @(#)Collator.java    1.6 97/02/06
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1996-1997 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.6 02/06/97
  116.  * @author      Helena Shih
  117.  */
  118.  
  119. public abstract class Collator implements Cloneable, Serializable {
  120.     /**
  121.      * Collator strength value.  When set, only PRIMARY differences are
  122.      * considered significant during comparison. The assignment of strengths
  123.      * to language features is locale dependant. A common example is for
  124.      * different base letters ("a" vs "b") to be considered a PRIMARY difference.
  125.      * @see java.text.Collator#setStrength
  126.      * @see java.text.Collator#getStrength
  127.      */
  128.     public final static int PRIMARY = 0;
  129.     /**
  130.      * Collator strength value.  When set, only SECONDARY and above differences are
  131.      * considered significant during comparison. The assignment of strengths
  132.      * to language features is locale dependant. A common example is for
  133.      * different accented forms of the same base letter ("a" vs "\u00E4") to be
  134.      * considered a SECONDARY difference.
  135.      * @see java.text.Collator#setStrength
  136.      * @see java.text.Collator#getStrength
  137.      */
  138.     public final static int SECONDARY = 1;
  139.     /**
  140.      * Collator strength value.  When set, only TERTIARY and above differences are
  141.      * considered significant during comparison. The assignment of strengths
  142.      * to language features is locale dependant. A common example is for
  143.      * case differences ("a" vs "A") to be considered a TERTIARY difference.
  144.      * @see java.text.Collator#setStrength
  145.      * @see java.text.Collator#getStrength
  146.      */
  147.     public final static int TERTIARY = 2;
  148.  
  149.     /**
  150.      * Collator strength value.  When set, all differences are
  151.      * considered significant during comparison. The assignment of strengths
  152.      * to language features is locale dependant. A common example is for characters
  153.      * with equivalent Unicode spellings ("\u00E4" vs "a\u0308") to be considered IDENTICAL.
  154.      */
  155.     public final static int IDENTICAL = 3;
  156.  
  157.     /**
  158.      * Decomposition mode value. With NO_DECOMPOSITION
  159.      * set, accented characters will not be decomposed for collation. This
  160.      * provides the fastest collation but will only produce correct results
  161.      * for languages that do not use accents.
  162.      * @see java.text.Collator#getDecomposition
  163.      * @see java.text.Collator#setDecomposition
  164.      */
  165.     public final static int NO_DECOMPOSITION = 0;
  166.  
  167.     /**
  168.      * Decomposition mode value. With CANONICAL_DECOMPOSITION
  169.      * set, characters that are canonical variants according to Unicode 2.0
  170.      * will be decomposed for collation. This is the default setting and
  171.      * should be used to get correct collation of accented characters.
  172.      * @see java.text.Collator#getDecomposition
  173.      * @see java.text.Collator#setDecomposition
  174.      */
  175.     public final static int CANONICAL_DECOMPOSITION = 1;
  176.  
  177.     /**
  178.      * Decomposition mode value. With FULL_DECOMPOSITION
  179.      * set, both Unicode canonical variants and Unicode compatibility variants
  180.      * will be decomposed for collation.  This causes not only accented
  181.      * characters to be collated, but also characters that have special formats
  182.      * to be collated with their norminal form. For example, the half-width and
  183.      * full-width ASCII and Katakana characters are then collated together.
  184.      * FULL_DECOMPOSITION is the most complete and therefore the slowest
  185.      * decomposition mode.
  186.      * @see java.text.Collator#getDecomposition
  187.      * @see java.text.Collator#setDecomposition
  188.      */
  189.     public final static int FULL_DECOMPOSITION = 2;
  190.  
  191.     /**
  192.      * Gets the Collator for the current default locale.
  193.      * The default locale is determined by java.util.Locale.getDefault.
  194.      * @return the Collator for the default locale.(for example, en_US)
  195.      * @see java.util.Locale#getDefault
  196.      */
  197.     public static synchronized Collator getInstance() {
  198.         return getInstance(Locale.getDefault());
  199.     }
  200.  
  201.     /**
  202.      * Gets the Collator for the desired locale.
  203.      * @param desiredLocale the desired locale.
  204.      * @return the Collator for the desired locale.
  205.      * @see java.util.Locale
  206.      * @see java.util.ResourceBundle
  207.      */
  208.     public static synchronized
  209.     Collator getInstance(Locale desiredLocale)
  210.     {
  211.         RuleBasedCollator result = null;
  212.         result = (RuleBasedCollator) cache.get(desiredLocale);
  213.         if (result != null) {
  214.             return (Collator)result.clone();  // make the world safe
  215.         }
  216.  
  217.         // Load the resource of the desired locale from resource
  218.         // manager.
  219.         String colString;
  220.         try {
  221.             ResourceBundle resource = ResourceBundle.getBundle
  222.                                       ("java.text.resources.LocaleElements",
  223.                                        desiredLocale);
  224.  
  225.             colString = resource.getString("CollationElements");
  226.         } catch (MissingResourceException e) {
  227.             // return default US collation
  228.             colString = "";
  229.         }
  230.         try
  231.         {
  232.             result = new RuleBasedCollator( CollationRules.DEFAULTRULES +
  233.                                             colString );
  234.         }
  235.         catch(ParseException foo)
  236.         {
  237.             // predefined tables should contain correct grammar
  238.             try {
  239.                 result = new RuleBasedCollator( CollationRules.DEFAULTRULES );
  240.             } catch (ParseException bar) {
  241.                 // do nothing
  242.             }
  243.         }
  244.         cache.put(desiredLocale,result);
  245.         return result;
  246.     }
  247.  
  248.     /**
  249.      * Compares the source string to the target string according to the
  250.      * collation rules for this Collator.  Returns an integer less than,
  251.      * equal to or greater than zero depending on whether the source String is
  252.      * less than, equal to or greater than the target string.  See the Collator
  253.      * class description for an example of use.
  254.      * <p>
  255.      * For a one time comparison, this method has the best performance. If a
  256.      * given String will be involved in multiple comparisons, CollationKey.compareTo
  257.      * has the best performance. See the Collator class description for an example
  258.      * using CollationKeys.
  259.      * @param source the source string.
  260.      * @param target the target string.
  261.      * @return Returns an integer value. Value is less than zero if source is less than
  262.      * target, value is zero if source and target are equal, value is greater than zero
  263.      * if source is greater than target.
  264.      * @see java.text.CollationKey
  265.      * @see java.text.Collator#getCollationKey
  266.      */
  267.     public abstract int compare(String source, String target);
  268.  
  269.     /**
  270.      * Transforms the String into a series of bits that can be compared bitwise
  271.      * to other CollationKeys. CollationKeys provide better performance than
  272.      * Collator.compare when Strings are involved in multiple comparisons.
  273.      * See the Collator class description for an example using CollationKeys.
  274.      * @param source the string to be transformed into a collation key.
  275.      * @return the CollationKey for the given String based on this Collator's collation
  276.      * rules. If the source String is null, a null CollationKey is returned.
  277.      * @see java.text.CollationKey
  278.      * @see java.text.Collator#compare
  279.      */
  280.     public abstract CollationKey getCollationKey(String source);
  281.  
  282.     /**
  283.      * Convenience method for comparing the equality of two strings based on
  284.      * this Collator's collation rules.
  285.      * @param source the source string to be compared with.
  286.      * @param target the target string to be compared with.
  287.      * @return true if the strings are equal according to the collation
  288.      * rules.  false, otherwise.
  289.      * @see java.text.Collator#compare
  290.      */
  291.     public boolean equals(String source, String target)
  292.     {
  293.         if (compare(source, target) == Collator.EQUAL)
  294.             return true;
  295.         else
  296.             return false;
  297.     }
  298.  
  299.     /**
  300.      * Returns this Collator's strength property.  The strength property determines
  301.      * the minimum level of difference considered significant during comparison.
  302.      * See the Collator class description for an example of use.
  303.      * @return this Collator's current strength property.
  304.      * @see java.text.Collator#setStrength
  305.      * @see java.text.Collator#PRIMARY
  306.      * @see java.text.Collator#SECONDARY
  307.      * @see java.text.Collator#TERTIARY
  308.      * @see java.text.Collator#IDENTICAL
  309.      */
  310.     public synchronized int getStrength()
  311.     {
  312.         return strength;
  313.     }
  314.  
  315.     /**
  316.      * Sets this Collator's strength property.  The strength property determines
  317.      * the minimum level of difference considered significant during comparison.
  318.      * See the Collator class description for an example of use.
  319.      * @param the new strength value.
  320.      * @see java.text.Collator#getStrength
  321.      * @see java.text.Collator#PRIMARY
  322.      * @see java.text.Collator#SECONDARY
  323.      * @see java.text.Collator#TERTIARY
  324.      * @see java.text.Collator#IDENTICAL
  325.      * @exception  IllegalArgumentException If the new strength value is not one of
  326.      * PRIMARY, SECONDARY, TERTIARY or IDENTICAL.
  327.      */
  328.     public synchronized void setStrength(int newStrength) {
  329.         if ((newStrength != PRIMARY) &&
  330.             (newStrength != SECONDARY) &&
  331.             (newStrength != TERTIARY))
  332.             throw new IllegalArgumentException("Incorrect comparison level.");
  333.         strength = newStrength;
  334.     }
  335.  
  336.     /**
  337.      * Get the decomposition mode of this Collator. Decomposition mode
  338.      * determines how Unicode composed characters are handled. Adjusting
  339.      * decomposition mode allows the user to select between faster and more
  340.      * complete collation behavior.
  341.      * <p>The three values for decomposition mode are:
  342.      * <UL>
  343.      * <LI>NO_DECOMPOSITION,
  344.      * <LI>CANONICAL_DECOMPOSITION
  345.      * <LI>FULL_DECOMPOSITION.
  346.      * </UL>
  347.      * See the documentation for these three constants for a description
  348.      * of their meaning.
  349.      * @return the decomposition mode
  350.      * @see java.text.Collator#setDecomposition
  351.      * @see java.text.Collator#NO_DECOMPOSITION
  352.      * @see java.text.Collator#CANONICAL_DECOMPOSITION
  353.      * @see java.text.Collator#FULL_DECOMPOSITION
  354.      */
  355.     public synchronized int getDecomposition()
  356.     {
  357.         return decmp;
  358.     }
  359.     /**
  360.      * Set the decomposition mode of this Collator. See getDecomposition
  361.      * for a description of decomposition mode.
  362.      * @param the new decomposition mode
  363.      * @see java.text.Collator#getDecomposition
  364.      * @see java.text.Collator#NO_DECOMPOSITION
  365.      * @see java.text.Collator#CANONICAL_DECOMPOSITION
  366.      * @see java.text.Collator#FULL_DECOMPOSITION
  367.      * @exception IllegalArgumentException If the given value is not a valid decomposition
  368.      * mode.
  369.      */
  370.     public synchronized void setDecomposition(int decompositionMode) {
  371.         if ((decompositionMode != NO_DECOMPOSITION) &&
  372.             (decompositionMode != CANONICAL_DECOMPOSITION) &&
  373.             (decompositionMode != FULL_DECOMPOSITION))
  374.             throw new IllegalArgumentException("Wrong decomposition mode.");
  375.         decmp = decompositionMode;
  376.     }
  377.  
  378.     /**
  379.      * Get the set of Locales for which Collators are installed.
  380.      * @return the list of available locales which collators are installed.
  381.      */
  382.     public static synchronized Locale[] getAvailableLocales() {
  383.         return LocaleData.getAvailableLocales("CollationElements");
  384.     }
  385.  
  386.     /**
  387.      * Overrides Cloneable
  388.      */
  389.     public Object clone()
  390.     {
  391.         try {
  392.             return (Collator)super.clone();
  393.         } catch (CloneNotSupportedException e) {
  394.             throw new InternalError();
  395.         }
  396.     }
  397.  
  398.     /**
  399.      * Compares the equality of two Collators.
  400.      * @param that the Collator to be compared with this.
  401.      * @return true if this Collator is the same as that Collator;
  402.      * false otherwise.
  403.      */
  404.     public boolean equals(Object that)
  405.     {
  406.         if (this == that) return true;
  407.         if (getClass() != that.getClass()) return false;
  408.         Collator other = (Collator) that;
  409.         return ((strength == other.strength) &&
  410.                 (decmp == other.decmp));
  411.     }
  412.  
  413.     /**
  414.      * Generates the hash code for this Collator.
  415.      */
  416.     abstract public synchronized int hashCode();
  417.  
  418.     /**
  419.      * Default constructor.  This constructor is
  420.      * protected so subclasses can get access to it. Users typically create
  421.      * a Collator sub-class by calling the factory method getInstance.
  422.      * @see java.text.Collator#getInstance
  423.      */
  424.     protected Collator()
  425.     {
  426.         strength = TERTIARY;
  427.         decmp = CANONICAL_DECOMPOSITION;
  428.     }
  429.  
  430.     private int strength = 0;
  431.     private int decmp = 0;
  432.     private static Hashtable cache = new Hashtable();
  433.  
  434.     //
  435.     // FIXME: These three constants should be removed.
  436.     //
  437.     /**
  438.      * LESS is returned if source string is compared to be less than target
  439.      * string in the compare() method.
  440.      * @see java.text.Collator#compare
  441.      */
  442.     final static int LESS = -1;
  443.     /**
  444.      * EQUAL is returned if source string is compared to be equal to target
  445.      * string in the compare() method.
  446.      * @see java.text.Collator#compare
  447.      */
  448.     final static int EQUAL = 0;
  449.     /**
  450.      * GREATER is returned if source string is compared to be greater than
  451.      * target string in the compare() method.
  452.      * @see java.text.Collator#compare
  453.      */
  454.     final static int GREATER = 1;
  455.  
  456. }
  457.