Skip to content

Commit b1041d0

Browse files
committed
Fix #1233
1 parent 609a0f8 commit b1041d0

File tree

4 files changed

+49
-18
lines changed

4 files changed

+49
-18
lines changed

release-notes/VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Project: jackson-databind
3636
(reported by Lokesh K)
3737
#1221: Use `Throwable.addSuppressed()` directly and/or via try-with-resources
3838
#1232: Add support for `JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES`
39+
#1232: Add support for `JsonFormat.Feature.WRITE_SORTED_MAP_ENTRIES`
3940

4041
2.7.5 (not yet released)
4142

src/main/java/com/fasterxml/jackson/databind/DeserializationContext.java

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,11 +1248,27 @@ public JsonMappingException weirdNumberException(Number value, Class<?> instClas
12481248
instClass.getName(), String.valueOf(value), msg),
12491249
value, instClass);
12501250
}
1251-
1251+
1252+
/**
1253+
* Helper method for constructing instantiation exception for specified type,
1254+
* to indicate problem with physically constructing instance of
1255+
* specified class (missing constructor, exception from constructor)
1256+
*<p>
1257+
* Note that most of the time this method should NOT be called; instead,
1258+
* {@link #handleInstantiationProblem} should be called which will call this method
1259+
* if necessary.
1260+
*/
1261+
public JsonMappingException instantiationException(Class<?> instClass, Throwable t) {
1262+
return JsonMappingException.from(_parser,
1263+
String.format("Can not construct instance of %s, problem: %s",
1264+
instClass.getName(), t.getMessage()), t);
1265+
}
1266+
12521267
/**
12531268
* Helper method for constructing exception to indicate that given type id
12541269
* could not be resolved to a valid subtype of specified base type, during
12551270
* polymorphic deserialization.
1271+
*<p>
12561272
* Note that most of the time this method should NOT be called; instead,
12571273
* {@link #handleUnknownTypeId} should be called which will call this method
12581274
* if necessary.
@@ -1269,29 +1285,14 @@ public JsonMappingException unknownTypeIdException(JavaType baseType, String typ
12691285

12701286
/*
12711287
/**********************************************************
1272-
/* Methods for constructing semantic exceptions; mostly
1273-
/* deprecated since 2.8; to be replaced by `reportXxx()`
1288+
/* Methods for constructing semantic exceptions
12741289
/**********************************************************
12751290
*/
1276-
1291+
12771292
/**
1278-
* Helper method for constructing instantiation exception for specified type,
1279-
* to indicate problem with physically constructing instance of
1280-
* specified class (missing constructor, exception from constructor)
1281-
*
12821293
* @deprecated Since 2.8 use {@link #reportInstantiationException} instead
12831294
*/
12841295
@Deprecated
1285-
public JsonMappingException instantiationException(Class<?> instClass, Throwable t) {
1286-
return JsonMappingException.from(_parser,
1287-
String.format("Can not construct instance of %s, problem: %s", instClass.getName(), t.getMessage()), t);
1288-
}
1289-
1290-
/**
1291-
*
1292-
* @deprecated Since 2.8 use {@link #reportInstantiationException} instead
1293-
*/
1294-
@Deprecated
12951296
public JsonMappingException instantiationException(Class<?> instClass, String msg) {
12961297
return JsonMappingException.from(_parser,
12971298
String.format("Can not construct instance of %s: %s",

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.lang.reflect.Type;
55
import java.util.*;
66

7+
import com.fasterxml.jackson.annotation.JsonFormat;
78
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
89
import com.fasterxml.jackson.annotation.JsonInclude;
910
import com.fasterxml.jackson.core.*;
@@ -387,6 +388,13 @@ public JsonSerializer<?> createContextual(SerializerProvider provider,
387388
Boolean b = intr.findSerializationSortAlphabetically(propertyAcc);
388389
sortKeys = (b != null) && b.booleanValue();
389390
}
391+
JsonFormat.Value format = findFormatOverrides(provider, property, Map.class);
392+
if (format != null) {
393+
Boolean B = format.getFeature(JsonFormat.Feature.WRITE_SORTED_MAP_ENTRIES);
394+
if (B != null) {
395+
sortKeys = B.booleanValue();
396+
}
397+
}
390398
MapSerializer mser = withResolved(property, keySer, ser, ignored, sortKeys);
391399
if (suppressableValue != _suppressableValue) {
392400
mser = mser.withContentInclusion(suppressableValue);

src/test/java/com/fasterxml/jackson/databind/struct/FormatFeaturesTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,18 @@ static class CaseInsensitiveRoleWrapper
9595
public Role role;
9696
}
9797

98+
static class SortedKeysMap {
99+
@JsonFormat(with = JsonFormat.Feature.WRITE_SORTED_MAP_ENTRIES)
100+
public Map<String,Integer> values = new LinkedHashMap<>();
101+
102+
protected SortedKeysMap() { }
103+
104+
public SortedKeysMap put(String key, int value) {
105+
values.put(key, value);
106+
return this;
107+
}
108+
}
109+
98110
/*
99111
/**********************************************************
100112
/* Test methods, writing with single-element unwrapping
@@ -230,4 +242,13 @@ public void testCaseInsensitive() throws Exception {
230242
assertEquals("12", w.role.ID);
231243
assertEquals("Foo", w.role.Name);
232244
}
245+
246+
// [databind#1232]: allow forcing sorting on Map keys
247+
public void testOrderedMaps() throws Exception {
248+
SortedKeysMap map = new SortedKeysMap()
249+
.put("b", 2)
250+
.put("a", 1);
251+
assertEquals(aposToQuotes("{'values':{'a':1,'b':2}}"),
252+
MAPPER.writeValueAsString(map));
253+
}
233254
}

0 commit comments

Comments
 (0)