From 4fcaf6f67e78abf3fa3ddbf8f768483b20146668 Mon Sep 17 00:00:00 2001 From: rikkarth Date: Tue, 10 Sep 2024 19:57:32 +0100 Subject: [PATCH 1/5] ObjectMapper.toJsonNode base implementation unit-test in ObjectMapperTest to validate base solution --- .../tools/jackson/databind/ObjectMapper.java | 26 +++++++++++++++++++ .../jackson/databind/ObjectMapperTest.java | 23 ++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/main/java/tools/jackson/databind/ObjectMapper.java b/src/main/java/tools/jackson/databind/ObjectMapper.java index 3071181f0c..e106526119 100644 --- a/src/main/java/tools/jackson/databind/ObjectMapper.java +++ b/src/main/java/tools/jackson/databind/ObjectMapper.java @@ -10,6 +10,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.Collector; import tools.jackson.core.*; import tools.jackson.core.exc.StreamReadException; @@ -563,6 +564,31 @@ public Collection getRegisteredModules() { return _savedBuilderState.modules(); } + /* + /********************************************************************** + /* Collectors for Stream support. + /********************************************************************** + */ + + /** + * Creates a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode}. + *

+ * This method uses this instance of {@link ObjectMapper} to create an empty {@link ArrayNode} and then adds each + * {@link JsonNode} to it. + *

+ * + * @return a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode} + * + * @since 3.0 + */ + public Collector toJsonNode() { + return Collector.of( + this::createArrayNode, // supplier + ArrayNode::add, // accumulator + ArrayNode::addAll // combiner + ); + } + /* /********************************************************************** /* Public API: constructing Parsers that are properly linked diff --git a/src/test/java/tools/jackson/databind/ObjectMapperTest.java b/src/test/java/tools/jackson/databind/ObjectMapperTest.java index bfe6fe5b23..22d1bf490f 100644 --- a/src/test/java/tools/jackson/databind/ObjectMapperTest.java +++ b/src/test/java/tools/jackson/databind/ObjectMapperTest.java @@ -7,6 +7,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.util.*; +import java.util.stream.IntStream; import java.util.stream.Collectors; import java.util.zip.ZipOutputStream; @@ -100,6 +101,28 @@ public void testProps() assertSame(nf, m.getNodeFactory()); } + @Test + public void testCollector() + { + final ObjectMapper objectMapper = new ObjectMapper(); + + final JsonNode jsonNodeResult = IntStream.range(0, 10) + .mapToObj(i -> { + ObjectNode objectNode = objectMapper.createObjectNode(); + objectNode.put("testString", "example"); + objectNode.put("testNumber", i); + objectNode.put("testBoolean", true); + + return objectNode; + }) + .collect(objectMapper.toJsonNode()); + + System.out.println(jsonNodeResult.toPrettyString()); + + assertEquals(10, jsonNodeResult.size()); + jsonNodeResult.forEach(jsonNode -> assertFalse(jsonNode.isEmpty())); + } + // Test to ensure that we can check property ordering defaults... @Test public void testConfigForPropertySorting() throws Exception From 84b9ff14823a0a5b7f20079214a1d2f9c814b0e1 Mon Sep 17 00:00:00 2001 From: rikkarth Date: Thu, 12 Sep 2024 23:13:35 +0100 Subject: [PATCH 2/5] implementation moved to util.JacksonCollectors --- .../tools/jackson/databind/ObjectMapper.java | 25 ------------ .../databind/util/JacksonCollectors.java | 38 +++++++++++++++++++ .../jackson/databind/ObjectMapperTest.java | 22 ----------- .../databind/util/JacksonCollectorsTest.java | 35 +++++++++++++++++ 4 files changed, 73 insertions(+), 47 deletions(-) create mode 100644 src/main/java/tools/jackson/databind/util/JacksonCollectors.java create mode 100644 src/test/java/tools/jackson/databind/util/JacksonCollectorsTest.java diff --git a/src/main/java/tools/jackson/databind/ObjectMapper.java b/src/main/java/tools/jackson/databind/ObjectMapper.java index e106526119..7ef0b29919 100644 --- a/src/main/java/tools/jackson/databind/ObjectMapper.java +++ b/src/main/java/tools/jackson/databind/ObjectMapper.java @@ -564,31 +564,6 @@ public Collection getRegisteredModules() { return _savedBuilderState.modules(); } - /* - /********************************************************************** - /* Collectors for Stream support. - /********************************************************************** - */ - - /** - * Creates a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode}. - *

- * This method uses this instance of {@link ObjectMapper} to create an empty {@link ArrayNode} and then adds each - * {@link JsonNode} to it. - *

- * - * @return a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode} - * - * @since 3.0 - */ - public Collector toJsonNode() { - return Collector.of( - this::createArrayNode, // supplier - ArrayNode::add, // accumulator - ArrayNode::addAll // combiner - ); - } - /* /********************************************************************** /* Public API: constructing Parsers that are properly linked diff --git a/src/main/java/tools/jackson/databind/util/JacksonCollectors.java b/src/main/java/tools/jackson/databind/util/JacksonCollectors.java new file mode 100644 index 0000000000..b9c774903c --- /dev/null +++ b/src/main/java/tools/jackson/databind/util/JacksonCollectors.java @@ -0,0 +1,38 @@ +package tools.jackson.databind.util; + +import java.util.stream.Collector; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeFactory; + +/** + * Utility class that provides custom {@link Collector} implementations to support Stream operations. + *

+ * This class is not meant to be instantiated and serves only as a utility class. + *

+ */ +public class JacksonCollectors { + + private JacksonCollectors() { + throw new UnsupportedOperationException("Utility class cannot be instantiated."); + } + + /** + * Creates a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode}. + *

+ * This method uses a {@link JsonNodeFactory} to create an empty {@link ArrayNode} and then adds each + * {@link JsonNode} to it. + *

+ * + * @return a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode} + */ + public static Collector toJsonNode() { + final JsonNodeFactory jsonNodeFactory = new JsonNodeFactory(); + + return Collector.of( + jsonNodeFactory::arrayNode, // supplier + ArrayNode::add, // accumulator + ArrayNode::addAll // combiner + ); + } +} diff --git a/src/test/java/tools/jackson/databind/ObjectMapperTest.java b/src/test/java/tools/jackson/databind/ObjectMapperTest.java index 22d1bf490f..778831eb22 100644 --- a/src/test/java/tools/jackson/databind/ObjectMapperTest.java +++ b/src/test/java/tools/jackson/databind/ObjectMapperTest.java @@ -101,28 +101,6 @@ public void testProps() assertSame(nf, m.getNodeFactory()); } - @Test - public void testCollector() - { - final ObjectMapper objectMapper = new ObjectMapper(); - - final JsonNode jsonNodeResult = IntStream.range(0, 10) - .mapToObj(i -> { - ObjectNode objectNode = objectMapper.createObjectNode(); - objectNode.put("testString", "example"); - objectNode.put("testNumber", i); - objectNode.put("testBoolean", true); - - return objectNode; - }) - .collect(objectMapper.toJsonNode()); - - System.out.println(jsonNodeResult.toPrettyString()); - - assertEquals(10, jsonNodeResult.size()); - jsonNodeResult.forEach(jsonNode -> assertFalse(jsonNode.isEmpty())); - } - // Test to ensure that we can check property ordering defaults... @Test public void testConfigForPropertySorting() throws Exception diff --git a/src/test/java/tools/jackson/databind/util/JacksonCollectorsTest.java b/src/test/java/tools/jackson/databind/util/JacksonCollectorsTest.java new file mode 100644 index 0000000000..5e1d7eb94f --- /dev/null +++ b/src/test/java/tools/jackson/databind/util/JacksonCollectorsTest.java @@ -0,0 +1,35 @@ +package tools.jackson.databind.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +import java.util.stream.IntStream; +import org.junit.jupiter.api.Test; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.ObjectMapper; +import tools.jackson.databind.node.ObjectNode; + +public class JacksonCollectorsTest { + + @Test + public void testToJsonNode() + { + final ObjectMapper objectMapper = new ObjectMapper(); + + final JsonNode jsonNodeResult = IntStream.range(0, 10) + .mapToObj(i -> { + ObjectNode objectNode = objectMapper.createObjectNode(); + objectNode.put("testString", "example"); + objectNode.put("testNumber", i); + objectNode.put("testBoolean", true); + + return objectNode; + }) + .collect(JacksonCollectors.toJsonNode()); + + System.out.println(jsonNodeResult.toPrettyString()); + + assertEquals(10, jsonNodeResult.size()); + jsonNodeResult.forEach(jsonNode -> assertFalse(jsonNode.isEmpty())); + } +} From 4ad6737f8ecba5159e8ef138d76d80849b026147 Mon Sep 17 00:00:00 2001 From: rikkarth Date: Fri, 13 Sep 2024 07:53:49 +0100 Subject: [PATCH 3/5] cleanup, toJsonNode minor change --- .../java/tools/jackson/databind/util/JacksonCollectors.java | 5 ++++- .../tools/jackson/databind/util/JacksonCollectorsTest.java | 2 -- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/tools/jackson/databind/util/JacksonCollectors.java b/src/main/java/tools/jackson/databind/util/JacksonCollectors.java index b9c774903c..5ed7b8a8d2 100644 --- a/src/main/java/tools/jackson/databind/util/JacksonCollectors.java +++ b/src/main/java/tools/jackson/databind/util/JacksonCollectors.java @@ -3,6 +3,7 @@ import java.util.stream.Collector; import tools.jackson.databind.JsonNode; import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.JsonNodeCreator; import tools.jackson.databind.node.JsonNodeFactory; /** @@ -25,9 +26,11 @@ private JacksonCollectors() { *

* * @return a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode} + * + * @since 2.18 */ public static Collector toJsonNode() { - final JsonNodeFactory jsonNodeFactory = new JsonNodeFactory(); + final JsonNodeCreator jsonNodeFactory = JsonNodeFactory.instance; return Collector.of( jsonNodeFactory::arrayNode, // supplier diff --git a/src/test/java/tools/jackson/databind/util/JacksonCollectorsTest.java b/src/test/java/tools/jackson/databind/util/JacksonCollectorsTest.java index 5e1d7eb94f..cedc044060 100644 --- a/src/test/java/tools/jackson/databind/util/JacksonCollectorsTest.java +++ b/src/test/java/tools/jackson/databind/util/JacksonCollectorsTest.java @@ -27,8 +27,6 @@ public void testToJsonNode() }) .collect(JacksonCollectors.toJsonNode()); - System.out.println(jsonNodeResult.toPrettyString()); - assertEquals(10, jsonNodeResult.size()); jsonNodeResult.forEach(jsonNode -> assertFalse(jsonNode.isEmpty())); } From 0c205129bfd913c602af64c4982c83cccac8c14e Mon Sep 17 00:00:00 2001 From: rikkarth Date: Fri, 13 Sep 2024 07:55:27 +0100 Subject: [PATCH 4/5] cleanup, toJsonNode minor change --- .../java/tools/jackson/databind/util/JacksonCollectors.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/tools/jackson/databind/util/JacksonCollectors.java b/src/main/java/tools/jackson/databind/util/JacksonCollectors.java index 5ed7b8a8d2..e5abadf997 100644 --- a/src/main/java/tools/jackson/databind/util/JacksonCollectors.java +++ b/src/main/java/tools/jackson/databind/util/JacksonCollectors.java @@ -11,6 +11,8 @@ *

* This class is not meant to be instantiated and serves only as a utility class. *

+ * + * @since 2.18 */ public class JacksonCollectors { From 66024d9d86e5b108a13fbffee21d258abde0e8c0 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Thu, 19 Sep 2024 20:17:18 -0700 Subject: [PATCH 5/5] Minor cleanup --- .../tools/jackson/databind/ObjectMapper.java | 1 - .../databind/util/JacksonCollectors.java | 21 +++++++------------ .../jackson/databind/ObjectMapperTest.java | 1 - 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/main/java/tools/jackson/databind/ObjectMapper.java b/src/main/java/tools/jackson/databind/ObjectMapper.java index 7ef0b29919..3071181f0c 100644 --- a/src/main/java/tools/jackson/databind/ObjectMapper.java +++ b/src/main/java/tools/jackson/databind/ObjectMapper.java @@ -10,7 +10,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicReference; -import java.util.stream.Collector; import tools.jackson.core.*; import tools.jackson.core.exc.StreamReadException; diff --git a/src/main/java/tools/jackson/databind/util/JacksonCollectors.java b/src/main/java/tools/jackson/databind/util/JacksonCollectors.java index e5abadf997..efe70ef1df 100644 --- a/src/main/java/tools/jackson/databind/util/JacksonCollectors.java +++ b/src/main/java/tools/jackson/databind/util/JacksonCollectors.java @@ -14,12 +14,7 @@ * * @since 2.18 */ -public class JacksonCollectors { - - private JacksonCollectors() { - throw new UnsupportedOperationException("Utility class cannot be instantiated."); - } - +public abstract class JacksonCollectors { /** * Creates a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode}. *

@@ -28,16 +23,16 @@ private JacksonCollectors() { *

* * @return a {@link Collector} that collects {@link JsonNode} elements into an {@link ArrayNode} - * - * @since 2.18 */ public static Collector toJsonNode() { - final JsonNodeCreator jsonNodeFactory = JsonNodeFactory.instance; + return toJsonNode(JsonNodeFactory.instance); + } + public static Collector toJsonNode(JsonNodeCreator nodeCreator) { return Collector.of( - jsonNodeFactory::arrayNode, // supplier - ArrayNode::add, // accumulator - ArrayNode::addAll // combiner - ); + nodeCreator::arrayNode, // supplier + ArrayNode::add, // accumulator + ArrayNode::addAll // combiner + ); } } diff --git a/src/test/java/tools/jackson/databind/ObjectMapperTest.java b/src/test/java/tools/jackson/databind/ObjectMapperTest.java index 778831eb22..bfe6fe5b23 100644 --- a/src/test/java/tools/jackson/databind/ObjectMapperTest.java +++ b/src/test/java/tools/jackson/databind/ObjectMapperTest.java @@ -7,7 +7,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.*; import java.util.*; -import java.util.stream.IntStream; import java.util.stream.Collectors; import java.util.zip.ZipOutputStream;