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

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

commit 5e448b7280f1c8e5833b5832f19442cefea17f6b
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Mar 9 16:41:28 2026 +0100

    CAMEL-23160: camel-core - Add type converter for camel-util-json
---
 .../camel/converter/json/JsonConverterTest.java    |  99 ++++++++++++++
 .../stream/CamelSupportBulkConverterLoader.java    | 144 +++++++++++++++++++++
 .../services/org/apache/camel/TypeConverterLoader  |   2 +-
 .../apache/camel/converter/json/JsonConverter.java |  47 +++++++
 .../java/org/apache/camel/util/json/JsonArray.java |  22 ++++
 .../org/apache/camel/util/json/JsonObject.java     |  22 ++++
 6 files changed, 335 insertions(+), 1 deletion(-)

diff --git 
a/core/camel-core/src/test/java/org/apache/camel/converter/json/JsonConverterTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/converter/json/JsonConverterTest.java
new file mode 100644
index 000000000000..6bc743e268b9
--- /dev/null
+++ 
b/core/camel-core/src/test/java/org/apache/camel/converter/json/JsonConverterTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.converter.json;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class JsonConverterTest extends ContextTestSupport {
+
+    private static final String BOOKS
+            = """
+                    {
+                        "library": {
+                            "book": [
+                                {
+                                    "title": "No Title",
+                                    "author": "F. Scott Fitzgerald",
+                                    "year": "1925",
+                                    "genre": "Classic",
+                                    "id": "bk101"
+                                },
+                                {
+                                    "title": "1984",
+                                    "author": "George Orwell",
+                                    "year": "1949",
+                                    "genre": "Dystopian",
+                                    "id": "bk102"
+                                }
+                            ]
+                        }
+                    }
+                    """;
+
+    private static final String BOOKS_ARR = """
+                [
+                    {
+                        "title": "No Title",
+                        "author": "F. Scott Fitzgerald",
+                        "year": "1925",
+                        "genre": "Classic",
+                        "id": "bk101"
+                    },
+                    {
+                        "title": "1984",
+                        "author": "George Orwell",
+                        "year": "1949",
+                        "genre": "Dystopian",
+                        "id": "bk102"
+                    }
+                ]
+            """;
+
+    @Test
+    public void testConvertObject() throws Exception {
+        JsonObject jo = context.getTypeConverter().convertTo(JsonObject.class, 
BOOKS);
+        Assertions.assertNotNull(jo);
+
+        JsonArray arr = jo.getJsonObject("library").getJsonArray("book");
+        Assertions.assertEquals(2, arr.size());
+        JsonObject b1 = arr.getJsonObject(0);
+        JsonObject b2 = arr.getJsonObject(1);
+        Assertions.assertEquals("No Title", b1.getString("title"));
+        Assertions.assertEquals(1925, b1.getInteger("year"));
+        Assertions.assertEquals("1984", b2.getString("title"));
+        Assertions.assertEquals(1949, b2.getInteger("year"));
+    }
+
+    @Test
+    public void testConvertArray() throws Exception {
+        JsonArray arr = context.getTypeConverter().convertTo(JsonArray.class, 
BOOKS_ARR);
+        Assertions.assertNotNull(arr);
+
+        Assertions.assertEquals(2, arr.size());
+        JsonObject b1 = arr.getJsonObject(0);
+        JsonObject b2 = arr.getJsonObject(1);
+        Assertions.assertEquals("No Title", b1.getString("title"));
+        Assertions.assertEquals(1925, b1.getInteger("year"));
+        Assertions.assertEquals("1984", b2.getString("title"));
+        Assertions.assertEquals(1949, b2.getInteger("year"));
+    }
+
+}
diff --git 
a/core/camel-support/src/generated/java/org/apache/camel/converter/stream/CamelSupportBulkConverterLoader.java
 
