This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git

commit fdd7d9b9d8736b3e85ad9cefc1e7671c7abc9a3e
Author: Claus Ibsen <[email protected]>
AuthorDate: Sat Jun 4 10:05:09 2022 +0200

    CAMEL-18165: camel-jackson - Add out of the box type converters for 
converting to/from JSonNode
---
 .../converter/JacksonTypeConvertersLoader.java     |  30 +++++
 .../src/main/docs/jackson-dataformat.adoc          |  12 +-
 .../jackson/converter/JacksonTypeConverters.java   |  72 +++++++++++
 .../converter/JacksonJSonNodeConverterTest.java    | 139 +++++++++++++++++++++
 4 files changed, 249 insertions(+), 4 deletions(-)

diff --git 
a/components/camel-jackson/src/generated/java/org/apache/camel/component/jackson/converter/JacksonTypeConvertersLoader.java
 
b/components/camel-jackson/src/generated/java/org/apache/camel/component/jackson/converter/JacksonTypeConvertersLoader.java
index ec2fda53072..a527933abc1 100644
--- 
a/components/camel-jackson/src/generated/java/org/apache/camel/component/jackson/converter/JacksonTypeConvertersLoader.java
+++ 
b/components/camel-jackson/src/generated/java/org/apache/camel/component/jackson/converter/JacksonTypeConvertersLoader.java
@@ -37,9 +37,39 @@ public final class JacksonTypeConvertersLoader implements 
TypeConverterLoader, C
 
     @Override
     public void load(TypeConverterRegistry registry) throws 
TypeConverterLoaderException {
+        registerConverters(registry);
         registerFallbackConverters(registry);
     }
 
+    private void registerConverters(TypeConverterRegistry registry) {
+        addTypeConverter(registry, byte[].class, 
com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toByteArray((com.fasterxml.jackson.databind.JsonNode)
 value, exchange));
+        addTypeConverter(registry, 
com.fasterxml.jackson.databind.JsonNode.class, byte[].class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toJsonNode((byte[]) value, exchange));
+        addTypeConverter(registry, 
com.fasterxml.jackson.databind.JsonNode.class, java.io.File.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toJsonNode((java.io.File) value, exchange));
+        addTypeConverter(registry, 
com.fasterxml.jackson.databind.JsonNode.class, java.io.InputStream.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toJsonNode((java.io.InputStream) value, exchange));
+        addTypeConverter(registry, 
com.fasterxml.jackson.databind.JsonNode.class, java.io.Reader.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toJsonNode((java.io.Reader) value, exchange));
+        addTypeConverter(registry, 
com.fasterxml.jackson.databind.JsonNode.class, java.lang.String.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toJsonNode((java.lang.String) value, exchange));
+        addTypeConverter(registry, 
com.fasterxml.jackson.databind.JsonNode.class, java.util.Map.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toJsonNode((java.util.Map) value, exchange));
+        addTypeConverter(registry, java.io.InputStream.class, 
com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toInputStream((com.fasterxml.jackson.databind.JsonNode)
 value, exchange));
+        addTypeConverter(registry, java.io.Reader.class, 
com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toReader((com.fasterxml.jackson.databind.JsonNode) 
value, exchange));
+        addTypeConverter(registry, java.lang.String.class, 
com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toString((com.fasterxml.jackson.databind.JsonNode) 
value, exchange));
+        addTypeConverter(registry, java.util.Map.class, 
com.fasterxml.jackson.databind.JsonNode.class, false,
+            (type, exchange, value) -> 
getJacksonTypeConverters().toMap((com.fasterxml.jackson.databind.JsonNode) 
value, exchange));
+    }
+
+    private static void addTypeConverter(TypeConverterRegistry registry, 
Class<?> toType, Class<?> fromType, boolean allowNull, 
SimpleTypeConverter.ConversionMethod method) { 
+        registry.addTypeConverter(toType, fromType, new 
SimpleTypeConverter(allowNull, method));
+    }
+
     private void registerFallbackConverters(TypeConverterRegistry registry) {
         addFallbackTypeConverter(registry, false, false, (type, exchange, 
value) -> getJacksonTypeConverters().convertTo(type, exchange, value, 
registry));
     }
