You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by fm...@apache.org on 2026/04/17 12:20:55 UTC

(camel) branch main updated: camel-jbang: pre-compile grep/find patterns and cache SimpleDateFormat in action commands

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

fmariani 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 7754713aa622 camel-jbang: pre-compile grep/find patterns and cache SimpleDateFormat in action commands
7754713aa622 is described below

commit 7754713aa62249d94e64b68febc3c5d040fbbe76
Author: Croway <fe...@gmail.com>
AuthorDate: Thu Apr 16 13:01:41 2026 +0200

    camel-jbang: pre-compile grep/find patterns and cache SimpleDateFormat in action commands
    
    Pre-compile regex patterns at startup instead of calling Pattern.compile()
    on every log/trace line. Cache SimpleDateFormat instances as fields instead
    of creating new ones per line. Add missing Pattern.quote() in CamelStubAction
    for consistency with the other action commands.
---
 .../core/commands/action/ActionBaseCommand.java    | 17 ++++++++++
 .../jbang/core/commands/action/CamelLogAction.java | 37 ++++++++++------------
 .../core/commands/action/CamelReceiveAction.java   | 31 +++++++-----------
 .../core/commands/action/CamelStubAction.java      | 26 +++++++++------
 .../core/commands/action/CamelTraceAction.java     | 35 +++++++++-----------
 5 files changed, 76 insertions(+), 70 deletions(-)

diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionBaseCommand.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionBaseCommand.java
index b391178a9cdc..4eba851ed482 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionBaseCommand.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/ActionBaseCommand.java
@@ -21,6 +21,7 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.regex.Pattern;
 
 import org.apache.camel.dsl.jbang.core.commands.CamelCommand;
 import org.apache.camel.dsl.jbang.core.commands.CamelJBangMain;
@@ -132,6 +133,22 @@ abstract class ActionBaseCommand extends CamelCommand {
         return null;
     }
 
