Skip to content
This repository was archived by the owner on Jan 22, 2019. It is now read-only.

Commit 1f1a057

Browse files
committed
Fix #109
1 parent 2bcdcb5 commit 1f1a057

File tree

6 files changed

+177
-69
lines changed

6 files changed

+177
-69
lines changed

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ Project: jackson-dataformat-csv
2020
#103: `JsonGenerator.Feature.IGNORE_UNKNOWN` does not prevent error when writing structured values
2121
#106: Null fields are always ignored when serializing list of objects
2222
(reported, fix contributed by Brian M)
23+
#109: Allow specifying (via `CsvSchema`) a way to map "extra" columns into specific
24+
key (to use via any setter)
2325

2426
2.6.5 (not yet released)
2527

src/main/java/com/fasterxml/jackson/dataformat/csv/CsvParser.java

+47-34
Original file line numberDiff line numberDiff line change
@@ -692,51 +692,64 @@ protected JsonToken _handleNextEntry() throws IOException
692692
}
693693
_currentValue = next;
694694
if (_columnIndex >= _columnCount) {
695-
_currentName = null;
696-
697-
// 09-Jan-2016, tatu: With [dataformat-csv#95], this may actually be just fine
698-
if (Feature.IGNORE_TRAILING_UNMAPPABLE.enabledIn(_formatFeatures)) {
699-
_state = STATE_SKIP_EXTRA_COLUMNS;
700-
return _skipUntilEndOfLine();
701-
}
702-
703-
// 14-Mar-2012, tatu: As per [dataformat-csv#1], let's allow one specific case
704-
// of extra: if we get just one all-whitespace entry, that can be just skipped
705-
if (_columnIndex == _columnCount) {
706-
next = next.trim();
707-
if (next.length() == 0) {
708-
/* if so, need to verify we then get the end-of-record;
709-
* easiest to do by just calling ourselves again...
710-
*/
711-
return _handleNextEntryExpectEOL();
712-
}
713-
}
714-
715-
// 21-May-2015, tatu: Need to enter recovery mode, to skip remainder of the line
716-
_state = STATE_SKIP_EXTRA_COLUMNS;
717-
_reportMappingError("Too many entries: expected at most "+_columnCount+" (value #"+_columnCount+" ("+next.length()+" chars) \""+next+"\")");
695+
return _handleExtraColumn(next);
718696
}
719697
_state = STATE_NAMED_VALUE;
720698
_currentName = _schema.columnName(_columnIndex);
721699
return JsonToken.FIELD_NAME;
722700
}
723701

724-
protected JsonToken _handleNextEntryExpectEOL() throws IOException
702+
/**
703+
* Helper method called when an extraneous column value is found.
704+
* What happens then depends on configuration, but there are three
705+
* main choices: ignore value (and rest of line); expose extra value
706+
* as "any property" using configured name, or throw an exception.
707+
*
708+
* @since 2.7
709+
*/
710+
protected JsonToken _handleExtraColumn(String value) throws IOException
725711
{
726-
String next = _reader.nextString();
712+
// If "any properties" enabled, expose as such
713+
String anyProp = _schema.getAnyPropertyName();
714+
if (anyProp != null) {
715+
_currentName = anyProp;
716+
_state = STATE_NAMED_VALUE;
717+
return JsonToken.FIELD_NAME;
718+
}
727719

728-
if (next != null) { // should end of record or input
729-
_reportMappingError("Too many entries: expected at most "+_columnCount+" (value #"+_columnCount+" ("+next.length()+" chars) \""+next+"\")");
720+
_currentName = null;
721+
// With [dataformat-csv#95] we'll simply ignore extra
722+
if (Feature.IGNORE_TRAILING_UNMAPPABLE.enabledIn(_formatFeatures)) {
723+
_state = STATE_SKIP_EXTRA_COLUMNS;
724+
return _skipUntilEndOfLine();
730725
}
731-
_parsingContext = _parsingContext.getParent();
732-
if (!_reader.startNewLine()) {
733-
_state = STATE_DOC_END;
734-
} else {
735-
_state = STATE_RECORD_START;
726+
727+
// 14-Mar-2012, tatu: As per [dataformat-csv#1], let's allow one specific case
728+
// of extra: if we get just one all-whitespace entry, that can be just skipped
729+
_state = STATE_SKIP_EXTRA_COLUMNS;
730+
if (_columnIndex == _columnCount) {
731+
value = value.trim();
732+
if (value.isEmpty()) {
733+
// if so, need to verify we then get the end-of-record;
734+
// easiest to do by just calling ourselves again...
735+
String next = _reader.nextString();
736+
if (next == null) { // should end of record or input
737+
_parsingContext = _parsingContext.getParent();
738+
if (!_reader.startNewLine()) {
739+
_state = STATE_DOC_END;
740+
} else {
741+
_state = STATE_RECORD_START;
742+
}
743+
return JsonToken.END_OBJECT;
744+
}
745+
}
736746
}
737-
return JsonToken.END_OBJECT;
747+
748+
// 21-May-2015, tatu: Need to enter recovery mode, to skip remainder of the line
749+
_reportMappingError("Too many entries: expected at most "+_columnCount+" (value #"+_columnCount+" ("+value.length()+" chars) \""+value+"\")");
750+
return null;
738751
}
739-
752+
740753
protected JsonToken _handleNamedValue() throws IOException
741754
{
742755
// 06-Oct-2015, tatu: During recovery, may get past all regular columns,

0 commit comments

Comments
 (0)