You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2023/12/03 16:45:40 UTC

(camel) branch main updated: CAMEL-20178: camel-jbang - Transform message to support components

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 da9b9290287 CAMEL-20178: camel-jbang - Transform message to support components
da9b9290287 is described below

commit da9b929028745bb2df923e2f3c8712ad09efbe83
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sun Dec 3 17:45:27 2023 +0100

    CAMEL-20178: camel-jbang - Transform message to support components
---
 .../modules/ROOT/pages/camel-jbang.adoc            | 50 ++++++++++++++++++++++
 .../camel/cli/connector/LocalCliConnector.java     | 18 +++++++-
 .../commands/action/TransformMessageAction.java    | 16 +++++--
 3 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index 6e36e24ba63..fa67359692b 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -2386,6 +2386,56 @@ You can also transform the message from JSon to XML as shown (or any other kind
     id: setBody-fa01
 ----
 
+=== Transforming message using Components
+
+Some components can also be used for message transformation such as Flatpack, Velocity, Freemarker, Thymaleaf, and good old XSLT.
+
+TIP: You can use `camel catalog component --filter=transform` to see which components can be transformation.
+
+Given the below XML in the `sample.xml` file:
+
+[source,xml]
+----
+<hash>
+  <id type="integer">1369</id>
+  <uid>8c946e1a-fdc5-40d3-9098-44271bdfad65</uid>
+  <account-number>8673088731</account-number>
+  <iban>GB38EFUA27474531363797</iban>
+  <bank-name>ABN AMRO MEZZANINE (UK) LIMITED</bank-name>
+  <routing-number>053228004</routing-number>
+  <swift-bic>AACCGB21</swift-bic>
+</hash>
+----
+
+Then you can transform this using an XSLT named `mystyle.xsl`:
+
+[source,xml]
+----
+<?xml version = "1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+  <xsl:template match="/">
+    <bank>
+    	<name><xsl:value-of select="/hash/bank-name/text()"/></name>
+    	<bic><xsl:value-of select="/hash/swift-bic/text()"/></bic>
+    </bank>
+  </xsl:template>
+
+</xsl:stylesheet>
+----
+
+Then you can do live changes to the stylesheet and see the output in real-time with Camel JBang by running:
+
+[source,bash]
+----
+$ camel transform message --body=file:sample.xml --component=xslt --template=file:mystyle.xsl --pretty --watch
+----
+
+You can then edit the `mystyle.xsl` file, and save the file, and watch the terminal for updated result.
+
+You can find this example at: https://github.com/apache/camel-kamelets-examples/tree/main/jbang/xslt-transform
+
+
 == Listing what Camel components is available
 
 Camel comes with a lot of artifacts out of the box which comes as:
diff --git a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
index 05871e4d527..df593973039 100644
--- a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
+++ b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java
@@ -64,6 +64,7 @@ import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.spi.CliConnector;
 import org.apache.camel.spi.CliConnectorFactory;
 import org.apache.camel.spi.ContextReloadStrategy;
+import org.apache.camel.spi.EndpointUriFactory;
 import org.apache.camel.spi.Language;
 import org.apache.camel.spi.Resource;
 import org.apache.camel.spi.ResourceLoader;
@@ -277,8 +278,9 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C
         long timestamp = System.currentTimeMillis();
         String source = root.getString("source");
         String language = root.getString("language");
+        String component = root.getString("component");
         String template = Jsoner.unescape(root.getStringOrDefault("template", ""));
-        if (template.startsWith("file:")) {
+        if (component == null && template.startsWith("file:")) {
             template = "resource:" + template;
         }
         String body = Jsoner.unescape(root.getString("body"));
@@ -380,6 +382,20 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C
                     String result = lastSourceExpression.evaluate(out, String.class);
                     out.getMessage().setBody(result);
                 }
+            } else if (component != null) {
+                // transform via component
+                out.setPattern(ExchangePattern.InOut);
+                out.getMessage().setBody(inputBody);
+                if (inputHeaders != null) {
+                    out.getMessage().setHeaders(inputHeaders);
+                }
+                String uri = component + ":" + template;
+                // must disable any kind of content cache on the component, so template is always reloaded
+                EndpointUriFactory euf = camelContext.getCamelContextExtension().getEndpointUriFactory(component);
+                if (euf.propertyNames().contains("contentCache")) {
+                    uri = uri + "?contentCache=false";
+                }
+                out = producer.send(uri, out);
             } else {
                 // transform via language
                 Language lan = camelContext.resolveLanguage(language);
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/TransformMessageAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/TransformMessageAction.java
index fd07c1c96d4..140d6193a70 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/TransformMessageAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/TransformMessageAction.java
@@ -64,6 +64,11 @@ public class TransformMessageAction extends ActionWatchCommand {
                         description = "The language to use for message transformation")
     private String language;
 
+    @CommandLine.Option(names = {
+            "--component" },
+                        description = "The component to use for message transformation")
+    private String component;
+
     @CommandLine.Option(names = {
             "--template" },
                         description = "The template to use for message transformation (prefix with file: to refer to loading message body from file)")
@@ -112,12 +117,12 @@ public class TransformMessageAction extends ActionWatchCommand {
     @Override
     public Integer doCall() throws Exception {
         // either source or language/template is required
-        if (source == null && template == null && language == null) {
-            System.err.println("Either source or template and language must be configured");
+        if (source == null && template == null && language == null && component == null) {
+            System.err.println("Either source or template and language/component must be configured");
             return -1;
         }
-        if (source == null && (template == null || language == null)) {
-            System.err.println("Both template and language must be configured");
+        if (source == null && (template == null || language == null && component == null)) {
+            System.err.println("Both template and language/component must be configured");
             return -1;
         }
 
@@ -166,6 +171,9 @@ public class TransformMessageAction extends ActionWatchCommand {
         if (language != null) {
             root.put("language", language);
         }
+        if (component != null) {
+            root.put("component", component);
+        }
         if (template != null) {
             root.put("template", Jsoner.escape(template));
         }