b/core/camel-support/src/generated/java/org/apache/camel/converter/stream/CamelSupportBulkConverterLoader.java
new file mode 100644
index 000000000000..7a7a1177fc87
--- /dev/null
+++ 
b/core/camel-support/src/generated/java/org/apache/camel/converter/stream/CamelSupportBulkConverterLoader.java
@@ -0,0 +1,144 @@
+/* Generated by camel build tools - do NOT edit this file! */
+package org.apache.camel.converter.stream;
+
+import javax.annotation.processing.Generated;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.CamelContextAware;
+import org.apache.camel.DeferredContextBinding;
+import org.apache.camel.Exchange;
+import org.apache.camel.Ordered;
+import org.apache.camel.TypeConversionException;
+import org.apache.camel.TypeConverterLoaderException;
+import org.apache.camel.TypeConverter;
+import org.apache.camel.spi.TypeConvertible;
+import org.apache.camel.spi.BulkTypeConverters;
+import org.apache.camel.spi.TypeConverterLoader;
+import org.apache.camel.spi.TypeConverterRegistry;
+
+/**
+ * Generated by camel build tools - do NOT edit this file!
+ */
+@Generated("org.apache.camel.maven.packaging.TypeConverterLoaderGeneratorMojo")
+@SuppressWarnings("unchecked")
+@DeferredContextBinding
+public final class CamelSupportBulkConverterLoader implements 
TypeConverterLoader, BulkTypeConverters, CamelContextAware {
+
+    private CamelContext camelContext;
+
+    public CamelSupportBulkConverterLoader() {
+    }
+
+    @Override
+    public void setCamelContext(CamelContext camelContext) {
+        this.camelContext = camelContext;
+    }
+
+    @Override
+    public CamelContext getCamelContext() {
+        return camelContext;
+    }
+
+    @Override
+    public int size() {
+        return 8;
+    }
+
+    @Override
+    public void load(TypeConverterRegistry registry) throws 
TypeConverterLoaderException {
+        registry.addBulkTypeConverters(this);
+        doRegistration(registry);
+    }
+
+    @Override
+    public <T> T convertTo(Class<?> from, Class<T> to, Exchange exchange, 
Object value) throws TypeConversionException {
+        try {
+            Object obj = doConvertTo(from, to, exchange, value);
+            return (T) obj;
+        } catch (TypeConversionException e) {
+            throw e;
+        } catch (Exception e) {
+            throw new TypeConversionException(value, to, e);
+        }
+    }
+
+    private Object doConvertTo(Class<?> from, Class<?> to, Exchange exchange, 
Object value) throws Exception {
+        if (to == byte[].class) {
+            if (value instanceof org.apache.camel.StreamCache) {
+                return 
org.apache.camel.converter.stream.StreamCacheConverter.convertToByteArray((org.apache.camel.StreamCache)
 value, exchange);
+            }
+        } else if (to == java.nio.ByteBuffer.class) {
+            if (value instanceof org.apache.camel.StreamCache) {
+                return 
org.apache.camel.converter.stream.StreamCacheConverter.convertToByteBuffer((org.apache.camel.StreamCache)
 value, exchange);
+            }
+        } else if (to == org.apache.camel.StreamCache.class) {
+            if (value instanceof java.io.ByteArrayInputStream) {
+                return 
org.apache.camel.converter.stream.StreamCacheConverter.convertToStreamCache((java.io.ByteArrayInputStream)
 value, exchange);
+            }
+            if (value instanceof java.io.InputStream) {
+                return 
org.apache.camel.converter.stream.StreamCacheConverter.convertToStreamCache((java.io.InputStream)
 value, exchange);
+            }
+            if (value instanceof 
org.apache.camel.converter.stream.CachedOutputStream) {
+                return 
org.apache.camel.converter.stream.StreamCacheConverter.convertToStreamCache((org.apache.camel.converter.stream.CachedOutputStream)
 value, exchange);
+            }
+            if (value instanceof java.io.Reader) {
+                return 
org.apache.camel.converter.stream.StreamCacheConverter.convertToStreamCache((java.io.Reader)
 value, exchange);
+            }
+        } else if (to == org.apache.camel.util.json.JsonArray.class) {
+            if (value instanceof java.lang.String) {
+                return 
org.apache.camel.converter.json.JsonConverter.convertToJsonArray((java.lang.String)
 value, exchange);
+            }
+        } else if (to == org.apache.camel.util.json.JsonObject.class) {
+            if (value instanceof java.lang.String) {
+                return 
org.apache.camel.converter.json.JsonConverter.convertToJsonObject((java.lang.String)
 value, exchange);
+            }
+        }
+        return null;
+    }
+
+    private void doRegistration(TypeConverterRegistry registry) {
+        registry.addConverter(new 
TypeConvertible<>(org.apache.camel.StreamCache.class, byte[].class), this);
+        registry.addConverter(new 
TypeConvertible<>(org.apache.camel.StreamCache.class, 
java.nio.ByteBuffer.class), this);
+        registry.addConverter(new 
TypeConvertible<>(java.io.ByteArrayInputStream.class, 
org.apache.camel.StreamCache.class), this);
+        registry.addConverter(new TypeConvertible<>(java.io.InputStream.class, 
org.apache.camel.StreamCache.class), this);
+        registry.addConverter(new 
TypeConvertible<>(org.apache.camel.converter.stream.CachedOutputStream.class, 
org.apache.camel.StreamCache.class), this);
+        registry.addConverter(new TypeConvertible<>(java.io.Reader.class, 
org.apache.camel.StreamCache.class), this);
+        registry.addConverter(new TypeConvertible<>(java.lang.String.class, 
org.apache.camel.util.json.JsonArray.class), this);
+        registry.addConverter(new TypeConvertible<>(java.lang.String.class, 
org.apache.camel.util.json.JsonObject.class), this);
+    }
+
+    public TypeConverter lookup(Class<?> to, Class<?> from) {
+        if (to == byte[].class) {
+            if (from == org.apache.camel.StreamCache.class) {
+                return this;
+            }
+        } else if (to == java.nio.ByteBuffer.class) {
+            if (from == org.apache.camel.StreamCache.class) {
+                return this;
+            }
+        } else if (to == org.apache.camel.StreamCache.class) {
+            if (from == java.io.ByteArrayInputStream.class) {
+                return this;
+            }
+            if (from == java.io.InputStream.class) {
+                return this;
+            }
+            if (from == 
org.apache.camel.converter.stream.CachedOutputStream.class) {
+                return this;
+            }
+            if (from == java.io.Reader.class) {
+                return this;
+            }
+        } else if (to == org.apache.camel.util.json.JsonArray.class) {
+            if (from == java.lang.String.class) {
+                return this;
+            }
+        } else if (to == org.apache.camel.util.json.JsonObject.class) {
+            if (from == java.lang.String.class) {
+                return this;
+            }
+        }
+        return null;
+    }
+
+}
diff --git 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
 
