Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,9 @@ public JsonDeserializer<?> createEnumDeserializer(DeserializationContext ctxt,
"Invalid `@JsonCreator` annotated Enum factory method [%s]: needs to return compatible type",
factory.toString()));
}
deser = EnumDeserializer.deserializerForCreator(config, enumClass, factory, valueInstantiator, creatorProps);
deser = EnumDeserializer.deserializerForCreator(
config, enumClass, factory, valueInstantiator, creatorProps,
constructEnumResolver(enumClass, config, beanDesc));
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public EnumDeserializer(EnumResolver byNameResolver) {
@Deprecated
public static JsonDeserializer<?> deserializerForCreator(DeserializationConfig config,
Class<?> enumClass, AnnotatedMethod factory) {
return deserializerForCreator(config, enumClass, factory, null, null);
return deserializerForCreator(config, enumClass, factory, null, null, null);
}

/**
Expand All @@ -172,16 +172,15 @@ public static JsonDeserializer<?> deserializerForCreator(DeserializationConfig c
* @since 2.8
*/
public static JsonDeserializer<?> deserializerForCreator(DeserializationConfig config,
Class<?> enumClass, AnnotatedMethod factory,
ValueInstantiator valueInstantiator, SettableBeanProperty[] creatorProps)
Class<?> enumClass, AnnotatedMethod factory, ValueInstantiator valueInstantiator,
SettableBeanProperty[] creatorProps, EnumResolver byNameResolver)
{
if (config.canOverrideAccessModifiers()) {
ClassUtil.checkAndFixAccess(factory.getMember(),
config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS));
}
return new FactoryBasedEnumDeserializer(enumClass, factory,
factory.getParameterType(0),
valueInstantiator, creatorProps);
return new FactoryBasedEnumDeserializer(enumClass, factory, factory.getParameterType(0),
valueInstantiator, creatorProps, byNameResolver);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.fasterxml.jackson.databind.deser.std;

import java.io.IOException;
import java.util.Objects;

import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
Expand All @@ -15,6 +16,7 @@
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
import com.fasterxml.jackson.databind.type.LogicalType;
import com.fasterxml.jackson.databind.util.ClassUtil;
import com.fasterxml.jackson.databind.util.EnumResolver;

/**
* Deserializer that uses a single-String static factory method
Expand All @@ -34,6 +36,7 @@ class FactoryBasedEnumDeserializer
protected final JsonDeserializer<?> _deser;
protected final ValueInstantiator _valueInstantiator;
protected final SettableBeanProperty[] _creatorProps;
protected final Enum<?> _defaultValue;

protected final boolean _hasArgs;

Expand All @@ -45,7 +48,8 @@ class FactoryBasedEnumDeserializer
private transient volatile PropertyBasedCreator _propCreator;

public FactoryBasedEnumDeserializer(Class<?> cls, AnnotatedMethod f, JavaType paramType,
ValueInstantiator valueInstantiator, SettableBeanProperty[] creatorProps)
ValueInstantiator valueInstantiator, SettableBeanProperty[] creatorProps,
EnumResolver enumResolver)
{
super(cls);
_factory = f;
Expand All @@ -56,6 +60,13 @@ public FactoryBasedEnumDeserializer(Class<?> cls, AnnotatedMethod f, JavaType pa
_deser = null;
_valueInstantiator = valueInstantiator;
_creatorProps = creatorProps;
_defaultValue = Objects.nonNull(enumResolver)? enumResolver.getDefaultValue() : null;
}

public FactoryBasedEnumDeserializer(Class<?> cls, AnnotatedMethod f, JavaType paramType,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs to be marked @deprecated (will add)

ValueInstantiator valueInstantiator, SettableBeanProperty[] creatorProps)
{
this(cls, f, paramType, valueInstantiator, creatorProps, null);
}

/**
Expand All @@ -70,6 +81,7 @@ public FactoryBasedEnumDeserializer(Class<?> cls, AnnotatedMethod f)
_deser = null;
_valueInstantiator = null;
_creatorProps = null;
_defaultValue = null;
}

protected FactoryBasedEnumDeserializer(FactoryBasedEnumDeserializer base,
Expand All @@ -80,6 +92,7 @@ protected FactoryBasedEnumDeserializer(FactoryBasedEnumDeserializer base,
_hasArgs = base._hasArgs;
_valueInstantiator = base._valueInstantiator;
_creatorProps = base._creatorProps;
_defaultValue = base._defaultValue;

_deser = deser;
}
Expand Down Expand Up @@ -202,6 +215,10 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
if (ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) {
return null;
}

if (ctxt.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll move this before as null... plus, should only return non-null _defaultValue, I think.

return _defaultValue;
}
// 12-Oct-2021, tatu: Should probably try to provide better exception since
// we likely hit argument incompatibility... Or can this happen?
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ public JsonDeserializer<?> findEnumDeserializer(final Class<?> type, final Deser
for (AnnotatedMethod am : factoryMethods) {
final JsonCreator creator = am.getAnnotation(JsonCreator.class);
if (creator != null) {
return EnumDeserializer.deserializerForCreator(config, type, am, null, null);
return EnumDeserializer.deserializerForCreator(
config, type, am, null, null, null);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static enum EnumWithDefaultAnnoAndConstructor {
}

static enum StrictEnumCreator {
A, B;
A, B, @JsonEnumDefaultValue UNKNOWN;

@JsonCreator public static StrictEnumCreator fromId(String value) {
for (StrictEnumCreator e: values()) {
Expand Down Expand Up @@ -453,7 +453,7 @@ public void testAllowUnknownEnumValuesReadAsNull() throws Exception
assertNull(reader.forType(TestEnum.class).readValue(" 4343 "));
}

// Ability to ignore unknown Enum values:
// Ability to ignore unknown Enum values as null:

// [databind#1642]
@Test
Expand Down Expand Up @@ -483,6 +483,19 @@ public void testAllowUnknownEnumValuesAsMapKeysReadAsNull() throws Exception
assertTrue(result.map.containsKey(null));
}

// Ability to ignore unknown Enum values as a defined default:

// [databind#4979]
@Test
public void testAllowUnknownEnumValuesReadAsDefaultWithCreatorMethod4979() throws Exception
{
ObjectReader reader = MAPPER.reader(
DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
assertEquals(
StrictEnumCreator.UNKNOWN,
reader.forType(StrictEnumCreator.class).readValue("\"NO-SUCH-VALUE\""));
}

@Test
public void testDoNotAllowUnknownEnumValuesAsMapKeysWhenReadAsNullDisabled() throws Exception
{
Expand Down