de.siegmar.fastcsv.reader.AbstractBaseCsvCallbackHandler Maven / Gradle / Ivy
Show all versions of fastcsv Show documentation
package de.siegmar.fastcsv.reader;
import java.util.Objects;
/**
* Base class for {@link CsvCallbackHandler} implementations that handles their own field storage and record building.
*
* This implementation is stateful and must not be reused.
*
* @param the type of the record
*/
public abstract class AbstractBaseCsvCallbackHandler extends CsvCallbackHandler {
private long startingLineNumber;
private boolean comment;
private boolean emptyLine;
private int fieldCount;
/**
* Constructs a new instance.
*/
protected AbstractBaseCsvCallbackHandler() {
}
/**
* The starting line number of the current record.
*
* See {@link CsvCallbackHandler#beginRecord(long)} and {@link CsvRecord#getStartingLineNumber()}.
*
* @return the starting line number of the current record
*/
protected long getStartingLineNumber() {
return startingLineNumber;
}
/**
* Returns whether the current record is a comment.
*
* @return {@code true} if the current record is a comment
*/
protected boolean isComment() {
return comment;
}
/**
* Returns whether the current record is an empty line.
*
* @return {@code true} if the current record is an empty line
*/
protected boolean isEmptyLine() {
return emptyLine;
}
/**
* Returns the number of fields in the current record.
*
* @return the number of fields in the current record
*/
protected int getFieldCount() {
return fieldCount;
}
/**
* {@inheritDoc}
* Resets the internal state of this handler and delegates to {@link #handleBegin(long)}.
*/
@SuppressWarnings("checkstyle:HiddenField")
@Override
protected final void beginRecord(final long startingLineNumber) {
this.startingLineNumber = startingLineNumber;
fieldCount = 0;
comment = false;
emptyLine = true;
handleBegin(startingLineNumber);
}
/**
* Handles the beginning of a record.
*
* This method is called at the beginning of each record.
*
* @param startingLineNumber the line number where the record starts (starting with 1)
*/
@SuppressWarnings("checkstyle:HiddenField")
protected void handleBegin(final long startingLineNumber) {
}
/**
* {@inheritDoc}
*
* This implementation delegates to {@link #handleField(int, char[], int, int, boolean)} after updating the
* {@link #emptyLine} flag and before incrementing the {@link #fieldCount}.
*/
@Override
protected final void addField(final char[] buf, final int offset, final int len, final boolean quoted) {
emptyLine = emptyLine && fieldCount == 0 && len == 0 && !quoted;
handleField(fieldCount++, buf, offset, len, quoted);
}
/**
* Handles a field.
*
* This method is called for each field in the record.
*
* See {@link CsvCallbackHandler#addField(char[], int, int, boolean)} for more details on the parameters.
*
* @param fieldIdx the index of the field in the record (starting with 0)
* @param buf the internal buffer that contains the field value (among other data)
* @param offset the offset of the field value in the buffer
* @param len the length of the field value
* @param quoted {@code true} if the field was quoted
*/
protected void handleField(final int fieldIdx, final char[] buf, final int offset, final int len,
final boolean quoted) {
}
/**
* {@inheritDoc}
*
* This implementation delegates to {@link #handleComment(char[], int, int)} after updating the {@link #comment}
* and {@link #emptyLine} flag and before incrementing the {@link #fieldCount}.
*/
@Override
protected final void setComment(final char[] buf, final int offset, final int len) {
comment = true;
emptyLine = false;
handleComment(buf, offset, len);
fieldCount++;
}
/**
* Handles a comment.
*
* This method is called for each comment line.
*
* See {@link CsvCallbackHandler#setComment(char[], int, int)} for more details on the parameters.
*
* @param buf the internal buffer that contains the field value (among other data)
* @param offset the offset of the field value in the buffer
* @param len the length of the field value
*/
protected void handleComment(final char[] buf, final int offset, final int len) {
}
/**
* Builds a wrapper for the record that contains information necessary for the {@link CsvReader} in order to
* determine how to process the record.
*
* @param record the actual record to be returned by the {@link CsvReader}, must not be {@code null}
* @return the wrapper for the actual record
* @throws NullPointerException if {@code null} is passed for {@code record}
*/
protected RecordWrapper wrapRecord(final T record) {
return new RecordWrapper<>(comment, emptyLine, fieldCount,
Objects.requireNonNull(record, "record must not be null"));
}
}