Whops! Was actually able to complete [JACKSON-756] fix for 1.9 as well as 2.x...
diff --git a/src/mapper/java/org/codehaus/jackson/map/SerializationConfig.java b/src/mapper/java/org/codehaus/jackson/map/SerializationConfig.java
index 578f8f5..2cfac31 100644
--- a/src/mapper/java/org/codehaus/jackson/map/SerializationConfig.java
+++ b/src/mapper/java/org/codehaus/jackson/map/SerializationConfig.java
@@ -934,7 +934,6 @@
* @deprecated since 1.9 should either use {@link #withSerializationInclusion}
* to construct new instance, or configure through {@link ObjectMapper}
*/
- @SuppressWarnings("deprecation")
@Deprecated
public void setSerializationInclusion(JsonSerialize.Inclusion props)
{
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/BeanDeserializerFactory.java b/src/mapper/java/org/codehaus/jackson/map/deser/BeanDeserializerFactory.java
index 5a6d46a..0b0be35 100644
--- a/src/mapper/java/org/codehaus/jackson/map/deser/BeanDeserializerFactory.java
+++ b/src/mapper/java/org/codehaus/jackson/map/deser/BeanDeserializerFactory.java
@@ -12,6 +12,7 @@
import org.codehaus.jackson.map.type.*;
import org.codehaus.jackson.map.util.ArrayBuilders;
import org.codehaus.jackson.map.util.ClassUtil;
+import org.codehaus.jackson.map.util.EnumResolver;
import org.codehaus.jackson.type.JavaType;
/**
@@ -316,12 +317,45 @@
}
// And then other one-offs; first, Enum:
if (type.isEnumType()) {
- return StdKeyDeserializers.constructEnumKeyDeserializer(config, type);
+ return _createEnumKeyDeserializer(config, type, property);
}
// One more thing: can we find ctor(String) or valueOf(String)?
kdes = StdKeyDeserializers.findStringBasedKeyDeserializer(config, type);
return kdes;
}
+
+ private KeyDeserializer _createEnumKeyDeserializer(DeserializationConfig config, JavaType type,
+ BeanProperty property)
+ throws JsonMappingException
+ {
+ BasicBeanDescription beanDesc = config.introspect(type);
+ Class<?> enumClass = type.getRawClass();
+ EnumResolver<?> enumRes = constructEnumResolver(enumClass, config);
+ // [JACKSON-193] May have @JsonCreator for static factory method:
+ for (AnnotatedMethod factory : beanDesc.getFactoryMethods()) {
+ if (config.getAnnotationIntrospector().hasCreatorAnnotation(factory)) {
+ int argCount = factory.getParameterCount();
+ if (argCount == 1) {
+ Class<?> returnType = factory.getRawType();
+ // usually should be class, but may be just plain Enum<?> (for Enum.valueOf()?)
+ if (returnType.isAssignableFrom(enumClass)) {
+ // note: mostly copied from 'EnumDeserializer.deserializerForCreator(...)'
+ if (factory.getParameterType(0) != String.class) {
+ throw new IllegalArgumentException("Parameter #0 type for factory method ("+factory+") not suitable, must be java.lang.String");
+ }
+ if (config.canOverrideAccessModifiers()) {
+ ClassUtil.checkAndFixAccess(factory.getMember());
+ }
+ return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes, factory);
+ }
+ }
+ throw new IllegalArgumentException("Unsuitable method ("+factory+") decorated with @JsonCreator (for Enum type "
+ +enumClass.getName()+")");
+ }
+ }
+ // [JACKSON-749] Also, need to consider @JsonValue, if one found
+ return StdKeyDeserializers.constructEnumKeyDeserializer(enumRes);
+ }
@Override
protected JsonDeserializer<?> _findCustomArrayDeserializer(ArrayType type, DeserializationConfig config,
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/std/StdKeyDeserializer.java b/src/mapper/java/org/codehaus/jackson/map/deser/std/StdKeyDeserializer.java
index 4b8a459..524a3f2 100644
--- a/src/mapper/java/org/codehaus/jackson/map/deser/std/StdKeyDeserializer.java
+++ b/src/mapper/java/org/codehaus/jackson/map/deser/std/StdKeyDeserializer.java
@@ -8,6 +8,8 @@
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.io.NumberInput;
import org.codehaus.jackson.map.*;
+import org.codehaus.jackson.map.introspect.AnnotatedMethod;
+import org.codehaus.jackson.map.util.ClassUtil;
import org.codehaus.jackson.map.util.EnumResolver;
/**
@@ -223,15 +225,24 @@
{
protected final EnumResolver<?> _resolver;
- protected EnumKD(EnumResolver<?> er)
- {
+ protected final AnnotatedMethod _factory;
+
+ protected EnumKD(EnumResolver<?> er, AnnotatedMethod factory) {
super(er.getEnumClass());
_resolver = er;
+ _factory = factory;
}
@Override
- public Enum<?> _parse(String key, DeserializationContext ctxt) throws JsonMappingException
+ public Object _parse(String key, DeserializationContext ctxt) throws JsonMappingException
{
+ if (_factory != null) {
+ try {
+ return _factory.call1(key);
+ } catch (Exception e) {
+ ClassUtil.unwrapAndThrowAsIAE(e);
+ }
+ }
Enum<?> e = _resolver.findEnum(key);
if (e == null) {
throw ctxt.weirdKeyException(_keyClass, key, "not one of values for Enum class");
diff --git a/src/mapper/java/org/codehaus/jackson/map/deser/std/StdKeyDeserializers.java b/src/mapper/java/org/codehaus/jackson/map/deser/std/StdKeyDeserializers.java
index 1518fad..a121925 100644
--- a/src/mapper/java/org/codehaus/jackson/map/deser/std/StdKeyDeserializers.java
+++ b/src/mapper/java/org/codehaus/jackson/map/deser/std/StdKeyDeserializers.java
@@ -7,6 +7,7 @@
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.KeyDeserializer;
import org.codehaus.jackson.map.type.*;
+import org.codehaus.jackson.map.introspect.AnnotatedMethod;
import org.codehaus.jackson.map.introspect.BasicBeanDescription;
import org.codehaus.jackson.map.util.ClassUtil;
import org.codehaus.jackson.map.util.EnumResolver;
@@ -67,11 +68,14 @@
{
return StdKeyDeserializer.StringKD.forType(type.getClass());
}
-
- public static KeyDeserializer constructEnumKeyDeserializer(DeserializationConfig config, JavaType type)
- {
- EnumResolver<?> er = EnumResolver.constructUnsafe(type.getRawClass(), config.getAnnotationIntrospector());
- return new StdKeyDeserializer.EnumKD(er);
+
+ public static KeyDeserializer constructEnumKeyDeserializer(EnumResolver<?> enumResolver) {
+ return new StdKeyDeserializer.EnumKD(enumResolver, null);
+ }
+
+ public static KeyDeserializer constructEnumKeyDeserializer(EnumResolver<?> enumResolver,
+ AnnotatedMethod factory) {
+ return new StdKeyDeserializer.EnumKD(enumResolver, factory);
}
public static KeyDeserializer findStringBasedKeyDeserializer(DeserializationConfig config, JavaType type)
diff --git a/src/test/org/codehaus/jackson/map/deser/TestEnumDeserialization.java b/src/test/org/codehaus/jackson/map/deser/TestEnumDeserialization.java
index 54461ca..39a61dd 100644
--- a/src/test/org/codehaus/jackson/map/deser/TestEnumDeserialization.java
+++ b/src/test/org/codehaus/jackson/map/deser/TestEnumDeserialization.java
@@ -207,8 +207,6 @@
assertEquals("value", value.get(EnumWithCreator.A));
}
- /*
- // 17-Jan-2012, Tatu: Turns out I have to punt full fix up to 2.0; requires API change.
public void testEnumWithCreatorMaps() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
@@ -216,7 +214,6 @@
new TypeReference<java.util.HashMap<EnumWithCreator,String>>() {});
assertEquals("value", value.get(EnumWithCreator.A));
}
- */
public void testEnumWithCreatorEnumSets() throws Exception
{
diff --git a/src/test/org/codehaus/jackson/map/ser/TestNullSerialization.java b/src/test/org/codehaus/jackson/map/ser/TestNullSerialization.java
index 80fef9e..37b0947 100644
--- a/src/test/org/codehaus/jackson/map/ser/TestNullSerialization.java
+++ b/src/test/org/codehaus/jackson/map/ser/TestNullSerialization.java
@@ -4,6 +4,8 @@
import org.codehaus.jackson.*;
import org.codehaus.jackson.map.*;
+import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
+import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
public class TestNullSerialization
extends BaseMapTest
@@ -18,6 +20,18 @@
}
}
+ static class NullBean<T> {
+ public T value = null;
+
+ public NullBean(T v) { value = v; }
+ }
+
+ /*
+ /**********************************************************
+ /* Test methods
+ /**********************************************************
+ */
+
public void testSimple() throws Exception
{
assertEquals("null", new ObjectMapper().writeValueAsString(null));
@@ -31,4 +45,13 @@
m.setSerializerProvider(sp);
assertEquals("\"foobar\"", m.writeValueAsString(null));
}
+
+ public void testDefaultNonNull() throws Exception
+ {
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector());
+ mapper.setSerializationInclusion(Inclusion.NON_NULL);
+ assertEquals("{\"value\":\"abc\"}", mapper.writeValueAsString(new NullBean("abc")));
+ assertEquals("{}", mapper.writeValueAsString(new NullBean(null)));
+ }
}