Skip to content

Commit 74339e4

Browse files
committed
This adds the posibility to use 'ignorecase' access, to headers mapping
1 parent 2f76dfa commit 74339e4

3 files changed

Lines changed: 74 additions & 18 deletions

File tree

src/main/java/org/apache/commons/csv/CSVFormat.java

Lines changed: 59 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ public CSVFormat getFormat() {
210210
private final String[] header; // array of header column names
211211
private final String[] headerComments; // array of header comment lines
212212
private final boolean skipHeaderRecord;
213+
private final boolean ignoreHeaderCase; // should ignore header names case
213214

214215
/**
215216
* Standard comma separated format, as for {@link #RFC4180} but allowing empty lines.
@@ -226,7 +227,7 @@ public CSVFormat getFormat() {
226227
* @see Predefined#Default
227228
*/
228229
public static final CSVFormat DEFAULT = new CSVFormat(COMMA, DOUBLE_QUOTE_CHAR, null, null, null, false, true,
229-
CRLF, null, null, null, false, false);
230+
CRLF, null, null, null, false, false, false);
230231

231232
/**
232233
* Comma separated format as defined by <a href="http://tools.ietf.org/html/rfc4180">RFC 4180</a>.
@@ -361,7 +362,7 @@ private static boolean isLineBreak(final Character c) {
361362
* @see #TDF
362363
*/
363364
public static CSVFormat newFormat(final char delimiter) {
364-
return new CSVFormat(delimiter, null, null, null, null, false, false, null, null, null, null, false, false);
365+
return new CSVFormat(delimiter, null, null, null, null, false, false, null, null, null, null, false, false, false);
365366
}
366367

