Skip to content

Commit 1e05426

Browse files
committed
Fixed #130
1 parent f0e05b8 commit 1e05426

File tree

4 files changed

+68
-16
lines changed

4 files changed

+68
-16
lines changed

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ Modules:
1111
2.12.0 (not yet released)
1212

1313
#71: (yaml) Hex number as an entry of an Object causing problem(s) with binding to POJO
14+
#130: (yaml) Empty String deserialized as `null` instead of empty string
15+
(reported by iulianrosca@github)
1416
#175: (yaml) Add `YAMLGenerator.Feature.INDENT_ARRAYS_WITH_INDICATOR` to indent by 2 spaces
1517
(requested by Jesper N; fix contributed by Damian S)
1618
#199: (csv) Empty Lists can only be String-typed in CSV

yaml/src/main/java/com/fasterxml/jackson/dataformat/yaml/YAMLMapper.java

+24-3
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,30 @@ public Builder(YAMLMapper m) {
3131
/******************************************************************
3232
*/
3333

34-
// No Parser-features yet
35-
34+
public Builder enable(YAMLParser.Feature... features) {
35+
for (YAMLParser.Feature f : features) {
36+
_mapper.enable(f);
37+
}
38+
return this;
39+
}
40+
41+
public Builder disable(YAMLParser.Feature... features) {
42+
for (YAMLParser.Feature f : features) {
43+
_mapper.disable(f);
44+
}
45+
return this;
46+
}
47+
48+
public Builder configure(YAMLParser.Feature f, boolean state)
49+
{
50+
if (state) {
51+
_mapper.enable(f);
52+
} else {
53+
_mapper.disable(f);
54+
}
55+
return this;
56+
}
57+
3658
public Builder enable(YAMLGenerator.Feature... features) {
3759
for (YAMLGenerator.Feature f : features) {
3860
_mapper.enable(f);
@@ -71,7 +93,6 @@ public YAMLMapper(YAMLMapper base) {
7193
super(base);
7294
}
7395

74-
@SuppressWarnings("unchecked")
7596
public static YAMLMapper.Builder builder() {
7697
return new YAMLMapper.Builder(new YAMLMapper());
7798
}

yaml/src/main/java/com/fasterxml/jackson/dataformat/yaml/YAMLParser.java

+22-9
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,15 @@ public class YAMLParser extends ParserBase
3030
*/
3131
public enum Feature implements FormatFeature // in 2.9
3232
{
33+
/**
34+
* Feature that determines whether an empty {@link String} will be parsed
35+
* as {@code null}. Logic is part of YAML 1.1
36+
* <a href="https://yaml.org/type/null.html">Null Language-Independent Type</a>.
37+
*<p>
38+
* Feature is enabled by default in Jackson 2.12 for backwards-compatibility
39+
* reasons.
40+
*/
41+
EMPTY_STRING_AS_NULL(true)
3342
;
3443

3544
final boolean _defaultState;
@@ -84,6 +93,9 @@ private Feature(boolean defaultState) {
8493

8594
protected int _formatFeatures;
8695

96+
// @since 2.12
97+
protected boolean _cfgEmptyStringsToNull;
98+
8799
/*
88100
/**********************************************************************
89101
/* Input sources
@@ -164,9 +176,9 @@ public YAMLParser(IOContext ctxt, BufferRecycler br,
164176
_formatFeatures = formatFeatures;
165177
_reader = reader;
166178
_yamlParser = new ParserImpl(new StreamReader(reader));
179+
_cfgEmptyStringsToNull = Feature.EMPTY_STRING_AS_NULL.enabledIn(formatFeatures);
167180
}
168181

169-
170182
@Override
171183
public ObjectCodec getCodec() {
172184
return _objectCodec;
@@ -260,11 +272,11 @@ protected void _closeInput() throws IOException {
260272
_reader.close();
261273
}
262274
}
263-
275+
264276
/*
265-
/**********************************************************
277+
/**********************************************************
266278
/* FormatFeature support
267-
/**********************************************************
279+
/**********************************************************
268280
*/
269281

270282
@Override
@@ -275,6 +287,7 @@ public int getFormatFeatures() {
275287
@Override
276288
public JsonParser overrideFormatFeatures(int values, int mask) {
277289
_formatFeatures = (_formatFeatures & ~mask) | (values & mask);
290+
_cfgEmptyStringsToNull = Feature.EMPTY_STRING_AS_NULL.enabledIn(_formatFeatures);
278291
return this;
279292
}
280293

@@ -291,6 +304,7 @@ public JsonParser overrideFormatFeatures(int values, int mask) {
291304
public JsonParser enable(YAMLParser.Feature f)
292305
{
293306
_formatFeatures |= f.getMask();
307+
_cfgEmptyStringsToNull = Feature.EMPTY_STRING_AS_NULL.enabledIn(_formatFeatures);
294308
return this;
295309
}
296310

@@ -301,6 +315,7 @@ public JsonParser enable(YAMLParser.Feature f)
301315
public JsonParser disable(YAMLParser.Feature f)
302316
{
303317
_formatFeatures &= ~f.getMask();
318+
_cfgEmptyStringsToNull = Feature.EMPTY_STRING_AS_NULL.enabledIn(_formatFeatures);
304319
return this;
305320
}
306321

@@ -520,13 +535,11 @@ protected JsonToken _decodeScalar(ScalarEvent scalar) throws IOException
520535
_textValue = value;
521536
_cleanedTextValue = null;
522537

523-
// [dataformats-text#130]: uncomment for 2.13 either as-is, or
524-
// behind a new feature
525-
/*
526-
if (value.isEmpty()) {
538+
// [dataformats-text#130]: Allow determining whether empty String is
539+
// coerced into null or not
540+
if (!_cfgEmptyStringsToNull && value.isEmpty()) {
527541
return JsonToken.VALUE_STRING;
528542
}
529-
*/
530543

531544
// we may get an explicit tag, if so, use for corroborating...
532545
String typeTag = scalar.getTag();

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/failing/NullFromEmptyString130Test.java

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package com.fasterxml.jackson.dataformat.yaml.failing;
22

3-
import com.fasterxml.jackson.databind.ObjectMapper;
43
import com.fasterxml.jackson.dataformat.yaml.ModuleTestBase;
4+
import com.fasterxml.jackson.dataformat.yaml.YAMLMapper;
5+
import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
56

67
// [dataformats-text#130]: Easy enough to fix, if we choose to,
78
// but due to timing cannot include in 2.12 (too close to release
@@ -19,13 +20,28 @@ public void setValue(String str) {
1920
}
2021
}
2122

22-
private final ObjectMapper MAPPER = newObjectMapper();
23+
private final YAMLMapper MAPPER = newObjectMapper();
2324

2425
// [dataformats-text#130]
2526
public void testEmptyValueToNull130() throws Exception
2627
{
27-
Value130 v = MAPPER.readerFor(Value130.class)
28+
// by default, empy Strings are coerced:
29+
assertTrue(MAPPER.getFactory().isEnabled(YAMLParser.Feature.EMPTY_STRING_AS_NULL));
30+
31+
{
32+
Value130 v = MAPPER.readValue("value: \n", Value130.class);
33+
assertNull(v.value);
34+
v = MAPPER.readerFor(Value130.class)
35+
.readValue("value: \n");
36+
assertNull(v.value);
37+
}
38+
39+
// but can change that:
40+
{
41+
Value130 v = MAPPER.readerFor(Value130.class)
42+
.without(YAMLParser.Feature.EMPTY_STRING_AS_NULL)
2843
.readValue("value: \n");
29-
assertEquals("", v.value);
44+
assertEquals("", v.value);
45+
}
3046
}
3147
}

0 commit comments

Comments
 (0)