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

  1. /*
  2.  * @(#)CollationElementIterator.java    1.11 97/02/06
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996, 1997 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1996 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.lang.Character;
  34. import java.util.Vector;
  35.  
  36. /**
  37.  * The <code>CollationElementIterator</code> class is used as an iterator
  38.  * to walk through each character of an international string. Use the iterator
  39.  * to return the ordering priority of the positioned character. The ordering
  40.  * priority of a character, which we refer to as a key, defines how a character
  41.  * is collated in the given collation object.
  42.  *
  43.  * <p>
  44.  * For example, consider the following in Spanish:
  45.  * <blockquote>
  46.  * <pre>
  47.  * "ca" -> the first key is key('c') and second key is key('a').
  48.  * "cha" -> the first key is key('ch') and second key is key('a').
  49.  * </pre>
  50.  * </blockquote>
  51.  * And in German,
  52.  * <blockquote>
  53.  * <pre>
  54.  * "\u00e4b"-> the first key is key('a'), the second key is key('e'), and
  55.  * the third key is key('b').
  56.  * </pre>
  57.  * </blockquote>
  58.  * The key of a character is an integer composed of primary order(short),
  59.  * secondary order(byte), and tertiary order(byte). Java strictly defines
  60.  * the size and signedness of its primitive data types. Therefore, the static
  61.  * functions <code>primaryOrder</code>, <code>secondaryOrder</code>, and
  62.  * <code>tertiaryOrder</code> return <code>int</code>, <code>short</code>,
  63.  * and <code>short</code> respectively to ensure the correctness of the key
  64.  * value.
  65.  *
  66.  * <p>
  67.  * Example of the iterator usage,
  68.  * <blockquote>
  69.  * <pre>
  70.  * // get the first key of the string
  71.  * String str = "This is a test";
  72.  * CollationElementIterator c =
  73.  *     new CollationElementIterator(str, 0, str.length(),
  74.  *                                  Collator.getInstance());
  75.  * int primaryOrder = CollationElementIterator.primaryOrder(c->next());
  76.  * </pre>
  77.  * </blockquote>
  78.  *
  79.  * <p>
  80.  * <code>CollationElementIterator.next</code> returns the collation order
  81.  * of the next character. A collation order consists of primary order,
  82.  * secondary order and tertiary order. The data type of the collation
  83.  * order is <strong>int</strong>. The first 16 bits of a collation order
  84.  * is its primary order; the next 8 bits is the secondary order and the
  85.  * last 8 bits is the tertiary order.
  86.  *
  87.  * @see                Collator
  88.  * @see                RuleBasedCollator
  89.  * @version            1.11 02/06/97
  90.  * @author             Helena Shih
  91.  */
  92. public final class CollationElementIterator
  93. {
  94.     /**
  95.      * Null order which indicates the end of string is reached by the
  96.      * cursor.
  97.      */
  98.     public final static int NULLORDER = 0xffffffff;
  99.     /**
  100.      * CollationElementIterator constructor.  This takes the source string and
  101.      * the collation object.  The cursor will walk thru the source string based
  102.      * on the predefined collation rules.  If the source string is empty,
  103.      * NULLORDER will be returned on the calls to next().
  104.      * @param sourceText the source string.
  105.      * @param order the collation object.
  106.      */
  107.     CollationElementIterator(String sourceText, RuleBasedCollator order) {
  108.         if ( sourceText.length() != 0 ) {
  109.             text = new DecompositionIterator(sourceText, 0,
  110.                                              sourceText.length(),
  111.                                              order.getDecomposition());
  112.         }
  113.         ordering = order;
  114.     }
  115.     /**
  116.      * Resets the cursor to the beginning of the string.
  117.      */
  118.     public void reset()
  119.     {
  120.         if (text != null)
  121.             text.reset();
  122.         buffer = null;
  123.         expIndex = 0;
  124.         swapOrder = 0;
  125.     }
  126.     /**
  127.      * Get the ordering priority of the next character in the string.
  128.      * @return the next character's ordering.  Returns NULLORDER if
  129.      * the end of string is reached.
  130.      */
  131.     public int next()
  132.     {
  133.         if (text == null)
  134.             return NULLORDER;
  135.         if (buffer != null)
  136.         {
  137.             if (expIndex < buffer.length)
  138.             {
  139.                 return buffer[expIndex++];
  140.             }
  141.             else
  142.             {
  143.                 buffer = null;
  144.                 expIndex = 0;
  145.             }
  146.         } else if (swapOrder != 0) {
  147.             int order = swapOrder;
  148.             swapOrder = 0;
  149.             return order;
  150.         }
  151.         char ch = text.next();
  152.         if (ch == DecompositionIterator.NULLORDER)
  153.             return NULLORDER;
  154.         int value = ordering.getUnicodeOrder(ch);
  155.         if (value == RuleBasedCollator.UNMAPPED)
  156.         {
  157.             swapOrder = ch;
  158.             swapOrder <<= RuleBasedCollator.SECONDARYORDERSHIFT;
  159.             return UNMAPPEDCHARVALUE;
  160.         }
  161.         else if (value < RuleBasedCollator.CHARINDEX)
  162.         {
  163.             return value;
  164.         }
  165.         // contract characters
  166.         else if (value >= RuleBasedCollator.CONTRACTCHARINDEX)
  167.         {
  168.             return nextContractChar(ch);
  169.         }
  170.         else if (value >= RuleBasedCollator.EXPANDCHARINDEX)
  171.         {
  172.             buffer = ordering.getExpandValueList(ch);
  173.             expIndex = 0;
  174.             return buffer[expIndex++];
  175.         }
  176.         else if (value >= RuleBasedCollator.CHARINDEX)
  177.         {
  178.             return RuleBasedCollator.UNMAPPED;
  179.         }
  180.         return NULLORDER;
  181.     }
  182.     /**
  183.      * Get the primary order of a collation order.
  184.      * @param order the collation order
  185.      * @return the primary order of a collation order.
  186.      */
  187.     public final static int primaryOrder(int order)
  188.     {
  189.         order &= RuleBasedCollator.PRIMARYORDERMASK;
  190.         return (order >>> RuleBasedCollator.PRIMARYORDERSHIFT);
  191.     }
  192.     /**
  193.      * Get the secondary order of a collation order.
  194.      * @param order the collation order
  195.      * @return the secondary order of a collation order.
  196.      */
  197.     public final static short secondaryOrder(int order)
  198.     {
  199.         order = order & RuleBasedCollator.SECONDARYORDERMASK;
  200.         return ((short)(order >> RuleBasedCollator.SECONDARYORDERSHIFT));
  201.     }
  202.     /**
  203.      * Get the tertiary order of a collation order.
  204.      * @param order the collation order
  205.      * @return the tertiary order of a collation order.
  206.      */
  207.     public final static short tertiaryOrder(int order)
  208.     {
  209.         return ((short)(order &= RuleBasedCollator.TERTIARYORDERMASK));
  210.     }
  211.     //============================================================
  212.     // privates
  213.     //============================================================
  214.     private int getEntry(Vector list, String name) {
  215.         for (int i = 0; i < list.size(); i++) {
  216.             EntryPair pair = (EntryPair)list.elementAt(i);
  217.             if (pair.entryName.equals(name)) {
  218.                 return i;
  219.             }
  220.         }
  221.         return RuleBasedCollator.UNMAPPED;
  222.     }
  223.     /**
  224.      * Get the ordering priority of the next contracting character in the
  225.      * string.
  226.      * @param ch the starting character of a contracting character token
  227.      * @return the next contracting character's ordering.  Returns NULLORDER
  228.      * if the end of string is reached.
  229.      */
  230.     private int nextContractChar(char ch)
  231.     {
  232.         EntryPair pair = null;
  233.         Vector list = ordering.getContractValues(ch);
  234.         int intValue = 0;
  235.         key.setLength(0);
  236.         key.append(ch);
  237.         int n = 0;
  238.         if ((n = getEntry(list, key.toString())) != RuleBasedCollator.UNMAPPED) {
  239.             pair = (EntryPair)list.elementAt(n);
  240.             intValue = pair.value;
  241.         }
  242.         while((ch = text.next()) != DecompositionIterator.NULLORDER)
  243.         {
  244.             key.append(ch);
  245.             if ((n = getEntry(list, key.toString())) ==
  246.                      RuleBasedCollator.UNMAPPED) {
  247.                 ch = text.previous();
  248.                 break;
  249.             }
  250.             pair = (EntryPair)list.elementAt(n);
  251.             intValue = pair.value;
  252.         }
  253.         // if contracting char is also an expanding char
  254.         if ((intValue  - RuleBasedCollator.EXPANDCHARINDEX) >= 0)
  255.         {
  256.             buffer = ordering.getExpandValueList
  257.                      (intValue - RuleBasedCollator.EXPANDCHARINDEX);
  258.             expIndex = 0;
  259.             intValue = buffer[expIndex++];
  260.         }
  261.         return intValue;
  262.     }
  263.  
  264.     final static int UNMAPPEDCHARVALUE = 0x7FFF0000;
  265.  
  266.     private DecompositionIterator text = null;
  267.     private int[] buffer = null;
  268.     private int expIndex = 0;
  269.     private StringBuffer key = new StringBuffer(5);
  270.     private int swapOrder = 0;
  271.     private RuleBasedCollator ordering;
  272. }
  273.