Skip to content

Commit ceab973

Browse files
authored
Move Enum related features from SerializationFeature to EnumFeature (#5087)
1 parent 3bbfe41 commit ceab973

24 files changed

+136
-101
lines changed

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ Versions: 3.x (for earlier see VERSION-2.x)
1414
#5066: Move date/time `SerializationFeature`s into `DateTimeFeature` (3.0)
1515
#5067: Move date/time `DeserializationFeature`s into `DateTimeFeature` (3.0)
1616
- Branch rename "master" -> "3.x" [JSTEP-12]
17+
#5080: Move Enum-related SerializationFeatures into EnumFeature (3.0)
18+
(contributed by Joo-Hyuk K)
1719

1820
3.0.0-rc3 (not yet released)
1921

src/main/java/tools/jackson/databind/ObjectMapper.java

+9
Original file line numberDiff line numberDiff line change
@@ -1979,6 +1979,15 @@ public ObjectWriter writer(SerializationFeature first,
19791979
return _newWriter(serializationConfig().with(first, other));
19801980
}
19811981

1982+
/**
1983+
* Factory method for constructing {@link ObjectWriter} with
1984+
* specified features enabled (compared to settings that this
1985+
* mapper instance has).
1986+
*/
1987+
public ObjectWriter writer(DatatypeFeature f) {
1988+
return _newWriter(serializationConfig().with(f));
1989+
}
1990+
19821991
/**
19831992
* Factory method for constructing {@link ObjectWriter} that will
19841993
* serialize objects using specified {@link DateFormat}; or, if

src/main/java/tools/jackson/databind/SerializationFeature.java

-45
Original file line numberDiff line numberDiff line change
@@ -182,51 +182,6 @@ public enum SerializationFeature implements ConfigFeature
182182
*/
183183
WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS(false),
184184

185-
/**
186-
* Feature that determines standard serialization mechanism used for
187-
* Enum values: if enabled, return value of <code>Enum.toString()</code>
188-
* is used; if disabled, return value of <code>Enum.name()</code> is used.
189-
*<p>
190-
* Note: this feature should usually have same value
191-
* as {@link DeserializationFeature#READ_ENUMS_USING_TO_STRING}.
192-
*<p>
193-
* Feature is enabled by default as of Jackson 3.0 (in 2.x it was disabled).
194-
*/
195-
WRITE_ENUMS_USING_TO_STRING(true),
196-
197-
/**
198-
* Feature that determines whether Java Enum values are serialized
199-
* as numbers (true), or textual values (false). If textual values are
200-
* used, other settings are also considered.
201-
* If this feature is enabled,
202-
* return value of <code>Enum.ordinal()</code>
203-
* (an integer) will be used as the serialization.
204-
*<p>
205-
* Note that this feature has precedence over {@link #WRITE_ENUMS_USING_TO_STRING},
206-
* which is only considered if this feature is set to false.
207-
*<p>
208-
* Note that since 2.10, this does NOT apply to {@link Enum}s written as
209-
* keys of {@link java.util.Map} values, which has separate setting,
210-
* {@link #WRITE_ENUM_KEYS_USING_INDEX}.
211-
*<p>
212-
* Feature is disabled by default.
213-
*/
214-
WRITE_ENUMS_USING_INDEX(false),
215-
216-
/**
217-
* Feature that determines whether {link Enum}s
218-
* used as {@link java.util.Map} keys are serialized
219-
* as using {@link Enum#ordinal()} or not.
220-
* Similar to {@link #WRITE_ENUMS_USING_INDEX} used when writing
221-
* {@link Enum}s as regular values.
222-
*<p>
223-
* NOTE: counterpart for this settings is
224-
* {@link EnumFeature#READ_ENUM_KEYS_USING_INDEX}.
225-
*<p>
226-
* Feature is disabled by default.
227-
*/
228-
WRITE_ENUM_KEYS_USING_INDEX(false),
229-
230185
/**
231186
* Feature that determines whether Container properties (POJO properties
232187
* with declared value of Collection or array; i.e. things that produce JSON

src/main/java/tools/jackson/databind/cfg/EnumFeature.java

+59-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package tools.jackson.databind.cfg;
22

3-
import tools.jackson.databind.SerializationFeature;
3+
import tools.jackson.databind.DeserializationFeature;
44

55
/**
66
* New Datatype-specific configuration options related to handling of
@@ -14,7 +14,7 @@ public enum EnumFeature implements DatatypeFeature
1414
* index of <code>Enum</code>;
1515
*<p>
1616
* Note: this feature should be symmetric to
17-
* as {@link SerializationFeature#WRITE_ENUM_KEYS_USING_INDEX}.
17+
* as {@link #WRITE_ENUM_KEYS_USING_INDEX}.
1818
*<p>
1919
* Feature is disabled by default.
2020
*
@@ -34,7 +34,63 @@ public enum EnumFeature implements DatatypeFeature
3434
*
3535
* @since 2.15
3636
*/
37-
WRITE_ENUMS_TO_LOWERCASE(false);
37+
WRITE_ENUMS_TO_LOWERCASE(false),
38+
39+
40+
/**
41+
* Feature that determines standard serialization mechanism used for
42+
* Enum values: if enabled, return value of <code>Enum.toString()</code>
43+
* is used; if disabled, return value of <code>Enum.name()</code> is used.
44+
*<p>
45+
* Note: this feature should usually have same value
46+
* as {@link DeserializationFeature#READ_ENUMS_USING_TO_STRING}.
47+
*<p>
48+
* Feature used to be one of {@link tools.jackson.databind.SerializationFeature}s
49+
* in Jackson 2.x but was moved here in 3.0.
50+
*<p>
51+
* Feature is enabled by default as of Jackson 3.0 (in 2.x it was disabled).
52+
*/
53+
WRITE_ENUMS_USING_TO_STRING(true),
54+
55+
/**
56+
* Feature that determines whether Java Enum values are serialized
57+
* as numbers (true), or textual values (false). If textual values are
58+
* used, other settings are also considered.
59+
* If this feature is enabled,
60+
* return value of <code>Enum.ordinal()</code>
61+
* (an integer) will be used as the serialization.
62+
*<p>
63+
* Note that this feature has precedence over {@link #WRITE_ENUMS_USING_TO_STRING},
64+
* which is only considered if this feature is set to false.
65+
*<p>
66+
* Note that since 2.10, this does NOT apply to {@link Enum}s written as
67+
* keys of {@link java.util.Map} values, which has separate setting,
68+
* {@link #WRITE_ENUM_KEYS_USING_INDEX}.
69+
*<p>
70+
* Feature used to be one of {@link tools.jackson.databind.SerializationFeature}s
71+
* in Jackson 2.x but was moved here in 3.0.
72+
*<p>
73+
* Feature is disabled by default.
74+
*/
75+
WRITE_ENUMS_USING_INDEX(false),
76+
77+
/**
78+
* Feature that determines whether {link Enum}s
79+
* used as {@link java.util.Map} keys are serialized
80+
* as using {@link Enum#ordinal()} or not.
81+
* Similar to {@link #WRITE_ENUMS_USING_INDEX} used when writing
82+
* {@link Enum}s as regular values.
83+
*<p>
84+
* NOTE: counterpart for this settings is
85+
* {@link EnumFeature#READ_ENUM_KEYS_USING_INDEX}.
86+
*<p>
87+
* Feature used to be one of {@link tools.jackson.databind.SerializationFeature}s
88+
* in Jackson 2.x but was moved here in 3.0.
89+
*<p>
90+
* Feature is disabled by default.
91+
*/
92+
WRITE_ENUM_KEYS_USING_INDEX(false),
93+
;
3894

3995
private final static int FEATURE_INDEX = DatatypeFeatures.FEATURE_INDEX_ENUM;
4096

src/main/java/tools/jackson/databind/cfg/MapperBuilder.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -818,7 +818,7 @@ public B configureForJackson2() {
818818
.enable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
819819
.enable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS,
820820
DateTimeFeature.WRITE_DURATIONS_AS_TIMESTAMPS)
821-
.disable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
821+
.disable(EnumFeature.WRITE_ENUMS_USING_TO_STRING)
822822
.disable(DateTimeFeature.ONE_BASED_MONTHS)
823823
;
824824
}