b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
index 67c03404364e..1ef7881f482d 100644
--- 
a/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
+++ 
b/core/camel-support/src/generated/resources/META-INF/services/org/apache/camel/TypeConverterLoader
@@ -1,2 +1,2 @@
 # Generated by camel build tools - do NOT edit this file!
-org.apache.camel.converter.stream.StreamCacheBulkConverterLoader
+org.apache.camel.converter.stream.CamelSupportBulkConverterLoader
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/converter/json/JsonConverter.java
 
b/core/camel-support/src/main/java/org/apache/camel/converter/json/JsonConverter.java
new file mode 100644
index 000000000000..15b4d75cd1f3
--- /dev/null
+++ 
b/core/camel-support/src/main/java/org/apache/camel/converter/json/JsonConverter.java
@@ -0,0 +1,47 @@
+/*
+ * 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.converter.json;
+
+import org.apache.camel.Converter;
+import org.apache.camel.Exchange;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
+
+/**
+ * A set of {@link Converter} methods for camel-util-json objects.
+ */
+@Converter(generateBulkLoader = true)
+public final class JsonConverter {
+
+    /**
+     * Utility classes should not have a public constructor.
+     */
+    private JsonConverter() {
+    }
+
+    @Converter(order = 1)
+    public static JsonObject convertToJsonObject(String json, Exchange 
exchange) throws Exception {
+        return Jsoner.deserialize(json, (JsonObject) null);
+    }
+
+    @Converter(order = 2)
+    public static JsonArray convertToJsonArray(String json, Exchange exchange) 
throws Exception {
+        return (JsonArray) Jsoner.deserialize(json);
+    }
+
+}
diff --git 
a/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonArray.java
 
b/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonArray.java
index fadc301de0fa..fa1ed51f1f95 100644
--- 
a/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonArray.java
+++ 
b/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonArray.java
@@ -71,6 +71,28 @@ public class JsonArray extends ArrayList<Object> implements 
Jsonable {
         }
     }
 
+    /**
+     * A convenience method that assumes there is another JsonObject at the 
given index.
+     *
+     * @param  index              representing where the value is expected to 
be at.
+     * @return                    the value stored at the key.
+     * @throws ClassCastException if the value didn't match the assumed return 
type.
+     */
+    public JsonObject getJsonObject(final int index) {
+        return getMap(index);
+    }
+
+    /**
+     * A convenience method that assumes there is a JsonArray at the given 
index.
+     *
+     * @param  index              representing where the value is expected to 
be at.
+     * @return                    the value stored at the key.
+     * @throws ClassCastException if the value didn't match the assumed return 
type.
+     */
+    public JsonArray getJsonArray(final int index) {
+        return getCollection(index);
+    }
+
     /**
      * A convenience method that assumes there is a BigDecimal, Number, or 
String at the given index. If a Number or
      * String is there it is used to construct a new BigDecimal.
diff --git 
a/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java
 
b/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java
index 13354f2c87ad..e3c93873a2be 100644
--- 
a/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java
+++ 
b/tooling/camel-util-json/src/main/java/org/apache/camel/util/json/JsonObject.java
@@ -55,6 +55,28 @@ public class JsonObject extends LinkedHashMap<String, 
Object> implements Jsonabl
         super(map);
     }
 
+    /**
+     * A convenience method that assumes there is another JsonObject at the 
given key.
+     *
+     * @param  key                representing where the value ought to be 
stored at.
+     * @return                    the value stored at the key.
+     * @throws ClassCastException if the value didn't match the assumed return 
type.
+     */
+    public JsonObject getJsonObject(final String key) {
+        return getMap(key);
+    }
+
+    /**
+     * A convenience method that assumes there is a JsonArray at the given key.
+     *
+     * @param  key                representing where the value ought to be 
stored at.
+     * @return                    the value stored at the key.
+     * @throws ClassCastException if the value didn't match the assumed return 
type.
+     */
+    public JsonArray getJsonArray(final String key) {
+        return getCollection(key);
+    }
+
     /**
      * A convenience method that assumes there is a BigDecimal, Number, or 
String at the given key. If a Number is there
      * its Number#toString() is used to construct a new BigDecimal(String). If 
a String is there it is used to construct

Reply via email to