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
The following commit(s) were added to refs/heads/main by this push:
new 44e2fb14b7e CAMEL-22361: camel-groovy-xml - Add data format that uses
groovy xml that is easy to use and no need for POJOs
44e2fb14b7e is described below
commit 44e2fb14b7e122a50a9004990ba78ecb7ceb70ca
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Aug 22 16:29:08 2025 +0200
CAMEL-22361: camel-groovy-xml - Add data format that uses groovy xml that
is easy to use and no need for POJOs
---
.../org/apache/camel/groovy/xml/groovyXml.json | 2 +-
.../src/main/docs/groovyXml-dataformat.adoc | 2 +-
.../camel/groovy/xml/GroovyXmlDataFormat.java | 21 ++++---
.../camel/groovy/xml/GroovyXmlDataFormatTest.java | 70 ++++++++++++++++++++++
4 files changed, 85 insertions(+), 10 deletions(-)
diff --git
a/components/camel-groovy-xml/src/generated/resources/META-INF/org/apache/camel/groovy/xml/groovyXml.json
b/components/camel-groovy-xml/src/generated/resources/META-INF/org/apache/camel/groovy/xml/groovyXml.json
index af52a11b703..20da0954eab 100644
---
a/components/camel-groovy-xml/src/generated/resources/META-INF/org/apache/camel/groovy/xml/groovyXml.json
+++
b/components/camel-groovy-xml/src/generated/resources/META-INF/org/apache/camel/groovy/xml/groovyXml.json
@@ -3,7 +3,7 @@
"kind": "dataformat",
"name": "groovyXml",
"title": "Groovy XML",
- "description": "Transform between XML and Java Map via Groovy",
+ "description": "Transform between XML and Groovy Node (Map structure)
objects.",
"deprecated": false,
"firstVersion": "4.15.0",
"label": "dataformat,transformation,xml",
diff --git
a/components/camel-groovy-xml/src/main/docs/groovyXml-dataformat.adoc
b/components/camel-groovy-xml/src/main/docs/groovyXml-dataformat.adoc
index 9a8a4e878b2..67ccc1e1eb0 100644
--- a/components/camel-groovy-xml/src/main/docs/groovyXml-dataformat.adoc
+++ b/components/camel-groovy-xml/src/main/docs/groovyXml-dataformat.adoc
@@ -2,7 +2,7 @@
:doctitle: Groovy XML
:shortname: groovyXml
:artifactid: camel-groovy-xml
-:description: Transform between XML and Java Map via Groovy
+:description: Transform between XML and Groovy Node (Map structure) objects.
:since: 4.15
:supportlevel: Preview
:tabs-sync-option:
diff --git
a/components/camel-groovy-xml/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java
b/components/camel-groovy-xml/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java
index c5d99b5a851..d29d19e4882 100644
---
a/components/camel-groovy-xml/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java
+++
b/components/camel-groovy-xml/src/main/java/org/apache/camel/groovy/xml/GroovyXmlDataFormat.java
@@ -39,9 +39,9 @@ import org.apache.camel.util.StringHelper;
@Dataformat("groovyXml")
public class GroovyXmlDataFormat extends ServiceSupport implements DataFormat,
DataFormatName {
- int START_TAG = 1;
- int VALUE = 2;
- int END_TAG = 3;
+ private static final int START_TAG = 1;
+ private static final int VALUE = 2;
+ private static final int END_TAG = 3;
@Override
public void marshal(Exchange exchange, Object graph, OutputStream stream)
throws Exception {
@@ -122,6 +122,7 @@ public class GroovyXmlDataFormat extends ServiceSupport
implements DataFormat, D
}
private void doSerialize(CamelContext context, Map<String, Object> map,
List<Line> lines) {
+ boolean root = false;
for (var e : map.entrySet()) {
String key = e.getKey();
@@ -132,6 +133,7 @@ public class GroovyXmlDataFormat extends ServiceSupport
implements DataFormat, D
// root tag
if (lines.isEmpty()) {
+ root = true;
lines.add(new Line(key, null, START_TAG));
}
@@ -140,7 +142,7 @@ public class GroovyXmlDataFormat extends ServiceSupport
implements DataFormat, D
if (e.getValue() instanceof Map cm) {
doSerialize(context, cm, lines);
} else if (e.getValue() instanceof List cl) {
- doSerialize(context, cl, key, lines);
+ doSerialize(context, cl, key, lines, root);
} else {
String val =
context.getTypeConverter().convertTo(String.class, e.getValue());
if (val != null) {
@@ -154,14 +156,17 @@ public class GroovyXmlDataFormat extends ServiceSupport
implements DataFormat, D
}
}
- private void doSerialize(CamelContext context, List list, String key,
List<Line> lines) {
- // list of map or value entries
+ private void doSerialize(CamelContext context, List list, String key,
List<Line> lines, boolean root) {
for (var e : list) {
- lines.add(new Line(key, null, START_TAG));
+ if (!root) {
+ lines.add(new Line(key, null, START_TAG));
+ }
if (e instanceof Map map) {
doSerialize(context, map, lines);
}
- lines.add(new Line(key, null, END_TAG));
+ if (!root) {
+ lines.add(new Line(key, null, END_TAG));
+ }
}
}
diff --git
a/components/camel-groovy-xml/src/test/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatTest.java
b/components/camel-groovy-xml/src/test/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatTest.java
index a82685ebee2..59ef9b44ba3 100644
---
a/components/camel-groovy-xml/src/test/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatTest.java
+++
b/components/camel-groovy-xml/src/test/java/org/apache/camel/groovy/xml/GroovyXmlDataFormatTest.java
@@ -94,6 +94,40 @@ public class GroovyXmlDataFormatTest extends
CamelTestSupport {
}
""";
+ private static final String COUNTRIES
+ = """
+ <countries>
+ <country>Norway</country>
+ <country>Denmark</country>
+ <country>Sweden</country>
+ <country>Germany</country>
+ <country>Finland</country>
+ </countries>
+ """;
+
+ private static final String COUNTRIES_JSON
+ = """
+ {
+ "countries": [
+ {
+ "country": "Norway"
+ },
+ {
+ "country": "Denmark"
+ },
+ {
+ "country": "Sweden"
+ },
+ {
+ "country": "Germany"
+ },
+ {
+ "country": "Finland"
+ }
+ ]
+ }
+ """;
+
@Test
public void testUnmarshal() throws Exception {
getMockEndpoint("mock:unmarshal").expectedMessageCount(1);
@@ -198,6 +232,42 @@ public class GroovyXmlDataFormatTest extends
CamelTestSupport {
MockEndpoint.assertIsSatisfied(context);
}
+ @Test
+ public void testUnmarshalArray() throws Exception {
+ getMockEndpoint("mock:unmarshal").expectedMessageCount(1);
+
+ Object out = template.requestBody("direct:unmarshal", COUNTRIES);
+ Assertions.assertNotNull(out);
+ Assertions.assertInstanceOf(Node.class, out);
+
+ Node n = (Node) out;
+ Assertions.assertEquals(5, n.children().size());
+ Assertions.assertEquals("country[attributes={}; value=[Norway]]",
n.children().get(0).toString());
+ Assertions.assertEquals("country[attributes={}; value=[Denmark]]",
n.children().get(1).toString());
+ Assertions.assertEquals("country[attributes={}; value=[Sweden]]",
n.children().get(2).toString());
+ Assertions.assertEquals("country[attributes={}; value=[Germany]]",
n.children().get(3).toString());
+ Assertions.assertEquals("country[attributes={}; value=[Finland]]",
n.children().get(4).toString());
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Test
+ public void testMarshalArrayJacksonJSon() throws Exception {
+ getMockEndpoint("mock:marshal").expectedMessageCount(1);
+
+ ObjectMapper om = new JsonMapper();
+ JsonNode root = om.readTree(COUNTRIES_JSON);
+
+ Object out = template.requestBody("direct:marshal", root);
+ Assertions.assertNotNull(out);
+ Assertions.assertInstanceOf(byte[].class, out);
+
+ String xml = context.getTypeConverter().convertTo(String.class, out);
+ Assertions.assertEquals(COUNTRIES, xml);
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
@Override
protected RoutesBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {