1 /*
2 * CsvJdbc - a JDBC driver for CSV files
3 * Copyright (C) 2001 Jonathan Ackerman
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17 package org.relique.jdbc.csv;
18
19 import java.io.*;
20 import java.util.*;
21 import java.sql.SQLException;
22
23 /***
24 * This class is a helper class that handles the reading and parsing of data
25 * from a .csv file.
26 *
27 * @author Jonathan Ackerman
28 * @author Sander Brienen
29 * @author Stuart Mottram (fritto)
30 * @author Jason Bedell
31 * @author Tomasz Skutnik
32 * @created 25 November 2001
33 * @version $Id: CsvReader.html,v 1.1 2003/05/12 16:19:47 sinisa Exp $
34 */
35
36 public class CsvReader
37 {
38 private BufferedReader input;
39 private String[] columnNames;
40 private String[] columns;
41 private java.lang.String buf = null;
42 private char separator = ',';
43 private boolean suppressHeaders = false;
44 private String tableName;
45 private String fileName;
46 private String charset = null;
47
48
49 /***
50 *Constructor for the CsvReader object
51 *
52 * @param fileName Description of Parameter
53 * @exception Exception Description of Exception
54 * @since
55 */
56 public CsvReader(String fileName) throws Exception
57 {
58 this(fileName, ',', false,null);
59 }
60
61
62 /***
63 * Insert the method's description here.
64 *
65 * Creation date: (6-11-2001 15:02:42)
66 *
67 * @param fileName java.lang.String
68 * @param separator char
69 * @param suppressHeaders boolean
70 * @exception java.lang.Exception The exception description.
71 * @since
72 */
73 public CsvReader(String fileName, char separator, boolean suppressHeaders, String charset)
74 throws java.lang.Exception
75 {
76 this.separator = separator;
77 this.suppressHeaders = suppressHeaders;
78 this.fileName = fileName;
79 this.charset = charset;
80
81 if (charset != null) {
82 input = new BufferedReader(new InputStreamReader(new FileInputStream(fileName),charset));
83 } else {
84 input = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)));
85 }
86 // input = new BufferedReader(new FileReader(fileName));
87 if (this.suppressHeaders)
88 {
89 // No column names available. Read first data line and determine number of colums.
90 buf = input.readLine();
91 String[] data = parseCsvLine(buf);
92 columnNames = new String[data.length];
93 for (int i = 0; i < data.length; i++)
94 {
95 columnNames[i] = "COLUMN" + String.valueOf(i+1);
96 }
97 data = null;
98 // throw away.
99 }
100 else
101 {
102 String headerLine = input.readLine();
103 columnNames = parseCsvLine(headerLine);
104 }
105 }
106
107
108 /***
109 *Gets the columnNames attribute of the CsvReader object
110 *
111 * @return The columnNames value
112 * @since
113 */
114 public String[] getColumnNames()
115 {
116 return columnNames;
117 }
118
119
120 public String getTableName() {
121 if(tableName != null)
122 return tableName;
123
124 int lastSlash = 0;
125 for(int i = fileName.length()-1; i >= 0; i--)
126 if(fileName.charAt(i) == '/' || fileName.charAt(i) == '//') {
127 lastSlash = i;
128 break;
129 }
130 tableName = fileName.substring(lastSlash+1, fileName.length() - 4);
131 return tableName;
132 }
133
134 /***
135 * Get the value of the column at the specified index.
136 *
137 * @param columnIndex Description of Parameter
138 * @return The column value
139 * @since
140 */
141
142 public String getColumn(int columnIndex) throws SQLException
143 {
144 if (columnIndex >= columns.length)
145 {
146 return null;
147 }
148 return columns[columnIndex];
149 }
150
151 /***
152 * Get value from column at specified name.
153 * If the column name is not found, throw an error.
154 *
155 * @param columnName Description of Parameter
156 * @return The column value
157 * @exception SQLException Description of Exception
158 * @since
159 */
160
161 public String getColumn(String columnName) throws SQLException
162 {
163 for (int loop = 0; loop < columnNames.length; loop++)
164 {
165 if (columnName.equalsIgnoreCase(columnNames[loop]) || columnName.equalsIgnoreCase(getTableName() + "." + columnNames[loop]))
166 {
167 return getColumn(loop);
168 }
169 }
170 throw new SQLException("Column '" + columnName + "' not found.");
171 }
172
173
174 /***
175 *Description of the Method
176 *
177 * @return Description of the Returned Value
178 * @exception SQLException Description of Exception
179 * @since
180 */
181 public boolean next() throws SQLException {
182 columns = new String[columnNames.length];
183 String dataLine = null;
184 try {
185 if (suppressHeaders && (buf != null)) {
186 // The buffer is not empty yet, so use this first.
187 dataLine = buf;
188 buf = null;
189 } else {
190 // read new line of data from input.
191 dataLine = input.readLine();
192 }
193 if (dataLine == null) {
194 input.close();
195 return false;
196 }
197 } catch (IOException e) {
198 throw new SQLException(e.toString());
199 }
200 columns = parseCsvLine(dataLine);
201 return true;
202 }
203
204
205 /***
206 *Description of the Method
207 *
208 * @since
209 */
210 public void close()
211 {
212 try
213 {
214 input.close();
215 buf = null;
216 }
217 catch (Exception e)
218 {
219 }
220 }
221
222
223 // This code updated with code by Stuart Mottram to handle line breaks in fields
224 // see bug #492063
225 protected String[] parseCsvLine(String line) throws SQLException
226 {
227 Vector values = new Vector();
228 boolean inQuotedString = false;
229 String value = "";
230 String orgLine = line;
231 int currentPos = 0;
232 int fullLine = 0;
233
234 while (fullLine == 0){
235 currentPos = 0;
236 line += separator;
237 while (currentPos < line.length())
238 {
239 char currentChar = line.charAt(currentPos);
240 if (value.length() == 0 && currentChar == '"' && !inQuotedString)
241 {
242 currentPos++;
243 inQuotedString = true;
244 continue;
245 }
246 if (currentChar == '"')
247 {
248 char nextChar = line.charAt(currentPos + 1);
249 if (nextChar == '"')
250 {
251 value += currentChar;
252 currentPos++;
253 }
254 else
255 {
256 if (!inQuotedString)
257 {
258 throw new SQLException("Unexpected '\"' in position " + currentPos + ". Line=" + orgLine);
259 }
260 if (inQuotedString && nextChar != separator)
261 {
262 throw new SQLException("Expecting " + separator + " in position " + (currentPos + 1) + ". Line=" + orgLine);
263 }
264 values.add(value);
265 value = "";
266 inQuotedString = false;
267 currentPos++;
268 }
269 }
270 else
271 {
272 if (currentChar == separator)
273 {
274 if (inQuotedString)
275 {
276 value += currentChar;
277 }
278 else
279 {
280 values.add(value);
281 value = "";
282 }
283 }
284 else
285 {
286 value += currentChar;
287 }
288 }
289 currentPos++;
290 }
291 if (inQuotedString){
292 // Remove extra , added at start
293 value = value.substring(0,value.length()-1);
294 try {
295 line = input.readLine();
296 } catch (IOException e) {
297 throw new SQLException(e.toString());
298 }
299 } else {
300 fullLine = 1;
301 }
302
303 }
304 String[] retVal = new String[values.size()];
305 values.copyInto(retVal);
306 return retVal;
307 }
308 }
309
This page automatically generated by Maven