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 2024/07/06 09:43:51 UTC

(camel) branch main updated: CAMEL-20945: camel-jbang - Run java route without need for class wrapper

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 516345dbdf9 CAMEL-20945: camel-jbang - Run java route without need for class wrapper
516345dbdf9 is described below

commit 516345dbdf9c82b0cb7fdcb2217429c788298eaa
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Sat Jul 6 11:43:34 2024 +0200

    CAMEL-20945: camel-jbang - Run java route without need for class wrapper
---
 .../modules/ROOT/pages/camel-jbang.adoc            | 21 ++++++++++++
 .../apache/camel/dsl/jbang/core/commands/Run.java  | 40 ++++++++++++++++------
 2 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
index 432b9f083ff..eb36d0b1b27 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-jbang.adoc
@@ -290,6 +290,27 @@ This is very limited as the CLI argument is a bit cumbersome to use than files.
 
 NOTE: Using `--code` is only usable for very quick and small prototypes.
 
+From *Camel 4.8* onwards the `--code` parameter can also refer to a `.java` source file,
+that are not wrapped in a `public class` which makes it possible to quickly try a prototype
+with some Camel java based routes such as the following stored in a file named `quick.java`:
+
+[source,java]
+----
+from("timer:java?period=1000")
+    .setBody()
+        .simple("Hello Quick Camel from ${routeId}")
+    .log("${body}");
+----
+
+Then you can run this route via:
+
+[source,bash]
+----
+camel run --code=quick.java
+----
+
+NOTE: You cannot use `--dev` to hot-reload this on code changes.
+
 === Running Routes from source directory
 
 You can also run dev mode when running Camel with `--source-dir`, such as:
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
index 5fc79bfe8db..4fe450512fc 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Run.java
@@ -283,7 +283,7 @@ public class Run extends CamelCommand {
     @Option(names = { "--open-api" }, description = "Adds an OpenAPI spec from the given file (json or yaml file)")
     String openapi;
 
-    @Option(names = { "--code" }, description = "Run the given string as Java DSL route")
+    @Option(names = { "--code" }, description = "Run the given text or file as Java DSL routes")
     String code;
 
     @Option(names = { "--verbose" }, description = "Verbose output of startup activity (dependency resolution and downloading")
@@ -428,8 +428,23 @@ public class Run extends CamelCommand {
 
         // route code as option
         if (!empty && code != null) {
+            // code may refer to an existing file
+            String name = "CodeRoute";
+            boolean file = false;
+            File f = new File(code);
+            if (f.isFile() && f.exists()) {
+                // must be a java file
+                boolean java = f.getName().endsWith(".java");
+                if (!java) {
+                    printer().println("ERROR: Only java source files is accepted when using --code parameter");
+                    return 1;
+                }
+                code = Files.readString(f.toPath());
+                name = FileUtil.onlyName(f.getName());
+                file = true;
+            }
             // store code in temporary file
-            String codeFile = loadFromCode(code);
+            String codeFile = loadFromCode(code, name, file);
             // use code as first file
             files.add(0, codeFile);
         }
@@ -1329,19 +1344,22 @@ public class Run extends CamelCommand {
         return main.getExitCode();
     }
 
-    private String loadFromCode(String code) throws IOException {
-        String fn = CommandLineHelper.CAMEL_JBANG_WORK_DIR + "/CodeRoute.java";
+    private String loadFromCode(String code, String name, boolean file) throws IOException {
+        String fn = CommandLineHelper.CAMEL_JBANG_WORK_DIR + "/" + name + ".java";
         InputStream is = Run.class.getClassLoader().getResourceAsStream("templates/code-java.tmpl");
         String content = IOHelper.loadText(is);
         IOHelper.close(is);
-        // need to replace single quote as double quotes and end with semicolon
-        code = code.replace("'", "\"");
-        code = code.trim();
+        if (!file) {
+            // need to replace single quote as double quotes (from input string)
+            code = code.replace("'", "\"");
+            code = code.trim();
+        }
+        // ensure the code ends with semicolon to finish the java statement
         if (!code.endsWith(";")) {
             code = code + ";";
         }
-        content = content.replaceFirst("\\{\\{ \\.Name }}", "CodeRoute");
-        content = content.replaceFirst("\\{\\{ \\.Code }}", code);
+        content = StringHelper.replaceFirst(content, "{{ .Name }}", name);
+        content = StringHelper.replaceFirst(content, "{{ .Code }}", code);
         Files.writeString(Paths.get(fn), content);
         return "file:" + fn;
     }
@@ -1417,8 +1435,8 @@ public class Run extends CamelCommand {
             if ("java".equals(ext)) {
                 String fqn = determineClassName(t.toString());
                 if (fqn == null) {
-                    throw new IllegalArgumentException(
-                            "Cannot determine the Java class name from the source in the clipboard");
+                    // wrap code in wrapper
+                    return loadFromCode(t.toString(), "ClipboardRoute", true);
                 }
                 // drop package in file name
                 String cn = fqn;