+    /**
+     * Quotes each element in the given array with {@link Pattern#quote} and compiles a case-insensitive pattern for it.
+     * The array is modified in place (elements are replaced with their quoted form).
+     *
+     * @param  values the raw search terms
+     * @return        compiled patterns ready for matching
+     */
+    static Pattern[] quoteAndCompilePatterns(String[] values) {
+        Pattern[] patterns = new Pattern[values.length];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = Pattern.quote(values[i]);
+            patterns[i] = Pattern.compile("(?i)" + values[i]);
+        }
+        return patterns;
+    }
+
     /**
      * Prepares and writes an action to the action file.
      *
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
index aad9637a14c0..481bf35c7f1a 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelLogAction.java
@@ -116,9 +116,13 @@ public class CamelLogAction extends ActionBaseCommand {
     String[] grep;
 
     String findAnsi;
+    Pattern[] grepPatterns;
+    Pattern[] findPatterns;
 
     private int nameMaxWidth;
     private boolean prefixShown;
+    private final SimpleDateFormat sdfMain = new SimpleDateFormat(TIMESTAMP_MAIN);
+    private final SimpleDateFormat sdfSB = new SimpleDateFormat(TIMESTAMP_SB);
 
     private final Map<String, Ansi.Color> colors = new HashMap<>();
 
@@ -136,19 +140,11 @@ public class CamelLogAction extends ActionBaseCommand {
             // read existing log files (skip by tail/since)
             if (find != null) {
                 findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
-                for (int i = 0; i < find.length; i++) {
-                    String f = find[i];
-                    f = Pattern.quote(f);
-                    find[i] = f;
-                }
+                findPatterns = quoteAndCompilePatterns(find);
             }
             if (grep != null) {
                 findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
-                for (int i = 0; i < grep.length; i++) {
-                    String f = grep[i];
-                    f = Pattern.quote(f);
-                    grep[i] = f;
-                }
+                grepPatterns = quoteAndCompilePatterns(grep);
             }
             Date limit = null;
             if (since != null) {
@@ -413,14 +409,14 @@ public class CamelLogAction extends ActionBaseCommand {
                 before = StringHelper.before(line, "---");
                 after = StringHelper.after(line, "---", line);
             }
-            if (find != null) {
-                for (String f : find) {
-                    after = after.replaceAll("(?i)" + f, findAnsi);
+            if (findPatterns != null) {
+                for (Pattern p : findPatterns) {
+                    after = p.matcher(after).replaceAll(findAnsi);
                 }
             }
-            if (grep != null) {
-                for (String g : grep) {
-                    after = after.replaceAll("(?i)" + g, findAnsi);
+            if (grepPatterns != null) {
+                for (Pattern p : grepPatterns) {
+                    after = p.matcher(after).replaceAll(findAnsi);
                 }
             }
             line = before != null ? before + "---" + after : after;
@@ -494,7 +490,7 @@ public class CamelLogAction extends ActionBaseCommand {
         // if using spring boot then adjust the timestamp to uniform camel-main style
         String ts = StringHelper.before(line, "  ");
         if (ts != null && ts.contains("T")) {
-            SimpleDateFormat sdf = new SimpleDateFormat(TIMESTAMP_SB);
+            SimpleDateFormat sdf = sdfSB;
             try {
                 // the log can be in color or not so we need to unescape always
                 sdf.parse(unescapeAnsi(ts));
@@ -524,7 +520,7 @@ public class CamelLogAction extends ActionBaseCommand {
         line = unescapeAnsi(line);
         String ts = StringHelper.before(line, "  ");
         if (ts != null && !ts.isBlank()) {
-            SimpleDateFormat sdf = new SimpleDateFormat(TIMESTAMP_MAIN);
+            SimpleDateFormat sdf = sdfMain;
             try {
                 Date row = sdf.parse(ts);
                 return row.compareTo(limit) >= 0;
@@ -542,9 +538,8 @@ public class CamelLogAction extends ActionBaseCommand {
         // the log can be in color or not so we need to unescape always
         line = unescapeAnsi(line);
         String after = StringHelper.after(line, "---", line);
-        for (String g : grep) {
-            boolean m = Pattern.compile("(?i)" + g).matcher(after).find();
-            if (m) {
+        for (Pattern p : grepPatterns) {
+            if (p.matcher(after).find()) {
                 return true;
             }
         }
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java
index eea76f25b01a..e2b4e669e304 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelReceiveAction.java
@@ -213,6 +213,8 @@ public class CamelReceiveAction extends ActionBaseCommand {
     private volatile long pid;
 
     String findAnsi;
+    Pattern[] grepPatterns;
+    Pattern[] findPatterns;
     private int nameMaxWidth;
     private boolean prefixShown;
     private MessageTableHelper tableHelper;
@@ -521,19 +523,11 @@ public class CamelReceiveAction extends ActionBaseCommand {
             // read existing received files (skip by tail/since)
             if (find != null) {
                 findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
-                for (int i = 0; i < find.length; i++) {
-                    String f = find[i];
-                    f = Pattern.quote(f);
-                    find[i] = f;
-                }
+                findPatterns = quoteAndCompilePatterns(find);
             }
             if (grep != null) {
                 findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
-                for (int i = 0; i < grep.length; i++) {
-                    String f = grep[i];
-                    f = Pattern.quote(f);
-                    grep[i] = f;
-                }
+                grepPatterns = quoteAndCompilePatterns(grep);
             }
             Date limit = null;
             if (since != null) {
@@ -840,9 +834,8 @@ public class CamelReceiveAction extends ActionBaseCommand {
         if (grep == null) {
             return true;
         }
-        for (String g : grep) {
-            boolean m = Pattern.compile("(?i)" + g).matcher(line).find();
-            if (m) {
+        for (Pattern p : grepPatterns) {
+            if (p.matcher(line).find()) {
                 return true;
             }
         }
@@ -911,14 +904,14 @@ public class CamelReceiveAction extends ActionBaseCommand {
         String[] lines = data.split(System.lineSeparator());
         if (lines.length > 0) {
             for (String line : lines) {
-                if (find != null) {
-                    for (String f : find) {
-                        line = line.replaceAll("(?i)" + f, findAnsi);
+                if (findPatterns != null) {
+                    for (Pattern p : findPatterns) {
+                        line = p.matcher(line).replaceAll(findAnsi);
                     }
                 }
-                if (grep != null) {
-                    for (String g : grep) {
-                        line = line.replaceAll("(?i)" + g, findAnsi);
+                if (grepPatterns != null) {
+                    for (Pattern p : grepPatterns) {
+                        line = p.matcher(line).replaceAll(findAnsi);
                     }
                 }
                 if (nameWithPrefix != null) {
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelStubAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelStubAction.java
index 18fb3bac0087..ff8f2e8b1c21 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelStubAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelStubAction.java
@@ -100,6 +100,8 @@ public class CamelStubAction extends ActionWatchCommand {
 
     private volatile long pid;
     String findAnsi;
+    Pattern[] grepPatterns;
+    Pattern[] findPatterns;
     private MessageTableHelper tableHelper;
     private final Map<String, Ansi.Color> exchangeIdColors = new HashMap<>();
     private int exchangeIdColorsIndex = 1;
@@ -127,8 +129,13 @@ public class CamelStubAction extends ActionWatchCommand {
             }
             return color;
         });
-        if (find != null || grep != null) {
+        if (find != null) {
             findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
+            findPatterns = quoteAndCompilePatterns(find);
+        }
+        if (grep != null) {
+            findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
+            grepPatterns = quoteAndCompilePatterns(grep);
         }
 
         List<Row> rows = new ArrayList<>();
@@ -257,9 +264,8 @@ public class CamelStubAction extends ActionWatchCommand {
         if (grep == null) {
             return true;
         }
-        for (String g : grep) {
-            boolean m = Pattern.compile("(?i)" + g).matcher(line).find();
-            if (m) {
+        for (Pattern p : grepPatterns) {
+            if (p.matcher(line).find()) {
                 return true;
             }
         }
@@ -308,14 +314,14 @@ public class CamelStubAction extends ActionWatchCommand {
                                     printer().println();
                                 }
                                 for (String line : lines) {
-                                    if (find != null) {
-                                        for (String f : find) {
-                                            line = line.replaceAll("(?i)" + f, findAnsi);
+                                    if (findPatterns != null) {
+                                        for (Pattern p : findPatterns) {
+                                            line = p.matcher(line).replaceAll(findAnsi);
                                         }
                                     }
-                                    if (grep != null) {
-                                        for (String g : grep) {
-                                            line = line.replaceAll("(?i)" + g, findAnsi);
+                                    if (grepPatterns != null) {
+                                        for (Pattern p : grepPatterns) {
+                                            line = p.matcher(line).replaceAll(findAnsi);
                                         }
                                     }
                                     printer().print(" ");
diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelTraceAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelTraceAction.java
index 397cd69ab767..d24b7f03c21c 100644
--- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelTraceAction.java
+++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelTraceAction.java
@@ -69,6 +69,7 @@ public class CamelTraceAction extends ActionBaseCommand {
 
     private static final int NAME_MAX_WIDTH = 25;
     private static final int NAME_MIN_WIDTH = 10;
+    private static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
 
     private CommandHelper.ReadConsoleTask waitUserTask;
 
@@ -186,6 +187,8 @@ public class CamelTraceAction extends ActionBaseCommand {
     boolean pretty;
 
     String findAnsi;
+    Pattern[] grepPatterns;
+    Pattern[] findPatterns;
 
     private int nameMaxWidth;
     private boolean prefixShown;
@@ -195,6 +198,7 @@ public class CamelTraceAction extends ActionBaseCommand {
     private final Map<String, Ansi.Color> nameColors = new HashMap<>();
     private final Map<String, Ansi.Color> exchangeIdColors = new HashMap<>();
     private int exchangeIdColorsIndex = 1;
+    private final SimpleDateFormat sdfTimestamp = new SimpleDateFormat(TIMESTAMP_FORMAT);
 
     public CamelTraceAction(CamelJBangMain main) {
         super(main);
@@ -347,19 +351,11 @@ public class CamelTraceAction extends ActionBaseCommand {
             // read existing trace files (skip by tail/since)
             if (find != null) {
                 findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
-                for (int i = 0; i < find.length; i++) {
-                    String f = find[i];
-                    f = Pattern.quote(f);
-                    find[i] = f;
-                }
+                findPatterns = quoteAndCompilePatterns(find);
             }
             if (grep != null) {
                 findAnsi = Ansi.ansi().fg(Ansi.Color.BLACK).bg(Ansi.Color.YELLOW).a("$0").reset().toString();
-                for (int i = 0; i < grep.length; i++) {
-                    String f = grep[i];
-                    f = Pattern.quote(f);
-                    grep[i] = f;
-                }
+                grepPatterns = quoteAndCompilePatterns(grep);
             }
             Date limit = null;
             if (since != null) {
@@ -709,9 +705,8 @@ public class CamelTraceAction extends ActionBaseCommand {
         if (grep == null) {
             return true;
         }
-        for (String g : grep) {
-            boolean m = Pattern.compile("(?i)" + g).matcher(line).find();
-            if (m) {
+        for (Pattern p : grepPatterns) {
+            if (p.matcher(line).find()) {
                 return true;
             }
         }
@@ -769,7 +764,7 @@ public class CamelTraceAction extends ActionBaseCommand {
             if (ago) {
                 ts = String.format("%12s", TimeUtils.printSince(row.timestamp) + " ago");
             } else {
-                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+                SimpleDateFormat sdf = sdfTimestamp;
                 ts = sdf.format(new Date(row.timestamp));
             }
             if (loggingColor) {
@@ -841,14 +836,14 @@ public class CamelTraceAction extends ActionBaseCommand {
         if (lines.length > 0) {
             printer().println();
             for (String line : lines) {
-                if (find != null) {
-                    for (String f : find) {
-                        line = line.replaceAll("(?i)" + f, findAnsi);
+                if (findPatterns != null) {
+                    for (Pattern fp : findPatterns) {
+                        line = fp.matcher(line).replaceAll(findAnsi);
                     }
                 }
-                if (grep != null) {
-                    for (String g : grep) {
-                        line = line.replaceAll("(?i)" + g, findAnsi);
+                if (grepPatterns != null) {
+                    for (Pattern gp : grepPatterns) {
+                        line = gp.matcher(line).replaceAll(findAnsi);
                     }
                 }
                 if (nameWithPrefix != null) {