diff --git a/components/camel-jackson/src/main/docs/jackson-dataformat.adoc 
b/components/camel-jackson/src/main/docs/jackson-dataformat.adoc
index b4098f20959..0f96603425d 100644
--- a/components/camel-jackson/src/main/docs/jackson-dataformat.adoc
+++ b/components/camel-jackson/src/main/docs/jackson-dataformat.adoc
@@ -40,14 +40,18 @@ and then use it. When this happens you should set a `INFO` 
logging from Camel.
 == Using Jackson for automatic type conversion
 
 The `camel-jackson` module allows integrating Jackson as a 
xref:manual::type-converter.adoc[Type Converter].
-This works in similar ways that xref:dataformats:jaxb-dataformat.adoc[JAXB] 
integrates with Camels type converter.
 
-To use this `camel-jackson` must be enabled, which is done by setting the 
following options
-on the `CamelContext` global options, as shown:
+This gives a set of out of the box converters to/from the Jackson type 
`JSonNode`, such as converting
+from `JSonNode` to `String` or vice-versa.
+
+=== Enabling more type converters and support for POJOs
+
+To enable POJO conversion support for `camel-jackson` then this must be 
enabled,
+which is done by setting the following options on the `CamelContext` global 
options, as shown:
 
 [source,java]
 ----
-// Enable Jackson JSON type converter.
+// Enable Jackson JSON type converter for more types.
 camelContext.getGlobalOptions().put("CamelJacksonEnableTypeConverter", "true");
 // Allow Jackson JSON to convert to pojo types also
 // (by default Jackson only converts to String and other simple types)
diff --git 
a/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/converter/JacksonTypeConverters.java
 
b/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/converter/JacksonTypeConverters.java
index 0751d2c110e..20830dc5986 100644
--- 
a/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/converter/JacksonTypeConverters.java
+++ 
b/components/camel-jackson/src/main/java/org/apache/camel/component/jackson/converter/JacksonTypeConverters.java
@@ -16,13 +16,17 @@
  */
 package org.apache.camel.component.jackson.converter;
 
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.Reader;
 import java.nio.ByteBuffer;
 import java.util.Map;
 import java.util.Set;
 
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.Module;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.apache.camel.CamelContext;
@@ -61,6 +65,74 @@ public final class JacksonTypeConverters {
         this.lock = new Object();
     }
 
