package net.sf.jabref.util; /** * A String tokenizer that works just like StringTokenizer, but considers quoted * characters (which do not act as delimiters). */ public class QuotedStringTokenizer { private final String m_content; private final int m_contentLength; private final String m_delimiters; private final char m_quoteChar; private int m_index = 0; /** * @param content * The String to be tokenized. * @param delimiters * The delimiter characters. * @param quoteCharacter * The quoting character. Every character (including, but not * limited to, delimiters) that is preceded by this character is * not treated as a delimiter, but as a token component. */ public QuotedStringTokenizer(String content, String delimiters, char quoteCharacter) { m_content = content; m_delimiters = delimiters; m_quoteChar = quoteCharacter; m_contentLength = m_content.length(); // skip leading delimiters while (isDelimiter(m_content.charAt(m_index)) && m_index < m_contentLength) ++m_index; } public String nextToken() { char c; StringBuffer sb = new StringBuffer(); while (m_index < m_contentLength) { c = m_content.charAt(m_index); if (c == m_quoteChar) { // next is quoted ++m_index; if (m_index < m_contentLength) // sanity check sb.append(m_content.charAt(m_index)); // ignore for delimiter search! } else if (isDelimiter(c)) { // unit finished // advance index until next token or end do { ++m_index; } while (m_index < m_contentLength && isDelimiter(m_content.charAt(m_index))); return sb.toString(); } sb.append(c); ++m_index; } return sb.toString(); } private boolean isDelimiter(char c) { return m_delimiters.indexOf(c) >= 0; } public boolean hasMoreTokens() { return m_index < m_contentLength; } }