001    package org.vmdb.hl7;
002    
003    import java.util.*;
004    import java.io.*;
005    
006    /**
007     * <p><Title:> String List Modified String Tokenizer. </p>
008     * <p>Description: HL7 Network Connectivity For VMDB. </p>
009     * <p>Copyright: Copyright (c) 2002-2003. </p>
010     * <p>Company: Veterinary Medical Database (VMDB). </p>
011     * <p>More or less take over from the StringTokenizer class but with two
012     * modifications.  First, two sequential tokens result in an empty string
013     * rather than no token.  Second getIndex and setIndex allow saving and
014     * restoring state to allow roll-back of reading from the list.
015     * @author Michael K. Martin
016     * @version 1.0
017     */
018    
019    public class StringList implements Serializable {
020       /** NULL character used to specify no escape character. */
021       public static final char NONE = '\0';
022       private Vector vData;
023       private int iCurIndex;
024    
025       /**
026        * Construct a string list, splitting the data string with the delimiter
027        * character.
028        * @param sData String to be tokenized
029        * @param cDelimiter char Character dividing the data into tokens.
030        */
031       public StringList( String sData, char cDelimiter ) {
032          init( sData, cDelimiter );
033       }
034    
035       /**
036        * Construct a string list, splitting the data string with the delimiter
037        * character.
038        * @param rData Reader to be tokenized
039        * @param cDelimiter char Character dividing the data into tokens.
040        */
041       public StringList( Reader rData, char cDelimiter ) {
042          init( rData, cDelimiter );
043       }
044    
045       /**
046        * Populate this string list, splitting the data string with the delimiter
047        * character.
048        * @param sData String to be tokenized
049        * @param cDelimiter char Character dividing the data into tokens.
050        */
051       public void init( String sData, char cDelimiter ) {
052          StringReader sbR = new StringReader( sData );
053          init( sbR, cDelimiter );
054       }
055    
056       /**
057        * Populate this string list, splitting the data string with the delimiter
058        * character.
059        * @param sData std::string to be tokenized
060        * @param cDelimiter char Character dividing the data into tokens.
061        */
062       public void init( Reader rData, char cDelimiter ) {
063          vData = new Vector();
064          int iNext;
065          char cNext;
066          StringBuffer sb = new StringBuffer();
067          int iBreaker = 0;
068          try {
069             while( (iNext = rData.read()) != -1 )  {
070                cNext = (char)iNext;
071                if( iBreaker++ < 0 ) break;
072                if( cNext == cDelimiter ) {
073                   vData.add( sb.toString() );
074                   sb.setLength(0);
075                }
076                else {
077                   sb.append( cNext );
078                }
079             }
080          } catch( IOException e ) {
081             e.printStackTrace();
082          }
083          if( sb.length() > 0 )
084             vData.add( sb.toString() );
085          iCurIndex = 0;
086       }
087    
088       /**
089        * This is mostly a debugging method.  It converts the string list to
090        * one line per token format.
091        * @return String in one line per token format.
092        */
093       public String toString() {
094          Iterator it = vData.iterator();
095          StringBuffer sb = new StringBuffer();
096          int i = 0;
097          while( it.hasNext() ) {
098             if(i++ >= iCurIndex) {
099                sb.append( (String)it.next() );
100                sb.append( "\n" );
101             }
102             else it.next();
103          }
104          return sb.toString();
105       }
106    
107       /**
108        * Test list for existence of one or more remaining tokens.
109        * @return true if any more strings remain to be returned.
110        */
111       public boolean hasMoreStrings() {
112          return iCurIndex >= 0 && iCurIndex < vData.size();
113       }
114    
115       /**
116        * Get the next string from the list of tokenized strings.
117        * @return next string.
118        */
119       public String nextString() {
120          return (String)vData.elementAt( iCurIndex++ );
121       }
122    
123       /**
124        * Move the pointer back one, having the effect of putting the last
125        * string retrieved back onto the list.
126        * @return true if the pointer could be moved back or false if it was already
127        * at the beginning of the list.
128        */
129       public boolean undoNext() {
130          if( iCurIndex > 0 ) {
131             iCurIndex--;
132             return true;
133          }
134          else {
135             return false;
136          }
137       }
138    
139       /**
140        * Return the number of strings in the tokenized list.
141        * @return integer number of strings.
142        */
143       public int size() {
144          if( vData == null ) return 0;
145          else return vData.size();
146       }
147    
148       /**
149        * Get the current location of the string retrieval pointer as an integer.<br><br>
150        * This can be saved and used later to undo a number of nextString() calls.
151        * The effect is of bookmarking a location.
152        * @return integer position in list.
153        */
154       public int getIndex() { return iCurIndex; }
155    
156       /**
157        * Return the current location pointer to a saved location.
158        * @param iCurIndex int saved from a call to getIndex()
159        */
160       public void setIndex( int iCurIndex ) { this.iCurIndex = iCurIndex; }
161    
162    } // End class StringList
163