+    @Converter
+    public JsonNode toJsonNode(String text, Exchange exchange) throws 
Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(text);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(byte[] arr, Exchange exchange) throws Exception 
{
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(arr);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(InputStream is, Exchange exchange) throws 
Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(is);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(File file, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(file);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(Reader reader, Exchange exchange) throws 
Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.readTree(reader);
+    }
+
+    @Converter
+    public JsonNode toJsonNode(Map map, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.valueToTree(map);
+    }
+
+    @Converter
+    public String toString(JsonNode node, Exchange exchange) throws Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        // output as string in pretty mode
+        return 
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(node);
+    }
+
+    @Converter
+    public byte[] toByteArray(JsonNode node, Exchange exchange) throws 
Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.writeValueAsBytes(node);
+    }
+
+    @Converter
+    public InputStream toInputStream(JsonNode node, Exchange exchange) throws 
Exception {
+        byte[] arr = toByteArray(node, exchange);
+        return new ByteArrayInputStream(arr);
+    }
+
+    @Converter
+    public Map<String, Object> toMap(JsonNode node, Exchange exchange) throws 
Exception {
+        ObjectMapper mapper = resolveObjectMapper(exchange.getContext());
+        return mapper.convertValue(node, new TypeReference<Map<String, 
Object>>() {
+        });
+    }
+
+    @Converter
+    public Reader toReader(JsonNode node, Exchange exchange) throws Exception {
+        InputStream is = toInputStream(node, exchange);
+        return new InputStreamReader(is);
+    }
+
     @Converter(fallback = true)
     public <T> T convertTo(Class<T> type, Exchange exchange, Object value, 
TypeConverterRegistry registry) throws Exception {
 
diff --git 
a/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java
 
b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java
new file mode 100644
index 00000000000..a34300ea244
--- /dev/null
+++ 
b/components/camel-jackson/src/test/java/org/apache/camel/component/jackson/converter/JacksonJSonNodeConverterTest.java
@@ -0,0 +1,139 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.camel.component.jackson.converter;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.camel.Exchange;
+import org.apache.camel.support.DefaultExchange;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+public class JacksonJSonNodeConverterTest extends CamelTestSupport {
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void stringToJsonNode() {
+        Exchange exchange = new DefaultExchange(context);
+
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, 
exchange, "{ \"message\": \"Hello World\" }");
+        assertNotNull(node);
+
+        Assertions.assertEquals("\"Hello World\"", 
node.get("message").toString());
+    }
+
+    @Test
+    public void byteArrayToJsonNode() {
+        Exchange exchange = new DefaultExchange(context);
+
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, 
exchange,
+                "{ \"message\": \"Bye World\" 
}".getBytes(StandardCharsets.UTF_8));
+        assertNotNull(node);
+
+        Assertions.assertEquals("\"Bye World\"", 
node.get("message").toString());
+    }
+
+    @Test
+    public void inputStreamToJsonNode() {
+        Exchange exchange = new DefaultExchange(context);
+
+        ByteArrayInputStream bis = new ByteArrayInputStream("{ \"message\": 
\"Bye World\" }".getBytes(StandardCharsets.UTF_8));
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, 
exchange, bis);
+        assertNotNull(node);
+
+        Assertions.assertEquals("\"Bye World\"", 
node.get("message").toString());
+    }
+
+    @Test
+    public void mapToJsonNode() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Hello Camel");
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, 
exchange, map);
+        assertNotNull(node);
+
+        Assertions.assertEquals("\"Hello Camel\"", 
node.get("message").toString());
+    }
+
+    @Test
+    public void jsonNodeToString() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Hello Camel");
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, 
exchange, map);
+
+        String text = context.getTypeConverter().convertTo(String.class, 
exchange, node);
+        assertNotNull(text);
+
+        Assertions.assertEquals("{\n  \"message\" : \"Hello Camel\"\n}", text);
+    }
+
+    @Test
+    public void jsonNodeToByteArray() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Hello Camel");
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, 
exchange, map);
+
+        byte[] arr = context.getTypeConverter().convertTo(byte[].class, 
exchange, node);
+        assertNotNull(arr);
+        String s = context.getTypeConverter().convertTo(String.class, 
exchange, arr);
+
+        Assertions.assertEquals("{\"message\":\"Hello Camel\"}", s);
+    }
+
+    @Test
+    public void jsonNodeToInputStream() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Hello Camel");
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, 
exchange, map);
+
+        InputStream is = 
context.getTypeConverter().convertTo(InputStream.class, exchange, node);
+        assertNotNull(is);
+        String s = context.getTypeConverter().convertTo(String.class, 
exchange, is);
+
+        Assertions.assertEquals("{\"message\":\"Hello Camel\"}", s);
+    }
+
+    @Test
+    public void jsonNodeToMap() {
+        Exchange exchange = new DefaultExchange(context);
+
+        Map<String, Object> map = Map.of("message", "Bye Camel", "age", 44);
+        JsonNode node = context.getTypeConverter().convertTo(JsonNode.class, 
exchange, map);
+
+        Map out = context.getTypeConverter().convertTo(Map.class, exchange, 
node);
+        assertNotNull(out);
+
+        Assertions.assertEquals(2, out.size());
+        Assertions.assertEquals("Bye Camel", out.get("message"));
+        Assertions.assertEquals(44, out.get("age"));
+    }
+
+}

Reply via email to