diff options
author | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-06-18 19:52:36 -0700 |
---|---|---|
committer | Tatu Saloranta <tatu.saloranta@iki.fi> | 2020-06-18 19:52:36 -0700 |
commit | 67764a75e3689111b91f40be7507ec3de9e130a5 (patch) | |
tree | de059fca7762aa59b8f07cee5a261619d2c7f0dd /src | |
parent | a5c8f5836a60034b86821fdde699de85e96c55e2 (diff) | |
download | jackson-databind-67764a75e3689111b91f40be7507ec3de9e130a5.tar.gz |
Start work on fixing #2767
Diffstat (limited to 'src')
3 files changed, 86 insertions, 13 deletions
diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java index c16ff697c..40986330d 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumMapDeserializer.java @@ -124,7 +124,7 @@ public class EnumMapDeserializer /* Validation, post-processing (ResolvableDeserializer) /********************************************************** */ - + @Override public void resolve(DeserializationContext ctxt) throws JsonMappingException { @@ -234,18 +234,18 @@ public class EnumMapDeserializer return (EnumMap<?,?>) _valueInstantiator.createUsingDelegate(ctxt, _delegateDeserializer.deserialize(p, ctxt)); } - // Ok: must point to START_OBJECT - JsonToken t = p.currentToken(); - if ((t != JsonToken.START_OBJECT) && (t != JsonToken.FIELD_NAME) && (t != JsonToken.END_OBJECT)) { - // (empty) String may be ok however; or single-String-arg ctor - if (t == JsonToken.VALUE_STRING) { - return (EnumMap<?,?>) _valueInstantiator.createFromString(ctxt, p.getText()); - } - // slightly redundant (since String was passed above), but also handles empty array case: - return _deserializeFromEmpty(p, ctxt); + // Ok: must point to START_OBJECT (or similar) + switch (p.currentTokenId()) { + case JsonTokenId.ID_START_OBJECT: + case JsonTokenId.ID_END_OBJECT: + case JsonTokenId.ID_FIELD_NAME: + return deserialize(p, ctxt, constructMap(ctxt)); + case JsonTokenId.ID_STRING: + return (EnumMap<?,?>) _valueInstantiator.createFromString(ctxt, p.getText()); + default: } - EnumMap result = constructMap(ctxt); - return deserialize(p, ctxt, result); + // slightly redundant (since String was passed above), but also handles empty array case: + return _deserializeFromEmpty(p, ctxt); } @Override diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKScalarsTest.java b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKScalarsTest.java index 48070ed40..cdf9ec1ac 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKScalarsTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKScalarsTest.java @@ -118,7 +118,7 @@ public class JDKScalarsTest public Void value; } - private final ObjectMapper MAPPER = new ObjectMapper(); + private final ObjectMapper MAPPER = newJsonMapper(); /* /********************************************************** diff --git a/src/test/java/com/fasterxml/jackson/failing/UnwrapSingleArrayMiscTest.java b/src/test/java/com/fasterxml/jackson/failing/UnwrapSingleArrayMiscTest.java new file mode 100644 index 000000000..f00485e49 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/failing/UnwrapSingleArrayMiscTest.java @@ -0,0 +1,73 @@ +package com.fasterxml.jackson.failing; + +import java.util.Collections; +import java.util.EnumMap; +import java.util.Map; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.exc.MismatchedInputException; + +public class UnwrapSingleArrayMiscTest extends BaseMapTest +{ + private final ObjectMapper UNWRAPPING_MAPPER = jsonMapperBuilder() + .enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS) + .build(); + + /* + /********************************************************** + /* Tests methods, POJOs + /********************************************************** + */ + + public void testSimplePOJOUnwrapping() throws Exception + { + ObjectReader r = UNWRAPPING_MAPPER.readerFor(IntWrapper.class); + IntWrapper w = r.readValue(aposToQuotes("[{'i':42}]")); + assertEquals(42, w.i); + + try { + r.readValue(aposToQuotes("[{'i':42},{'i':16}]")); + fail("Did not throw exception while reading a value from a multi value array"); + } catch (MismatchedInputException e) { + verifyException(e, "more than one value"); + } + } + + /* + /********************************************************** + /* Tests methods, Maps + /********************************************************** + */ + + // [databind#2767]: should work for Maps, too + public void testSimpleMapUnwrapping() throws Exception + { + ObjectReader r = UNWRAPPING_MAPPER.readerFor(Map.class); + Map<String,Object> m = r.readValue(aposToQuotes("[{'stuff':42}]")); + assertEquals(Collections.<String,Object>singletonMap("stuff", Integer.valueOf(42)), m); + + try { + r.readValue(aposToQuotes("[{'i':42},{'i':16}]")); + fail("Did not throw exception while reading a value from a multi value array"); + } catch (MismatchedInputException e) { + verifyException(e, "more than one value"); + } + } + + public void testEnumMapUnwrapping() throws Exception + { + ObjectReader r = UNWRAPPING_MAPPER.readerFor(new TypeReference<EnumMap<ABC,Integer>>() { }); + EnumMap<ABC,Integer> m = r.readValue(aposToQuotes("[{'A':42}]")); + EnumMap<ABC,Integer> exp = new EnumMap<>(ABC.class); + exp.put(ABC.A, Integer.valueOf(42)); + assertEquals(exp, m); + + try { + r.readValue(aposToQuotes("[{'A':42},{'B':13}]")); + fail("Did not throw exception while reading a value from a multi value array"); + } catch (MismatchedInputException e) { + verifyException(e, "more than one value"); + } + } +} |