From 2c60b44a5fc0565a97ef56d19e7461a75cb36790 Mon Sep 17 00:00:00 2001
From: Oswaldo Baptista Vicente Junior
<45291656+oswaldobapvicjr@users.noreply.github.com>
Date: Sun, 14 Aug 2022 00:44:44 -0300
Subject: [PATCH] Add support to Jackson's JsonNode
---
jsonmerge-core/pom.xml | 8 +
.../provider/JacksonJsonNodeJsonProvider.java | 168 ++++++++++++++++++
...MergerJacksonJsonNodeJsonProviderTest.java | 108 +++++++++++
.../JacksonJsonNodeJsonProviderTest.java | 42 +++++
pom.xml | 1 -
5 files changed, 326 insertions(+), 1 deletion(-)
create mode 100644 jsonmerge-core/src/main/java/net/obvj/jsonmerge/provider/JacksonJsonNodeJsonProvider.java
create mode 100644 jsonmerge-core/src/test/java/net/obvj/jsonmerge/JsonMergerJacksonJsonNodeJsonProviderTest.java
create mode 100644 jsonmerge-core/src/test/java/net/obvj/jsonmerge/provider/JacksonJsonNodeJsonProviderTest.java
diff --git a/jsonmerge-core/pom.xml b/jsonmerge-core/pom.xml
index 8bea437..07fa7f8 100644
--- a/jsonmerge-core/pom.xml
+++ b/jsonmerge-core/pom.xml
@@ -35,6 +35,7 @@
2.7.0
20220320
2.9.1
+ 2.13.3
@@ -73,5 +74,12 @@
true
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ ${jackson.version}
+ true
+
+
diff --git a/jsonmerge-core/src/main/java/net/obvj/jsonmerge/provider/JacksonJsonNodeJsonProvider.java b/jsonmerge-core/src/main/java/net/obvj/jsonmerge/provider/JacksonJsonNodeJsonProvider.java
new file mode 100644
index 0000000..2bfacf2
--- /dev/null
+++ b/jsonmerge-core/src/main/java/net/obvj/jsonmerge/provider/JacksonJsonNodeJsonProvider.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2022 obvj.net
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package net.obvj.jsonmerge.provider;
+
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.Spliterator;
+import java.util.function.Consumer;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
+/**
+ * A specialized {@link JsonProvider} implementation for {@code Jackson}'s
+ * {@link JsonNode}.
+ *
+ * @author oswaldo.bapvic.jr (Oswaldo Junior)
+ * @since 1.0.0
+ *
+ * @see Jackson Project home
+ * @see JsonNode
+ * @see ObjectNode
+ * @see ArrayNode
+ */
+public class JacksonJsonNodeJsonProvider implements JsonProvider
+{
+ private ObjectNode toJsonObject(final Object jsonObject)
+ {
+ return (ObjectNode) jsonObject;
+ }
+
+ private ArrayNode toJsonArray(final Object jsonArray)
+ {
+ return (ArrayNode) jsonArray;
+ }
+
+ /**
+ * Converts an object to a {@link JsonNode}.
+ *
+ * @param object the object to be converted
+ * @return a {@link JsonNode} from the specified object
+ */
+ public JsonNode toJsonNode(final Object object)
+ {
+ return object instanceof JsonNode ? (JsonNode) object
+ : new ObjectMapper().convertValue(object, JsonNode.class);
+ }
+
+ @Override
+ public boolean isJsonObject(final Object object)
+ {
+ return object instanceof ObjectNode;
+ }
+
+ @Override
+ public boolean isJsonArray(final Object object)
+ {
+ return object instanceof ArrayNode;
+ }
+
+ @Override
+ public boolean isEmpty(final Object jsonObject)
+ {
+ return toJsonObject(jsonObject).isEmpty();
+ }
+
+ @Override
+ public Object newJsonObject()
+ {
+ return JsonNodeFactory.instance.objectNode();
+ }
+
+ @Override
+ public Object newJsonObject(final Object sourceJsonObject)
+ {
+ return JsonNodeFactory.instance.objectNode().setAll(toJsonObject(sourceJsonObject));
+ }
+
+ @Override
+ public Object newJsonArray()
+ {
+ return JsonNodeFactory.instance.arrayNode();
+ }
+
+ @Override
+ public Object newJsonArray(final Object sourceJsonArray)
+ {
+ return JsonNodeFactory.instance.arrayNode().addAll(toJsonArray(sourceJsonArray));
+ }
+
+ @Override
+ public Set> entrySet(final Object jsonObject)
+ {
+ Iterator> iterator = toJsonObject(jsonObject).fields();
+ Iterable> iterable = () -> iterator;
+ return (Set) StreamSupport.stream(iterable.spliterator(), false).collect(Collectors.toSet());
+ }
+
+ @Override
+ public Object get(final Object jsonObject, final String key)
+ {
+ return toJsonObject(jsonObject).get(key);
+ }
+
+
+ @Override
+ public void put(final Object jsonObject, final String key, final Object value)
+ {
+ toJsonObject(jsonObject).set(key, toJsonNode(value));
+ }
+
+ @Override
+ public void putIfAbsent(final Object jsonObject, final String key, final Object value)
+ {
+ ObjectNode json = toJsonObject(jsonObject);
+ if (json.get(key) == null)
+ {
+ json.set(key, toJsonNode(value));
+ }
+ }
+
+ @Override
+ public void add(final Object jsonArray, final Object element)
+ {
+ toJsonArray(jsonArray).add(toJsonNode(element));
+ }
+
+ @Override
+ public void forEachElementInArray(final Object jsonArray, final Consumer super Object> action)
+ {
+ toJsonArray(jsonArray).forEach(action);
+ }
+
+ @Override
+ public boolean arrayContains(final Object jsonArray, final Object element)
+ {
+ return stream(jsonArray).anyMatch(element::equals);
+ }
+
+ @Override
+ public Stream