Skip to content

Commit a20921d

Browse files
committed
Merge branch '2.18'
2 parents b2592b3 + 3ddbc97 commit a20921d

File tree

6 files changed

+68
-9
lines changed

6 files changed

+68
-9
lines changed

release-notes/VERSION-2.x

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ Project: jackson-databind
4848
`@JsonProperty` and javac `-parameters`
4949
(reported by Alexandre J)
5050
#4570: Deprecate `ObjectMapper.canDeserialize()`/`ObjectMapper.canSerialize()`
51+
#4580: Add `MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER` to use
52+
Creator properties' declaration order for sorting
5153

5254
2.17.2 (not yet released)
5355

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

+17
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,23 @@ public enum MapperFeature
302302
*/
303303
SORT_CREATOR_PROPERTIES_FIRST(true),
304304

305+
/**
306+
* Feature that defines whether Creator properties (ones passed through
307+
* constructor or static factory method) should be sorted in their declaration
308+
* order if {@link #SORT_CREATOR_PROPERTIES_FIRST} is also enabled.
309+
* This is usually used to prevent alphabetic sorting for
310+
* Creator properties even if {@link #SORT_PROPERTIES_ALPHABETICALLY} is
311+
* enabled for other types of properties.
312+
*<p>
313+
* NOTE: if {@link #SORT_CREATOR_PROPERTIES_FIRST} is disabled, this feature
314+
* has no effect.
315+
*<p>
316+
* Feature is disabled by default (for backwards compatibility)
317+
*
318+
* @since 2.18
319+
*/
320+
SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER(false),
321+
305322
/*
306323
/**********************************************************************
307324
/* Name-related features

src/main/java/tools/jackson/databind/introspect/POJOPropertiesCollector.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -1531,7 +1531,11 @@ protected void _sortProperties(Map<String, POJOPropertyBuilder> props)
15311531
* so creator properties still fully predate non-creator ones.
15321532
*/
15331533
Collection<POJOPropertyBuilder> cr;
1534-
if (sortAlpha) {
1534+
// 18-Jun-2024, tatu: [databind#4580] We may want to retain declaration
1535+
// order regardless
1536+
boolean sortCreatorPropsByAlpha = sortAlpha
1537+
&& !_config.isEnabled(MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER);
1538+
if (sortCreatorPropsByAlpha) {
15351539
TreeMap<String, POJOPropertyBuilder> sorted =
15361540
new TreeMap<String,POJOPropertyBuilder>();
15371541
for (POJOPropertyBuilder prop : _creatorProperties) {

src/test-jdk17/java/tools/jackson/databind/jdk17/RecordPrivate4175Test.java renamed to src/test-jdk17/java/tools/jackson/databind/records/RecordPrivate4175Test.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tools.jackson.databind.jdk17;
1+
package tools.jackson.databind.records;
22

33
import java.util.Collections;
44

src/test-jdk17/java/tools/jackson/databind/records/RecordSerializationOrderTest.java

+29-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.fasterxml.jackson.annotation.JsonProperty;
66
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
77

8+
import tools.jackson.databind.MapperFeature;
89
import tools.jackson.databind.ObjectMapper;
910
import tools.jackson.databind.testutil.DatabindTestUtil;
1011

@@ -14,18 +15,20 @@ public class RecordSerializationOrderTest extends DatabindTestUtil
1415
{
1516
record NestedRecordOne(String id, String email, NestedRecordTwo nestedRecordTwo) {}
1617
record NestedRecordOneWithJsonProperty(String id, String email,
17-
@JsonProperty("nestedProperty") NestedRecordTwo nestedRecordTwo) {}
18+
@JsonProperty("nestedProperty") NestedRecordTwo nestedRecordTwo) {}
1819
record NestedRecordOneWithJsonPropertyIndex(@JsonProperty(index = 2) String id,
19-
@JsonProperty(index = 0) String email,
20-
@JsonProperty(value = "nestedProperty", index = 1) NestedRecordTwo nestedRecordTwo) {}
20+
@JsonProperty(index = 0) String email,
21+
@JsonProperty(value = "nestedProperty", index = 1) NestedRecordTwo nestedRecordTwo) {}
2122

2223
@JsonPropertyOrder({"email", "nestedProperty", "id"})
2324
record NestedRecordOneWithJsonPropertyOrder(String id,
24-
String email,
25-
@JsonProperty(value = "nestedProperty") NestedRecordTwo nestedRecordTwo) {}
25+
String email,
26+
@JsonProperty(value = "nestedProperty") NestedRecordTwo nestedRecordTwo) {}
2627

2728
record NestedRecordTwo(String id, String passport) {}
2829

30+
record CABRecord(String c, String a, String b) {}
31+
2932
private final ObjectMapper MAPPER = newJsonMapper();
3033

3134
/*
@@ -72,4 +75,25 @@ public void testSerializationOrderWithJsonPropertyOrder() throws Exception {
7275
final String expected = "{\"email\":\"[email protected]\",\"nestedProperty\":{\"id\":\"2\",\"passport\":\"111110\"},\"id\":\"1\"}";
7376
assertEquals(expected, output);
7477
}
78+
79+
// [databind#4580]
80+
@Test
81+
public void testSerializationOrderWrtCreatorAlphabetic() throws Exception {
82+
// In 3.0, sorting by Alphabetic enabled by default so
83+
assertEquals(a2q("{'a':'a','b':'b','c':'c'}"),
84+
MAPPER.writeValueAsString(new CABRecord("c", "a", "b")));
85+
// But can disable
86+
assertEquals(a2q("{'c':'c','a':'a','b':'b'}"),
87+
jsonMapperBuilder()
88+
.disable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
89+
.build()
90+
.writeValueAsString(new CABRecord("c", "a", "b")));
91+
// Except if we tell it not to:
92+
assertEquals(a2q("{'c':'c','a':'a','b':'b'}"),
93+
jsonMapperBuilder()
94+
.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
95+
.enable(MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER)
96+
.build()
97+
.writeValueAsString(new CABRecord("c", "a", "b")));
98+
}
7599
}

src/test/java/tools/jackson/databind/ser/SerializationOrderTest.java

+14-2
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,20 @@ public void testCreatorVsExplicitOrdering() throws Exception
205205
@Test
206206
public void testAlphaAndCreatorOrdering() throws Exception
207207
{
208-
String json = ALPHA_MAPPER.writeValueAsString(new BeanForGH311(2, 1));
209-
assertEquals("{\"a\":1,\"b\":2}", json);
208+
assertEquals(a2q("{'a':1,'b':2}"),
209+
ALPHA_MAPPER.writeValueAsString(new BeanForGH311(2, 1)));
210+
}
211+
212+
// [databind#4580]
213+
@Test
214+
public void testAlphaAndCreatorDeclarationOrdering() throws Exception
215+
{
216+
final ObjectMapper mapper = jsonMapperBuilder()
217+
.enable(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY)
218+
.enable(MapperFeature.SORT_CREATOR_PROPERTIES_BY_DECLARATION_ORDER)
219+
.build();
220+
assertEquals(a2q("{'b':2,'a':1}"),
221+
mapper.writeValueAsString(new BeanForGH311(2, 1)));
210222
}
211223

212224
// [databind#2555]

0 commit comments

Comments
 (0)