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 5b55ceb0203 CAMEL-20845: camel-core - Simple language to make it easy 
to replace texts (#14412)
5b55ceb0203 is described below

commit 5b55ceb020374340fbe9275fa646da1a8321e33f
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jun 7 09:06:18 2024 +0200

    CAMEL-20845: camel-core - Simple language to make it easy to replace texts 
(#14412)
---
 .../modules/languages/pages/simple-language.adoc   | 37 ++++++++++++++++++++++
 .../language/simple/SimpleExpressionBuilder.java   | 27 ++++++++++++++++
 .../simple/ast/SimpleFunctionExpression.java       | 27 ++++++++++++++++
 .../apache/camel/language/simple/SimpleTest.java   | 16 ++++++++++
 .../camel/support/builder/ExpressionBuilder.java   | 29 +++++++++++++++++
 .../java/org/apache/camel/util/StringHelper.java   | 19 +++++++++++
 6 files changed, 155 insertions(+)

diff --git 
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
 
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
index 313a125297d..025a3aafa48 100644
--- 
a/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
+++ 
b/core/camel-core-languages/src/main/docs/modules/languages/pages/simple-language.adoc
@@ -238,6 +238,12 @@ constant field from Exchange as: 
`org.apache.camel.Exchange.FILE_NAME`
 |random(min,max) |Integer |returns a random Integer between _min_ (included) 
and
 _max_ (excluded)
 
+|replace(from,to) |String |replace all the string values in the message body.
+To make it easier to replace single and double quotes, then you can use XML 
escaped values `\&quot;` as double quote, `\&apos;` as single quote, and 
`\&empty;` as empty value.
+
+|replace(from,to,exp) |String |replace all the string values in the given 
expression.
+To make it easier to replace single and double quotes, then you can use XML 
escaped values `\&quot;` as double quote, `\&apos;` as single quote, and 
`\&empty;` as empty value.
+
 |collate(group) |List |The collate function iterates the message body and 
groups
 the data into sub lists of specified size. This can be used with the
 Splitter EIP to split a message body and group/batch
@@ -846,6 +852,37 @@ You can nest functions, such as shown below:
 </setHeader>
 ----
 
+=== Replacing double and single quotes
+
+You can use the `replace` function to more easily replace all single or double 
quotes in the message body.
+
+For example to replace all double quotes with single quotes:
+
+[source,java]
+----
+from("direct:order")
+  .transform().simple("${replace(&quot;,&apos;)}")
+  .to("mock:reply");
+----
+
+And to replace all single quotes with double quotes:
+
+[source,xml]
+----
+<setBody>
+  <simple>${replace(&apos;,&quot;)}</simple>
+</setBody>
+----
+
+Or to remove all double quotes:
+
+[source,xml]
+----
+<setBody>
+  <simple>${replace(&quot;&empty;)}</simple>
+</setBody>
+----
+
 == Setting result type
 
 You can now provide a result type to the xref:simple-language.adoc[Simple]
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
index 3203ec7deb9..82d0a18b7b0 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleExpressionBuilder.java
@@ -207,6 +207,33 @@ public final class SimpleExpressionBuilder {
         };
     }
 
+    /**
+     * Replaces string values from the expression
+     */
+    public static Expression replaceExpression(final String expression, final 
String from, final String to) {
+        return new ExpressionAdapter() {
+            private Expression exp;
+
+            @Override
+            public void init(CamelContext context) {
+                exp = 
context.resolveLanguage("simple").createExpression(expression);
+                exp.init(context);
+                exp = ExpressionBuilder.replaceAll(exp, from, to);
+                exp.init(context);
+            }
+
+            @Override
+            public Object evaluate(Exchange exchange) {
+                return exp.evaluate(exchange, Object.class);
+            }
+
+            @Override
+            public String toString() {
+                return "replace(" + expression + "," + from + "," + to + ")";
+            }
+        };
+    }
+
     /**
      * Hashes the value using the given algorithm
      */
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
index 0ba3b65788a..e9c2a41bb00 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/ast/SimpleFunctionExpression.java
@@ -660,6 +660,33 @@ public class SimpleFunctionExpression extends 
LiteralExpression {
     private Expression createSimpleExpressionMisc(String function) {
         String remainder;
 
+        // replace function
+        remainder = ifStartsWithReturnRemainder("replace(", function);
+        if (remainder != null) {
+            String values = StringHelper.before(remainder, ")");
+            if (values == null || ObjectHelper.isEmpty(values)) {
+                throw new SimpleParserException(
+                        "Valid syntax: ${replace(from,to)} or 
${replace(from,to,expression)} was: " + function,
+                        token.getIndex());
+            }
+            String[] tokens = StringQuoteHelper.splitSafeQuote(values, ',', 
false);
+            if (tokens.length > 3) {
+                throw new SimpleParserException(
+                        "Valid syntax: ${replace(from,to,expression)} was: " + 
function, token.getIndex());
+            }
+            String from = StringHelper.xmlDecode(tokens[0]);
+            String to = StringHelper.xmlDecode(tokens[1]);
+            // special to make it easy to replace to an empty value (ie remove)
+            if ("&empty;".equals(to)) {
+                to = "";
+            }
+            String exp = "${body}";
+            if (tokens.length == 3) {
+                exp = tokens[2];
+            }
+            return SimpleExpressionBuilder.replaceExpression(exp, from, to);
+        }
+
         // random function
         remainder = ifStartsWithReturnRemainder("random(", function);
         if (remainder != null) {
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
index 2e685ff1068..8b24519a8da 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/language/simple/SimpleTest.java
@@ -2045,6 +2045,22 @@ public class SimpleTest extends LanguageTestSupport {
         assertTrue(num >= 0 && num < 20, "Should be 10..20");
     }
 
+    @Test
+    public void testReplaceAllExpression() {
+        exchange.getMessage().setBody("Hello a how are you");
+        assertExpression("${replace(a,b)}", "Hello b how bre you");
+        exchange.getMessage().setBody("{\"foo\": \"cheese\"}");
+        assertExpression("${replace(&quot;,&apos;)}", "{'foo': 'cheese'}");
+        exchange.getMessage().setBody("{'foo': 'cheese'}");
+        assertExpression("${replace(&apos;,&quot;)}", "{\"foo\": \"cheese\"}");
+        exchange.getMessage().setBody("{\"foo\": \"cheese\"}");
+        assertExpression("${replace(&quot;,&empty;)}", "{foo: cheese}");
+
+        exchange.getMessage().setBody("Hello");
+        exchange.getMessage().setHeader("foo", "{\"foo\": \"cheese\"}");
+        assertExpression("${replace(&quot;,&apos;,${header.foo})}", "{'foo': 
'cheese'}");
+    }
+
     @Test
     public void testListRemoveByInstance() {
         List<Object> data = new ArrayList<>();
diff --git 
a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
 
b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
index fa2e6d0ad00..01de2babfe7 100644
--- 
a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
+++ 
b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java
@@ -1841,6 +1841,35 @@ public class ExpressionBuilder {
         };
     }
 
+    /**
+     * Replaces string values in the given expression.
+     */
+    public static Expression replaceAll(
+            final Expression expression,
+            final String from, final String to) {
+        return new ExpressionAdapter() {
+            @Override
+            public Object evaluate(Exchange exchange) {
+                String text = expression.evaluate(exchange, String.class);
+                if (text == null) {
+                    return null;
+                }
+                return text.replace(from, to);
+            }
+
+            @Override
+            public void init(CamelContext context) {
+                super.init(context);
+                expression.init(context);
+            }
+
+            @Override
+            public String toString() {
+                return "replaceAll(" + expression + ", " + from + ", " + to + 
")";
+            }
+        };
+    }
+
     /**
      * Transforms the expression into a String then performs the regex 
replaceAll to transform the String and return the
      * result
diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java 
b/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
index 4c6c8446915..73a164a58e1 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/StringHelper.java
@@ -218,10 +218,29 @@ public final class StringHelper {
         // must replace amp first, so we dont replace &lt; to amp later
         return text.replace("&", "&amp;")
                 .replace("\"", "&quot;")
+                .replace("'", "&apos;")
                 .replace("<", "&lt;")
                 .replace(">", "&gt;");
     }
 
+    /**
+     * Decodes the text into safe XML by replacing XML tokens with character 
values
+     *
+     * @param  text the text
+     * @return      the encoded text
+     */
+    public static String xmlDecode(final String text) {
+        if (text == null) {
+            return "";
+        }
+        // must replace amp first, so we dont replace &lt; to amp later
+        return text.replace("&amp;", "&")
+                .replace("&quot;", "\"")
+                .replace("&apos;", "'")
+                .replace("&lt;", "<")
+                .replace("&gt;", ">");
+    }
+
     /**
      * Determines if the string has at least one letter in upper case
      *

Reply via email to