1
1
package com .fasterxml .jackson .databind .deser .std ;
2
2
3
3
import java .io .IOException ;
4
+ import java .util .Arrays ;
4
5
import java .util .Objects ;
5
6
6
7
import com .fasterxml .jackson .annotation .JsonFormat ;
7
8
8
9
import com .fasterxml .jackson .core .*;
9
10
10
11
import com .fasterxml .jackson .databind .*;
12
+ import com .fasterxml .jackson .databind .annotation .EnumNaming ;
11
13
import com .fasterxml .jackson .databind .annotation .JacksonStdImpl ;
12
14
import com .fasterxml .jackson .databind .cfg .CoercionAction ;
13
15
import com .fasterxml .jackson .databind .cfg .CoercionInputShape ;
@@ -65,6 +67,32 @@ public class EnumDeserializer
65
67
*/
66
68
protected final boolean _isFromIntValue ;
67
69
70
+ protected Boolean _useEnumNaming ;
71
+
72
+ protected volatile EnumNamingStrategy _namingStrategy ;
73
+
74
+ /**
75
+ * Marker flag for cases where we expect actual integral value for Enum,
76
+ * based on {@code @JsonValue} (and equivalent) annotated accessor.
77
+ *
78
+ * @since 2.15
79
+ */
80
+ protected boolean _isEnumNamingSet ;
81
+
82
+ /**
83
+ * @since 2.15
84
+ */
85
+ protected EnumNamingStrategy _namingStrategy = new EnumNamingStrategies .NoOpEnumNamingStrategy ();
86
+
87
+
88
+ private void _initEnumNamingStrategy () {
89
+ EnumNaming enumNamingAnnotation = _valueClass .getAnnotation (EnumNaming .class );
90
+ if (enumNamingAnnotation != null ) {
91
+ _isEnumNamingSet = true ;
92
+ ClassUtil .createInstance (enumNamingAnnotation .value (), true );
93
+ }
94
+ }
95
+
68
96
/**
69
97
* @since 2.9
70
98
*/
@@ -76,6 +104,7 @@ public EnumDeserializer(EnumResolver byNameResolver, Boolean caseInsensitive)
76
104
_enumDefaultValue = byNameResolver .getDefaultValue ();
77
105
_caseInsensitive = caseInsensitive ;
78
106
_isFromIntValue = byNameResolver .isFromIntValue ();
107
+ _initEnumNamingStrategy ();
79
108
}
80
109
81
110
/**
@@ -92,6 +121,7 @@ protected EnumDeserializer(EnumDeserializer base, Boolean caseInsensitive,
92
121
_isFromIntValue = base ._isFromIntValue ;
93
122
_useDefaultValueForUnknownEnum = useDefaultValueForUnknownEnum ;
94
123
_useNullForUnknownEnum = useNullForUnknownEnum ;
124
+ _initEnumNamingStrategy ();
95
125
}
96
126
97
127
/**
@@ -254,6 +284,12 @@ protected Object _fromString(JsonParser p, DeserializationContext ctxt,
254
284
CompactStringObjectMap lookup = ctxt .isEnabled (DeserializationFeature .READ_ENUMS_USING_TO_STRING )
255
285
? _getToStringLookup (ctxt ) : _lookupByName ;
256
286
Object result = lookup .find (text );
287
+
288
+ if (result == null && _getUseEnumNaming ()) {
289
+ String translatedText = _getNamingStrategy ().translate (text );
290
+ result = lookup .find (translatedText );
291
+ }
292
+
257
293
if (result == null ) {
258
294
String trimmed = text .trim ();
259
295
if ((trimmed == text ) || (result = lookup .find (trimmed )) == null ) {
@@ -317,6 +353,12 @@ private final Object _deserializeAltString(JsonParser p, DeserializationContext
317
353
CompactStringObjectMap lookup , String nameOrig ) throws IOException
318
354
{
319
355
String name = nameOrig .trim ();
356
+
357
+ if (_isEnumNamingSet ) {
358
+ String translatedValue = _namingStrategy .translate (name );
359
+ return lookup .find (translatedValue );
360
+ }
361
+
320
362
if (name .isEmpty ()) { // empty or blank
321
363
// 07-Jun-2021, tatu: [databind#3171] Need to consider Default value first
322
364
// (alas there's bit of duplication here)
@@ -413,6 +455,30 @@ protected CompactStringObjectMap _getToStringLookup(DeserializationContext ctxt)
413
455
return lookup ;
414
456
}
415
457
458
+ protected Boolean _getUseEnumNaming () {
459
+ if (_useEnumNaming == null ) {
460
+ _useEnumNaming = _valueClass .getAnnotation (EnumNaming .class ) != null ;
461
+ }
462
+ return _useEnumNaming ;
463
+ }
464
+
465
+ protected EnumNamingStrategy _getNamingStrategy () {
466
+ EnumNamingStrategy namingStrategy = _namingStrategy ;
467
+ if (namingStrategy == null ) {
468
+ synchronized (this ) {
469
+ namingStrategy = _namingStrategy ;
470
+ if (namingStrategy == null ) {
471
+ EnumNaming enumNamingAnnotation = _valueClass .getAnnotation (EnumNaming .class );
472
+ namingStrategy = enumNamingAnnotation == null
473
+ ? new EnumNamingStrategies .NoOpEnumNamingStrategy ()
474
+ : ClassUtil .createInstance (enumNamingAnnotation .value (), true );
475
+ _namingStrategy = namingStrategy ;
476
+ }
477
+ }
478
+ }
479
+ return namingStrategy ;
480
+ }
481
+
416
482
// @since 2.15
417
483
protected boolean useNullForUnknownEnum (DeserializationContext ctxt ) {
418
484
return Boolean .TRUE .equals (_useNullForUnknownEnum )
0 commit comments