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

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

commit 56d19593e5b8c6d138f8479f0131897e5ab09753
Author: Claus Ibsen <[email protected]>
AuthorDate: Tue Dec 23 16:01:01 2025 +0100

    camel-jbang - Add plugin for route-parser
---
 bom/camel-bom/pom.xml                              |   5 +
 .../camel/dsl/jbang/core/common/PluginType.java    |   3 +-
 .../jbang/core/commands/plugin/PluginGetTest.java  |  22 ++--
 .../{ => camel-jbang-plugin-route-parser}/pom.xml  |  47 ++++---
 .../camel-jbang-plugin-route-parser                |   2 +
 .../jbang/core/commands/parser/ParserPlugin.java   |  32 +++++
 .../core/commands/parser/RouteParserCommand.java   | 146 +++++++++++++++++++++
 dsl/camel-jbang/pom.xml                            |   1 +
 parent/pom.xml                                     |   5 +
 9 files changed, 235 insertions(+), 28 deletions(-)

diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index e399a6774f85..869f1c3f83db 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -1222,6 +1222,11 @@
         <artifactId>camel-jbang-plugin-kubernetes</artifactId>
         <version>4.17.0-SNAPSHOT</version>
       </dependency>
+      <dependency>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-jbang-plugin-route-parser</artifactId>
+        <version>4.17.0-SNAPSHOT</version>
+      </dependency>
       <dependency>
         <groupId>org.apache.camel</groupId>
         <artifactId>camel-jbang-plugin-test</artifactId>
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginType.java
 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginType.java
