Skip to content
This repository was archived by the owner on Jan 22, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions src/main/java/com/fasterxml/jackson/dataformat/csv/CsvParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public enum Feature // implements FormatFeature // for 2.7
* Default value is false, as per <a href="http://tools.ietf.org/html/rfc4180">RFC-4180</a>.
*/
TRIM_SPACES(false),

/**
* Feature that determines how stream of records (usually CSV lines, but sometimes
* multiple lines when linefeeds are included in quoted values) is exposed:
Expand Down Expand Up @@ -802,27 +802,36 @@ protected JsonToken _handleArrayValue() throws IOException
/**
* Method called to process the expected header line
*/
protected void _readHeaderLine() throws IOException
{
/* Two separate cases:
*
* (a) We already have a Schema with columns; if so, header will be skipped
* (b) Otherwise, need to find column definitions; empty one is not acceptable
protected void _readHeaderLine() throws IOException {
/*
When the header line is present and the settings ask for it
to be processed, two different options are possible:

a) The schema has been populated. In this case, build a new
schema where the order matches the *actual* order in which
the given CSV file offers its columns, iif _schema.reordersColumns()
is set to true; there cases the consumer of the csv file
knows about the columns but not necessarily the order in
which they are defined.

b) The schema has not been populated. In this case, build a
default schema based on the columns found in the header.
*/

if (_schema.size() > 0) { // case (a); skip all/any
while (_reader.nextString() != null) { }
if (_schema.size() > 0 && !_schema.reordersColumns()) {
//noinspection StatementWithEmptyBody
while (_reader.nextString() != null) { /* does nothing */ }
return;
}
// case (b); read all

// either the schema is empty or reorder columns flag is set
String name;
// base setting on existing schema, but drop columns
CsvSchema.Builder builder = _schema.rebuild().clearColumns();

while ((name = _reader.nextString()) != null) {
// one more thing: always trim names, regardless of config settings
name = name.trim();

// See if "old" schema defined type; if so, use that type...
CsvSchema.Column prev = _schema.column(name);
if (prev != null) {
Expand All @@ -831,6 +840,7 @@ protected void _readHeaderLine() throws IOException
builder.addColumn(name);
}
}

// Ok: did we get any columns?
CsvSchema newSchema = builder.build();
int size = newSchema.size();
Expand Down
27 changes: 27 additions & 0 deletions src/main/java/com/fasterxml/jackson/dataformat/csv/CsvSchema.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ public class CsvSchema
protected final static int ENCODING_FEATURE_USE_HEADER = 0x0001;
protected final static int ENCODING_FEATURE_SKIP_FIRST_DATA_ROW = 0x0002;
protected final static int ENCODING_FEATURE_ALLOW_COMMENTS = 0x0004;
protected final static int ENCODING_FEATURE_REORDER_COLUMNS = 0x0008;

protected final static int DEFAULT_ENCODING_FEATURES = 0;

Expand Down Expand Up @@ -454,6 +455,19 @@ public Builder setUseHeader(boolean b) {
return this;
}

/**
* Use in combination with setUseHeader. When use header flag is
* is set, this setting will reorder the columns defined in this
* schema to match the order set by the header.
*
* @param b Enable / Disable this setting
* @return This Builder instance
*/
public Builder setReorderColumns(boolean b) {
_feature(ENCODING_FEATURE_REORDER_COLUMNS, b);
return this;
}

/**
* Method for specifying whether Schema should indicate that
* the first line that is not a header (if header handling enabled)
Expand Down Expand Up @@ -774,6 +788,18 @@ public CsvSchema withUseHeader(boolean state) {
return _withFeature(ENCODING_FEATURE_USE_HEADER, state);
}

/**
* Returns a clone of this instance by changing or setting the
* column reordering flag
*
* @param state New value for setting
* @return A copy of itself, ensuring the setting for
* the column reordering feature.
*/
public CsvSchema withColumnReordering(boolean state) {
return _withFeature(ENCODING_FEATURE_REORDER_COLUMNS, state);
}

/**
* Helper method for constructing and returning schema instance that
* is similar to this one, except that it will be using header line.
Expand Down Expand Up @@ -968,6 +994,7 @@ public String getSchemaType() {
*/

public boolean usesHeader() { return (_features & ENCODING_FEATURE_USE_HEADER) != 0; }
public boolean reordersColumns() { return (_features & ENCODING_FEATURE_REORDER_COLUMNS) != 0; }
public boolean skipsFirstDataRow() { return (_features & ENCODING_FEATURE_SKIP_FIRST_DATA_ROW) != 0; }
public boolean allowsComments() { return (_features & ENCODING_FEATURE_ALLOW_COMMENTS) != 0; }

Expand Down
Loading