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

davsclaus pushed a commit to branch fix/CAMEL-23756
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 7a3b660f632e0540103c34ccde281b985782aa65
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Jun 15 13:32:36 2026 +0200

    CAMEL-23756: camel-jbang-mcp - Support Java DSL as source format in route 
transform tool
    
    Co-Authored-By: Claude <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 dsl/camel-jbang/camel-jbang-mcp/pom.xml            |   4 +
 .../jbang/core/commands/mcp/TransformTools.java    |  74 ++++++++-
 .../core/commands/mcp/TransformToolsTest.java      | 168 +++++++++++++++++++++
 3 files changed, 238 insertions(+), 8 deletions(-)

diff --git a/dsl/camel-jbang/camel-jbang-mcp/pom.xml 
b/dsl/camel-jbang/camel-jbang-mcp/pom.xml
index ccf1351464ca..9bab3f333f9c 100644
--- a/dsl/camel-jbang/camel-jbang-mcp/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-mcp/pom.xml
@@ -111,6 +111,10 @@
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-yaml-dsl</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-java-joor-dsl</artifactId>
+        </dependency>
 
         <!-- Swagger/OpenAPI parser for contract-first OpenAPI tools -->
         <dependency>
diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java
index 8b19c5e21ceb..604f7339b7da 100644
--- 
a/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/main/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformTools.java
@@ -25,6 +25,8 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import jakarta.enterprise.context.ApplicationScoped;
 import jakarta.inject.Inject;
