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 * @created 25 November 2001
32 * @version $Id: CsvWriter.html,v 1.1 2003/05/12 16:19:47 sinisa Exp $
33 */
34
35 public class CsvWriter
36 {
37 private RandomAccessFile input;
38 private RandomAccessFile output;
39 private String[] columnNames;
40 private String[] columns;
41 private java.lang.String buf = null;
42 private char separator = ',';
43 private String tableName;
44 private String fileName;
45 private int counter;
46 private long current;
47 private long endLine;
48
49
50 /***
51 *Constructor for the CsvReader object
52 *
53 * @param fileName Description of Parameter
54 * @exception Exception Description of Exception
55 * @since
56 */
57 public CsvWriter(String fileName) throws Exception
58 {
59 this(fileName, ',');
60 }
61
62
63 /***
64 * Insert the method's description here.
65 *
66 * Creation date: (6-11-2001 15:02:42)
67 *
68 * @param fileName java.lang.String
69 * @param separator char
70 * @exception java.lang.Exception The exception description.
71 * @since
72 */
73 public CsvWriter(String fileName, char separator)
74 throws java.lang.Exception
75 {
76 this.separator = separator;
77 this.fileName = fileName;
78
79 this.input = new RandomAccessFile(fileName,"rw");
80 String headerLine = this.input.readLine();
81 columnNames = parseCsvLine(headerLine);
82 counter = 1;
83 current = 0;
84 endLine=0;
85 }
86
87
88 /***
89 *Gets the columnNames attribute of the CsvReader object
90 *
91 * @return The columnNames value
92 * @since
93 */
94 public String[] getColumnNames()
95 {
96 return columnNames;
97 }
98
99
100 public String getTableName() {
101 if(tableName != null)
102 return tableName;
103
104 int lastSlash = 0;
105 for(int i = fileName.length()-1; i >= 0; i--)
106 if(fileName.charAt(i) == '/' || fileName.charAt(i) == '//') {
107 lastSlash = i;
108 break;
109 }
110 tableName = fileName.substring(lastSlash+1, fileName.length() - 4);
111 return tableName;
112 }
113
114 /***
115 * Get the value of the column at the specified index.
116 *
117 * @param columnIndex Description of Parameter
118 * @return The column value
119 * @since
120 */
121
122 public String getColumn(int columnIndex)
123 {
124 return columns[columnIndex];
125 }
126
127 /***
128 * Get value from column at specified name.
129 * If the column name is not found, throw an error.
130 *
131 * @param columnName Description of Parameter
132 * @return The column value
133 * @exception SQLException Description of Exception
134 * @since
135 */
136
137 public String getColumn(String columnName) throws SQLException
138 {
139 for (int loop = 0; loop < columnNames.length; loop++)
140 {
141 if (columnName.equalsIgnoreCase(columnNames[loop]) || columnName.equalsIgnoreCase(getTableName() + "." + columnNames[loop]))
142 {
143 return getColumn(loop);
144 }
145 }
146 throw new SQLException("Column '" + columnName + "' not found.");
147 }
148
149
150 /***
151 *Description of the Method
152 *
153 * @return Description of the Returned Value
154 * @exception SQLException Description of Exception
155 * @since
156 */
157 public boolean next() throws SQLException, IOException {
158 columns = new String[columnNames.length];
159 String dataLine = null;
160 current = input.getFilePointer();
161
162 try {
163 if (buf != null) {
164 // The buffer is not empty yet, so use this first.
165 dataLine = buf;
166 buf = null;
167 } else {
168 // read new line of data from input.
169 dataLine = this.input.readLine();
170 }
171 if (dataLine == null) {
172 this.input.close();
173 return false;
174 }
175 } catch (IOException e) {
176 throw new SQLException(e.toString());
177 }
178 columns = parseCsvLine(dataLine);
179 endLine = input.getFilePointer();
180 return true;
181 }
182
183
184 /***
185 *Description of the Method
186 *
187 * @since
188 */
189 public void close()
190 {
191 try
192 {
193 this.input.close();
194 buf = null;
195 }
196 catch (Exception e)
197 {
198 }
199 }
200
201
202 // This code updated with code by Stuart Mottram to handle line breaks in fields
203 // see bug #492063
204 protected String[] parseCsvLine(String line) throws SQLException
205 {
206 Vector values = new Vector();
207 boolean inQuotedString = false;
208 String value = "";
209 String orgLine = line;
210 int currentPos = 0;
211 int fullLine = 0;
212
213 while (fullLine == 0){
214 currentPos = 0;
215 line += separator;
216 while (currentPos < line.length())
217 {
218 char currentChar = line.charAt(currentPos);
219 if (value.length() == 0 && currentChar == '"' && !inQuotedString)
220 {
221 currentPos++;
222 inQuotedString = true;
223 continue;
224 }
225 if (currentChar == '"')
226 {
227 char nextChar = line.charAt(currentPos + 1);
228 if (nextChar == '"')
229 {
230 value += currentChar;
231 currentPos++;
232 }
233 else
234 {
235 if (!inQuotedString)
236 {
237 throw new SQLException("Unexpected '\"' in position " + currentPos + ". Line=" + orgLine);
238 }
239 if (inQuotedString && nextChar != separator)
240 {
241 throw new SQLException("Expecting " + separator + " in position " + (currentPos + 1) + ". Line=" + orgLine);
242 }
243 values.add(value);
244 value = "";
245 inQuotedString = false;
246 currentPos++;
247 }
248 }
249 else
250 {
251 if (currentChar == separator)
252 {
253 if (inQuotedString)
254 {
255 value += currentChar;
256 }
257 else
258 {
259 values.add(value);
260 value = "";
261 }
262 }
263 else
264 {
265 value += currentChar;
266 }
267 }
268 currentPos++;
269 }
270 if (inQuotedString){
271 // Remove extra , added at start
272 value = value.substring(0,value.length()-1);
273 try {
274 line = this.input.readLine();
275 } catch (IOException e) {
276 throw new SQLException(e.toString());
277 }
278 } else {
279 fullLine = 1;
280 }
281
282 }
283 String[] retVal = new String[values.size()];
284 values.copyInto(retVal);
285 return retVal;
286 }
287
288 protected boolean newLine(String[] colNames, String[] colValues) throws IOException {
289 String newLine="";
290 for(int i=0;i<columnNames.length; i++) {
291 boolean find = false;
292 for(int j=0;j<colNames.length; j++) {
293 if(colNames[j].equalsIgnoreCase(columnNames[i])) {
294 if(colValues[j]==null || colValues[j].equals("null"))
295 newLine=newLine+",";
296 else {
297 if(colValues[j].indexOf("'")!=-1)
298 colValues[j]=colValues[j].trim().substring(1,colValues[j].trim().length()-1);
299 newLine=newLine+"\""+colValues[j]+"\""+",";
300 }
301 find = true;
302 }
303 }
304 if(!find)
305 newLine=newLine+",";
306 }
307 if(!newLine.equals(""))
308 newLine=newLine.substring(0,newLine.length()-1);
309
310 RandomAccessFile raf = new RandomAccessFile(this.fileName,"rw");
311 long l = raf.length();
312 raf.seek(l);
313 raf.writeBytes("\n"+newLine);
314 raf.close();
315
316 return true;
317 }
318
319 protected boolean createTable(String[] colNames, String table) throws IOException {
320 String newLine="";
321 for(int i=0;i<colNames.length; i++) {
322 newLine=newLine+"\""+colNames[i]+"\",";
323 }
324 if(!newLine.equals(""))
325 newLine=newLine.substring(0,newLine.length()-1);
326
327 String fileName = tableName;
328
329 RandomAccessFile raf = new RandomAccessFile(this.fileName,"rw");
330 raf.writeBytes(newLine);
331 raf.close();
332
333 return true;
334 }
335
336
337 protected boolean updateField(String[] colNames, String[] colValues, String[] colWhereNames, String[] colWhereValues) throws IOException, SQLException {
338 while(next()) {
339 counter++;
340 boolean find = false;
341 out:
342 for(int i=0; i<colWhereNames.length; i++) {
343 if(colWhereValues[i]!=null) {
344 if(colWhereValues[i].indexOf("'")!=-1)
345 colWhereValues[i]=colWhereValues[i].trim().substring(1,colWhereValues[i].trim().length()-1);
346 }
347 if(!getColumn(colWhereNames[i]).equals(colWhereValues[i]))
348 break out;
349 if(i==(colWhereNames.length-1))
350 find = true;
351 }
352
353 if(find) {
354 for(int i=0; i< columnNames.length; i++) {
355 for(int j=0; j<colNames.length; j++) {
356 if(colNames[j].equalsIgnoreCase(columnNames[i]))
357 columns[i]=colValues[j];
358 }
359 }
360 String updatedLine = "";
361 for(int i=0; i<columns.length; i++) {
362 if(columns[i]==null || columns[i].equalsIgnoreCase("null")|| columns[i].equals(""))
363 updatedLine=updatedLine+",";
364 else {
365 if((columns[i].indexOf("'")!=-1) ||(columns[i].indexOf("\"")!=-1))
366 columns[i]=columns[i].trim().substring(1,columns[i].trim().length()-1);
367 updatedLine=updatedLine+"\""+columns[i]+"\""+",";
368 }
369
370 }
371 if(!updatedLine.equals("")) {
372 input.seek(endLine);
373 String line="";
374 String newLine="";
375
376 while((newLine=input.readLine())!=null){
377 line+=newLine+"\n";
378 }
379 if(line!=null) {
380 if(!line.equals(""))
381 line=line.substring(0,line.length()-1);
382 }
383 updatedLine=updatedLine.substring(0,updatedLine.length()-1);
384 input.seek(current);
385 input.writeBytes(updatedLine);
386 if(input.getFilePointer()!=input.length()) {
387 // input.seek(endLine+1);
388 input.writeBytes("\n");
389 if(line!=null){
390 if(!line.equals(""))
391 input.writeBytes(line);
392 input.setLength(input.getFilePointer());
393 }
394 // input.seek(endLine);
395 }
396 //input.seek(endLine+1);
397 // input.close();
398 }
399 }
400 }
401 return true;
402 }
403
404 }
405
This page automatically generated by Maven