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.time.LocalDate;
39 import java.time.format.DateTimeFormatter;
40 import java.util.ArrayList;
41 import java.util.Collections;
42 import java.util.Date;
43 import java.util.List;
44 import java.util.Optional;
45 import java.util.Properties;
46 import java.util.function.DoubleSupplier;
47 import java.util.function.IntSupplier;
48 import java.util.function.LongSupplier;
49 import java.util.function.Supplier;
50
51 import net.sf.flatpack.ordering.OrderBy;
52 import net.sf.flatpack.structure.ColumnMetaData;
53 import net.sf.flatpack.structure.Row;
54 import net.sf.flatpack.util.FPException;
55 import net.sf.flatpack.util.FPInvalidUsageException;
56 import net.sf.flatpack.util.ParserUtils;
57 import net.sf.flatpack.xml.MetaData;
58
59
60
61
62
63
64 public class DefaultDataSet implements DataSet {
65 private static final String NEW_LINE = System.lineSeparator();
66
67 private final List<Row> rows = new ArrayList<>();
68
69 private final List<DataError> errors = new ArrayList<>();
70
71 private Properties pzConvertProps = null;
72
73
74 private int pointer = -1;
75
76
77 private boolean lowerCase = false;
78
79
80 private boolean upperCase = false;
81 private String[] columns = null;
82
83
84
85
86
87 private boolean strictNumericParse = false;
88
89 private MetaData metaData;
90
91 private final Parser parser;
92
93 private Record currentRecord;
94
95 public DefaultDataSet(final MetaData pzMetaData, final Parser pzparser) {
96 this.metaData = pzMetaData;
97 this.parser = pzparser;
98 }
99
100 public void addRow(final Row row) {
101 rows.add(row);
102 }
103
104 public void addError(final DataError dataError) {
105 errors.add(dataError);
106 }
107
108
109
110
111
112
113 @Override
114 public String[] getColumns() {
115
116 if (columns == null && metaData != null) {
117 final List<ColumnMetaData> cmds = metaData.getColumnsNames();
118 columns = new String[cmds.size()];
119 for (int i = 0; i < cmds.size(); i++) {
120 final ColumnMetaData column = cmds.get(i);
121 columns[i] = column.getColName();
122 }
123 }
124
125 return columns;
126 }
127
128
129
130
131
132
133 @Override
134 public String[] getColumns(final String recordID) {
135 String[] array = null;
136
137 if (metaData != null) {
138 final List<ColumnMetaData> cmds = ParserUtils.getColumnMetaData(recordID, metaData);
139 array = new String[cmds.size()];
140 for (int i = 0; i < cmds.size(); i++) {
141 final ColumnMetaData column = cmds.get(i);
142 array[i] = column.getColName();
143 }
144 }
145
146 return array;
147 }
148
149 @Override
150 public Date getDate(final String column) throws ParseException {
151 return currentRecord.getDate(column);
152 }
153
154 @Override
155 public Date getDate(final String column, final SimpleDateFormat sdf) throws ParseException {
156 return currentRecord.getDate(column, sdf);
157 }
158
159 @Override
160 public double getDouble(final String column) {
161 return currentRecord.getDouble(column);
162 }
163
164 @Override
165 public BigDecimal getBigDecimal(final String column) {
166 return currentRecord.getBigDecimal(column);
167 }
168
169 @Override
170 public Object getObject(final String column, final Class<?> classToConvertTo) {
171 return currentRecord.getObject(column, classToConvertTo);
172 }
173
174 @Override
175 public BigDecimal getBigDecimal(final String column, final Supplier<BigDecimal> defaultSupplier) {
176 return currentRecord.getBigDecimal(column, defaultSupplier);
177 }
178
179 @Override
180 public Date getDate(final String column, final SimpleDateFormat sdf, final Supplier<Date> defaultSupplier) throws ParseException {
181 return currentRecord.getDate(column, sdf, defaultSupplier);
182 }
183
184 @Override
185 public Date getDate(final String column, final Supplier<Date> defaultSupplier) throws ParseException {
186 return currentRecord.getDate(column, defaultSupplier);
187 }
188
189 @Override
190 public double getDouble(final String column, final DoubleSupplier defaultSupplier) {
191 return currentRecord.getDouble(column, defaultSupplier);
192 }
193
194 @Override
195 public int getInt(final String column, final IntSupplier defaultSupplier) {
196 return currentRecord.getInt(column, defaultSupplier);
197 }
198
199 @Override
200 public long getLong(final String column, final LongSupplier defaultSupplier) {
201 return currentRecord.getLong(column, defaultSupplier);
202 }
203
204 @Override
205 public String getString(final String column, final Supplier<String> defaultSupplier) {
206 return currentRecord.getString(column, defaultSupplier);
207 }
208
209
210
211
212
213
214 @Override
215 public int getErrorCount() {
216 if (getErrors() != null) {
217 return getErrors().size();
218 }
219
220 return 0;
221 }
222
223
224
225
226
227
228 @Override
229 public List<DataError> getErrors() {
230 return errors;
231 }
232
233
234
235
236
237
238 @Override
239 public int getIndex() {
240 return pointer;
241 }
242
243 @Override
244 public int getInt(final String column) {
245 return currentRecord.getInt(column);
246 }
247
248 @Override
249 public long getLong(final String column) {
250 return currentRecord.getLong(column);
251 }
252
253
254
255
256
257
258 @Override
259 public int getRowCount() {
260 return rows.size();
261 }
262
263
264
265
266
267
268 @Override
269 public int getRowNo() {
270 return currentRecord.getRowNo();
271 }
272
273
274
275
276
277
278 @Override
279 public String getString(final String column) {
280 return currentRecord.getString(column);
281 }
282
283 @Override
284 public void setValue(final String column, final String value) {
285 final Row row = rows.get(pointer);
286 final int colIndex = ParserUtils.getColumnIndex(row.getMdkey(), metaData, column, parser.isColumnNamesCaseSensitive());
287
288 row.setValue(colIndex, value);
289 }
290
291
292
293
294
295
296 @Override
297 public void goBottom() {
298 pointer = rows.size() - 1;
299 }
300
301
302
303
304
305
306 @Override
307 public void goTop() {
308 pointer = -1;
309 }
310
311
312
313
314
315
316 @Override
317 public boolean isAnError(final int lineNo) {
318 for (int i = 0; i < errors.size(); i++) {
319 if (errors.get(i).getLineNo() == lineNo && errors.get(i).getErrorLevel() > 1) {
320 return true;
321 }
322 }
323 return false;
324 }
325
326
327
328
329
330
331 @Override
332 public boolean next() {
333 if (pointer < rows.size() && pointer + 1 != rows.size()) {
334 pointer++;
335 currentRecord = new RowRecord(rows.get(pointer), metaData, parser.isColumnNamesCaseSensitive(), pzConvertProps, strictNumericParse,
336 upperCase, lowerCase, parser.isNullEmptyStrings());
337 return true;
338 }
339 currentRecord = null;
340 return false;
341 }
342
343 @Override
344 public Optional<Record> getRecord() {
345 return Optional.ofNullable(currentRecord);
346 }
347
348
349
350
351
352
353 @Override
354 public void orderRows(final OrderBy ob) {
355 if (ob != null) {
356 ob.setMetaData(getMetaData());
357 ob.setParser(parser);
358 Collections.sort(rows, ob);
359 goTop();
360 }
361 }
362
363
364
365
366
367
368 @Override
369 public boolean previous() {
370 if (pointer <= 0) {
371 currentRecord = null;
372 return false;
373 }
374 pointer--;
375 currentRecord = new RowRecord(rows.get(pointer), metaData, parser.isColumnNamesCaseSensitive(), pzConvertProps, strictNumericParse, upperCase,
376 lowerCase, parser.isNullEmptyStrings());
377 return true;
378 }
379
380
381
382
383 @Override
384 public void setLowerCase() {
385 upperCase = false;
386 lowerCase = true;
387 }
388
389
390
391
392 @Override
393 public void setUpperCase() {
394 upperCase = true;
395 lowerCase = false;
396 }
397
398
399
400
401
402
403
404 @Override
405 public boolean isRecordID(final String recordID) {
406 return currentRecord.isRecordID(recordID);
407 }
408
409 @Override
410 public String getRecordID() {
411 return currentRecord.getRecordID();
412 }
413
414
415
416
417
418
419
420
421 @Override
422 public void absolute(final int localPointer) {
423 if (localPointer < 0 || localPointer >= rows.size()) {
424 throw new IndexOutOfBoundsException("INVALID POINTER LOCATION: " + localPointer);
425 }
426
427 pointer = localPointer;
428 currentRecord = new RowRecord(rows.get(pointer), metaData, parser.isColumnNamesCaseSensitive(), pzConvertProps, strictNumericParse, upperCase,
429 lowerCase, parser.isNullEmptyStrings());
430 }
431
432
433
434
435
436
437
438
439
440
441
442 @Override
443 public void setStrictNumericParse(final boolean strictNumericParse) {
444 this.strictNumericParse = strictNumericParse;
445 }
446
447
448
449
450
451
452 @Override
453 public void remove() {
454 rows.remove(pointer);
455 pointer--;
456 }
457
458 @Override
459 public void setPZConvertProps(final Properties props) {
460 this.pzConvertProps = props;
461 }
462
463
464
465
466
467 protected void setPointer(final int pointer) {
468 this.pointer = pointer;
469 }
470
471 @Override
472 public void clearRows() {
473 pointer = -1;
474
475 rows.clear();
476 }
477
478 @Override
479 public void clearAll() {
480 clearRows();
481 clearErrors();
482 }
483
484 @Override
485 public void clearErrors() {
486 errors.clear();
487 }
488
489 public MetaData getMetaData() {
490 return metaData;
491 }
492
493 public void setMetaData(final MetaData metaData) {
494 this.metaData = metaData;
495 this.columns = null;
496 }
497
498 @Override
499 public String toString() {
500 final StringBuilder buf = new StringBuilder();
501 buf.append("Errors:").append(errors.size()).append(NEW_LINE);
502 buf.append("Rows:").append(rows.size()).append(NEW_LINE);
503 buf.append("Position:").append(pointer).append(NEW_LINE);
504 buf.append("Conversion Props:").append(pzConvertProps).append(NEW_LINE);
505 buf.append("MetaData:").append(metaData).append(NEW_LINE);
506 return buf.toString();
507 }
508
509 @Override
510 public boolean contains(final String column) {
511 if (pointer == -1) {
512 throw new IndexOutOfBoundsException("dataset on invalid row. need to call next()");
513 }
514 return currentRecord.contains(column);
515 }
516
517
518
519
520
521
522
523
524 @Override
525 public boolean isRowEmpty() {
526 if (!parser.isFlagEmptyRows()) {
527
528
529 throw new FPInvalidUsageException("Parser.isFlagEmptyRows(true) must be set before using isRowEmpty()");
530 }
531
532 if (pointer < 0) {
533 throw new FPException("Cursor on invalid row.. Make sure next() is called and returns true");
534 }
535
536 return rows.get(pointer).isEmpty();
537 }
538
539
540
541
542
543
544 @Override
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 rows.get(pointer).getRawData();
557 }
558
559 @Override
560 public LocalDate getLocalDate(final String column, final Supplier<LocalDate> defaultSupplier) throws ParseException {
561 return currentRecord.getLocalDate(column, defaultSupplier);
562 }
563
564 @Override
565 public LocalDate getLocalDate(final String column) throws ParseException {
566 return currentRecord.getLocalDate(column);
567 }
568
569 @Override
570 public LocalDate getLocalDate(final String column, DateTimeFormatter dtf) throws ParseException {
571 return currentRecord.getLocalDate(column, dtf);
572 }
573
574 @Override
575 public LocalDate getLocalDate(final String column, final String dateFormat, final Supplier<LocalDate> defaultSupplier) throws ParseException {
576 return currentRecord.getLocalDate(column, dateFormat, defaultSupplier);
577 }
578
579 @Override
580 public LocalDate getLocalDate(final String column, final String dateFormat) throws ParseException {
581 return currentRecord.getLocalDate(column, dateFormat);
582 }
583 }