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

Option to force quoting of empty strings #127

Merged
merged 1 commit into from
Aug 25, 2016
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
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ public enum Feature
* @since 2.5
*/
ALWAYS_QUOTE_STRINGS(false),

/**
* Feature that determines whether values written as empty Strings (from <code>java.lang.String</code>
* valued POJO properties) should be forced to be quoted.
*/
ALWAYS_QUOTE_EMPTY_STRINGS(false),
;

protected final boolean _defaultState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ public class CsvEncoder
* @since 2.5
*/
protected boolean _cfgAlwaysQuoteStrings;

protected boolean _cfgAlwaysQuoteEmptyStrings;

/*
/**********************************************************
Expand Down Expand Up @@ -166,6 +168,7 @@ public CsvEncoder(IOContext ctxt, int csvFeatures, Writer out, CsvSchema schema)
_cfgOptimalQuoting = CsvGenerator.Feature.STRICT_CHECK_FOR_QUOTING.enabledIn(csvFeatures);
_cfgIncludeMissingTail = !CsvGenerator.Feature.OMIT_MISSING_TAIL_COLUMNS.enabledIn(_csvFeatures);
_cfgAlwaysQuoteStrings = CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS.enabledIn(csvFeatures);
_cfgAlwaysQuoteEmptyStrings = CsvGenerator.Feature.ALWAYS_QUOTE_EMPTY_STRINGS.enabledIn(csvFeatures);

_outputBuffer = ctxt.allocConcatBuffer();
_bufferRecyclable = true;
Expand Down Expand Up @@ -193,7 +196,8 @@ public CsvEncoder(CsvEncoder base, CsvSchema newSchema)
_cfgOptimalQuoting = base._cfgOptimalQuoting;
_cfgIncludeMissingTail = base._cfgIncludeMissingTail;
_cfgAlwaysQuoteStrings = base._cfgAlwaysQuoteStrings;

_cfgAlwaysQuoteEmptyStrings = base._cfgAlwaysQuoteEmptyStrings;

_outputBuffer = base._outputBuffer;
_bufferRecyclable = base._bufferRecyclable;
_outputEnd = base._outputEnd;
Expand Down Expand Up @@ -232,6 +236,7 @@ public CsvEncoder overrideFormatFeatures(int feat) {
_cfgOptimalQuoting = CsvGenerator.Feature.STRICT_CHECK_FOR_QUOTING.enabledIn(feat);
_cfgIncludeMissingTail = !CsvGenerator.Feature.OMIT_MISSING_TAIL_COLUMNS.enabledIn(feat);
_cfgAlwaysQuoteStrings = CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS.enabledIn(feat);
_cfgAlwaysQuoteEmptyStrings = CsvGenerator.Feature.ALWAYS_QUOTE_EMPTY_STRINGS.enabledIn(feat);
}
return this;
}
Expand Down Expand Up @@ -870,6 +875,9 @@ protected boolean _mayNeedQuotes(String value, int length)
if (_cfgEscapeCharacter > 0) {
return _needsQuotingLoose(value, _cfgEscapeCharacter);
}
if (_cfgAlwaysQuoteEmptyStrings && length == 0) {
return true;
}
return _needsQuotingLoose(value);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,20 +190,39 @@ public void testForcedQuoting60() throws Exception
CsvMapper mapper = mapperForCsv();
mapper.enable(CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS);
CsvSchema schema = CsvSchema.builder()
.addColumn("id")
.addColumn("amount")
.build();
.addColumn("id")
.addColumn("amount")
.build();
String result = mapper.writer(schema)
.writeValueAsString(new Entry("abc", 1.25));
.writeValueAsString(new Entry("abc", 1.25));
assertEquals("\"abc\",1.25\n", result);

// Also, as per [dataformat-csv#81], should be possible to change dynamically
result = mapper.writer(schema)
.without(CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS)
.writeValueAsString(new Entry("xyz", 2.5));
.without(CsvGenerator.Feature.ALWAYS_QUOTE_STRINGS)
.writeValueAsString(new Entry("xyz", 2.5));
assertEquals("xyz,2.5\n", result);
}

public void testForcedQuotingEmptyStrings() throws Exception
{
CsvMapper mapper = mapperForCsv();
mapper.enable(CsvGenerator.Feature.ALWAYS_QUOTE_EMPTY_STRINGS);
CsvSchema schema = CsvSchema.builder()
.addColumn("id")
.addColumn("amount")
.build();
String result = mapper.writer(schema)
.writeValueAsString(new Entry("", 1.25));
assertEquals("\"\",1.25\n", result);

// Also, as per [dataformat-csv#81], should be possible to change dynamically
result = mapper.writer(schema)
.without(CsvGenerator.Feature.ALWAYS_QUOTE_EMPTY_STRINGS)
.writeValueAsString(new Entry("", 2.5));
assertEquals(",2.5\n", result);
}

// Must comment '#', at least if it starts the line
public void testQuotingOfCommentChar() throws Exception
{
Expand Down