1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 package org.melati.poem.csv;
56
57 import java.io.BufferedReader;
58 import java.io.File;
59 import java.io.FileReader;
60 import java.io.IOException;
61 import java.io.Writer;
62 import java.util.Enumeration;
63 import java.util.Hashtable;
64 import java.util.NoSuchElementException;
65 import java.util.Vector;
66
67 import org.melati.poem.Persistent;
68 import org.melati.poem.Table;
69
70
71
72
73 public class CSVTable {
74
75 protected Table<?> table = null;
76 protected File data = null;
77 protected Hashtable<String,CSVColumn> columns = new Hashtable<String,CSVColumn>();
78 protected Vector<CSVColumn> columnsInUploadOrder = new Vector<CSVColumn>();
79 protected CSVColumn primaryKey = null;
80 protected Vector<CSVRecord> records = new Vector<CSVRecord>();
81 protected BufferedReader reader = null;
82 protected CSVFileParser parser = null;
83
84
85 private int lineNo;
86
87
88 private int recordNo;
89
90
91
92
93
94
95
96
97 public CSVTable(Table<?> table, File data) {
98 this.table = table;
99 this.data = data;
100 try {
101 reader = new BufferedReader(new FileReader(this.data));
102 parser = new CSVFileParser(this.reader);
103 } catch (Exception e) {
104 throw new RuntimeException(e);
105 }
106 }
107
108
109
110
111
112
113
114
115
116 public void define() throws IOException {
117 parser.nextRecord();
118 lineNo = 1;
119 recordNo = 0;
120
121 while (parser.recordHasMoreFields()) {
122 String key = parser.nextField();
123 CSVColumn col = columns.get(key);
124 if (col == null)
125 throw new CSVParseException(
126 "I don't know what to do with the column in " + data.getPath() +
127 " called " + key);
128 columnsInUploadOrder.addElement(col);
129 }
130 }
131
132
133
134
135 public void addColumn(String csvName, String poemName) {
136 columns.put(csvName, new CSVColumn(poemName));
137 }
138
139
140
141
142 public void addColumn(String csvName, String poemName, boolean isPrimaryKey)
143 throws CSVPrimaryKeyColumnAlreadySetException {
144 if (isPrimaryKey && primaryKey != null)
145 throw new CSVPrimaryKeyColumnAlreadySetException(table.getName());
146 CSVColumn col = new CSVColumn(poemName, isPrimaryKey);
147 columns.put(csvName, col);
148 if (isPrimaryKey)
149 primaryKey = col;
150 }
151
152
153
154
155 public void addColumn(String csvName,
156 String foreignPoemName, CSVTable foreignTable) {
157 columns.put(csvName, new CSVColumn(foreignPoemName, foreignTable));
158 }
159
160
161
162
163
164
165
166
167
168
169
170 public void load(boolean writeOnFly)
171 throws IOException, CSVParseException, NoPrimaryKeyInCSVTableException,
172 CSVWriteDownException {
173
174 try {
175 define();
176
177 CSVRecord record;
178 while(null != (record = parseRecord())) {
179 record.setLineNo(lineNo++);
180 record.setRecordNo(recordNo++);
181 if (writeOnFly)
182 record.makePersistent();
183 else
184 records.addElement(record);
185 }
186
187 }
188 catch (IllegalArgumentException e) {
189 throw new CSVParseException("Failed to load field in " +
190 data.getPath() +
191 " line " + lineNo +
192 ": " + e.toString());
193 }
194 catch (NoSuchElementException f) {
195 throw new CSVParseException("Failed to read column header in " +
196 data.getPath() +
197 " line " + lineNo +
198 ": " + f.toString());
199 }
200 finally {
201 reader.close();
202 }
203 }
204
205
206
207
208
209
210
211
212
213
214
215 public CSVRecord parseRecord() throws IOException, CSVParseException {
216 if (!parser.nextRecord())
217 return null;
218
219 int i = 0;
220 String value = null;
221 try {
222 CSVRecord record = new CSVRecord(table);
223 for (; i < columnsInUploadOrder.size(); i++) {
224 value = parser.nextField();
225 CSVColumn col = (CSVColumn)columnsInUploadOrder.elementAt(i);
226 record.addField(new CSVField(col, value));
227 }
228 record.setLineNo(parser.getLineNo());
229 return record;
230 }
231 catch (IllegalArgumentException e) {
232 throw new CSVParseException("Failed to read data field no. " +
233 (i+1) +
234 " in " +
235 data +
236 " line " + lineNo +
237 ": " + e.toString());
238 }
239 catch (NoSuchElementException f) {
240 String message = "Problem with data field no. " + (i+1) +
241 " of " + columnsInUploadOrder.size() +
242 " in " + data +
243 " line " + lineNo;
244
245 if (value == null) {
246 message += " (Check last line of file) : " +
247 f.toString();
248 } else {
249 message += ", Value:" + value + ": " + f.toString();
250 }
251 throw new CSVParseException(message);
252 }
253 }
254
255
256
257
258
259 public void emptyTable() {
260 Enumeration<?> rows = table.selection();
261 while(rows.hasMoreElements()) {
262 Persistent p = (Persistent)rows.nextElement();
263 p.delete();
264 }
265 }
266
267
268
269
270
271 public void writeRecords()
272 throws NoPrimaryKeyInCSVTableException, CSVWriteDownException {
273 for (int i = 0; i < records.size(); i++) {
274 ((CSVRecord)records.elementAt(i)).makePersistent();
275 }
276 }
277
278
279
280
281
282
283
284
285 protected Persistent getRecordWithID(String csvValue)
286 throws NoPrimaryKeyInCSVTableException, CSVWriteDownException {
287 if (primaryKey == null)
288 throw new NoPrimaryKeyInCSVTableException(table.getName(), csvValue);
289
290 for (int i = 0; i < records.size(); i++) {
291 CSVRecord record = (CSVRecord)records.elementAt(i);
292 if (record.primaryKeyValue != null &&
293 record.primaryKeyValue.equals(csvValue))
294 return record.getPersistent();
295 }
296 return null;
297 }
298
299
300
301
302 public void report(boolean recordDetails, boolean fieldDetails,
303 Writer output) throws IOException {
304
305 output.write("*** TABLE: " + table.getName().toUpperCase() + " **\n\n");
306 output.write("** I have read " + records.size() + " records of " +
307 columnsInUploadOrder.size() + " fields\n");
308
309 if (recordDetails) {
310 for (int i = 0; i < records.size(); i++) {
311 CSVRecord record = (CSVRecord)records.elementAt(i);
312 output.write(" Record: CSV primary key = " +
313 record.primaryKeyValue);
314
315 if (record.poemRecord == null)
316 output.write(", No Poem Persistent written\n");
317 else
318 output.write(", Poem Troid = " + record.poemRecord.getTroid() + "\n");
319
320 if (fieldDetails) {
321 for (int j = 0; j < record.getFields().size(); j++) {
322 CSVField field = (CSVField)record.getFields().elementAt(j);
323 output.write(field.column + "=\"" + field.value);
324 if (j < record.getFields().size()-1)
325 output.write("\",");
326 else
327 output.write("\"\n");
328 }
329 }
330 }
331 }
332 output.write("** Currently " + table.count(null) +
333 " Persistents in this table\n\n");
334 }
335
336
337
338
339
340
341 public String getName() {
342 return table.getName();
343 }
344 }
345