@@ -47,7 +47,7 @@ public enum Feature
47
47
/**
48
48
* Feature that determines how stream of records (usually CSV lines, but sometimes
49
49
* multiple lines when linefeeds are included in quoted values) is exposed:
50
- * either as a sequence of Objects (false), or as an array of Objects (true).
50
+ * either as a sequence of Objects (false), or as an Array of Objects (true).
51
51
* Using stream of Objects is convenient when using
52
52
* <code>ObjectMapper.readValues(...)</code>
53
53
* and array of Objects convenient when binding to <code>List</code>s or
@@ -56,7 +56,17 @@ public enum Feature
56
56
* Default value is false, meaning that by default a CSV document is exposed as
57
57
* a sequence of root-level Object entries.
58
58
*/
59
- WRAP_AS_ARRAY (false )
59
+ WRAP_AS_ARRAY (false ),
60
+
61
+ /**
62
+ * Feature that allows ignoring of unmappable "extra" columns; that is, values for
63
+ * columns that appear after columns for which types are defined. When disabled,
64
+ * an exception is thrown for such column values, but if enabled, they are
65
+ * silently ignored.
66
+ *
67
+ * @since 2.7
68
+ */
69
+ IGNORE_TRAILING_UNMAPPABLE (false ),
60
70
;
61
71
62
72
final boolean _defaultState ;
@@ -516,17 +526,7 @@ public JsonToken nextToken() throws IOException
516
526
return (_currToken = _handleArrayValue ());
517
527
case STATE_SKIP_EXTRA_COLUMNS :
518
528
// Need to just skip whatever remains
519
- _state = STATE_RECORD_START ;
520
- while (_reader .nextString () != null ) { }
521
-
522
- // But once we hit the end of the logical line, get out
523
- // NOTE: seems like we should always be within Object, but let's be conservative
524
- // and check just in case
525
- _parsingContext = _parsingContext .getParent ();
526
- _state = _reader .startNewLine () ? STATE_RECORD_START : STATE_DOC_END ;
527
- return (_currToken = _parsingContext .inArray ()
528
- ? JsonToken .END_ARRAY : JsonToken .END_OBJECT );
529
-
529
+ return _skipUntilEndOfLine ();
530
530
case STATE_DOC_END :
531
531
_reader .close ();
532
532
if (_parsingContext .inRoot ()) {
@@ -690,14 +690,18 @@ protected JsonToken _handleNextEntry() throws IOException
690
690
}
691
691
return JsonToken .END_OBJECT ;
692
692
}
693
- _state = STATE_NAMED_VALUE ;
694
693
_currentValue = next ;
695
694
if (_columnIndex >= _columnCount ) {
696
695
_currentName = null ;
697
- /* 14-Mar-2012, tatu: As per [Issue-1], let's allow one specific
698
- * case of extra: if we get just one all-whitespace entry, that
699
- * can be just skipped
700
- */
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
701
705
if (_columnIndex == _columnCount ) {
702
706
next = next .trim ();
703
707
if (next .length () == 0 ) {
@@ -707,10 +711,12 @@ protected JsonToken _handleNextEntry() throws IOException
707
711
return _handleNextEntryExpectEOL ();
708
712
}
709
713
}
714
+
710
715
// 21-May-2015, tatu: Need to enter recovery mode, to skip remainder of the line
711
716
_state = STATE_SKIP_EXTRA_COLUMNS ;
712
717
_reportMappingError ("Too many entries: expected at most " +_columnCount +" (value #" +_columnCount +" (" +next .length ()+" chars) \" " +next +"\" )" );
713
718
}
719
+ _state = STATE_NAMED_VALUE ;
714
720
_currentName = _schema .columnName (_columnIndex );
715
721
return JsonToken .FIELD_NAME ;
716
722
}
@@ -889,6 +895,19 @@ protected void _readHeaderLine() throws IOException {
889
895
setSchema (builder .build ());
890
896
}
891
897
898
+ protected final JsonToken _skipUntilEndOfLine () throws IOException
899
+ {
900
+ while (_reader .nextString () != null ) { }
901
+
902
+ // But once we hit the end of the logical line, get out
903
+ // NOTE: seems like we should always be within Object, but let's be conservative
904
+ // and check just in case
905
+ _parsingContext = _parsingContext .getParent ();
906
+ _state = _reader .startNewLine () ? STATE_RECORD_START : STATE_DOC_END ;
907
+ return (_currToken = _parsingContext .inArray ()
908
+ ? JsonToken .END_ARRAY : JsonToken .END_OBJECT );
909
+ }
910
+
892
911
/*
893
912
/**********************************************************
894
913
/* String value handling
0 commit comments