From 2ab21fe42cf4f2b2ec144a3543750af8906a7061 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Wed, 5 Apr 2023 19:09:06 +0900 Subject: [PATCH 1/4] Feature --- .../deser/std/StdNodeBasedDeserializer.java | 25 +++++++++ .../convert/TestUpdateViaObjectReader.java | 51 +++++++++++++++++-- 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdNodeBasedDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdNodeBasedDeserializer.java index 0bdb8afe87..80fd0111c2 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdNodeBasedDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdNodeBasedDeserializer.java @@ -61,6 +61,19 @@ public void resolve(DeserializationContext ctxt) throws JsonMappingException { public abstract T convert(JsonNode root, DeserializationContext ctxt) throws IOException; + /** + * Facilitates usage with {@link ObjectMapper#readerForUpdating(Object)} and {@link #deserialize(JsonParser, DeserializationContext, Object)} + * by eliminating the need to manually convert the value to a {@link JsonNode}. + * + * If this method is not overridden, it falls back to the behavior of {@link #convert(JsonNode, DeserializationContext)}. + * + * @since 2.15 + */ + public T convert(JsonNode root, DeserializationContext ctxt, T newValue) throws IOException { + ctxt.handleBadMerge(this); + return convert(root, ctxt); + } + /* /********************************************************** /* JsonDeserializer impl @@ -73,6 +86,18 @@ public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOExcept return convert(n, ctxt); } + /** + * + * Added to support {@link #deserialize(JsonParser, DeserializationContext, Object)} + * + * @since 2.15 + */ + @Override + public T deserialize(JsonParser jp, DeserializationContext ctxt, T newValue) throws IOException { + JsonNode n = (JsonNode) _treeDeserializer.deserialize(jp, ctxt); + return convert(n, ctxt, newValue); + } + @Override public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer td) diff --git a/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java b/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java index c824c78ef3..2daa758e37 100644 --- a/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java +++ b/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java @@ -9,6 +9,7 @@ import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import com.fasterxml.jackson.databind.deser.std.StdNodeBasedDeserializer; import com.fasterxml.jackson.databind.module.SimpleModule; import static org.junit.Assert.assertArrayEquals; @@ -115,6 +116,36 @@ public AnimalWrapper deserialize(JsonParser json, DeserializationContext context } } + @JsonDeserialize(using = Custom3814Deserializer.class) + static class Bean3814 { + public int age; + + public Bean3814(int age) { + this.age = age; + } + + public void updateTo(JsonNode root) { + age = root.get("age").asInt(); + } + } + + static class Custom3814Deserializer extends StdNodeBasedDeserializer { + public Custom3814Deserializer() { + super(Bean3814.class); + } + + @Override + public Bean3814 convert(JsonNode root, DeserializationContext ctxt) throws IOException { + return null; + } + + @Override + public Bean3814 convert(JsonNode root, DeserializationContext ctxt, Bean3814 oldValue) throws IOException { + oldValue.updateTo(root); + return oldValue; + } + } + /* /******************************************************** /* Test methods @@ -233,7 +264,7 @@ public void testUpdatingWithViews() throws Exception } // [databind#744] - public void testIssue744() throws IOException + public void testIssue744() throws Exception { ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); @@ -274,7 +305,7 @@ public void testIssue744() throws IOException } // [databind#1831] - public void test1831UsingNode() throws IOException { + public void test1831UsingNode() throws Exception { String catJson = MAPPER.writeValueAsString(new Cat()); JsonNode jsonNode = MAPPER.readTree(catJson); AnimalWrapper optionalCat = new AnimalWrapper(); @@ -283,10 +314,24 @@ public void test1831UsingNode() throws IOException { assertSame(optionalCat, result); } - public void test1831UsingString() throws IOException { + public void test1831UsingString() throws Exception { String catJson = MAPPER.writeValueAsString(new Cat()); AnimalWrapper optionalCat = new AnimalWrapper(); AnimalWrapper result = MAPPER.readerForUpdating(optionalCat).readValue(catJson); assertSame(optionalCat, result); } + + // [databind#3814] + public void testObjectReaderForUpdating() throws Exception { + // Arrange + JsonNode root = MAPPER.readTree(a2q("{'age': 30 }")); + Bean3814 obj = new Bean3814(25); + + // Act + Bean3814 newObj = MAPPER.readerForUpdating(obj).readValue(root); + + // Assert + assertSame(obj, newObj); + assertEquals(30, newObj.age); + } } From d6391f023d1378b6f4e5cf87de1ae77a7a9fca80 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Wed, 5 Apr 2023 19:31:56 +0900 Subject: [PATCH 2/4] Add Another tet --- .../convert/TestUpdateViaObjectReader.java | 61 +++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java b/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java index 2daa758e37..ef639dc4fd 100644 --- a/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java +++ b/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java @@ -116,11 +116,11 @@ public AnimalWrapper deserialize(JsonParser json, DeserializationContext context } } - @JsonDeserialize(using = Custom3814Deserializer.class) - static class Bean3814 { + @JsonDeserialize(using = Custom3814DeserializerA.class) + static class Bean3814A { public int age; - public Bean3814(int age) { + public Bean3814A(int age) { this.age = age; } @@ -129,23 +129,48 @@ public void updateTo(JsonNode root) { } } - static class Custom3814Deserializer extends StdNodeBasedDeserializer { - public Custom3814Deserializer() { - super(Bean3814.class); + static class Custom3814DeserializerA extends StdNodeBasedDeserializer { + public Custom3814DeserializerA() { + super(Bean3814A.class); } @Override - public Bean3814 convert(JsonNode root, DeserializationContext ctxt) throws IOException { + public Bean3814A convert(JsonNode root, DeserializationContext ctxt) throws IOException { return null; } @Override - public Bean3814 convert(JsonNode root, DeserializationContext ctxt, Bean3814 oldValue) throws IOException { + public Bean3814A convert(JsonNode root, DeserializationContext ctxt, Bean3814A oldValue) throws IOException { oldValue.updateTo(root); return oldValue; } } + @JsonDeserialize(using = Custom3814DeserializerB.class) + static class Bean3814B { + public int age; + + public Bean3814B(int age) { + this.age = age; + } + + public void updateTo(JsonNode root) { + age = root.get("age").asInt(); + } + } + + static class Custom3814DeserializerB extends StdNodeBasedDeserializer { + public Custom3814DeserializerB() { + super(Bean3814B.class); + } + + @Override + public Bean3814B convert(JsonNode root, DeserializationContext ctxt) throws IOException { + return new Bean3814B(root.get("age").asInt()); + } + + } + /* /******************************************************** /* Test methods @@ -322,16 +347,30 @@ public void test1831UsingString() throws Exception { } // [databind#3814] - public void testObjectReaderForUpdating() throws Exception { + public void testObjectReaderForUpdating3814A() throws Exception { // Arrange JsonNode root = MAPPER.readTree(a2q("{'age': 30 }")); - Bean3814 obj = new Bean3814(25); + Bean3814A obj = new Bean3814A(25); // Act - Bean3814 newObj = MAPPER.readerForUpdating(obj).readValue(root); + Bean3814A newObj = MAPPER.readerForUpdating(obj).readValue(root); // Assert assertSame(obj, newObj); assertEquals(30, newObj.age); } + + // [databind#3814] + public void testObjectReaderForUpdating3814B() throws Exception { + // Arrange + JsonNode root = MAPPER.readTree(a2q("{'age': 30 }")); + Bean3814B obj = new Bean3814B(25); + + // Act + Bean3814B newObj = MAPPER.readerForUpdating(obj).readValue(root); + + // Assert + assertNotSame(obj, newObj); + assertEquals(30, newObj.age); + } } From 90e5f042c60f795d76acbd1a918af97b4137b8b9 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Wed, 5 Apr 2023 19:39:14 +0900 Subject: [PATCH 3/4] Fix javaDoc --- .../jackson/databind/deser/std/StdNodeBasedDeserializer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdNodeBasedDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdNodeBasedDeserializer.java index 80fd0111c2..40b802c77d 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdNodeBasedDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdNodeBasedDeserializer.java @@ -88,7 +88,7 @@ public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOExcept /** * - * Added to support {@link #deserialize(JsonParser, DeserializationContext, Object)} + * Added to support {@link #convert(JsonNode, DeserializationContext, Object)} * * @since 2.15 */ From 7f6c1bfbb9666a084b9d2e3e459fca015e2c65db Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Wed, 5 Apr 2023 20:00:32 +0900 Subject: [PATCH 4/4] Make tests more readable --- .../databind/convert/TestUpdateViaObjectReader.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java b/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java index ef639dc4fd..b945546e8b 100644 --- a/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java +++ b/src/test/java/com/fasterxml/jackson/databind/convert/TestUpdateViaObjectReader.java @@ -166,7 +166,7 @@ public Custom3814DeserializerB() { @Override public Bean3814B convert(JsonNode root, DeserializationContext ctxt) throws IOException { - return new Bean3814B(root.get("age").asInt()); + return null; } } @@ -347,7 +347,7 @@ public void test1831UsingString() throws Exception { } // [databind#3814] - public void testObjectReaderForUpdating3814A() throws Exception { + public void testReaderForUpdating3814() throws Exception { // Arrange JsonNode root = MAPPER.readTree(a2q("{'age': 30 }")); Bean3814A obj = new Bean3814A(25); @@ -361,7 +361,7 @@ public void testObjectReaderForUpdating3814A() throws Exception { } // [databind#3814] - public void testObjectReaderForUpdating3814B() throws Exception { + public void testReaderForUpdating3814DoesNotOverride() throws Exception { // Arrange JsonNode root = MAPPER.readTree(a2q("{'age': 30 }")); Bean3814B obj = new Bean3814B(25); @@ -371,6 +371,6 @@ public void testObjectReaderForUpdating3814B() throws Exception { // Assert assertNotSame(obj, newObj); - assertEquals(30, newObj.age); + assertNull(newObj); } }