367368
/**
@@ -405,14 +406,16 @@ public static CSVFormat valueOf(final String format) {
405406
* TODO
406407
* @param allowMissingColumnNames
407408
* TODO
409+
* @param ignoreHeaderCase
410+
* TODO
408411
* @throws IllegalArgumentException
409412
* if the delimiter is a line break character
410413
*/
411414
private CSVFormat(final char delimiter, final Character quoteChar, final QuoteMode quoteMode,
412415
final Character commentStart, final Character escape, final boolean ignoreSurroundingSpaces,
413416
final boolean ignoreEmptyLines, final String recordSeparator, final String nullString,
414417
final Object[] headerComments, final String[] header, final boolean skipHeaderRecord,
415-
final boolean allowMissingColumnNames) {
418+
final boolean allowMissingColumnNames, final boolean ignoreHeaderCase) {
416419
this.delimiter = delimiter;
417420
this.quoteCharacter = quoteChar;
418421
this.quoteMode = quoteMode;
@@ -426,6 +429,7 @@ private CSVFormat(final char delimiter, final Character quoteChar, final QuoteMo
426429
this.headerComments = toStringArray(headerComments);
427430
this.header = header == null ? null : header.clone();
428431
this.skipHeaderRecord = skipHeaderRecord;
432+
this.ignoreHeaderCase = ignoreHeaderCase;
429433
validate();
430434
}
431435

@@ -602,6 +606,15 @@ public boolean getIgnoreSurroundingSpaces() {
602606
return ignoreSurroundingSpaces;
603607
}
604608

609+
/**
610+
* Specifies whether header names will be accessed ignoring case.
611+
*
612+
* @return {@code true} if header names cases are ignored, {@code false} if they are case sensitive.
613+
*/
614+
public boolean getIgnoreHeaderCase() {
615+
return ignoreHeaderCase;
616+
}
617+
605618
/**
606619
* Gets the String to convert to and from {@code null}.
607620
* <ul>
@@ -666,6 +679,7 @@ public int hashCode() {
666679
result = prime * result + ((escapeCharacter == null) ? 0 : escapeCharacter.hashCode());
667680
result = prime * result + ((nullString == null) ? 0 : nullString.hashCode());
668681
result = prime * result + (ignoreSurroundingSpaces ? 1231 : 1237);
682+
result = prime * result + (ignoreHeaderCase ? 1231 : 1237);
669683
result = prime * result + (ignoreEmptyLines ? 1231 : 1237);
670684
result = prime * result + (skipHeaderRecord ? 1231 : 1237);
671685
result = prime * result + ((recordSeparator == null) ? 0 : recordSeparator.hashCode());
@@ -775,6 +789,9 @@ public String toString() {
775789
if (getIgnoreSurroundingSpaces()) {
776790
sb.append(" SurroundingSpaces:ignored");
777791
}
792+
if (getIgnoreHeaderCase()) {
793+
sb.append(" IgnoreHeaderCase:ignored");
794+
}
778795
sb.append(" SkipHeaderRecord:").append(skipHeaderRecord);
779796
if (headerComments != null) {
780797
sb.append(' ');
@@ -870,7 +887,7 @@ public CSVFormat withCommentMarker(final Character commentMarker) {
870887
}
871888
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
872889
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
873-
skipHeaderRecord, allowMissingColumnNames);
890+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
874891
}
875892

876893
/**
@@ -888,7 +905,7 @@ public CSVFormat withDelimiter(final char delimiter) {
888905
}
889906
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
890907
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
891-
skipHeaderRecord, allowMissingColumnNames);
908+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
892909
}
893910

894911
/**
@@ -919,7 +936,7 @@ public CSVFormat withEscape(final Character escape) {
919936
}
920937
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escape, ignoreSurroundingSpaces,
921938
ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
922-
allowMissingColumnNames);
939+
allowMissingColumnNames, ignoreHeaderCase);
923940
}
924941

925942
/**
@@ -947,7 +964,7 @@ public CSVFormat withEscape(final Character escape) {
947964
public CSVFormat withHeader(final String... header) {
948965
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
949966
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
950-
skipHeaderRecord, allowMissingColumnNames);
967+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
951968
}
952969

953970
/**
@@ -1015,7 +1032,7 @@ public CSVFormat withHeader(final ResultSetMetaData metaData) throws SQLExceptio
10151032
}
10161033
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
10171034
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, labels,
1018-
skipHeaderRecord, allowMissingColumnNames);
1035+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
10191036
}
10201037

10211038
/**
@@ -1036,7 +1053,7 @@ public CSVFormat withHeader(final ResultSetMetaData metaData) throws SQLExceptio
10361053
public CSVFormat withHeaderComments(final Object... headerComments) {
10371054
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
10381055
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1039-
skipHeaderRecord, allowMissingColumnNames);
1056+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
10401057
}
10411058

10421059
/**
@@ -1061,7 +1078,7 @@ public CSVFormat withAllowMissingColumnNames() {
10611078
public CSVFormat withAllowMissingColumnNames(final boolean allowMissingColumnNames) {
10621079
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
10631080
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1064-
skipHeaderRecord, allowMissingColumnNames);
1081+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
10651082
}
10661083

10671084
/**
@@ -1086,7 +1103,7 @@ public CSVFormat withIgnoreEmptyLines() {
10861103
public CSVFormat withIgnoreEmptyLines(final boolean ignoreEmptyLines) {
10871104
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
10881105
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1089-
skipHeaderRecord, allowMissingColumnNames);
1106+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
10901107
}
10911108

10921109
/**
@@ -1111,7 +1128,32 @@ public CSVFormat withIgnoreSurroundingSpaces() {
11111128
public CSVFormat withIgnoreSurroundingSpaces(final boolean ignoreSurroundingSpaces) {
11121129
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
11131130
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1114-
skipHeaderRecord, allowMissingColumnNames);
1131+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
1132+
}
1133+
1134+
/**
1135+
* Sets the header ignore case behavior to {@code true}.
1136+
*
1137+
* @return A new CSVFormat that will ignore case header name.
1138+
* @see #withIgnoreHeaderCase(boolean)
1139+
* @since ?
1140+
*/
1141+
public CSVFormat withIgnoreHeaderCase() {
1142+
return this.withIgnoreHeaderCase(true);
1143+
}
1144+
1145+
/**
1146+
* Sets if header names should be accessed ignoring case.
1147+
*
1148+
* @param ignoreHeaderCase
1149+
* the case mapping behavior, {@code true} to access name/values, {@code false} to leave the
1150+
* mapping as is.
1151+
* @return A new CSVFormat that will ignore case header name if specified as {@code true}
1152+
*/
1153+
public CSVFormat withIgnoreHeaderCase(final boolean ignoreHeaderCase) {
1154+
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
1155+
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1156+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
11151157
}
11161158

11171159
/**
@@ -1132,7 +1174,7 @@ public CSVFormat withIgnoreSurroundingSpaces(final boolean ignoreSurroundingSpac
11321174
public CSVFormat withNullString(final String nullString) {
11331175
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
11341176
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1135-
skipHeaderRecord, allowMissingColumnNames);
1177+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
11361178
}
11371179

11381180
/**
@@ -1163,7 +1205,7 @@ public CSVFormat withQuote(final Character quoteChar) {
11631205
}
11641206
return new CSVFormat(delimiter, quoteChar, quoteMode, commentMarker, escapeCharacter, ignoreSurroundingSpaces,
11651207
ignoreEmptyLines, recordSeparator, nullString, headerComments, header, skipHeaderRecord,
1166-
allowMissingColumnNames);
1208+
allowMissingColumnNames, ignoreHeaderCase);
11671209
}
11681210

11691211
/**
@@ -1177,7 +1219,7 @@ public CSVFormat withQuote(final Character quoteChar) {
11771219
public CSVFormat withQuoteMode(final QuoteMode quoteModePolicy) {
11781220
return new CSVFormat(delimiter, quoteCharacter, quoteModePolicy, commentMarker, escapeCharacter,
11791221
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1180-
skipHeaderRecord, allowMissingColumnNames);
1222+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
11811223
}
11821224

11831225
/**
@@ -1215,7 +1257,7 @@ public CSVFormat withRecordSeparator(final char recordSeparator) {
12151257
public CSVFormat withRecordSeparator(final String recordSeparator) {
12161258
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
12171259
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1218-
skipHeaderRecord, allowMissingColumnNames);
1260+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
12191261
}
12201262

12211263
/**
@@ -1242,6 +1284,6 @@ public CSVFormat withSkipHeaderRecord() {
12421284
public CSVFormat withSkipHeaderRecord(final boolean skipHeaderRecord) {
12431285
return new CSVFormat(delimiter, quoteCharacter, quoteMode, commentMarker, escapeCharacter,
12441286
ignoreSurroundingSpaces, ignoreEmptyLines, recordSeparator, nullString, headerComments, header,
1245-
skipHeaderRecord, allowMissingColumnNames);
1287+
skipHeaderRecord, allowMissingColumnNames, ignoreHeaderCase);
12461288
}
12471289
}

src/main/java/org/apache/commons/csv/CSVParser.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.List;
3434
import java.util.Map;
3535
import java.util.NoSuchElementException;
36+
import java.util.TreeMap;
3637

3738
import static org.apache.commons.csv.Token.Type.*;
3839

@@ -378,7 +379,9 @@ private Map<String, Integer> initializeHeader() throws IOException {
378379
Map<String, Integer> hdrMap = null;
379380
final String[] formatHeader = this.format.getHeader();
380381
if (formatHeader != null) {
381-
hdrMap = new LinkedHashMap<String, Integer>();
382+
hdrMap = this.format.getIgnoreHeaderCase()
383+
? new TreeMap<String, Integer>(String.CASE_INSENSITIVE_ORDER)
384+
: new LinkedHashMap<String, Integer>();
382385

383386
String[] headerRecord = null;
384387
if (formatHeader.length == 0) {

src/test/java/org/apache/commons/csv/CSVParserTest.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,4 +973,15 @@ private void validateRecordPosition(final String lineSeparator) throws IOExcepti
973973

974974
parser.close();
975975
}
976+
977+
@Test
978+
public void testIgnoreCaseHeaderMapping() throws Exception {
979+
final Reader in = new StringReader("1,2,3");
980+
final Iterator<CSVRecord> records = CSVFormat.DEFAULT.withHeader("One", "TWO", "three").withIgnoreHeaderCase()
981+
.parse(in).iterator();
982+
final CSVRecord record = records.next();
983+
assertEquals("1", record.get("one"));
984+
assertEquals("2", record.get("two"));
985+
assertEquals("3", record.get("THREE"));
986+
}
976987
}

0 commit comments

Comments
 (0)