src/main/java/tools/jackson/databind/ext/javatime/ser/OneBasedMonthSerializer.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import tools.jackson.databind.*;
88
import tools.jackson.databind.cfg.DateTimeFeature;
9+
import tools.jackson.databind.cfg.EnumFeature;
910

1011
public class OneBasedMonthSerializer extends ValueSerializer<Month>
1112
{
@@ -25,7 +26,7 @@ public void serialize(Month value, JsonGenerator gen, SerializationContext ctxt)
2526
// 15-Jan-2024, tatu: [modules-java8#274] This is not really sufficient
2627
// (see `jackson-databind` `EnumSerializer` for full logic), but has to
2728
// do for now. May need to add `@JsonFormat.shape` handling in future.
28-
if (ctxt.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX)) {
29+
if (ctxt.isEnabled(EnumFeature.WRITE_ENUMS_USING_INDEX)) {
2930
gen.writeNumber(value.ordinal() + 1);
3031
return;
3132
}

src/main/java/tools/jackson/databind/ser/jdk/EnumSerializer.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import tools.jackson.core.*;
1111
import tools.jackson.databind.*;
1212
import tools.jackson.databind.annotation.JacksonStdImpl;
13+
import tools.jackson.databind.cfg.EnumFeature;
1314
import tools.jackson.databind.introspect.AnnotatedClass;
1415
import tools.jackson.databind.introspect.EnumNamingStrategyFactory;
1516
import tools.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
@@ -137,7 +138,7 @@ public final void serialize(Enum<?> en, JsonGenerator g, SerializationContext ct
137138
return;
138139
}
139140
// [databind#749]: or via toString()?
140-
if (ctxt.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
141+
if (ctxt.isEnabled(EnumFeature.WRITE_ENUMS_USING_TO_STRING)) {
141142
g.writeString(_valuesByToString.serializedValueFor(en));
142143
return;
143144
}
@@ -164,7 +165,7 @@ public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType t
164165

165166
// Use toString()?
166167
if ((serializers != null) &&
167-
serializers.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
168+
serializers.isEnabled(EnumFeature.WRITE_ENUMS_USING_TO_STRING)) {
168169
for (SerializableString value : _valuesByToString.values()) {
169170
enums.add(value.getValue());
170171
}
@@ -189,7 +190,7 @@ protected final boolean _serializeAsIndex(SerializationContext ctxt)
189190
if (_serializeAsIndex != null) {
190191
return _serializeAsIndex;
191192
}
192-
return ctxt.isEnabled(SerializationFeature.WRITE_ENUMS_USING_INDEX);
193+
return ctxt.isEnabled(EnumFeature.WRITE_ENUMS_USING_INDEX);
193194
}
194195

195196
/**

src/main/java/tools/jackson/databind/ser/jdk/JDKKeySerializers.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import tools.jackson.core.*;
77
import tools.jackson.databind.*;
8+
import tools.jackson.databind.cfg.EnumFeature;
89
import tools.jackson.databind.introspect.AnnotatedClass;
910
import tools.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
1011
import tools.jackson.databind.ser.impl.PropertySerializerMap;
@@ -154,12 +155,12 @@ public void serialize(Object value, JsonGenerator g, SerializationContext provid
154155
{
155156
String key;
156157

157-
if (provider.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
158+
if (provider.isEnabled(EnumFeature.WRITE_ENUMS_USING_TO_STRING)) {
158159
key = value.toString();
159160
} else {
160161
Enum<?> e = (Enum<?>) value;
161162
// 14-Sep-2019, tatu: [databind#2129] Use this specific feature
162-
if (provider.isEnabled(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX)) {
163+
if (provider.isEnabled(EnumFeature.WRITE_ENUM_KEYS_USING_INDEX)) {
163164
key = String.valueOf(e.ordinal());
164165
} else {
165166
key = e.name();
@@ -299,7 +300,7 @@ public static EnumKeySerializer construct(Class<?> enumType,
299300
public void serialize(Object value, JsonGenerator g, SerializationContext serializers)
300301
throws JacksonException
301302
{
302-
if (serializers.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
303+
if (serializers.isEnabled(EnumFeature.WRITE_ENUMS_USING_TO_STRING)) {
303304
g.writeName(value.toString());
304305
return;
305306
}
@@ -309,7 +310,7 @@ public void serialize(Object value, JsonGenerator g, SerializationContext serial
309310
return;
310311
}
311312
// 14-Sep-2019, tatu: [databind#2129] Use this specific feature
312-
if (serializers.isEnabled(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX)) {
313+
if (serializers.isEnabled(EnumFeature.WRITE_ENUM_KEYS_USING_INDEX)) {
313314
g.writeName(String.valueOf(en.ordinal()));
314315
return;
315316
}

src/main/java/tools/jackson/databind/util/EnumValues.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private EnumValues(Class<Enum<?>> enumClass, SerializableString[] textual)
3636
* and name() might change dynamically.
3737
*/
3838
public static EnumValues construct(SerializationConfig config, AnnotatedClass enumClass) {
39-
if (config.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
39+
if (config.isEnabled(EnumFeature.WRITE_ENUMS_USING_TO_STRING)) {
4040
return constructFromToString(config, enumClass);
4141
}
4242
return constructFromName(config, enumClass);

src/test/java/tools/jackson/databind/deser/creators/EnumCreatorTest.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import tools.jackson.core.type.TypeReference;
1414

1515
import tools.jackson.databind.*;
16+
import tools.jackson.databind.cfg.EnumFeature;
1617
import tools.jackson.databind.deser.Deserializers;
1718
import tools.jackson.databind.deser.jdk.EnumDeserializer;
1819
import tools.jackson.databind.exc.ValueInstantiationException;
@@ -376,7 +377,7 @@ public void testEnumCreators1291() throws Exception
376377
{
377378
ObjectMapper mapper = jsonMapperBuilder()
378379
.disable(DeserializationFeature.READ_ENUMS_USING_TO_STRING)
379-
.disable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
380+
.disable(EnumFeature.WRITE_ENUMS_USING_TO_STRING)
380381
.build();
381382
String json = mapper.writeValueAsString(Enum1291.V2);
382383
Enum1291 result = mapper.readValue(json, Enum1291.class);

src/test/java/tools/jackson/databind/deser/enums/EnumDeserializationTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ public void testNumbersToEnums() throws Exception
402402
public void testEnumsWithIndex() throws Exception
403403
{
404404
String json = MAPPER.writer()
405-
.with(SerializationFeature.WRITE_ENUMS_USING_INDEX)
405+
.with(EnumFeature.WRITE_ENUMS_USING_INDEX)
406406
.writeValueAsString(TestEnum.RULES);
407407
assertEquals(String.valueOf(TestEnum.RULES.ordinal()), json);
408408
TestEnum result = MAPPER.readValue(json, TestEnum.class);
@@ -819,7 +819,7 @@ public void testEnumFeature_symmetric_to_writing() throws Exception {
819819
obj.map = objMap;
820820

821821
String deserObj = MAPPER.writer()
822-
.with(SerializationFeature.WRITE_ENUM_KEYS_USING_INDEX)
822+
.with(EnumFeature.WRITE_ENUM_KEYS_USING_INDEX)
823823
.writeValueAsString(obj);
824824

825825
ClassWithEnumMapKey result = MAPPER.reader()

src/test/java/tools/jackson/databind/deser/enums/EnumMapDeserializationTest.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import tools.jackson.core.type.TypeReference;
1212
import tools.jackson.databind.*;
13+
import tools.jackson.databind.cfg.EnumFeature;
1314
import tools.jackson.databind.json.JsonMapper;
1415
import tools.jackson.databind.testutil.NoCheckSubTypeValidator;
1516

@@ -313,13 +314,13 @@ public void testCustomEnumAsRootMapKey() throws Exception
313314
map.put(MyEnum2457.B, "2");
314315
assertEquals(a2q("{'A':'1','B':'2'}"),
315316
MAPPER.writer()
316-
.without(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
317+
.without(EnumFeature.WRITE_ENUMS_USING_TO_STRING)
317318
.writeValueAsString(map));
318319

319320
// But should be able to override
320321
assertEquals(a2q("{'"+MyEnum2457.A.toString()+"':'1','"+MyEnum2457.B.toString()+"':'2'}"),
321322
MAPPER.writer()
322-
.with(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
323+
.with(EnumFeature.WRITE_ENUMS_USING_TO_STRING)
323324
.writeValueAsString(map));
324325
}
325326

@@ -338,13 +339,13 @@ public void testCustomEnumAsRootMapKeyMixin() throws Exception
338339
map.put(MyEnum2457Base.B, "2");
339340
assertEquals(a2q("{'a_mixin':'1','b_mixin':'2'}"),
340341
mixinMapper.writer()
341-
.without(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
342+
.without(EnumFeature.WRITE_ENUMS_USING_TO_STRING)
342343
.writeValueAsString(map));
343344

344345
// But should be able to override
345346
assertEquals(a2q("{'"+MyEnum2457Base.A.toString()+"':'1','"+MyEnum2457Base.B.toString()+"':'2'}"),
346347
mixinMapper.writer()
347-
.with(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
348+
.with(EnumFeature.WRITE_ENUMS_USING_TO_STRING)
348349
.writeValueAsString(map));
349350
}
350351

src/test/java/tools/jackson/databind/deser/enums/EnumWithNullToString4355Test.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.junit.jupiter.api.Test;
44

55
import tools.jackson.databind.*;
6+
import tools.jackson.databind.cfg.EnumFeature;
67
import tools.jackson.databind.testutil.DatabindTestUtil;
78

89
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -28,7 +29,7 @@ public String toString() {
2829
}
2930

3031
private final ObjectMapper MAPPER = jsonMapperBuilder()
31-
.disable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING).build();
32+
.disable(EnumFeature.WRITE_ENUMS_USING_TO_STRING).build();
3233

3334
// [databind#4355]
3435
@Test

src/test/java/tools/jackson/databind/ext/javatime/ser/OneBasedMonthSerTest.java

+5-4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import tools.jackson.databind.ObjectWriter;
88
import tools.jackson.databind.SerializationFeature;
99
import tools.jackson.databind.cfg.DateTimeFeature;
10+
import tools.jackson.databind.cfg.EnumFeature;
1011
import tools.jackson.databind.ext.javatime.DateTimeTestBase;
1112
import tools.jackson.databind.json.JsonMapper;
1213

@@ -25,24 +26,24 @@ public Wrapper() { }
2526
public void testSerializationFromEnum() throws Exception
2627
{
2728
assertEquals( "\"JANUARY\"" , writerForOneBased()
28-
.with(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
29+
.with(EnumFeature.WRITE_ENUMS_USING_TO_STRING)
2930
.writeValueAsString(Month.JANUARY));
3031
assertEquals( "\"JANUARY\"" , writerForZeroBased()
31-
.with(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
32+
.with(EnumFeature.WRITE_ENUMS_USING_TO_STRING)
3233
.writeValueAsString(Month.JANUARY));
3334
}
3435

3536
@Test
3637
public void testSerializationFromEnumWithPattern_oneBased() throws Exception
3738
{
38-
ObjectWriter w = writerForOneBased().with(SerializationFeature.WRITE_ENUMS_USING_INDEX);
39+
ObjectWriter w = writerForOneBased().with(EnumFeature.WRITE_ENUMS_USING_INDEX);
3940
assertEquals( "{\"month\":1}" , w.writeValueAsString(new Wrapper(Month.JANUARY)));
4041
}
4142

4243
@Test
4344
public void testSerializationFromEnumWithPattern_zeroBased() throws Exception
4445
{
45-
ObjectWriter w = writerForZeroBased().with(SerializationFeature.WRITE_ENUMS_USING_INDEX);
46+
ObjectWriter w = writerForZeroBased().with(EnumFeature.WRITE_ENUMS_USING_INDEX);
4647
assertEquals( "{\"month\":0}" , w.writeValueAsString(new Wrapper(Month.JANUARY)));
4748
}
4849

0 commit comments

Comments
 (0)