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 a031ed4da9..349facdb31 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/BasicDeserializerFactory.java @@ -2429,7 +2429,7 @@ protected EnumResolver constructEnumResolver(Class enumClass, ClassUtil.checkAndFixAccess(jvAcc.getMember(), config.isEnabled(MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS)); } - return EnumResolver.constructUsingMethod(config, enumClass, jvAcc); + return EnumResolver.constructUsingMethod(config, beanDesc.getClassInfo(), jvAcc); } return EnumResolver.constructFor(config, beanDesc.getClassInfo()); } diff --git a/src/main/java/com/fasterxml/jackson/databind/util/EnumResolver.java b/src/main/java/com/fasterxml/jackson/databind/util/EnumResolver.java index 0569fef860..638551bcc7 100644 --- a/src/main/java/com/fasterxml/jackson/databind/util/EnumResolver.java +++ b/src/main/java/com/fasterxml/jackson/databind/util/EnumResolver.java @@ -302,7 +302,10 @@ private static EnumResolver _constructUsingEnumNamingStrategy( * on a method in Enum class. * * @since 2.12 + * @deprecated Since 2.16. + * Use {@link #constructUsingMethod(DeserializationConfig, AnnotatedClass, AnnotatedMember)} instead. */ + @Deprecated public static EnumResolver constructUsingMethod(DeserializationConfig config, Class enumCls0, AnnotatedMember accessor) { @@ -330,6 +333,44 @@ public static EnumResolver constructUsingMethod(DeserializationConfig config, ); } + /** + * Method used when actual String serialization is indicated using @JsonValue + * on a method in Enum class. + * + * @since 2.16 + */ + public static EnumResolver constructUsingMethod(DeserializationConfig config, + AnnotatedClass annotatedClass, AnnotatedMember accessor) + { + // prepare data + final AnnotationIntrospector ai = config.getAnnotationIntrospector(); + final boolean isIgnoreCase = config.isEnabled(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); + final Class enumCls0 = annotatedClass.getRawType(); + final Class> enumCls = _enumClass(enumCls0); + final Enum[] enumConstants = _enumConstants(enumCls0); + final Enum defaultEnum = _enumDefault(ai, annotatedClass, enumConstants); + + // build + HashMap> map = new HashMap>(); + // from last to first, so that in case of duplicate values, first wins + for (int i = enumConstants.length; --i >= 0; ) { + Enum en = enumConstants[i]; + try { + Object o = accessor.getValue(en); + if (o != null) { + map.put(o.toString(), en); + } + } catch (Exception e) { + throw new IllegalArgumentException("Failed to access @JsonValue of Enum value "+en+": "+e.getMessage()); + } + } + return new EnumResolver(enumCls, enumConstants, map, + defaultEnum, isIgnoreCase, + // 26-Sep-2021, tatu: [databind#1850] Need to consider "from int" case + _isIntType(accessor.getRawType()) + ); + } + public CompactStringObjectMap constructLookup() { return CompactStringObjectMap.construct(_enumsById); }