11package tools .jackson .databind .ser .jdk ;
22
33import java .util .LinkedHashSet ;
4+ import java .util .List ;
45import java .util .Objects ;
56import java .util .Set ;
67
1112import tools .jackson .databind .*;
1213import tools .jackson .databind .annotation .JacksonStdImpl ;
1314import tools .jackson .databind .cfg .EnumFeature ;
14- import tools .jackson .databind .introspect .AnnotatedClass ;
15- import tools .jackson .databind .introspect .EnumNamingStrategyFactory ;
15+ import tools .jackson .databind .cfg .MapperConfig ;
1616import tools .jackson .databind .jsonFormatVisitors .JsonFormatVisitorWrapper ;
1717import tools .jackson .databind .jsonFormatVisitors .JsonStringFormatVisitor ;
1818import tools .jackson .databind .ser .std .StdScalarSerializer ;
19+ import tools .jackson .databind .util .EnumDefinition ;
1920import tools .jackson .databind .util .EnumValues ;
21+ import tools .jackson .databind .util .EnumValuesToWrite ;
2022
2123/**
2224 * Standard serializer used for {@link java.lang.Enum} types.
@@ -29,62 +31,45 @@ public class EnumSerializer
2931 extends StdScalarSerializer <Enum <?>>
3032{
3133 /**
32- * This map contains pre-resolved values (since there are ways to customize
33- * actual String constants to use) to use as serializations.
34+ * Container for dynamically resolved serializations for the type.
3435 */
35- protected final EnumValues _values ;
36+ protected final EnumValuesToWrite _enumValuesToWrite ;
3637
3738 /**
3839 * Flag that is set if we statically know serialization choice between
3940 * index and textual format (null if it needs to be dynamically checked).
4041 */
4142 protected final Boolean _serializeAsIndex ;
4243
43- /**
44- * Map with key as converted property class defined implementation of {@link EnumNamingStrategy}
45- * and with value as Enum names collected using <code>Enum.name()</code>.
46- */
47- protected final EnumValues _valuesByEnumNaming ;
48-
49- /**
50- * Map that contains pre-resolved values for {@link Enum#toString} to use for serialization,
51- * while respecting {@link com.fasterxml.jackson.annotation.JsonProperty}
52- * and {@link tools.jackson.databind.cfg.EnumFeature#WRITE_ENUMS_TO_LOWERCASE}.
53- */
54- protected final EnumValues _valuesByToString ;
55-
5644 /*
5745 /**********************************************************************
5846 /* Life-cycle
5947 /**********************************************************************
6048 */
6149
62- public EnumSerializer (EnumValues v , Boolean serializeAsIndex , EnumValues valuesByEnumNaming ,
63- EnumValues valuesByToString )
50+ public EnumSerializer (EnumValuesToWrite enumValuesToWrite , Boolean serializeAsIndex )
6451 {
65- super (v . getEnumClass (), false );
66- _values = v ;
52+ super (enumValuesToWrite . enumClass (), false );
53+ _enumValuesToWrite = enumValuesToWrite ;
6754 _serializeAsIndex = serializeAsIndex ;
68- _valuesByEnumNaming = valuesByEnumNaming ;
69- _valuesByToString = valuesByToString ;
7055 }
7156
7257 /**
7358 * Factory method used by {@link tools.jackson.databind.ser.BasicSerializerFactory}
7459 * for constructing serializer instance of Enum types.
7560 */
76- @ SuppressWarnings ("unchecked" )
7761 public static EnumSerializer construct (Class <?> enumClass , SerializationConfig config ,
7862 BeanDescription beanDesc , JsonFormat .Value format )
7963 {
8064 // 08-Apr-2015, tatu: As per [databind#749], we cannot statically determine
8165 // between name() and toString(), need to construct `EnumValues` with names,
8266 // handle toString() case dynamically (for example)
83- EnumValues v = EnumValues .constructFromName (config , beanDesc .getClassInfo ());
84- EnumValues valuesByEnumNaming = constructEnumNamingStrategyValues (config , (Class <Enum <?>>) enumClass , beanDesc .getClassInfo ());
85- EnumValues valuesByToString = EnumValues .constructFromToString (config , beanDesc .getClassInfo ());
67+ // 26-Nov-2025, tatu: Further refactoring post-[databind#5432] to deprecate
68+ // `EnumValues`, replaced with `EnumValuesToWrite`
69+ EnumValuesToWrite writer = EnumDefinition .construct (config , beanDesc .getClassInfo ())
70+ .valuesToWrite (config );
8671 Boolean serializeAsIndex = _isShapeWrittenUsingIndex (enumClass , format , true , null );
87- return new EnumSerializer (v , serializeAsIndex , valuesByEnumNaming , valuesByToString );
72+ return new EnumSerializer (writer , serializeAsIndex );
8873 }
8974
9075 /**
@@ -103,8 +88,7 @@ public ValueSerializer<?> createContextual(SerializationContext ctxt,
10388 Boolean serializeAsIndex = _isShapeWrittenUsingIndex (type ,
10489 format , false , _serializeAsIndex );
10590 if (!Objects .equals (serializeAsIndex , _serializeAsIndex )) {
106- return new EnumSerializer (_values , serializeAsIndex ,
107- _valuesByEnumNaming , _valuesByToString );
91+ return new EnumSerializer (_enumValuesToWrite , serializeAsIndex );
10892 }
10993 }
11094 return this ;
@@ -116,7 +100,12 @@ public ValueSerializer<?> createContextual(SerializationContext ctxt,
116100 /**********************************************************************
117101 */
118102
119- public EnumValues getEnumValues () { return _values ; }
103+ @ Deprecated // @since 3.1
104+ public EnumValues getEnumValues () {
105+ // 26-Nov-2025, tatu: Unfortunate, but can't really support getting
106+ // such value, so better fail flamboyantly instead of quietly
107+ throw new UnsupportedOperationException ();
108+ }
120109
121110 /*
122111 /**********************************************************************
@@ -128,21 +117,17 @@ public ValueSerializer<?> createContextual(SerializationContext ctxt,
128117 public final void serialize (Enum <?> en , JsonGenerator g , SerializationContext ctxt )
129118 throws JacksonException
130119 {
131- if (_valuesByEnumNaming != null ) {
132- g .writeString (_valuesByEnumNaming .serializedValueFor (en ));
133- return ;
134- }
135120 // Serialize as index?
136121 if (_serializeAsIndex (ctxt )) {
137122 g .writeNumber (en .ordinal ());
138123 return ;
139124 }
140- // [databind#749]: or via toString()?
125+ final MapperConfig <?> config = ctxt . getConfig ();
141126 if (ctxt .isEnabled (EnumFeature .WRITE_ENUMS_USING_TO_STRING )) {
142- g .writeString (_valuesByToString . serializedValueFor ( en ));
127+ g .writeString (_enumValuesToWrite . enumValueFromToString ( config , en ));
143128 return ;
144- }
145- g .writeString (_values . serializedValueFor ( en ));
129+ }
130+ g .writeString (_enumValuesToWrite . enumValueFromName ( config , en ));
146131 }
147132
148133 /*
@@ -154,28 +139,30 @@ public final void serialize(Enum<?> en, JsonGenerator g, SerializationContext ct
154139 @ Override
155140 public void acceptJsonFormatVisitor (JsonFormatVisitorWrapper visitor , JavaType typeHint )
156141 {
157- SerializationContext serializers = visitor .getContext ();
158- if (_serializeAsIndex (serializers )) {
142+ SerializationContext ctxt = visitor .getContext ();
143+ if (_serializeAsIndex (ctxt )) {
159144 visitIntFormat (visitor , typeHint , JsonParser .NumberType .INT );
160145 return ;
161146 }
162147 JsonStringFormatVisitor stringVisitor = visitor .expectStringFormat (typeHint );
163148 if (stringVisitor != null ) {
164- Set <String > enums = new LinkedHashSet <String >();
149+ Set <String > enumStrings = new LinkedHashSet <>();
165150
166- // Use toString()?
167- if ((serializers != null ) &&
168- serializers .isEnabled (EnumFeature .WRITE_ENUMS_USING_TO_STRING )) {
169- for (SerializableString value : _valuesByToString .values ()) {
170- enums .add (value .getValue ());
151+ List <Enum <?>> enums = _enumValuesToWrite .enums ();
152+ if (_serializeAsIndex (ctxt )) {
153+ for (Enum <?> en : enums ) {
154+ enumStrings .add (String .valueOf (en .ordinal ()));
171155 }
172156 } else {
173- // No, serialize using name() or explicit overrides
174- for (SerializableString value : _values .values ()) {
175- enums .add (value .getValue ());
157+ final MapperConfig <?> config = ctxt .getConfig ();
158+ SerializableString [] values = ctxt .isEnabled (EnumFeature .WRITE_ENUMS_USING_TO_STRING )
159+ ? _enumValuesToWrite .allEnumValuesFromToString (config )
160+ : _enumValuesToWrite .allEnumValuesFromName (config );
161+ for (SerializableString sstr : values ) {
162+ enumStrings .add (sstr .getValue ());
176163 }
177164 }
178- stringVisitor .enumTypes (enums );
165+ stringVisitor .enumTypes (enumStrings );
179166 }
180167 }
181168
@@ -222,17 +209,4 @@ protected static Boolean _isShapeWrittenUsingIndex(Class<?> enumClass,
222209 "Unsupported serialization shape (%s) for Enum %s, not supported as %s annotation" ,
223210 shape , enumClass .getName (), (fromClass ? "class" : "property" )));
224211 }
225-
226- /**
227- * Factory method used to resolve an instance of {@link EnumValues}
228- * with {@link EnumNamingStrategy} applied for the target class.
229- */
230- protected static EnumValues constructEnumNamingStrategyValues (SerializationConfig config , Class <Enum <?>> enumClass ,
231- AnnotatedClass annotatedClass ) {
232- Object namingDef = config .getAnnotationIntrospector ().findEnumNamingStrategy (config , annotatedClass );
233- EnumNamingStrategy enumNamingStrategy = EnumNamingStrategyFactory .createEnumNamingStrategyInstance (
234- namingDef , config .canOverrideAccessModifiers (), config .getEnumNamingStrategy ());
235- return enumNamingStrategy == null ? null : EnumValues .constructUsingEnumNamingStrategy (
236- config , annotatedClass , enumNamingStrategy );
237- }
238212}
0 commit comments