Skip to content

Commit 006380c

Browse files
committed
refactor!: remove the RecordWrapper
1 parent 430adef commit 006380c

File tree

15 files changed

+83
-126
lines changed

15 files changed

+83
-126
lines changed

docs/src/content/docs/guides/upgrading.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,11 @@ The `CsvIndex` and `CsvPage` classes have been changed to Java records. With thi
5757
- firstPage.getStartingLineNumber();
5858
+ firstPage.startingLineNumber();
5959
```
60+
61+
## Record wrapper removal
62+
63+
The `RecordWrapper` class has been removed. It was a wrapper around the `CsvRecord` class that was used to provide parsing context information to the reading process.
64+
65+
If you implemented a custom callback handler by extending `AbstractBaseCsvCallbackHandler`, all you need to do is to return the `CsvRecord` instance directly instead of wrapping it in a `RecordWrapper`.
66+
67+
If you implemented a custom callback handler by implementing the `CsvCallbackHandler` interface, you also have to implement three additional methods: `isComment`, `isEmptyLine` and `getFieldCount`. Those methods simply have to return the information that was previously provided by the `RecordWrapper` instance.

example/src/main/java/example/ExampleCsvReaderWithCustomCallbackHandler.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import de.siegmar.fastcsv.reader.AbstractBaseCsvCallbackHandler;
1616
import de.siegmar.fastcsv.reader.CsvReader;
1717
import de.siegmar.fastcsv.reader.NamedCsvRecord;
18-
import de.siegmar.fastcsv.reader.RecordWrapper;
1918
import de.siegmar.fastcsv.writer.CsvWriter;
2019

2120
/// Example for implementing a custom callback handler.
@@ -202,7 +201,7 @@ private long materializeId(final char[] buf, final int offset, final int len) {
202201
}
203202

204203
@Override
205-
protected RecordWrapper<Measurement> buildRecord() {
204+
protected Measurement buildRecord() {
206205
if (recordCount++ == 0) {
207206
// Skip header
208207
return null;
@@ -213,7 +212,7 @@ protected RecordWrapper<Measurement> buildRecord() {
213212
.formatted(getFieldCount(), getStartingLineNumber()));
214213
}
215214

216-
return wrapRecord(new Measurement(id, timestamp, latitude, longitude, temperature));
215+
return new Measurement(id, timestamp, latitude, longitude, temperature);
217216
}
218217

219218
}

example/src/main/java/example/ExampleCsvReaderWithSpecialQuotedFieldHandling.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import de.siegmar.fastcsv.reader.AbstractBaseCsvCallbackHandler;
77
import de.siegmar.fastcsv.reader.CsvReader;
8-
import de.siegmar.fastcsv.reader.RecordWrapper;
98

109
/// Example for reading CSV data with custom handling of quoted fields.
1110
public class ExampleCsvReaderWithSpecialQuotedFieldHandling {
@@ -39,8 +38,8 @@ protected void handleBegin(final long startingLineNumber) {
3938
}
4039

4140
@Override
42-
protected RecordWrapper<List<QuotableField>> buildRecord() {
43-
return wrapRecord(List.copyOf(fields));
41+
protected List<QuotableField> buildRecord() {
42+
return List.copyOf(fields);
4443
}
4544

4645
}

lib/src/intTest/java/blackbox/reader/SkipRecordsTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
import de.siegmar.fastcsv.reader.CsvReader;
1414
import de.siegmar.fastcsv.reader.CsvRecordHandler;
1515
import de.siegmar.fastcsv.reader.FieldModifiers;
16-
import de.siegmar.fastcsv.reader.RecordWrapper;
1716
import testutil.CsvRecordAssert;
1817

1918
class SkipRecordsTest {
@@ -64,8 +63,8 @@ protected void handleField(final int fieldIdx, final char[] buf,
6463
}
6564

6665
@Override
67-
protected RecordWrapper<String[]> buildRecord() {
68-
return wrapRecord(fields.toArray(new String[0]));
66+
protected String[] buildRecord() {
67+
return fields.toArray(new String[0]);
6968
}
7069
};
7170
assertThat(crb.build(cbh, input).stream()).hasSize(2);

lib/src/main/java/de/siegmar/fastcsv/reader/AbstractBaseCsvCallbackHandler.java

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package de.siegmar.fastcsv.reader;
22

3-
import java.util.Objects;
4-
53
/// Base class for [CsvCallbackHandler] implementations that handles their own field storage and record building.
64
///
75
/// This implementation is stateful and must not be reused.
@@ -28,16 +26,19 @@ protected long getStartingLineNumber() {
2826
}
2927

3028
/// {@return whether the current record is a comment.}
29+
@Override
3130
protected boolean isComment() {
3231
return comment;
3332
}
3433

3534
/// {@return whether the current record is an empty line.}
35+
@Override
3636
protected boolean isEmptyLine() {
3737
return emptyLine;
3838
}
3939

4040
/// {@return the number of fields in the current record.}
41+
@Override
4142
protected int getFieldCount() {
4243
return fieldCount;
4344
}
@@ -112,15 +113,4 @@ protected final void setComment(final char[] buf, final int offset, final int le
112113
protected void handleComment(final char[] buf, final int offset, final int len) {
113114
}
114115

115-
/// Builds a wrapper for the record that contains information necessary for the [CsvReader] in order to
116-
/// determine how to process the record.
117-
///
118-
/// @param record the actual record to be returned by the [CsvReader], must not be `null`
119-
/// @return the wrapper for the actual record
120-
/// @throws NullPointerException if `null` is passed for `record`
121-
protected RecordWrapper<T> wrapRecord(final T record) {
122-
return new RecordWrapper<>(comment, emptyLine, fieldCount,
123-
Objects.requireNonNull(record, "record must not be null"));
124-
}
125-
126116
}

lib/src/main/java/de/siegmar/fastcsv/reader/AbstractInternalCsvCallbackHandler.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,21 @@ protected AbstractInternalCsvCallbackHandler(final int maxFields,
9292
fields = new String[Math.min(DEFAULT_INITIAL_FIELDS_SIZE, maxFields)];
9393
}
9494

95+
@Override
96+
protected boolean isComment() {
97+
return comment;
98+
}
99+
100+
@Override
101+
protected boolean isEmptyLine() {
102+
return emptyLine;
103+
}
104+
105+
@Override
106+
protected int getFieldCount() {
107+
return fieldIdx;
108+
}
109+
95110
/// {@inheritDoc}
96111
/// Resets the internal state of this handler.
97112
@SuppressWarnings("checkstyle:HiddenField")
@@ -204,15 +219,6 @@ protected String[] compactFields() {
204219
return ret;
205220
}
206221

207-
/// Builds a record wrapper for the given record.
208-
///
209-
/// @param rec the record, must not be `null`
210-
/// @return the record wrapper
211-
/// @throws NullPointerException if `rec` is `null`
212-
protected RecordWrapper<T> buildWrapper(final T rec) {
213-
return new RecordWrapper<>(comment, emptyLine, fieldIdx, rec);
214-
}
215-
216222
/// Abstract builder for [AbstractInternalCsvCallbackHandler] subclasses.
217223
///
218224
/// This class is for **internal use only** and should not be used directly. It will be sealed in a future release.

lib/src/main/java/de/siegmar/fastcsv/reader/CsvCallbackHandler.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,29 @@ public abstract class CsvCallbackHandler<T> {
1616
protected CsvCallbackHandler() {
1717
}
1818

19+
/// {@return whether the record denotes a comment}
20+
///
21+
/// If this method returns `true`, the record is a comment and cannot be a regular record.
22+
/// The [CsvReader] will skip the record if
23+
/// [de.siegmar.fastcsv.reader.CsvReader.CsvReaderBuilder#commentStrategy(CommentStrategy)]
24+
/// is set to [CommentStrategy#SKIP].
25+
protected abstract boolean isComment();
26+
27+
/// {@return whether the line is empty}
28+
///
29+
/// If this method returns `true`, the line is empty.
30+
/// The [CsvReader] will skip the record if
31+
/// [de.siegmar.fastcsv.reader.CsvReader.CsvReaderBuilder#skipEmptyLines(boolean)]
32+
/// is set to `true`.
33+
protected abstract boolean isEmptyLine();
34+
35+
/// {@return the number of fields in the record}
36+
///
37+
/// The [CsvReader] will check the number of fields in the record against the number of fields in other records if
38+
/// [de.siegmar.fastcsv.reader.CsvReader.CsvReaderBuilder#ignoreDifferentFieldCount(boolean)]
39+
/// is set to `false`.
40+
protected abstract int getFieldCount();
41+
1942
/// Called at the beginning of each record.
2043
///
2144
/// The `startingLineNumber` is the line number where the record starts (starting with 1).
@@ -64,12 +87,10 @@ protected CsvCallbackHandler() {
6487
/// @param len the length of the field value
6588
protected abstract void setComment(char[] buf, int offset, int len);
6689

67-
/// Called at the end of each CSV record to build an object representation of the record.
68-
///
69-
/// The returned wrapper is used by the [CsvReader] in order to determine how to process the record.
90+
/// Called at the end of each CSV record to build the actual record representation.
7091
///
71-
/// @return the record wrapper or `null` if the record should be ignored/skipped
72-
protected abstract RecordWrapper<T> buildRecord();
92+
/// @return the record or `null` if the record should be ignored/skipped as it is consumed by the callback handler.
93+
protected abstract T buildRecord();
7394

7495
/// Called at the end of the CSV reading process.
7596
protected void terminate() {

lib/src/main/java/de/siegmar/fastcsv/reader/CsvReader.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -223,29 +223,29 @@ private T fetchRecord() throws IOException {
223223

224224
@SuppressWarnings("checkstyle:ReturnCount")
225225
private T processRecord() {
226-
final RecordWrapper<T> recordWrapper = callbackHandler.buildRecord();
226+
final T csvRecord = callbackHandler.buildRecord();
227227

228228
// handle consumed records (e.g., header for named records)
229-
if (recordWrapper == null) {
229+
if (csvRecord == null) {
230230
return null;
231231
}
232232

233233
// handle comment lines
234-
if (recordWrapper.isComment()) {
235-
return commentStrategy == CommentStrategy.SKIP ? null : recordWrapper.getWrappedRecord();
234+
if (callbackHandler.isComment()) {
235+
return commentStrategy == CommentStrategy.SKIP ? null : csvRecord;
236236
}
237237

238238
// handle empty lines
239-
if (recordWrapper.isEmptyLine()) {
240-
return skipEmptyLines ? null : recordWrapper.getWrappedRecord();
239+
if (callbackHandler.isEmptyLine()) {
240+
return skipEmptyLines ? null : csvRecord;
241241
}
242242

243243
// check field count consistency
244244
if (!ignoreDifferentFieldCount) {
245-
checkFieldCountConsistency(recordWrapper.getFieldCount());
245+
checkFieldCountConsistency(callbackHandler.getFieldCount());
246246
}
247247

248-
return recordWrapper.getWrappedRecord();
248+
return csvRecord;
249249
}
250250

251251
private void checkFieldCountConsistency(final int fieldCount) {

lib/src/main/java/de/siegmar/fastcsv/reader/CsvRecordHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@ public static CsvRecordHandler of(final Consumer<CsvRecordHandlerBuilder> config
7373
}
7474

7575
@Override
76-
protected RecordWrapper<CsvRecord> buildRecord() {
77-
return buildWrapper(new CsvRecord(startingLineNumber, compactFields(), comment));
76+
protected CsvRecord buildRecord() {
77+
return new CsvRecord(startingLineNumber, compactFields(), comment);
7878
}
7979

8080
/// A builder for [CsvRecordHandler].

lib/src/main/java/de/siegmar/fastcsv/reader/IndexedCsvReader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,9 +213,9 @@ private List<T> readPage(final CsvIndex.CsvPage page) throws IOException {
213213
csvParser.reset(page.startingLineNumber() - 1);
214214

215215
for (int i = 0; i < pageSize && csvParser.parse(); i++) {
216-
final RecordWrapper<T> rec = csvRecordHandler.buildRecord();
216+
final T rec = csvRecordHandler.buildRecord();
217217
if (rec != null) {
218-
ret.add(rec.getWrappedRecord());
218+
ret.add(rec);
219219
}
220220
}
221221
} catch (final IOException e) {

0 commit comments

Comments
 (0)