Skip to content

Commit 643a617

Browse files
committed
Merge branch '2.6'
2 parents f6ae138 + ed7d416 commit 643a617

File tree

7 files changed

+158
-78
lines changed

7 files changed

+158
-78
lines changed

release-notes/VERSION

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Project: jackson-databind
1313

1414
2.6.3 (not yet released)
1515

16+
#749: `EnumMap` serialization ignores `SerializationFeature.WRITE_ENUMS_USING_TO_STRING`
17+
(reported by scubasau@github)
1618
#938: Regression: `StackOverflowError` with recursive types that contain `Map.Entry`
1719
(reported by jloisel@github)
1820
#940: Add missing `hashCode()` implementations for `JsonNode` types that did not have them

src/main/java/com/fasterxml/jackson/databind/ser/BasicSerializerFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,13 +237,13 @@ public JsonSerializer<Object> createKeySerializer(SerializationConfig config,
237237
}
238238
ser = new JsonValueSerializer(m, delegate);
239239
} else {
240-
ser = StdKeySerializers.getDefault();
240+
ser = StdKeySerializers.getFallbackKeySerializer(config, keyType.getRawClass());
241241
}
242242
}
243243
}
244244
}
245245

246-
// [Issue#120]: Allow post-processing
246+
// [databind#120]: Allow post-processing
247247
if (_factoryConfig.hasSerializerModifiers()) {
248248
for (BeanSerializerModifier mod : _factoryConfig.serializerModifiers()) {
249249
ser = mod.modifyKeySerializer(config, keyType, beanDesc, ser);

src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializer.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.fasterxml.jackson.databind.JavaType;
99
import com.fasterxml.jackson.databind.JsonMappingException;
1010
import com.fasterxml.jackson.databind.JsonNode;
11+
import com.fasterxml.jackson.databind.SerializationFeature;
1112
import com.fasterxml.jackson.databind.SerializerProvider;
1213
import com.fasterxml.jackson.databind.jsonFormatVisitors.JsonFormatVisitorWrapper;
1314

@@ -22,21 +23,31 @@ public class StdKeySerializer extends StdSerializer<Object>
2223
public StdKeySerializer() { super(Object.class); }
2324

2425
@Override
25-
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException {
26+
public void serialize(Object value, JsonGenerator g, SerializerProvider provider) throws IOException {
2627
String str;
2728
Class<?> cls = value.getClass();
28-
29+
2930
if (cls == String.class) {
3031
str = (String) value;
31-
} else if (Date.class.isAssignableFrom(cls)) {
32-
provider.defaultSerializeDateKey((Date) value, jgen);
32+
} else if (cls.isEnum()) {
33+
// 24-Sep-2015, tatu: Minor improvement over older (2.6.2 and before) code: at least
34+
// use name/toString() variation for as per configuration
35+
Enum<?> en = (Enum<?>) value;
36+
37+
if (provider.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)) {
38+
str = en.toString();
39+
} else {
40+
str = en.name();
41+
}
42+
} else if (value instanceof Date) {
43+
provider.defaultSerializeDateKey((Date) value, g);
3344
return;
3445
} else if (cls == Class.class) {
3546
str = ((Class<?>) value).getName();
3647
} else {
3748
str = value.toString();
3849
}
39-
jgen.writeFieldName(str);
50+
g.writeFieldName(str);
4051
}
4152

4253
@Override

src/main/java/com/fasterxml/jackson/databind/ser/std/StdKeySerializers.java

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ private StdKeySerializers() { }
2626
public static JsonSerializer<Object> getStdKeySerializer(SerializationConfig config,
2727
Class<?> rawKeyType, boolean useDefault)
2828
{
29+
// 24-Sep-2015, tatu: Important -- should ONLY consider types for which `@JsonValue`
30+
// can not be used, since caller has not yet checked for that annotation
31+
// This is why Enum types are not handled here quite yet
32+
2933
if (rawKeyType != null) {
3034
if (rawKeyType == String.class) {
3135
return DEFAULT_STRING_SERIALIZER;
@@ -43,14 +47,31 @@ public static JsonSerializer<Object> getStdKeySerializer(SerializationConfig con
4347
if (Calendar.class.isAssignableFrom(rawKeyType)) {
4448
return new Default(Default.TYPE_CALENDAR, rawKeyType);
4549
}
46-
// other types we know convert properly with 'toString()'?
50+
// other JDK types we know convert properly with 'toString()'?
4751
if (rawKeyType == java.util.UUID.class) {
4852
return new Default(Default.TYPE_TO_STRING, rawKeyType);
4953
}
54+
5055
}
5156
return useDefault ? DEFAULT_KEY_SERIALIZER : null;
5257
}
5358

59+
/**
60+
* Method called if no specified key serializer was located; will return a
61+
* "default" key serializer.
62+
*
63+
* @since 2.7
64+
*/
65+
public static JsonSerializer<Object> getFallbackKeySerializer(SerializationConfig config,
66+
Class<?> rawKeyType) {
67+
if (rawKeyType != null) {
68+
if (rawKeyType.isEnum()) {
69+
return new Default(Default.TYPE_ENUM, rawKeyType);
70+
}
71+
}
72+
return DEFAULT_KEY_SERIALIZER;
73+
}
74+
5475
/**
5576
* @deprecated Since 2.5
5677
*/
@@ -59,10 +80,13 @@ public static JsonSerializer<Object> getStdKeySerializer(JavaType keyType) {
5980
return getStdKeySerializer(null, keyType.getRawClass(), true);
6081
}
6182

83+
/**
84+
* @deprecated since 2.7
85+
*/
6286
public static JsonSerializer<Object> getDefault() {
6387
return DEFAULT_KEY_SERIALIZER;
6488
}
65-
89+
6690
/*
6791
/**********************************************************
6892
/* Standard implementations used
@@ -73,7 +97,8 @@ public static class Default extends StdSerializer<Object> {
7397
final static int TYPE_DATE = 1;
7498
final static int TYPE_CALENDAR = 2;
7599
final static int TYPE_CLASS = 3;
76-
final static int TYPE_TO_STRING = 4;
100+
final static int TYPE_ENUM = 4;
101+
final static int TYPE_TO_STRING = 5;
77102

78103
protected final int _typeId;
79104

@@ -83,20 +108,27 @@ public Default(int typeId, Class<?> type) {
83108
}
84109

85110
@Override
86-
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
111+
public void serialize(Object value, JsonGenerator g, SerializerProvider provider) throws IOException {
87112
switch (_typeId) {
88113
case TYPE_DATE:
89-
provider.defaultSerializeDateKey((Date)value, jgen);
114+
provider.defaultSerializeDateKey((Date)value, g);
90115
break;
91116
case TYPE_CALENDAR:
92-
provider.defaultSerializeDateKey(((Calendar) value).getTimeInMillis(), jgen);
117+
provider.defaultSerializeDateKey(((Calendar) value).getTimeInMillis(), g);
93118
break;
94119
case TYPE_CLASS:
95-
jgen.writeFieldName(((Class<?>)value).getName());
120+
g.writeFieldName(((Class<?>)value).getName());
121+
break;
122+
case TYPE_ENUM:
123+
{
124+
String str = provider.isEnabled(SerializationFeature.WRITE_ENUMS_USING_TO_STRING)
125+
? value.toString() : ((Enum<?>) value).name();
126+
g.writeFieldName(str);
127+
}
96128
break;
97129
case TYPE_TO_STRING:
98130
default:
99-
jgen.writeFieldName(value.toString());
131+
g.writeFieldName(value.toString());
100132
}
101133
}
102134
}
@@ -106,11 +138,11 @@ public static class StringKeySerializer extends StdSerializer<Object>
106138
public StringKeySerializer() { super(String.class, false); }
107139

108140
@Override
109-
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
110-
jgen.writeFieldName((String) value);
141+
public void serialize(Object value, JsonGenerator g, SerializerProvider provider) throws IOException {
142+
g.writeFieldName((String) value);
111143
}
112144
}
113-
145+
114146
/*
115147
/**********************************************************
116148
/* Deprecated implementations: to be removed in future
@@ -124,8 +156,8 @@ public static class DateKeySerializer extends StdSerializer<Date> {
124156
public DateKeySerializer() { super(Date.class); }
125157

126158
@Override
127-
public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
128-
provider.defaultSerializeDateKey(value, jgen);
159+
public void serialize(Date value, JsonGenerator g, SerializerProvider provider) throws IOException {
160+
provider.defaultSerializeDateKey(value, g);
129161
}
130162
}
131163

@@ -134,10 +166,10 @@ public static class CalendarKeySerializer extends StdSerializer<Calendar> {
134166
protected final static JsonSerializer<?> instance = new CalendarKeySerializer();
135167

136168
public CalendarKeySerializer() { super(Calendar.class); }
137-
169+
138170
@Override
139-
public void serialize(Calendar value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
140-
provider.defaultSerializeDateKey(value.getTimeInMillis(), jgen);
171+
public void serialize(Calendar value, JsonGenerator g, SerializerProvider provider) throws IOException {
172+
provider.defaultSerializeDateKey(value.getTimeInMillis(), g);
141173
}
142174
}
143175
}

src/test/java/com/fasterxml/jackson/databind/ser/TestJSONP.java renamed to src/test/java/com/fasterxml/jackson/databind/misc/TestJSONP.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.databind.ser;
1+
package com.fasterxml.jackson.databind.misc;
22

33
import com.fasterxml.jackson.databind.*;
44
import com.fasterxml.jackson.databind.type.TypeFactory;

src/test/java/com/fasterxml/jackson/databind/module/TestCustomEnumKeyDeserializer.java

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import java.io.IOException;
66
import java.util.*;
77

8-
import org.junit.Ignore;
98
import org.junit.Test;
109

1110
import com.fasterxml.jackson.core.*;
@@ -106,27 +105,6 @@ public Class<TestEnum> handledType() {
106105
}
107106
}
108107

109-
static class TestEnumModule extends SimpleModule {
110-
111-
public TestEnumModule() {
112-
super(Version.unknownVersion());
113-
}
114-
115-
@Override
116-
public void setupModule(SetupContext context) {
117-
context.setMixInAnnotations(TestEnum.class, TestEnumMixin.class);
118-
SimpleSerializers keySerializers = new SimpleSerializers();
119-
keySerializers.addSerializer(new TestEnumKeySerializer());
120-
context.addKeySerializers(keySerializers);
121-
}
122-
123-
public static ObjectMapper setupObjectMapper(ObjectMapper mapper) {
124-
final TestEnumModule module = new TestEnumModule();
125-
mapper.registerModule(module);
126-
return mapper;
127-
}
128-
}
129-
130108
static class Bean {
131109
private File rootDirectory;
132110
private String licenseString;
@@ -157,6 +135,20 @@ public void setReplacements(Map<TestEnum, Map<String, String>> replacements) {
157135
}
158136
}
159137

138+
static class TestEnumModule extends SimpleModule {
139+
public TestEnumModule() {
140+
super(Version.unknownVersion());
141+
}
142+
143+
@Override
144+
public void setupModule(SetupContext context) {
145+
context.setMixInAnnotations(TestEnum.class, TestEnumMixin.class);
146+
SimpleSerializers keySerializers = new SimpleSerializers();
147+
keySerializers.addSerializer(new TestEnumKeySerializer());
148+
context.addKeySerializers(keySerializers);
149+
}
150+
}
151+
160152
/*
161153
/**********************************************************
162154
/* Test methods
@@ -169,10 +161,11 @@ public void testWithEnumKeys() throws Exception {
169161
ObjectMapper plainObjectMapper = new ObjectMapper();
170162
JsonNode tree = plainObjectMapper.readTree(aposToQuotes("{'red' : [ 'a', 'b']}"));
171163

172-
ObjectMapper fancyObjectMapper = TestEnumModule.setupObjectMapper(new ObjectMapper());
164+
ObjectMapper fancyObjectMapper = new ObjectMapper().registerModule(new TestEnumModule());
165+
173166
// this line is might throw with Jackson 2.6.2.
174-
Map<TestEnum, Set<String>> map = fancyObjectMapper.convertValue(tree, new TypeReference<Map<TestEnum, Set<String>>>() {
175-
});
167+
Map<TestEnum, Set<String>> map = fancyObjectMapper.convertValue(tree,
168+
new TypeReference<Map<TestEnum, Set<String>>>() { } );
176169
assertNotNull(map);
177170
}
178171

@@ -181,15 +174,18 @@ public void testWithEnumKeys() throws Exception {
181174
// public void testWithTree749() throws Exception
182175
public void withTree749() throws Exception
183176
{
177+
ObjectMapper mapper = new ObjectMapper().registerModule(new TestEnumModule());
178+
184179
Map<KeyEnum, Object> inputMap = new LinkedHashMap<KeyEnum, Object>();
185180
Map<TestEnum, Map<String, String>> replacements = new LinkedHashMap<TestEnum, Map<String, String>>();
186181
Map<String, String> reps = new LinkedHashMap<String, String>();
187182
reps.put("1", "one");
188183
replacements.put(TestEnum.GREEN, reps);
189184
inputMap.put(KeyEnum.replacements, replacements);
190-
ObjectMapper mapper = TestEnumModule.setupObjectMapper(new ObjectMapper());
185+
191186
JsonNode tree = mapper.valueToTree(inputMap);
192187
ObjectNode ob = (ObjectNode) tree;
188+
193189
JsonNode inner = ob.get("replacements");
194190
String firstFieldName = inner.fieldNames().next();
195191
assertEquals("green", firstFieldName);

0 commit comments

Comments
 (0)