1 /* 2 * $Source$ 3 * $Revision$ 4 * 5 * Copyright (C) 2001 William Chesters 6 * 7 * Part of Melati (http://melati.org), a framework for the rapid 8 * development of clean, maintainable web applications. 9 * 10 * Melati is free software; Permission is granted to copy, distribute 11 * and/or modify this software under the terms either: 12 * 13 * a) the GNU General Public License as published by the Free Software 14 * Foundation; either version 2 of the License, or (at your option) 15 * any later version, 16 * 17 * or 18 * 19 * b) any version of the Melati Software License, as published 20 * at http://melati.org 21 * 22 * You should have received a copy of the GNU General Public License and 23 * the Melati Software License along with this program; 24 * if not, write to the Free Software Foundation, Inc., 25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA to obtain the 26 * GNU General Public License and visit http://melati.org to obtain the 27 * Melati Software License. 28 * 29 * Feel free to contact the Developers of Melati (http://melati.org), 30 * if you would like to work out a different arrangement than the options 31 * outlined here. It is our intention to allow Melati to be used by as 32 * wide an audience as possible. 33 * 34 * This program is distributed in the hope that it will be useful, 35 * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 37 * GNU General Public License for more details. 38 * 39 * Contact details for copyright holder: 40 * 41 * William Chesters <williamc At paneris.org> 42 */ 43 package org.melati.util; 44 45 import java.util.Enumeration; 46 import java.util.NoSuchElementException; 47 48 /** 49 * A utility for tokenising a string made up of comma-separated 50 * variables. Unlike Tim's effort, it handles quoted variables as 51 * well. 52 * 53 * <PRE> 54 * foo, bar om,,"baz, ,oof",xyz, -< 55 * "foo", " bar om", "", "baz, , oof", "xyz", "" 56 * </PRE> 57 * 58 * @author williamc AT paneris.org 59 */ 60 61 public class CSVStringEnumeration implements Enumeration<String> { 62 63 private String line = ""; 64 private boolean emptyLastField = false; 65 int p = 0; 66 67 /** 68 * Look at a new string. 69 */ 70 public void reset(String lineP) { 71 this.line = lineP; 72 p = 0; 73 } 74 75 /** 76 * Are there any more tokens to come? 77 * {@inheritDoc} 78 * @see java.util.Enumeration#hasMoreElements() 79 */ 80 public boolean hasMoreElements() { 81 return emptyLastField || p < line.length(); 82 } 83 84 /** 85 * Return the next token as an <TT>Object</TT>. 86 * {@inheritDoc} 87 * @see java.util.Enumeration#nextElement() 88 */ 89 public final String nextElement() { 90 return nextToken(); 91 } 92 93 /** 94 * @return the next token as a <TT>String</TT>. 95 */ 96 public String nextToken() { 97 98 if (emptyLastField) { 99 emptyLastField = false; 100 return ""; 101 } 102 103 if (p >= line.length()) throw new NoSuchElementException(); 104 105 if (line.charAt(p) == '"') { 106 ++p; 107 // we need to allow for quotes inside quoted fields, so now test for ", 108 int q = line.indexOf("\",", p); 109 // if it is not there, we are (hopefully) at the end of a line 110 if (q == -1 && (line.indexOf('"', p) == line.length()-1)) 111 q = line.length()-1; 112 113 if (q == -1) { 114 p = line.length(); 115 throw new IllegalArgumentException("Unclosed quotes"); 116 } 117 118 String it = line.substring(p, q); 119 120 ++q; 121 p = q+1; 122 if (q < line.length()) { 123 if (line.charAt(q) != ',') { 124 p = line.length(); 125 throw new IllegalArgumentException("No comma after quotes"); 126 } 127 else if (q == line.length() - 1) 128 emptyLastField = true; 129 } 130 return it; 131 } else { 132 int q = line.indexOf(',', p); 133 if (q == -1) { 134 String it = line.substring(p); 135 p = line.length(); 136 return it; 137 } else { 138 String it = line.substring(p, q); 139 if (q == line.length() - 1) 140 emptyLastField = true; 141 p = q + 1; 142 return it; 143 } 144 } 145 } 146 147 }