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 package net.sf.flatpack;
34
35 import java.math.BigDecimal;
36 import java.text.ParseException;
37 import java.text.SimpleDateFormat;
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.Date;
41 import java.util.Iterator;
42 import java.util.List;
43 import java.util.Locale;
44 import java.util.Properties;
45
46 import net.sf.flatpack.ordering.OrderBy;
47 import net.sf.flatpack.structure.ColumnMetaData;
48 import net.sf.flatpack.structure.Row;
49 import net.sf.flatpack.util.FPConstants;
50 import net.sf.flatpack.util.FPException;
51 import net.sf.flatpack.util.FPInvalidUsageException;
52 import net.sf.flatpack.util.FPStringUtils;
53 import net.sf.flatpack.util.ParserUtils;
54 import net.sf.flatpack.xml.MetaData;
55
56 /**
57 * @author Benoit Xhenseval
58 * @author Paul Zepernick
59 *
60 */
61 public class DefaultDataSet implements DataSet {
62 private final List rows = new ArrayList();
63
64 private final List errors = new ArrayList();
65
66 private Properties pzConvertProps = null;
67
68 /** Pointer for the current row in the array we are on */
69 private int pointer = -1;
70
71 /** flag to indicate if data should be pulled as lower case */
72 private boolean lowerCase = false;
73
74 /** flag to inidicate if data should be pulled as upper case */
75 private boolean upperCase = false;
76
77 /**
78 * flag to indicate if a strict parse should be used when getting doubles
79 * and ints
80 */
81 private boolean strictNumericParse = false;
82
83 private MetaData metaData;
84
85 private Parser parser;
86
87 public DefaultDataSet(final MetaData pzMetaData, final Parser pzparser) {
88 this.metaData = pzMetaData;
89 this.parser = pzparser;
90 }
91
92 public void addRow(final Row row) {
93 rows.add(row);
94 }
95
96 public void addError(final DataError dataError) {
97 errors.add(dataError);
98 }
99
100
101
102
103
104
105 public String[] getColumns() {
106 ColumnMetaData column = null;
107 String[] array = null;
108
109 if (
110 final List cmds = metaData.getColumnsNames();
111
112 array = new String[cmds.size()];
113 for (int i = 0; i < cmds.size(); i++) {
114 column = (ColumnMetaData) cmds.get(i);
115 array[i] = column.getColName();
116 }
117 }
118
119 return array;
120 }
121
122
123
124
125
126
127 public String[] getColumns(final String recordID) {
128 String[] array = null;
129
130 if (metaData != null) {
131 final List cmds = ParserUtils.getColumnMetaData(recordID, metaData);
132 array = new String[cmds.size()];
133 for (int i = 0; i < cmds.size(); i++) {
134 final ColumnMetaData column = (ColumnMetaData) cmds.get(i);
135 array[i] = column.getColName();
136 }
137 }
138
139 return array;
140 }
141
142
143
144
145
146
147 public Date getDate(final String column) throws ParseException {
148 return getDate(column, new SimpleDateFormat("yyyyMMdd"));
149 }
150
151
152
153
154
155
156
157 public Date getDate(final String column, final SimpleDateFormat sdf) throws ParseException {
158 final String s = getStringValue(column);
159 if (FPStringUtils.isBlank(s)) {
160
161 return null;
162 }
163 return sdf.parse(s);
164 }
165
166
167
168
169
170
171 public double getDouble(final String column) {
172 final StringBuffer newString = new StringBuffer();
173 final String s = getStringValue(column);
174
175 if (!strictNumericParse) {
176 newString.append(ParserUtils.stripNonDoubleChars(s));
177 } else {
178 newString.append(s);
179 }
180
181 return Double.parseDouble(newString.toString());
182 }
183
184
185
186
187
188
189 public BigDecimal getBigDecimal(final String column) {
190 final String s = getStringValue(column);
191
192 return new BigDecimal(s);
193 }
194
195 private String getStringValue(final String column) {
196 final Row row = (Row) rows.get(pointer);
197 return row.getValue(ParserUtils.getColumnIndex(row.getMdkey(), metaData, column, parser));
198 }
199
200 public Object getObject(final String column, final Class classToConvertTo) {
201 final String s = getStringValue(column);
202 return ParserUtils.runPzConverter(pzConvertProps, s, classToConvertTo);
203 }
204
205
206
207
208
209
210 public int getErrorCount() {
211 if (getErrors() != null) {
212 return getErrors().size();
213 }
214
215 return 0;
216 }
217
218
219
220
221
222
223 public List getErrors() {
224 return errors;
225 }
226
227
228
229
230
231
232 public int getIndex() {
233 return pointer;
234 }
235
236
237
238
239
240
241 public int getInt(final String column) {
242 final String s = getStringValue(column);
243
244 if (!strictNumericParse) {
245 return Integer.parseInt(ParserUtils.stripNonLongChars(s));
246 }
247
248 return Integer.parseInt(s);
249 }
250
251 public long getLong(final String column) {
252 final String s = getStringValue(column);
253
254 if (!strictNumericParse) {
255 return Long.parseLong(ParserUtils.stripNonLongChars(s));
256 }
257
258 return Long.parseLong(s);
259 }
260
261
262
263
264
265
266 public int getRowCount() {
267 return rows.size();
268 }
269
270
271
272
273
274
275 public int getRowNo() {
276 return ((Row) rows.get(pointer)).getRowNumber();
277 }
278
279
280
281
282
283
284 public String getString(final String column) {
285 String s = getStringValue(column);
286
287 if (parser.isNullEmptyStrings() && FPStringUtils.isBlank(s)) {
288 s = null;
289 } else if (upperCase) {
290
291
292
293 s = s.toUpperCase(Locale.getDefault());
294 }else if (lowerCase) {
295
296
297
298 s = s.toLowerCase(Locale.getDefault());
299 }
300
301
302 return s;
303 }
304
305 public void setValue(final String column, final String value) {
306 final Row row = (Row) rows.get(pointer);
307 final int colIndex = ParserUtils.getColumnIndex(row.getMdkey(), metaData, column, parser);
308
309 row.setValue(colIndex, value);
310 }
311
312
313
314
315
316
317 public void goBottom() {
318 pointer = rows.size() - 1;
319 }
320
321
322
323
324
325
326 public void goTop() {
327 pointer = -1;
328 }
329
330
331
332
333
334
335 public boolean isAnError(final int lineNo) {
336 for (int i = 0; i < errors.size(); i++) {
337 if (((DataError) errors.get(i)).getLineNo() == lineNo && ((DataError) errors.get(i)).getErrorLevel() > 1) {
338 return true;
339 }
340 }
341 return false;
342 }
343
344
345
346
347
348
349 public boolean next() {
350 if (pointer < rows.size() && pointer + 1 != rows.size()) {
351 pointer++;
352 return true;
353 }
354 return false;
355 }
356
357
358
359
360
361
362 public void orderRows(final OrderBy ob) {
363
364
365
366
367
368
369 if (ob != null && rows != null) {
370 final List cmds = metaData.getColumnsNames();
371
372
373 ob.setMetaData(getMetaData());
374 ob.setParser(parser);
375 Collections.sort(rows, ob);
376 goTop();
377 }
378 }
379
380
381
382
383
384
385 public boolean previous() {
386 if (pointer <= 0) {
387 return false;
388 }
389 pointer--;
390 return true;
391 }
392
393 /**
394 * Sets data in the DataSet to lowercase
395 */
396 public void setLowerCase() {
397 upperCase = false;
398 lowerCase = true;
399 }
400
401 /**
402 * Sets data in the DataSet to uppercase
403 */
404 public void setUpperCase() {
405 upperCase = true;
406 lowerCase = false;
407 }
408
409 /**
410 * Checks to see if the row has the given <RECORD> id
411 *
412 * @param recordID
413 * @return boolean
414 */
415 public boolean isRecordID(final String recordID) {
416 String rowID = ((Row) rows.get(pointer)).getMdkey();
417 if (rowID == null) {
418 rowID = FPConstants.DETAIL_ID;
419 }
420
421 return rowID.equals(recordID);
422 }
423
424 /**
425 * Sets the absolute position of the record pointer
426 *
427 * @param localPointer -
428 * int
429 * @exception IndexOutOfBoundsException
430 */
431 public void absolute(final int localPointer) {
432 if (localPointer < 0 || localPointer > rows.size() - 1) {
433 throw new IndexOutOfBoundsException("INVALID POINTER LOCATION: " + localPointer);
434 }
435
436 pointer = localPointer;
437 }
438
439 /**
440 * Setting this to True will parse text as is and throw a
441 * NumberFormatException. Setting to false, which is the default, will
442 * remove any non numeric charcter from the field. The remaining numeric
443 * chars's will be returned. If it is an empty string,or there are no
444 * numeric chars, 0 will be returned for getInt() and getDouble()
445 *
446 * @param strictNumericParse
447 * The strictNumericParse to set.
448 */
449 public void setStrictNumericParse(final boolean strictNumericParse) {
450 this.strictNumericParse = strictNumericParse;
451 }
452
453
454
455
456
457
458 public void remove() {
459 rows.remove(pointer);
460 pointer--;
461 }
462
463 public void setPZConvertProps(final Properties props) {
464 this.pzConvertProps = props;
465 }
466
467 /**
468 * @param pointer the pointer to set
469 */
470 protected void setPointer(final int pointer) {
471 this.pointer = pointer;
472 }
473
474 public void clearRows() {
475 pointer = -1;
476 rows.clear();
477 }
478
479 public void clearAll() {
480 clearRows();
481 clearErrors();
482 }
483
484 public void clearErrors() {
485 errors.clear();
486 }
487
488 public MetaData getMetaData() {
489 return metaData;
490 }
491
492 public void setMetaData(final MetaData metaData) {
493 this.metaData = metaData;
494 }
495
496 public String toString() {
497 final StringBuffer buf = new StringBuffer();
498 buf.append("Errors:").append(errors.size()).append(System.getProperty("line.separator"));
499 buf.append("Rows:").append(rows.size()).append(System.getProperty("line.separator"));
500 buf.append("Position:").append(pointer).append(System.getProperty("line.separator"));
501 buf.append("Conversion Props:").append(pzConvertProps).append(System.getProperty("line.separator"));
502 buf.append("MetaData:").append(metaData).append(System.getProperty("line.separator"));
503 return buf.toString();
504 }
505
506 public boolean contains(final String column) {
507 if (pointer == -1) {
508 throw new IndexOutOfBoundsException("dataset on invalid row. need to call next()");
509 }
510
511 final Iterator cmds = ParserUtils.getColumnMetaData(((Row) rows.get(pointer)).getMdkey(), metaData).iterator();
512 while (cmds.hasNext()) {
513 final ColumnMetaData cmd = (ColumnMetaData) cmds.next();
514 if (cmd.getColName().equalsIgnoreCase(column)) {
515 return true;
516 }
517 }
518
519 return false;
520
521 }
522
523 /**
524 * @throws FPInvalidUsageException Parser.isFlagEmptyRows() must be set to true before using this
525 * @throws FPException if cursor is on an invalid row
526 */
527 public boolean isRowEmpty() {
528 if (!parser.isFlagEmptyRows()) {
529
530
531 throw new FPInvalidUsageException("Parser.isFlagEmptyRows(true) must be set before using isRowEmpty()");
532 }
533
534 if (pointer < 0) {
535 throw new FPException("Cursor on invalid row.. Make sure next() is called and returns true");
536 }
537
538 return ((Row)rows.get(pointer)).isEmpty();
539 }
540
541 /**
542 * @throws FPInvalidUsageException
543 * @throws FPException if cursor is on an invalid row
544 */
545 public String getRawData() {
546 if (!parser.isStoreRawDataToDataSet()) {
547
548
549 throw new FPInvalidUsageException("Parser.isStoreRawDataToDataSet(true) must be set before using getRawData()");
550 }
551
552 if (pointer < 0) {
553 throw new FPException("Cursor on invalid row.. Make sure next() is called and returns true");
554 }
555
556 return ((Row)rows.get(pointer)).getRawData();
557 }
558 }