home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / main.bin / SimpleTextBoundary.java < prev    next >
Text File  |  1997-05-20  |  9KB  |  304 lines

  1. /*
  2.  * @(#)SimpleTextBoundary.java    1.11 97/01/27
  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 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.  
  34. /**
  35.  * SimpleTextBoundary is an implementation of the BreakIterator
  36.  * protocol.  SimpleTextBoundary uses a state machine to compute breaks.
  37.  * There are currently several subclasses of SimpleTextBoundary that
  38.  * compute breaks for sentences, words, lines, and characters.  They are
  39.  * accessable through static functions of SimpleTextBoundary.
  40.  * @see BreakIterator
  41.  */
  42.  
  43. final class SimpleTextBoundary extends BreakIterator
  44. {
  45.  
  46.     private int pos;
  47.     private CharacterIterator text;
  48.     private TextBoundaryData data;
  49.  
  50.     /**
  51.      * Create a SimpleTextBoundary using the specified tables. Currently,
  52.      * the table format is private.
  53.      * @param data data used for boundary determination
  54.      */
  55.     protected SimpleTextBoundary(TextBoundaryData data)
  56.     {
  57.         this.data = data;
  58.         text = new StringCharacterIterator("");
  59.         pos = text.getBeginIndex();
  60.     }
  61.  
  62.     /**
  63.      * Compares the equality of two SimpleTextBoundary objects.
  64.      * @param obj the SimpleTextBoundary object to be compared with.
  65.      * @return true if the given obj is the same as this
  66.      * SimpleTextBoundary object; false otherwise.
  67.      */
  68.     public boolean equals(Object obj)
  69.     {
  70.         if (this == obj)
  71.             return true;
  72.         if (!(obj instanceof SimpleTextBoundary))
  73.             return false;
  74.  
  75.         SimpleTextBoundary that = (SimpleTextBoundary) obj;
  76.  
  77.         // The data classes are final and sharable. Only the
  78.         // class type needs to be compared.
  79.         if (this.data.getClass() != that.data.getClass())
  80.             return false;
  81.         if (this.hashCode() != that.hashCode())
  82.             return false;
  83.         if (pos != that.pos)
  84.             return false;
  85.         if (!text.equals(that.text))
  86.             return false;
  87.         return true;
  88.     }
  89.  
  90.     /**
  91.      * Compute a hashcode for this enumeration
  92.      * @return A hash code
  93.      */
  94.     public int hashCode()
  95.     {
  96.         return getClass().hashCode() ^ text.hashCode();
  97.     }
  98.  
  99.     /**
  100.      * Overrides Cloneable
  101.      */
  102.     public Object clone()
  103.     {
  104.         try {
  105.             SimpleTextBoundary other = (SimpleTextBoundary) super.clone();
  106.             other.text = (CharacterIterator) text.clone();
  107.             // The data classes are final and sharable.
  108.             // They don't need to be cloned.
  109.             return other;
  110.         } catch (InternalError e) {
  111.             throw new InternalError();
  112.         }
  113.     }
  114.  
  115.     /**
  116.      * Get the text being scanned by the enumeration
  117.      * @return the text being scanned by the enumeration
  118.      */
  119.     public CharacterIterator getText()
  120.     {
  121.         return text;
  122.     }
  123.  
  124.     /**
  125.      * Set a new text string for enumeration.  The position of the
  126.      * enumerator is reset to first().
  127.      * @param newText new text to scan.
  128.      */
  129.     public void setText(String newText)
  130.     {
  131.         text = new StringCharacterIterator(newText);
  132.         pos = text.getBeginIndex();
  133.     }
  134.  
  135.     /**
  136.      * Set a new text to scan.  The position is reset to first().
  137.      * @param newText new text to scan.
  138.      */
  139.     public void setText(CharacterIterator newText)
  140.     {
  141.         text = newText;
  142.         pos = text.getBeginIndex();
  143.     }
  144.  
  145.     /**
  146.      * Return the first boundary. The iterator's current position is set
  147.      * to the first boundary.
  148.      */
  149.     public int first()
  150.     {
  151.         pos = text.getBeginIndex();
  152.         return pos;
  153.     }
  154.  
  155.     /**
  156.      * Return the last boundary. The iterator's current position is set
  157.      * to the last boundary.
  158.      */
  159.     public int last()
  160.     {
  161.         pos = text.getEndIndex();
  162.         return pos;
  163.     }
  164.  
  165.     /**
  166.      * Return the nth boundary from the current boundary
  167.      * @param index which boundary to return.  A value of 0
  168.      * does nothing.
  169.      * @return the nth boundary from the current position.
  170.      */
  171.     public int next(int increment)
  172.     {
  173.         int result = current();
  174.         if (increment < 0) {
  175.             for (int i = increment; (i < 0) && (result != DONE); ++i) {
  176.                 result = previous();
  177.             }
  178.         }
  179.         else {
  180.             for(int i = increment; (i > 0) && (result != DONE); --i) {
  181.                 result = next();
  182.             }
  183.         }
  184.         return result;
  185.     }
  186.  
  187.     /**
  188.      * Return the boundary preceding the last boundary
  189.      */
  190.     public int previous()
  191.     {
  192.         if (pos > text.getBeginIndex()) {
  193.             int startBoundary = pos;
  194.             pos = previousSafePosition(pos-1);
  195.             int prev = pos;
  196.             int next = next();
  197.             while (next < startBoundary && next != DONE) {
  198.                 prev = next;
  199.                 next = next();
  200.             }
  201.             pos = prev;
  202.             return pos;
  203.         }
  204.         else {
  205.             return DONE;
  206.         }
  207.     }
  208.  
  209.     /**
  210.      * Return the next text boundary
  211.      * @return the character offset of the text boundary or DONE if all
  212.      * boundaries have been returned.
  213.      */
  214.     public int next()
  215.     {
  216.         int result = pos;
  217.         if (pos < text.getEndIndex()) {
  218.             pos = nextPosition(pos);
  219.             result = pos;
  220.         }
  221.         else {
  222.             result = DONE;
  223.         }
  224.         return result;
  225.     }
  226.  
  227.     /**
  228.      * Return the first boundary after the specified offset
  229.      * @param offset the offset to start
  230.      * @return int the first boundary after offset
  231.      */
  232.     public int following(int offset)
  233.     {
  234.         if (offset < text.getBeginIndex() || offset >= text.getEndIndex())
  235.             throw new IllegalArgumentException(
  236.               "nextBoundaryAt offset out of bounds");
  237.         pos = previousSafePosition(offset);
  238.         int result;
  239.         do {
  240.             result = next();
  241.         } while (result <= offset && result != DONE);
  242.         return result;
  243.     }
  244.  
  245.     /**
  246.      * Return the boundary last returned by previous or next
  247.      * @return int the boundary last returned by previous or next
  248.      */
  249.     public int current()
  250.     {
  251.         return pos;
  252.     }
  253.  
  254.     //.................................................
  255.     //utility functions.  These functions don't change the current position.
  256.     private int previousSafePosition(int offset)
  257.     {
  258.         int result = text.getBeginIndex();
  259.         int state = data.backward().initialState();
  260.  
  261.         for (char c = text.setIndex(offset);
  262.              c != CharacterIterator.DONE && !data.backward().isEndState(state);
  263.              c = text.previous()) {
  264.  
  265.             state = data.backward().get(state, mappedChar(c));
  266.             if (data.backward().isMarkState(state)) {
  267.                 result = text.getIndex();
  268.             }
  269.         }
  270.         return result;
  271.     }
  272.  
  273.     private int nextPosition(int offset)
  274.     {
  275.         int getEndIndex = text.getEndIndex();
  276.         int state = data.forward().initialState();
  277.  
  278.         for (char c = text.setIndex(offset);
  279.              c != CharacterIterator.DONE && !data.forward().isEndState(state);
  280.              c = text.next()) {
  281.  
  282.             state = data.forward().get(state, mappedChar(c));
  283.             if (data.forward().isMarkState(state)) {
  284.                 getEndIndex = text.getIndex();
  285.             }
  286.         }
  287.         if (data.forward().isEndState(state)) {
  288.             return getEndIndex;
  289.         }
  290.         else if (text.current() != CharacterIterator.DONE) {
  291.             return getEndIndex;
  292.         }
  293.         else {
  294.             return text.getEndIndex();
  295.         }
  296.     }
  297.  
  298.     protected int mappedChar(char c)
  299.     {
  300.         return data.map().mappedChar(c);
  301.     }
  302.  
  303. }
  304.