@@ -52,6 +54,8 @@ import org.apache.camel.yaml.out.YamlModelWriter;
 @ApplicationScoped
 public class TransformTools {
 
+    private static final Pattern CLASS_NAME_PATTERN = 
Pattern.compile("(?:public\\s+)?class\\s+(\\w+)");
+
     @Inject
     CatalogService catalogService;
 
@@ -158,7 +162,8 @@ public class TransformTools {
      */
     @Tool(annotations = @Tool.Annotations(readOnlyHint = true, destructiveHint 
= false, openWorldHint = false),
           description = "Transform a Camel route between different DSL formats 
(YAML, XML). " +
-                        "Note: Java to YAML/XML transformation has 
limitations.")
+                        "Note: Java to YAML/XML transformation has 
limitations."
+                        + " Java DSL can only be used as source format, not as 
target format.")
     public TransformResult camel_transform_route(
             @ToolArg(description = "Route definition to transform") String 
route,
             @ToolArg(description = "Source format (yaml, xml, java)") String 
fromFormat,
@@ -181,13 +186,6 @@ public class TransformTools {
             return result;
         }
 
-        if ("java".equals(from)) {
-            result.supported = false;
-            result.note = "Java DSL to " + toFormat + " transformation is not 
supported. "
-                          + "There is no lightweight Java DSL parser 
available.";
-            return result;
-        }
-
         try {
             if ("xml".equals(from) && "yaml".equals(to)) {
                 result.result = transformXmlToYaml(route);
@@ -195,6 +193,12 @@ public class TransformTools {
             } else if ("yaml".equals(from) && "xml".equals(to)) {
                 result.result = transformYamlToXml(route);
                 result.supported = true;
+            } else if ("java".equals(from) && "yaml".equals(to)) {
+                result.result = transformJavaToFormat(route, "yaml");
+                result.supported = true;
+            } else if ("java".equals(from) && "xml".equals(to)) {
+                result.result = transformJavaToFormat(route, "xml");
+                result.supported = true;
             } else {
                 result.supported = false;
                 result.note = "Unsupported transformation: " + fromFormat + " 
to " + toFormat;
@@ -264,6 +268,60 @@ public class TransformTools {
         }
     }
 
+    private String transformJavaToFormat(String java, String targetFormat) 
throws Exception {
+        DefaultCamelContext ctx = new DefaultCamelContext();
+        try {
+            ctx.build();
+
+            String source = wrapSnippetIfNeeded(java);
+            String className = extractClassName(source);
+            Resource resource = ResourceHelper.fromString(className + ".java", 
source);
+            PluginHelper.getRoutesLoader(ctx).loadRoutes(resource);
+
+            List<RouteDefinition> routeDefs = ctx.getRouteDefinitions();
+            if (routeDefs == null || routeDefs.isEmpty()) {
+                throw new IllegalArgumentException(
+                        "Could not parse Java route. Ensure it contains a 
valid route definition.");
+            }
+
+            if ("yaml".equals(targetFormat)) {
+                YamlModelWriter writer = new YamlModelWriter();
+                List<JsonObject> roots = new ArrayList<>();
+                for (RouteDefinition route : routeDefs) {
+                    roots.add(writer.writeRouteDefinition(route));
+                }
+                return writer.printAsYaml(roots);
+            } else {
+                RoutesDefinition rd = new RoutesDefinition();
+                rd.setRoutes(routeDefs);
+
+                StringWriter sw = new StringWriter();
+                new 
org.apache.camel.xml.out.ModelWriter(sw).writeRoutesDefinition(rd);
+                return sw.toString();
+            }
+        } finally {
+            ctx.stop();
+        }
+    }
+
+    private static String wrapSnippetIfNeeded(String source) {
+        if (CLASS_NAME_PATTERN.matcher(source).find()) {
+            return source;
+        }
+        return "import org.apache.camel.builder.RouteBuilder;\n\n"
+               + "public class SnippetRoute extends RouteBuilder {\n"
+               + "    @Override\n"
+               + "    public void configure() {\n"
+               + "        " + source + "\n"
+               + "    }\n"
+               + "}\n";
+    }
+
+    private static String extractClassName(String source) {
+        Matcher m = CLASS_NAME_PATTERN.matcher(source);
+        return m.find() ? m.group(1) : "Route";
+    }
+
     /**
      * Tool to validate a YAML DSL route definition against the Camel YAML DSL 
JSON schema.
      */
diff --git 
a/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformToolsTest.java
 
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformToolsTest.java
new file mode 100644
index 000000000000..3d7644f97fd3
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-mcp/src/test/java/org/apache/camel/dsl/jbang/core/commands/mcp/TransformToolsTest.java
@@ -0,0 +1,168 @@
+/*
+ * 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.dsl.jbang.core.commands.mcp;
+
+import java.util.Optional;
+
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class TransformToolsTest {
+
+    private TransformTools createTools() {
+        CatalogService catalogService = new CatalogService();
+        catalogService.catalogRepos = Optional.empty();
+
+        TransformTools tools = new TransformTools();
+        tools.catalogService = catalogService;
+        return tools;
+    }
+
+    @Test
+    void transformXmlToYaml() {
+        TransformTools tools = createTools();
+        String xml = """
+                <routes xmlns="http://camel.apache.org/schema/spring";>
+                  <route>
+                    <from uri="timer:hello"/>
+                    <log message="Hello World"/>
+                  </route>
+                </routes>
+                """;
+
+        TransformTools.TransformResult result = 
tools.camel_transform_route(xml, "xml", "yaml");
+
+        assertThat(result.supported).isTrue();
+        assertThat(result.result).contains("timer");
+        assertThat(result.result).contains("log");
+    }
+
+    @Test
+    void transformYamlToXml() {
+        TransformTools tools = createTools();
+        String yaml = """
+                - route:
+                    from:
+                      uri: timer:hello
+                      steps:
+                        - log:
+                            message: Hello World
+                """;
+
+        TransformTools.TransformResult result = 
tools.camel_transform_route(yaml, "yaml", "xml");
+
+        assertThat(result.supported).isTrue();
+        assertThat(result.result).contains("timer:hello");
+        assertThat(result.result).contains("<log");
+    }
+
+    @Test
+    void transformJavaToYaml() {
+        TransformTools tools = createTools();
+        String java = """
+                import org.apache.camel.builder.RouteBuilder;
+
+                public class MyRoute extends RouteBuilder {
+                    @Override
+                    public void configure() {
+                        from("timer:hello")
+                            .log("Hello World");
+                    }
+                }
+                """;
+
+        TransformTools.TransformResult result = 
tools.camel_transform_route(java, "java", "yaml");
+
+        assertThat(result.supported).isTrue();
+        assertThat(result.result).contains("timer");
+        assertThat(result.result).contains("log");
+    }
+
+    @Test
+    void transformJavaToXml() {
+        TransformTools tools = createTools();
+        String java = """
+                import org.apache.camel.builder.RouteBuilder;
+
+                public class MyRoute extends RouteBuilder {
+                    @Override
+                    public void configure() {
+                        from("timer:hello")
+                            .log("Hello World");
+                    }
+                }
+                """;
+
+        TransformTools.TransformResult result = 
tools.camel_transform_route(java, "java", "xml");
+
+        assertThat(result.supported).isTrue();
+        assertThat(result.result).contains("timer:hello");
+        assertThat(result.result).contains("<log");
+    }
+
+    @Test
+    void transformJavaSnippetToYaml() {
+        TransformTools tools = createTools();
+        String snippet = """
+                from("timer:hello")
+                    .log("Hello World");
+                """;
+
+        TransformTools.TransformResult result = 
tools.camel_transform_route(snippet, "java", "yaml");
+
+        assertThat(result.supported).isTrue();
+        assertThat(result.result).contains("timer");
+        assertThat(result.result).contains("log");
+    }
+
+    @Test
+    void transformJavaSnippetToXml() {
+        TransformTools tools = createTools();
+        String snippet = """
+                from("timer:hello")
+                    .to("log:foo");
+                """;
+
+        TransformTools.TransformResult result = 
tools.camel_transform_route(snippet, "java", "xml");
+
+        assertThat(result.supported).isTrue();
+        assertThat(result.result).contains("timer:hello");
+        assertThat(result.result).contains("log:foo");
+    }
+
+    @Test
+    void sameFormatReturnsInput() {
+        TransformTools tools = createTools();
+        String yaml = "- route:\n    from:\n      uri: timer:hello\n";
+
+        TransformTools.TransformResult result = 
tools.camel_transform_route(yaml, "yaml", "yaml");
+
+        assertThat(result.supported).isTrue();
+        assertThat(result.result).isEqualTo(yaml);
+    }
+
+    @Test
+    void unsupportedFormatReturnsNotSupported() {
+        TransformTools tools = createTools();
+
+        TransformTools.TransformResult result = 
tools.camel_transform_route("some route", "groovy", "yaml");
+
+        assertThat(result.supported).isFalse();
+        assertThat(result.note).contains("Unsupported");
+    }
+}

Reply via email to