From 3f942182890de88d99ad3eb18c2fca5540a029a0 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Mon, 8 Oct 2018 21:50:43 -0700 Subject: [PATCH] Fix a problem with enabling/disabling `JsonReadFeature`s for `ObjectReader` --- .../databind/DeserializationConfig.java | 74 ++++++++++++++++++- .../jackson/databind/FullStreamReadTest.java | 12 +-- .../jackson/databind/ObjectMapperTest.java | 24 +++--- .../jackson/databind/ObjectReaderTest.java | 8 +- 4 files changed, 95 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java index 8867935fce..8ff4d1461d 100644 --- a/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java +++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationConfig.java @@ -3,7 +3,7 @@ import java.util.*; import com.fasterxml.jackson.core.*; - +import com.fasterxml.jackson.core.json.JsonReadFeature; import com.fasterxml.jackson.databind.cfg.*; import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; import com.fasterxml.jackson.databind.introspect.*; @@ -498,6 +498,10 @@ public DeserializationConfig withoutFeatures(JsonParser.Feature... features) */ public DeserializationConfig with(FormatFeature feature) { + // 08-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features: + if (feature instanceof JsonReadFeature) { + return _withJsonReadFeatures(feature); + } int newSet = _formatReadFeatures | feature.getMask(); int newMask = _formatReadFeaturesToChange | feature.getMask(); return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask)) ? this : @@ -514,6 +518,10 @@ public DeserializationConfig with(FormatFeature feature) */ public DeserializationConfig withFeatures(FormatFeature... features) { + // 08-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features: + if (features.length > 0 && (features[0] instanceof JsonReadFeature)) { + return _withJsonReadFeatures(features); + } int newSet = _formatReadFeatures; int newMask = _formatReadFeaturesToChange; for (FormatFeature f : features) { @@ -535,6 +543,10 @@ public DeserializationConfig withFeatures(FormatFeature... features) */ public DeserializationConfig without(FormatFeature feature) { + // 08-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features: + if (feature instanceof JsonReadFeature) { + return _withoutJsonReadFeatures(feature); + } int newSet = _formatReadFeatures & ~feature.getMask(); int newMask = _formatReadFeaturesToChange | feature.getMask(); return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask)) ? this : @@ -551,6 +563,10 @@ public DeserializationConfig without(FormatFeature feature) */ public DeserializationConfig withoutFeatures(FormatFeature... features) { + // 08-Oct-2018, tatu: Alas, complexity due to newly (2.10) refactored json-features: + if (features.length > 0 && (features[0] instanceof JsonReadFeature)) { + return _withoutJsonReadFeatures(features); + } int newSet = _formatReadFeatures; int newMask = _formatReadFeaturesToChange; for (FormatFeature f : features) { @@ -562,7 +578,61 @@ public DeserializationConfig withoutFeatures(FormatFeature... features) new DeserializationConfig(this, _mapperFeatures, _deserFeatures, _parserFeatures, _parserFeaturesToChange, newSet, newMask); - } + } + + // temporary for 2.10 + private DeserializationConfig _withJsonReadFeatures(FormatFeature... features) { + int parserSet = _parserFeatures; + int parserMask = _parserFeaturesToChange; + int newSet = _formatReadFeatures; + int newMask = _formatReadFeaturesToChange; + for (FormatFeature f : features) { + final int mask = f.getMask(); + newSet |= mask; + newMask |= mask; + + if (f instanceof JsonReadFeature) { + JsonParser.Feature oldF = ((JsonReadFeature) f).mappedFeature(); + if (oldF != null) { + final int pmask = oldF.getMask(); + parserSet |= pmask; + parserMask |= pmask; + } + } + } + return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask) + && (_parserFeatures == parserSet) && (_parserFeaturesToChange == parserMask) + ) ? this : + new DeserializationConfig(this, _mapperFeatures, _deserFeatures, + parserSet, parserMask, newSet, newMask); + } + + // temporary for 2.10 + private DeserializationConfig _withoutJsonReadFeatures(FormatFeature... features) { + int parserSet = _parserFeatures; + int parserMask = _parserFeaturesToChange; + int newSet = _formatReadFeatures; + int newMask = _formatReadFeaturesToChange; + for (FormatFeature f : features) { + final int mask = f.getMask(); + newSet &= ~mask; + newMask |= mask; + + if (f instanceof JsonReadFeature) { + JsonParser.Feature oldF = ((JsonReadFeature) f).mappedFeature(); + if (oldF != null) { + final int pmask = oldF.getMask(); + parserSet &= ~pmask; + parserMask |= pmask; + } + } + } + return ((_formatReadFeatures == newSet) && (_formatReadFeaturesToChange == newMask) + && (_parserFeatures == parserSet) && (_parserFeaturesToChange == parserMask) + ) ? this : + new DeserializationConfig(this, _mapperFeatures, _deserFeatures, + parserSet, parserMask, newSet, newMask); + } /* /********************************************************** diff --git a/src/test/java/com/fasterxml/jackson/databind/FullStreamReadTest.java b/src/test/java/com/fasterxml/jackson/databind/FullStreamReadTest.java index 6bfa5cc941..c3b0396e4b 100644 --- a/src/test/java/com/fasterxml/jackson/databind/FullStreamReadTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/FullStreamReadTest.java @@ -3,7 +3,8 @@ import java.util.*; import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.json.JsonReadFeature; + import com.fasterxml.jackson.databind.exc.MismatchedInputException; public class FullStreamReadTest extends BaseMapTest @@ -81,10 +82,11 @@ public void testMapperFailOnTrailing() throws Exception verifyException(e, "maybe a (non-standard) comment"); } - ObjectMapper strictWithComments = strict.copy(); - strictWithComments.enable(JsonParser.Feature.ALLOW_COMMENTS); + ObjectReader strictWithComments = strict.reader() + .with(JsonReadFeature.ALLOW_JAVA_COMMENTS); _verifyArray(strictWithComments.readTree(JSON_OK_ARRAY_WITH_COMMENT)); - _verifyCollection(strictWithComments.readValue(JSON_OK_ARRAY_WITH_COMMENT, List.class)); + _verifyCollection((List) strictWithComments.forType(List.class) + .readValue(JSON_OK_ARRAY_WITH_COMMENT)); } public void testReaderAcceptTrailing() throws Exception @@ -153,7 +155,7 @@ public void testReaderFailOnTrailing() throws Exception // but works if comments enabled etc - ObjectReader strictRWithComments = strictR.with(JsonParser.Feature.ALLOW_COMMENTS); + ObjectReader strictRWithComments = strictR.with(JsonReadFeature.ALLOW_JAVA_COMMENTS); _verifyCollection((List)strictRWithComments.forType(List.class).readValue(JSON_OK_ARRAY_WITH_COMMENT)); _verifyArray(strictRWithComments.readTree(JSON_OK_ARRAY_WITH_COMMENT)); diff --git a/src/test/java/com/fasterxml/jackson/databind/ObjectMapperTest.java b/src/test/java/com/fasterxml/jackson/databind/ObjectMapperTest.java index 554b401ee3..582ffa731f 100644 --- a/src/test/java/com/fasterxml/jackson/databind/ObjectMapperTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/ObjectMapperTest.java @@ -77,7 +77,7 @@ public void testParserFeatures() ObjectMapper mapper = new ObjectMapper(); assertTrue(mapper.isEnabled(JsonParser.Feature.AUTO_CLOSE_SOURCE)); - assertFalse(mapper.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); + assertFalse(mapper.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); mapper.disable(JsonParser.Feature.AUTO_CLOSE_SOURCE, JsonParser.Feature.STRICT_DUPLICATE_DETECTION); @@ -99,9 +99,9 @@ public void testCopy() throws Exception assertFalse(m.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)); InjectableValues inj = new InjectableValues.Std(); m.setInjectableValues(inj); - assertFalse(m.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); - m.enable(JsonParser.Feature.ALLOW_COMMENTS); - assertTrue(m.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); + assertFalse(m.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); + m.enable(JsonParser.Feature.IGNORE_UNDEFINED); + assertTrue(m.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); // // First: verify that handling of features is decoupled: @@ -138,7 +138,7 @@ public void testCopy() throws Exception assertEquals(0, m2.getDeserializationConfig().mixInCount()); // [databind#913]: Ensure JsonFactory Features copied - assertTrue(m2.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); + assertTrue(m2.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); } // [databind#1580] @@ -347,17 +347,17 @@ public void testCopyOfParserFeatures() throws Exception { // ensure we have "fresh" instance to start with ObjectMapper mapper = new ObjectMapper(); - assertFalse(mapper.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); - mapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true); - assertTrue(mapper.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); + assertFalse(mapper.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); + mapper.configure(JsonParser.Feature.IGNORE_UNDEFINED, true); + assertTrue(mapper.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); ObjectMapper copy = mapper.copy(); - assertTrue(copy.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); + assertTrue(copy.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); // also verify there's no back-linkage - copy.configure(JsonParser.Feature.ALLOW_COMMENTS, false); - assertFalse(copy.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); - assertTrue(mapper.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); + copy.configure(JsonParser.Feature.IGNORE_UNDEFINED, false); + assertFalse(copy.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); + assertTrue(mapper.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); } // since 2.8 diff --git a/src/test/java/com/fasterxml/jackson/databind/ObjectReaderTest.java b/src/test/java/com/fasterxml/jackson/databind/ObjectReaderTest.java index 1d67d55783..015721ebb0 100644 --- a/src/test/java/com/fasterxml/jackson/databind/ObjectReaderTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/ObjectReaderTest.java @@ -7,7 +7,7 @@ import java.util.Set; import com.fasterxml.jackson.core.*; - +import com.fasterxml.jackson.core.json.JsonReadFeature; import com.fasterxml.jackson.databind.cfg.ContextAttributes; import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -51,7 +51,7 @@ public void testParserFeatures() throws Exception final String JSON = "[ /* foo */ 7 ]"; // default won't accept comments, let's change that: ObjectReader reader = MAPPER.readerFor(int[].class) - .with(JsonParser.Feature.ALLOW_COMMENTS); + .with(JsonReadFeature.ALLOW_JAVA_COMMENTS); int[] value = reader.readValue(JSON); assertNotNull(value); @@ -60,7 +60,7 @@ public void testParserFeatures() throws Exception // but also can go back try { - reader.without(JsonParser.Feature.ALLOW_COMMENTS).readValue(JSON); + reader.without(JsonReadFeature.ALLOW_JAVA_COMMENTS).readValue(JSON); fail("Should not have passed"); } catch (JsonProcessingException e) { verifyException(e, "foo"); @@ -81,7 +81,7 @@ public void testFeatureSettings() throws Exception { ObjectReader r = MAPPER.reader(); assertFalse(r.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES)); - assertFalse(r.isEnabled(JsonParser.Feature.ALLOW_COMMENTS)); + assertFalse(r.isEnabled(JsonParser.Feature.IGNORE_UNDEFINED)); r = r.withoutFeatures(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, DeserializationFeature.FAIL_ON_INVALID_SUBTYPE);