index 98c0b081e897..5c952404d3b0 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginType.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/common/PluginType.java
@@ -27,7 +27,8 @@ public enum PluginType {
     KUBERNETES("kubernetes", "kubernetes", "Run Camel applications on 
Kubernetes", "4.8.0", null),
     GENERATE("generate", "generate", "Generate code such as DTOs", "4.8.0", 
null),
     EDIT("edit", "edit", "Edit Camel files with suggestions", "4.12.0", null),
-    TEST("test", "test", "Manage tests for Camel applications", "4.14.0", 
null);
+    TEST("test", "test", "Manage tests for Camel applications", "4.14.0", 
null),
+    ROUTE_PARSER("route-parser", "route-parser", "Parses Java route and dumps 
route structure", "4.17.0", null);
 
     private final String name;
     private final String command;
diff --git 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGetTest.java
 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGetTest.java
index 0bd83461a02a..887c0af4a879 100644
--- 
a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGetTest.java
+++ 
b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/plugin/PluginGetTest.java
@@ -70,12 +70,12 @@ class PluginGetTest extends CamelCommandBaseTestSupport {
         command.doCall();
 
         List<String> output = printer.getLines();
-        Assertions.assertEquals(7, output.size());
+        Assertions.assertEquals(8, output.size());
         Assertions.assertEquals("Supported plugins:", output.get(0));
-        Assertions.assertEquals("NAME        COMMAND     DEPENDENCY            
                          DESCRIPTION",
+        Assertions.assertEquals("NAME          COMMAND       DEPENDENCY        
                                DESCRIPTION",
                 output.get(2));
         Assertions.assertEquals(
-                "kubernetes  kubernetes  
org.apache.camel:camel-jbang-plugin-kubernetes  %s"
+                "kubernetes    kubernetes    
org.apache.camel:camel-jbang-plugin-kubernetes    %s"
                         .formatted(PluginType.KUBERNETES.getDescription()),
                 output.get(3));
     }
@@ -120,31 +120,35 @@ class PluginGetTest extends CamelCommandBaseTestSupport {
         command.doCall();
 
         List<String> output = printer.getLines();
-        Assertions.assertEquals(10, output.size());
+        Assertions.assertEquals(11, output.size());
         Assertions.assertEquals("NAME        COMMAND  DEPENDENCY               
          DESCRIPTION", output.get(0));
         Assertions.assertEquals(
                 "foo-plugin  foo      org.apache.camel:foo-plugin:1.0.0  
Plugin foo-plugin called with command foo",
                 output.get(1));
 
         Assertions.assertEquals("Supported plugins:", output.get(3));
-        Assertions.assertEquals("NAME        COMMAND     DEPENDENCY            
                          DESCRIPTION",
+        Assertions.assertEquals("NAME          COMMAND       DEPENDENCY        
                                DESCRIPTION",
                 output.get(5));
         Assertions.assertEquals(
-                "kubernetes  kubernetes  
org.apache.camel:camel-jbang-plugin-kubernetes  %s"
+                "kubernetes    kubernetes    
org.apache.camel:camel-jbang-plugin-kubernetes    %s"
                         .formatted(PluginType.KUBERNETES.getDescription()),
                 output.get(6));
         Assertions.assertEquals(
-                "generate    generate    
org.apache.camel:camel-jbang-plugin-generate    %s"
+                "generate      generate      
org.apache.camel:camel-jbang-plugin-generate      %s"
                         .formatted(PluginType.GENERATE.getDescription()),
                 output.get(7));
         Assertions.assertEquals(
-                "edit        edit        
org.apache.camel:camel-jbang-plugin-edit        %s"
+                "edit          edit          
org.apache.camel:camel-jbang-plugin-edit          %s"
                         .formatted(PluginType.EDIT.getDescription()),
                 output.get(8));
         Assertions.assertEquals(
-                "test        test        
org.apache.camel:camel-jbang-plugin-test        %s"
+                "test          test          
org.apache.camel:camel-jbang-plugin-test          %s"
                         .formatted(PluginType.TEST.getDescription()),
                 output.get(9));
+        Assertions.assertEquals(
+                "route-parser  route-parser  
org.apache.camel:camel-jbang-plugin-route-parser  %s"
+                        .formatted(PluginType.ROUTE_PARSER.getDescription()),
+                output.get(10));
     }
 
 }
diff --git a/dsl/camel-jbang/pom.xml 
b/dsl/camel-jbang/camel-jbang-plugin-route-parser/pom.xml
similarity index 56%
copy from dsl/camel-jbang/pom.xml
copy to dsl/camel-jbang/camel-jbang-plugin-route-parser/pom.xml
index d7bbf0cf4cbb..e6fed824f978 100644
--- a/dsl/camel-jbang/pom.xml
+++ b/dsl/camel-jbang/camel-jbang-plugin-route-parser/pom.xml
@@ -18,30 +18,41 @@
 
 -->
 <project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
         <groupId>org.apache.camel</groupId>
-        <artifactId>dsl</artifactId>
+        <artifactId>camel-jbang-parent</artifactId>
         <version>4.17.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
-    <artifactId>camel-jbang-parent</artifactId>
-    <packaging>pom</packaging>
-
-    <name>Camel :: JBang :: Parent</name>
-    <description>Camel JBang Modules (parent)</description>
-
-    <modules>
-        <module>camel-jbang-console</module>
-        <module>camel-jbang-core</module>
-        <module>camel-jbang-main</module>
-        <module>camel-jbang-plugin-generate</module>
-        <module>camel-jbang-plugin-edit</module>
-        <module>camel-jbang-plugin-kubernetes</module>
-        <module>camel-jbang-plugin-test</module>
-        <module>camel-jbang-it</module>
-        <module>camel-launcher</module>
-    </modules>
+    <artifactId>camel-jbang-plugin-route-parser</artifactId>
+
+    <name>Camel :: JBang :: Plugin :: Route Parser</name>
+    <description>Camel JBang Edit Route Parser</description>
+
+    <properties>
+        <firstVersion>4.17.0</firstVersion>
+        <label>jbang</label>
+        <supportLevel>Preview</supportLevel>
+        <camel-prepare-component>false</camel-prepare-component>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-jbang-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-route-parser</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jboss.forge.roaster</groupId>
+            <artifactId>roaster-jdt</artifactId>
+            <version>${roaster-version}</version>
+        </dependency>
+    </dependencies>
 </project>
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/generated/resources/META-INF/services/org/apache/camel/camel-jbang-plugin/camel-jbang-plugin-route-parser
 
b/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/generated/resources/META-INF/services/org/apache/camel/camel-jbang-plugin/camel-jbang-plugin-route-parser
new file mode 100644
index 000000000000..f89c31e6b57d
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/generated/resources/META-INF/services/org/apache/camel/camel-jbang-plugin/camel-jbang-plugin-route-parser
@@ -0,0 +1,2 @@
+# Generated by camel build tools - do NOT edit this file!
+class=org.apache.camel.dsl.jbang.core.commands.parser.ParserPlugin
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/main/java/org/apache/camel/dsl/jbang/core/commands/parser/ParserPlugin.java
 
b/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/main/java/org/apache/camel/dsl/jbang/core/commands/parser/ParserPlugin.java
new file mode 100644
index 000000000000..c6608535b448
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/main/java/org/apache/camel/dsl/jbang/core/commands/parser/ParserPlugin.java
@@ -0,0 +1,32 @@
+/*
+ * 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.parser;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.common.CamelJBangPlugin;
+import org.apache.camel.dsl.jbang.core.common.Plugin;
+import picocli.CommandLine;
+
+@CamelJBangPlugin(name = "camel-jbang-plugin-route-parser", firstVersion = 
"4.17.0")
+public class ParserPlugin implements Plugin {
+
+    @Override
+    public void customize(CommandLine commandLine, CamelJBangMain main) {
+        commandLine.addSubcommand("route-parser", new 
RouteParserCommand(main));
+    }
+
+}
diff --git 
a/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/main/java/org/apache/camel/dsl/jbang/core/commands/parser/RouteParserCommand.java
 
b/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/main/java/org/apache/camel/dsl/jbang/core/commands/parser/RouteParserCommand.java
new file mode 100644
index 000000000000..0863160b15f2
--- /dev/null
+++ 
b/dsl/camel-jbang/camel-jbang-plugin-route-parser/src/main/java/org/apache/camel/dsl/jbang/core/commands/parser/RouteParserCommand.java
@@ -0,0 +1,146 @@
+/*
+ * 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.parser;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
+import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
+import org.apache.camel.dsl.jbang.core.commands.CommandHelper;
+import org.apache.camel.parser.RouteBuilderParser;
+import org.apache.camel.parser.model.CamelNodeDetails;
+import org.apache.camel.util.FileUtil;
+import org.apache.camel.util.StopWatch;
+import org.fusesource.jansi.Ansi;
+import org.fusesource.jansi.AnsiConsole;
+import org.jboss.forge.roaster.Roaster;
+import org.jboss.forge.roaster.model.source.JavaClassSource;
+import picocli.CommandLine;
+
[email protected](name = "route-parser", description = "Parses Java route 
and dumps route structure")
+public class RouteParserCommand extends CamelCommand {
+
+    @CommandLine.Parameters(description = { "The Camel RouteBuilder Java 
source files to parse." },
+                            arity = "1..9",
+                            paramLabel = "<files>",
+                            parameterConsumer = FilesConsumer.class)
+    Path[] filePaths;
+    List<String> files = new ArrayList<>();
+
+    @CommandLine.Option(names = { "--raw" },
+                        description = "To output raw without metadata")
+    boolean raw;
+
+    @CommandLine.Option(names = { "--watch" },
+                        description = "Execute periodically and showing output 
fullscreen")
+    boolean watch;
+
+    private CommandHelper.ReadConsoleTask waitUserTask;
+
+    public RouteParserCommand(CamelJBangMain main) {
+        super(main);
+    }
+
+    @Override
+    public Integer doCall() throws Exception {
+        int exit;
+        final AtomicBoolean running = new AtomicBoolean(true);
+        if (watch) {
+            Thread t = new Thread(() -> {
+                waitUserTask = new CommandHelper.ReadConsoleTask(() -> 
running.set(false));
+                waitUserTask.run();
+            }, "WaitForUser");
+            t.start();
+            do {
+                exit = doWatchCall();
+                if (exit == 0) {
+                    // use 2-sec delay in watch mode
+                    try {
+                        StopWatch watch = new StopWatch();
+                        while (running.get() && watch.taken() < 2000) {
+                            Thread.sleep(100);
+                        }
+                    } catch (Exception e) {
+                        running.set(false);
+                    }
+                }
+            } while (exit == 0 && running.get());
+        } else {
+            exit = doWatchCall();
+        }
+        return exit;
+    }
+
+    protected Integer doWatchCall() throws Exception {
+        for (String file : files) {
+            Integer code = doDumpFile(file);
+            if (code != 0) {
+                return code;
+            }
+        }
+        return 0;
+    }
+
+    protected Integer doDumpFile(String file) throws Exception {
+        File f = new File(file);
+        if (!f.exists() || !f.isFile()) {
+            printer().printErr("File not found: " + file);
+            return -1;
+        }
+        String ext = FileUtil.onlyExt(file);
+        if (!"java".equals(ext)) {
+            printer().printErr("Only .java source file is supported");
+            return -1;
+        }
+        JavaClassSource clazz = (JavaClassSource) Roaster.parse(f);
+        String fqn = clazz.getQualifiedName();
+        fqn = fqn.replace('.', '/');
+        fqn = fqn + ".java";
+        List<CamelNodeDetails> list = 
RouteBuilderParser.parseRouteBuilderTree(clazz, fqn, true);
+        if (watch) {
+            clearScreen();
+        }
+        for (var route : list) {
+            printer().println();
+            if (!raw) {
+                printer().printf("Source: %s%n", route.getFileName());
+                
printer().println("--------------------------------------------------------------------------------");
+            }
+            String tree = route.dump(0);
+            printer().println(tree);
+            printer().println();
+        }
+        return 0;
+    }
+
+    protected void clearScreen() {
+        AnsiConsole.out().print(Ansi.ansi().eraseScreen().cursor(1, 1));
+    }
+
+    static class FilesConsumer extends 
CamelCommand.ParameterConsumer<RouteParserCommand> {
+        protected void doConsumeParameters(Stack<String> args, 
RouteParserCommand cmd) {
+            String arg = args.pop();
+            cmd.files.add(arg);
+        }
+    }
+
+}
diff --git a/dsl/camel-jbang/pom.xml b/dsl/camel-jbang/pom.xml
index d7bbf0cf4cbb..fea393926c71 100644
--- a/dsl/camel-jbang/pom.xml
+++ b/dsl/camel-jbang/pom.xml
@@ -40,6 +40,7 @@
         <module>camel-jbang-plugin-generate</module>
         <module>camel-jbang-plugin-edit</module>
         <module>camel-jbang-plugin-kubernetes</module>
+        <module>camel-jbang-plugin-route-parser</module>
         <module>camel-jbang-plugin-test</module>
         <module>camel-jbang-it</module>
         <module>camel-launcher</module>
diff --git a/parent/pom.xml b/parent/pom.xml
index dfd4138ba96f..7ede630cfd8f 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -3050,6 +3050,11 @@
                 <artifactId>camel-jbang-plugin-kubernetes</artifactId>
                 <version>${project.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.camel</groupId>
+                <artifactId>camel-jbang-plugin-route-parser</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.apache.camel</groupId>
                 <artifactId>camel-jbang-plugin-test</artifactId>

Reply via email to