From cd5430a91723ff8cd61928524ec21ab4e14b20f6 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Wed, 2 Nov 2016 22:17:18 -0700 Subject: [PATCH] Fix #1441 --- release-notes/CREDITS | 4 +++ release-notes/VERSION | 2 ++ .../deser/std/StdKeyDeserializer.java | 11 +++++-- .../module/TestCustomEnumKeyDeserializer.java | 33 +++++++++++++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/release-notes/CREDITS b/release-notes/CREDITS index dca5c919e4..f857af7789 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -562,6 +562,10 @@ Kevin Donnelly (kpdonn@github) * Reported #1432: Off by 1 bug in PropertyValueBuffer (2.8.5) +Nathanial Ofiesh (ofiesh@github) + * Reported #1441: Failure with custom Enum key deserializer, polymorphic types + (2.8.5) + Connor Kuhn (ckuhn@github) * Contributed #1341: FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY (2.9.0) diff --git a/release-notes/VERSION b/release-notes/VERSION index ff258a0c6e..2d60984c14 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -12,6 +12,8 @@ Project: jackson-databind #1432: Off by 1 bug in PropertyValueBuffer (reported by Kevin D) #1439: NPE when using with filter id, serializing `java.util.Map` types +#1441: Failure with custom Enum key deserializer, polymorphic types + (reported by Nathanial O) - Improvements to #1411 fix to ensure consistent `null` key handling 2.8.4 (14-Oct-2016) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdKeyDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdKeyDeserializer.java index 5e353d3884..d1148bac16 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdKeyDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdKeyDeserializer.java @@ -8,6 +8,7 @@ import java.net.URL; import java.util.*; +import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.io.NumberInput; import com.fasterxml.jackson.databind.*; @@ -15,6 +16,7 @@ import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.EnumResolver; +import com.fasterxml.jackson.databind.util.TokenBuffer; /** * Default {@link KeyDeserializer} implementation used for most {@link java.util.Map} @@ -303,16 +305,21 @@ protected DelegatingKD(Class cls, JsonDeserializer deser) { _delegate = deser; } + @SuppressWarnings("resource") @Override public final Object deserializeKey(String key, DeserializationContext ctxt) - throws IOException, JsonProcessingException + throws IOException { if (key == null) { // is this even legal call? return null; } + TokenBuffer tb = new TokenBuffer(ctxt.getParser(), ctxt); + tb.writeString(key); try { // Ugh... should not have to give parser which may or may not be correct one... - Object result = _delegate.deserialize(ctxt.getParser(), ctxt); + JsonParser p = tb.asParser(); + p.nextToken(); + Object result = _delegate.deserialize(p, ctxt); if (result != null) { return result; } diff --git a/src/test/java/com/fasterxml/jackson/databind/module/TestCustomEnumKeyDeserializer.java b/src/test/java/com/fasterxml/jackson/databind/module/TestCustomEnumKeyDeserializer.java index 14757fbd7a..fb6320143d 100644 --- a/src/test/java/com/fasterxml/jackson/databind/module/TestCustomEnumKeyDeserializer.java +++ b/src/test/java/com/fasterxml/jackson/databind/module/TestCustomEnumKeyDeserializer.java @@ -6,6 +6,7 @@ import org.junit.Test; +import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.core.type.TypeReference; @@ -149,6 +150,17 @@ public void setupModule(SetupContext context) { } } + // for [databind#1441] + + enum SuperTypeEnum { + FOO; + } + + @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@type", defaultImpl = SuperType.class) + static class SuperType { + public Map someMap; + } + /* /********************************************************** /* Test methods @@ -190,4 +202,25 @@ public void withTree749() throws Exception String firstFieldName = inner.fieldNames().next(); assertEquals("green", firstFieldName); } + + // [databind#1441] + public void testCustomEnumKeySerializerWithPolymorphic() throws IOException + { + SimpleModule simpleModule = new SimpleModule(); + simpleModule.addDeserializer(SuperTypeEnum.class, new JsonDeserializer() { + @Override + public SuperTypeEnum deserialize(JsonParser p, DeserializationContext deserializationContext) + throws IOException + { + return SuperTypeEnum.valueOf(p.getText()); + } + }); + ObjectMapper mapper = new ObjectMapper() + .registerModule(simpleModule); + + SuperType superType = mapper.readValue("{\"someMap\": {\"FOO\": \"bar\"}}", + SuperType.class); + assertEquals("Deserialized someMap.FOO should equal bar", "bar", + superType.someMap.get(SuperTypeEnum.FOO)); + } }