package org.radargun.utils; import java.util.Enumeration; import java.util.NoSuchElementException; /** * Tokenizer that allows string delims instead of char delims * * @author Radim Vansa <rvansa@redhat.com> */ public class Tokenizer implements Enumeration<String> { private String string; private String[] delims; private int pos = 0; private int nextDelimPos = -1; private String nextDelim; private boolean returnDelims; private boolean nextIsDelim = false; private boolean returnEmpty = false; public Tokenizer(String string, String[] delims) { this(string, delims, false, false, -1); } /** * Return delims and return empty cannot be true both as it wouldn't make sense to return empty string between * two consecutive delimiters. * * @param string * @param delims * @param returnDelims * @param returnEmpty */ public Tokenizer(String string, String[] delims, boolean returnDelims, boolean returnEmpty, int startIndex) { this.string = string; if (startIndex >= 0) { pos = startIndex; } if (string.isEmpty() && !returnEmpty) { pos = -1; } this.delims = delims; if (returnDelims && returnEmpty) { throw new IllegalArgumentException(); } this.returnDelims = returnDelims; this.returnEmpty = returnEmpty; findNextDelim(); if (nextDelimPos == pos) { nextIsDelim = true; pos += nextDelim.length(); if (pos >= string.length()) { pos = -1; } } } private void findNextDelim() { nextDelimPos = -1; nextDelim = null; for (String delim : delims) { int next = string.indexOf(delim, pos); if (next < 0) continue; if (nextDelimPos < 0 || next < nextDelimPos || (next == nextDelimPos && nextDelim.length() < delim.length())) { nextDelimPos = next; nextDelim = delim; } } } @Override public boolean hasMoreElements() { return hasMoreTokens(); } public boolean hasMoreTokens() { return (nextIsDelim && returnDelims) || pos >= 0; } @Override public String nextElement() { return nextToken(); } public String nextToken() { if (returnDelims && nextIsDelim) { nextIsDelim = false; String delim = nextDelim; if (pos >= 0) { findNextDelim(); if (nextDelimPos == pos) { nextIsDelim = true; pos += nextDelim.length(); if (pos >= string.length()) { pos = -1; } } } return delim; } if (pos < 0) { throw new NoSuchElementException(); } String token; if (nextDelimPos >= 0) { token = string.substring(pos, nextDelimPos); pos = nextDelimPos + nextDelim.length(); if (returnDelims) { nextIsDelim = true; } else { for (; ; ) { findNextDelim(); if (returnEmpty) { break; } if (nextDelimPos == pos) { pos += nextDelim.length(); } else { break; } } } if (pos >= string.length()) { pos = -1; } } else { token = string.substring(pos); pos = -1; } return token; } /* After calling nextToken it returns the position just after this token */ public int getPosition() { if (pos < 0) return string.length(); return pos; } }