From 129f9ba1abd5ed3a5d0f74c8270130c3715443ba Mon Sep 17 00:00:00 2001 From: Konstantin Labun Date: Thu, 15 Sep 2016 05:57:40 +0300 Subject: [PATCH] Fix #929 (Multi-args @JsonCreator for Enums) --- .../deser/BasicDeserializerFactory.java | 18 +++++------ .../std/FactoryBasedEnumDeserializer.java | 2 +- .../databind/creators/EnumCreatorTest.java | 20 ++++++++++++ .../jackson/failing/EnumCreatorTest929.java | 31 ------------------- 4 files changed, 28 insertions(+), 43 deletions(-) delete mode 100644 src/test/java/com/fasterxml/jackson/failing/EnumCreatorTest929.java diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java index 07e581ca74..9fd69e70af 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java @@ -1241,20 +1241,16 @@ public JsonDeserializer createEnumDeserializer(DeserializationContext ctxt, // May have @JsonCreator for static factory method: for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) { if (ctxt.getAnnotationIntrospector().hasCreatorAnnotation(factory)) { - int argCount = factory.getParameterCount(); - if (argCount == 1) { - Class returnType = factory.getRawReturnType(); - // usually should be class, but may be just plain Enum (for Enum.valueOf()?) - if (returnType.isAssignableFrom(enumClass)) { - deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory, valueInstantiator, creatorProps); - break; - } - } else if (argCount == 0) { // [databind#960] + if (factory.getParameterCount() == 0) { // [databind#960] deser = EnumDeserializer.deserializerForNoArgsCreator(config, enumClass, factory); break; } - throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type " - +enumClass.getName()+")"); + Class returnType = factory.getRawReturnType(); + // usually should be class, but may be just plain Enum (for Enum.valueOf()?) + if (returnType.isAssignableFrom(enumClass)) { + deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory, valueInstantiator, creatorProps); + break; + } } } diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java index a0e3f11191..12cbc7482b 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/FactoryBasedEnumDeserializer.java @@ -92,7 +92,7 @@ public JsonDeserializer createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException { - if ((_deser == null) && (_inputType != null)) { + if ((_deser == null) && (_inputType != null) && (_creatorProps == null)) { return new FactoryBasedEnumDeserializer(this, ctxt.findContextualValueDeserializer(_inputType, property)); } diff --git a/src/test/java/com/fasterxml/jackson/databind/creators/EnumCreatorTest.java b/src/test/java/com/fasterxml/jackson/databind/creators/EnumCreatorTest.java index 7b4734fb3e..fc177e8cf7 100644 --- a/src/test/java/com/fasterxml/jackson/databind/creators/EnumCreatorTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/creators/EnumCreatorTest.java @@ -172,6 +172,19 @@ public String toString() { } } + + static enum Enum929 + { + A, B, C; + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + static Enum929 forValues(@JsonProperty("id") int intProp, + @JsonProperty("name") String name) + { + return Enum929.valueOf(name); + } + } + /* /********************************************************** /* Test methods @@ -272,4 +285,11 @@ public void testEnumCreators1291() throws Exception Enum1291 result = mapper.readValue(json, Enum1291.class); assertSame(Enum1291.V2, result); } + + // for [databind#929] + public void testMultiArgEnumCreator() throws Exception + { + Enum929 v = MAPPER.readValue("{\"id\":3,\"name\":\"B\"}", Enum929.class); + assertEquals(Enum929.B, v); + } } diff --git a/src/test/java/com/fasterxml/jackson/failing/EnumCreatorTest929.java b/src/test/java/com/fasterxml/jackson/failing/EnumCreatorTest929.java deleted file mode 100644 index b5a9e281aa..0000000000 --- a/src/test/java/com/fasterxml/jackson/failing/EnumCreatorTest929.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.fasterxml.jackson.failing; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.*; - -// Ideally should allow multiple-parameter Creator; but not -// yet allowed or supported -public class EnumCreatorTest929 extends BaseMapTest -{ - static enum MyEnum - { - A, B, C; - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - static MyEnum forValues(@JsonProperty("id") int intProp, - @JsonProperty("name") String name) - { - return MyEnum.valueOf(name); - } - } - - private final ObjectMapper MAPPER = new ObjectMapper(); - - // for [databind#929] - public void testMultiArgEnumCreator() throws Exception - { - MyEnum v = MAPPER.readValue("{\"id\":3,\"name\":\"B\"}", MyEnum.class); - assertEquals(MyEnum.B, v); - } -}