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

  1. /*
  2.  * @(#)BreakIterator.java    1.19 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) 1996-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. import java.util.Vector;
  33. import java.util.Locale;
  34. import java.text.resources.*;
  35.  
  36. /**
  37.  * The <code>BreakIterator</code> class implements methods for finding
  38.  * the location of boundaries in text. Instances of <code>BreakIterator</code>
  39.  * maintain a current position and scan over text
  40.  * returning the index of characters where boundaries occur.
  41.  * Internally, <code>BreakIterator</code> scans text using a
  42.  * <code>CharacterIterator</code>, and is thus able to scan text held
  43.  * by any object implementing that protocol. A <code>StringCharacterIterator</code>
  44.  * is used to scan <code>String</code> objects passed to <code>setText</code>.
  45.  *
  46.  * <p>
  47.  * You use the factory methods provided by this class to create
  48.  * instances of various types of break iterators. In particular,
  49.  * use <code>getWordIterator</code>, <code>getLineIterator</code>,
  50.  * <code>getSentenceIterator</code>, and <code>getCharacterIterator</code>
  51.  * to create <code>BreakIterator</code>s that perform
  52.  * word, line, sentence, and character boundary analysis respectively.
  53.  * A single <code>BreakIterator</code> can work only on one unit
  54.  * (word, line, sentence, and so on). You must use a different iterator
  55.  * for each unit boundary analysis you wish to perform.
  56.  *
  57.  * <p>
  58.  * Line boundary analysis determines where a text string can be
  59.  * broken when line-wrapping. The mechanism correctly handles
  60.  * punctuation and hyphenated words.
  61.  *
  62.  * <p>
  63.  * Sentence boundary analysis allows selection with correct interpretation
  64.  * of periods within numbers and abbreviations, and trailing punctuation
  65.  * marks such as quotation marks and parentheses.
  66.  *
  67.  * <p>
  68.  * Word boundary analysis is used by search and replace functions, as
  69.  * well as within text editing applications that allow the user to
  70.  * select words with a double click. Word selection provides correct
  71.  * interpretation of punctuation marks within and following
  72.  * words. Characters that are not part of a word, such as symbols
  73.  * or punctuation marks, have word-breaks on both sides.
  74.  *
  75.  * <p>
  76.  * Character boundary analysis allows users to interact with characters
  77.  * as they expect to, for example, when moving the cursor through a text
  78.  * string. Character boundary analysis provides correct navigation of
  79.  * through character strings, regardless of how the character is stored.
  80.  * For example, an accented character might be stored as a base character
  81.  * and a diacritical mark. What users consider to be a character can
  82.  * differ between languages.
  83.  *
  84.  * <p>
  85.  * <code>BreakIterator</code> is intended for use with natural
  86.  * languages only. Do not use this class to tokenize a programming language.
  87.  *
  88.  * <P>
  89.  * <strong>Examples</strong>:<P>
  90.  * Creating and using text boundaries
  91.  * <blockquote>
  92.  * <pre>
  93.  * public static void main(String args[]) {
  94.  *      if (args.length == 1) {
  95.  *          String stringToExamine = args[0];
  96.  *          //print each word in order
  97.  *          BreakIterator boundary = BreakIterator.getWordInstance();
  98.  *          boundary.setText(stringToExamine);
  99.  *          printEachForward(boundary, stringToExamine);
  100.  *          //print each sentence in reverse order
  101.  *          boundary = BreakIterator.getSentenceInstance(Locale.US);
  102.  *          boundary.setText(stringToExamine);
  103.  *          printEachBackward(boundary, stringToExamine);
  104.  *          printFirst(boundary, stringToExamine);
  105.  *          printLast(boundary, stringToExamine);
  106.  *      }
  107.  * }
  108.  * </pre>
  109.  * </blockquote>
  110.  *
  111.  * Print each element in order
  112.  * <blockquote>
  113.  * <pre>
  114.  * public static void printEachForward(BreakIterator boundary, String source) {
  115.  *     int start = boundary.first();
  116.  *     for (int end = boundary.next();
  117.  *          end != BreakIterator.DONE;
  118.  *          start = end, end = boundary.next()) {
  119.  *          System.out.println(source.substring(start,end));
  120.  *     }
  121.  * }
  122.  * </pre>
  123.  * </blockquote>
  124.  *
  125.  * Print each element in reverse order
  126.  * <blockquote>
  127.  * <pre>
  128.  * public static void printEachBackward(BreakIterator boundary, String source) {
  129.  *     int end = boundary.last();
  130.  *     for (int start = boundary.previous();
  131.  *          start != BreakIterator.DONE;
  132.  *          end = start, start = boundary.previous()) {
  133.  *         System.out.println(source.substring(start,end));
  134.  *     }
  135.  * }
  136.  * </pre>
  137.  * </blockquote>
  138.  *
  139.  * Print first element
  140.  * <blockquote>
  141.  * <pre>
  142.  * public static void printFirst(BreakIterator boundary, String source) {
  143.  *     int start = boundary.first();
  144.  *     int end = boundary.next();
  145.  *     System.out.println(source.substring(start,end));
  146.  * }
  147.  * </pre>
  148.  * </blockquote>
  149.  *
  150.  * Print last element
  151.  * <blockquote>
  152.  * <pre>
  153.  * public static void printLast(BreakIterator boundary, String source) {
  154.  *     int end = boundary.last();
  155.  *     int start = boundary.previous();
  156.  *     System.out.println(source.substring(start,end));
  157.  * }
  158.  * </pre>
  159.  * </blockquote>
  160.  *
  161.  * Print the element at a specified position
  162.  * <blockquote>
  163.  * <pre>
  164.  * public static void printAt(BreakIterator boundary, int pos, String source) {
  165.  *     int end = boundary.following(pos);
  166.  *     int start = boundary.previous();
  167.  *     System.out.println(source.substring(start,end));
  168.  * }
  169.  * </pre>
  170.  * </blockquote>
  171.  *
  172.  * @see CharacterIterator
  173.  *
  174.  */
  175.  
  176. public abstract class BreakIterator implements Cloneable, java.io.Serializable
  177. {
  178.     /**
  179.      * Constructor. BreakIterator is stateless and has no default behavior.
  180.      */
  181.     protected BreakIterator()
  182.     {
  183.     }
  184.  
  185.     /**
  186.      * Create a copy of this iterator
  187.      * @return A copy of this
  188.      */
  189.     public Object clone()
  190.     {
  191.         try {
  192.             return super.clone();
  193.         }
  194.         catch (CloneNotSupportedException e) {
  195.             throw new InternalError();
  196.         }
  197.     }
  198.  
  199.     /**
  200.      * DONE is returned by previous() and next() after all valid
  201.      * boundaries have been returned.
  202.      */
  203.     public static final int DONE = -1;
  204.  
  205.     /**
  206.      * Return the first boundary. The iterator's current position is set
  207.      * to the first boundary.
  208.      * @return The character index of the first text boundary.
  209.      */
  210.     public abstract int first()
  211.         ;
  212.     /**
  213.      * Return the last boundary. The iterator's current position is set
  214.      * to the last boundary.
  215.      * @return The character index of the last text boundary.
  216.      */
  217.     public abstract int last();
  218.  
  219.     /**
  220.      * Return the nth boundary from the current boundary
  221.      * @param n which boundary to return.  A value of 0
  222.      * does nothing.  Negative values move to previous boundaries
  223.      * and positive values move to later boundaries.
  224.      * @return The index of the nth boundary from the current position.
  225.      */
  226.     public abstract int next(int n);
  227.  
  228.     /**
  229.      * Return the boundary following the current boundary.
  230.      * @return The character index of the next text boundary or DONE if all
  231.      * boundaries have been returned.  Equivalent to next(1).
  232.      */
  233.     public abstract int next();
  234.  
  235.     /**
  236.      * Return the boundary preceding the current boundary.
  237.      * @return The character index of the previous text boundary or DONE if all
  238.      * boundaries have been returned.
  239.      */
  240.     public abstract int previous();
  241.  
  242.     /**
  243.      * Return the first boundary following the specified offset.
  244.      * The value returned is always greater than the offset or
  245.      * the value BreakIterator.DONE
  246.      * @param offset the offset to begin scanning. Valid values
  247.      * are determined by the CharacterIterator passed to
  248.      * setText().  Invalid values cause
  249.      * an IllegalArgumentException to be thrown.
  250.      * @return The first boundary after the specified offset.
  251.      */
  252.     public abstract int following(int offset);
  253.  
  254.     /**
  255.      * Return the last boundary preceding the specfied offset.
  256.      * The value returned is always less than the offset or the value
  257.      * BreakIterator.DONE.
  258.      * @param offset the offset to begin scanning.  Valid values are
  259.      * determined by the CharacterIterator passed to setText().
  260.      * Invalid values cause an IllegalArgumentException to be thrown.
  261.      * @return The last boundary before the specified offset.
  262.      */
  263. // function made package private pending API-change approval
  264.     /*public*/ int preceding(int offset) {
  265.         // NOTE:  This implementation is here solely because we can't add new
  266.         // abstract methods to an existing class.  There is almost ALWAYS a
  267.         // better, faster way to do this.
  268.         int pos = following(offset);
  269.         while (pos >= offset && pos != DONE)
  270.             pos = previous();
  271.         return pos;
  272.     }
  273.  
  274.     /**
  275.      * Return true if the specfied position is a boundary position.
  276.      * @param offset the offset to check.
  277.      * @return True if "offset" is a boundary position.
  278.      */
  279. // function made package private pending API-change approval
  280.     /*public*/ boolean isBoundary(int offset) {
  281.         if (offset == 0)
  282.             return true;
  283.         else
  284.             return following(offset - 1) == offset;
  285.     }
  286.  
  287.     /**
  288.      * Return character index of the text boundary that was most recently
  289.      * returned by next(), previous(), first(), or last()
  290.      * @return The boundary most recently returned.
  291.      */
  292.     public abstract int current();
  293.  
  294.     /**
  295.      * Get the text being scanned
  296.      * @return the text being scanned
  297.      */
  298.     public abstract CharacterIterator getText();
  299.  
  300.     /**
  301.      * Set a new text string to be scanned.  The current scan
  302.      * position is reset to first().
  303.      * @param newText new text to scan.
  304.      */
  305.     public void setText(String newText)
  306.     {
  307.         setText(new StringCharacterIterator(newText));
  308.     }
  309.  
  310.     /**
  311.      * Set a new text for scanning.  The current scan
  312.      * position is reset to first().
  313.      * @param newText new text to scan.
  314.      */
  315.     public abstract void setText(CharacterIterator newText);
  316.  
  317.     /**
  318.      * Create BreakIterator for word-breaks using default locale.
  319.      * Returns an instance of a BreakIterator implementing word breaks.
  320.      * WordBreak  is usefull for word selection (ex. double click)
  321.      * @return A BreakIterator for word-breaks
  322.      * @see java.util.Locale#getDefault
  323.      */
  324.     public static BreakIterator getWordInstance()
  325.     {
  326.         return getWordInstance(Locale.getDefault());
  327.     }
  328.  
  329.     /**
  330.      * Create BreakIterator for word-breaks using specified locale.
  331.      * Returns an instance of a BreakIterator implementing word breaks.
  332.      * WordBreak is usefull for word selection (ex. double click)
  333.      * @param where the local.  If a specific WordBreak is not
  334.      * avaliable for the specified locale, a default WordBreak is returned.
  335.      * @return A BreakIterator for word-breaks
  336.      */
  337.     public static BreakIterator getWordInstance(Locale where)
  338.     {
  339.         return new SimpleTextBoundary(new WordBreakData());
  340.     }
  341.  
  342.     /**
  343.      * Create BreakIterator for line-breaks using default locale.
  344.      * Returns an instance of a BreakIterator implementing line breaks. Line
  345.      * breaks are logically possible line breaks, actual line breaks are
  346.      * usually determined based on display width.
  347.      * LineBreak is useful for word wrapping text.
  348.      * @return A BreakIterator for line-breaks
  349.      * @see java.util.Locale#getDefault
  350.      */
  351.     public static BreakIterator getLineInstance()
  352.     {
  353.         return getLineInstance(Locale.getDefault());
  354.     }
  355.  
  356.     /**
  357.      * Create BreakIterator for line-breaks using specified locale.
  358.      * Returns an instance of a BreakIterator implementing line breaks. Line
  359.      * breaks are logically possible line breaks, actual line breaks are
  360.      * usually determined based on display width.
  361.      * LineBreak is useful for word wrapping text.
  362.      * @param where the local.  If a specific LineBreak is not
  363.      * avaliable for the specified locale, a default LineBreak is returned.
  364.      * @return A BreakIterator for line-breaks
  365.      */
  366.     public static BreakIterator getLineInstance(Locale where)
  367.     {
  368.         return new SimpleTextBoundary(new LineBreakData());
  369.     }
  370.  
  371.     /**
  372.      * Create BreakIterator for character-breaks using default locale
  373.      * Returns an instance of a BreakIterator implementing character breaks.
  374.      * Character breaks are boundaries of combining character sequences.
  375.      * @return A BreakIterator for character-breaks
  376.      * @see Locale#getDefault
  377.      */
  378.     public static BreakIterator getCharacterInstance()
  379.     {
  380.         return getCharacterInstance(Locale.getDefault());
  381.     }
  382.  
  383.     /**
  384.      * Create BreakIterator for character-breaks using specified locale
  385.      * Returns an instance of a BreakIterator implementing character breaks.
  386.      * Character breaks are boundaries of combining character sequences.
  387.      * @param where the local.  If a specific character break is not
  388.      * avaliable for the specified local, a default character break is returned.
  389.      * @return A BreakIterator for character-breaks
  390.      */
  391.     public static BreakIterator getCharacterInstance(Locale where)
  392.     {
  393.         return new SimpleTextBoundary(new CharacterBreakData());
  394.     }
  395.  
  396.     /**
  397.      * Create BreakIterator for sentence-breaks using default locale
  398.      * Returns an instance of a BreakIterator implementing sentence breaks.
  399.      * @return A BreakIterator for sentence-breaks
  400.      * @see java.util.Locale#getDefault
  401.      */
  402.     public static BreakIterator getSentenceInstance()
  403.     {
  404.         return getSentenceInstance(Locale.getDefault());
  405.     }
  406.  
  407.     /**
  408.      * Create BreakIterator for sentence-breaks using specified locale
  409.      * Returns an instance of a BreakIterator implementing sentence breaks.
  410.      * @param where the local.  If a specific SentenceBreak is not
  411.      * avaliable for the specified local, a default SentenceBreak is returned.
  412.      * @return A BreakIterator for sentence-breaks
  413.      */
  414.     public static BreakIterator getSentenceInstance(Locale where)
  415.     {
  416.         return new SimpleTextBoundary(new SentenceBreakData());
  417.     }
  418.  
  419.     /**
  420.      * Get the set of Locales for which BreakIterators are installed
  421.      * @return available locales
  422.      */
  423.     public static synchronized Locale[] getAvailableLocales()
  424.     {
  425.         //FIX ME - this is a known bug.  It should return
  426.         //all locales.
  427.         return LocaleData.getAvailableLocales("NumberPatterns");
  428.     }
  429.  
  430. }
  431.