001 /* 002 * Copyright (c) Holger Pfaff - http://pfaff.ws 003 * 004 * This software maybe used for any purpose provided the 005 * above copyright notice is retained. It is supplied as is. 006 * No warranty expressed or implied - Use at your own risk. 007 */ 008 009 import java.util.Enumeration; 010 import java.util.Vector; 011 012 /** 013 * (#)StringSplitter.java 014 * @author Holger Pfaff 015 * @version 016 * Behaves much like StringTokenizer except that <code>delimiter</code> 017 * is used as whole as a delimiter instead of single delim characters, 018 * and the 'null space' between two delimiters is honored by default e.g: 019 * 020 * <code>delimiter</code> = "@-@" 021 * <code>string</code> = "one@-@@-@two@-@three@four-five@-@" 022 * 023 * StringTokenizer -> "one" "two" "three" "four" "five" 024 * StringSplitter -> "one" "" "two" "three@four-five" "" or 025 * StringSplitter -> "one" "two" "three@four-five" 026 * 027 */ 028 029 public class StringSplitter implements Enumeration { 030 031 /** 032 * pointer into string 033 */ 034 private int curpos = 0; 035 036 /** 037 * handle strings with zero length between to delims as separate tokens ? 038 */ 039 private boolean splitNull; 040 041 /** 042 * the string to work on 043 */ 044 private String string; 045 046 /** 047 * the delimiter to use 048 */ 049 private String delimiter; 050 051 /** 052 * length of origin string 053 */ 054 private int stringlen; 055 056 /** 057 * length of delimiter 058 */ 059 private int delimiterlen; 060 061 /** 062 * Construct a new StringSplitter. <code>null</code> strings will 063 * be handled as empty ones. 064 * 065 * @param string string to split. 066 * @param delimiter string to use as delimiter. 067 * 068 */ 069 public StringSplitter(String string, String delimiter) { 070 this(string, delimiter, true); 071 } 072 073 /** 074 * Construct a new StringSplitter. <code>null</code> strings will 075 * be handled as empty ones. 076 * 077 * @param string string to split. 078 * @param delimiter string to use as delimiter. 079 * @param splitNull handle strings with zero length between to delims as separate tokens?. 080 */ 081 public StringSplitter(String string, String delimiter, boolean splitNull) { 082 this.string = string == null ? new String("") : string; 083 this.stringlen = this.string.length(); 084 this.delimiter = delimiter == null ? new String(" ") : delimiter; 085 this.delimiterlen = this.delimiter.length(); 086 this.splitNull = splitNull; 087 } 088 089 /** 090 * Tests if there are more tokens/splitter available from this string. 091 */ 092 public boolean hasMoreTokens() { 093 return hasMoreTokens(curpos); 094 } 095 096 /** 097 * Tests if there are more tokens/splitter available from this string. 098 * 099 * @param pos position to start from. 100 */ 101 public boolean hasMoreTokens(int pos) { 102 return getNextPosition(pos) == -1 ? false : true; 103 } 104 105 /** 106 * Return index of next position within string. return -1 for none 107 * 108 * @param pos position to start from. 109 */ 110 public int getNextPosition(int pos) { 111 return getNextPosition(pos, false); 112 } 113 114 /** 115 * Return index of next position within string. return -1 for none 116 * 117 * @param pos position to start from. 118 * @param modcurpos should the curpos var be modified ? 119 */ 120 private int getNextPosition(int pos, boolean modcurpos) { 121 if(stringlen == 0 || pos > stringlen) { 122 return -1; 123 } else { 124 if(delimiterlen == 0) { 125 return pos == 0 ? stringlen : -1; 126 } else { 127 int end = string.indexOf(delimiter, pos); 128 if(end == -1) end = stringlen; 129 if(end == pos && splitNull == false) { 130 if(modcurpos) curpos += delimiterlen; 131 return getNextPosition(end + delimiterlen); // skip empty token 132 } else { 133 return end; 134 } 135 } 136 } 137 } 138 139 /** 140 * Returns the next token available from this string or null 141 */ 142 public String nextToken() { 143 int beg, end = getNextPosition(curpos, true); 144 if(end == -1) { 145 return null; 146 } else { 147 beg = curpos; curpos = end + delimiterlen; 148 return string.substring(beg, end); 149 } 150 } 151 152 /** 153 * Returns the remaining String of this string or null 154 */ 155 public String remainingString() { 156 return getNextPosition(curpos, false) == -1 ? null : string.substring(curpos); 157 } 158 159 /** 160 * Same as hasMoreTokens(). Implements Enumeration interface. 161 */ 162 public boolean hasMoreElements() { 163 return hasMoreTokens(); 164 } 165 166 /** 167 * Same as nextToken(). Implements Enumeration interface. 168 */ 169 public Object nextElement() { 170 return nextToken(); 171 } 172 173 /** 174 * Utility method to convert this splitter to a String array. 175 * Requires Util.class 176 */ 177 public String[] toArray() { 178 curpos = 0; return Util.enum2Array(this); 179 } 180 181 /** 182 * Utility method to convert this splitter to a Vector of Strings. 183 * Requires Util.class 184 */ 185 public Vector toVector() { 186 curpos = 0; return Util.enum2Vector(this); 187 } 188 189 /** 190 * Utility method to convert this splitter to a new String using 191 * <code>delimiter</code> as separator. 192 * Requires Util.class 193 * 194 * @param delimiter string to use as separator. 195 */ 196 public String toString(String delimiter) { 197 curpos = 0; return Util.enum2String(this, delimiter); 198 } 199 };