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 2023/04/14 16:28:10 UTC

[camel] 01/02: CAMEL-18904: Add functions to simple language to create empty map/li… (#9770)

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

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

commit 4fbbad60ee1c9ae0ca80fd0751d3bb3d24de3e51
Author: Louisa Frison <12...@users.noreply.github.com>
AuthorDate: Wed Apr 5 09:02:50 2023 +0200

    CAMEL-18904:  Add functions to simple language to create empty map/li… (#9770)
    
    * CAMEL-18904:  Add functions to simple language to create empty map/liststring
    
    * CAMEL-18904:  make empty()-simple expressions case-insensitive
    
    ---------
    
    Co-authored-by: louisa-fr <lo...@consol.de>
---
 .../modules/languages/pages/simple-language.adoc   |  6 ++++
 .../language/simple/SimpleExpressionBuilder.java   | 27 +++++++++++++++
 .../simple/ast/SimpleFunctionExpression.java       | 11 ++++++
 .../java/org/apache/camel/LanguageTestSupport.java | 20 ++++++++---
 .../apache/camel/language/simple/SimpleTest.java   | 39 ++++++++++++++++++++--
 5 files changed, 97 insertions(+), 6 deletions(-)

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 7023b95e8a5..4fa63aaded8 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
@@ -195,6 +195,12 @@ the given id.
 field you can append .FIELD_NAME. For example, you can refer to the
 constant field from Exchange as: `org.apache.camel.Exchange.FILE_NAME`
 
+|empty(type) |depends on parameter |Creates a new empty object of the type given as parameter. The type-parameter-Strings are case-insensitive. +
+
+`string` -> empty String +
+`list`   -> empty ArrayList +
+`map`    -> empty HashMap +
+
 |null |null |represents a *null*
 
 |random(value) |Integer |returns a random Integer between 0 (included) and _value_
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 0a400ed0709..2bee28b0db7 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
@@ -19,6 +19,8 @@ package org.apache.camel.language.simple;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
 import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Random;
@@ -243,6 +245,31 @@ public final class SimpleExpressionBuilder {
         };
     }
 
+    /**
+     * Returns a new empty object of the given type
+     */
+    public static Expression newEmptyExpression(String type) {
+
+        return new ExpressionAdapter() {
+            @Override
+            public Object evaluate(Exchange exchange) {
+                if ("map".equalsIgnoreCase(type)) {
+                    return new HashMap<>();
+                } else if ("string".equalsIgnoreCase(type)) {
+                    return "";
+                } else if ("list".equalsIgnoreCase(type)) {
+                    return new ArrayList<>();
+                }
+                throw new IllegalArgumentException("function empty(%s) has unknown type.".formatted(type));
+            }
+
+            @Override
+            public String toString() {
+                return "empty(%s)".formatted(type);
+            }
+        };
+    }
+
     /**
      * Returns a uuid string based on the given generator (default, classic, short, simple)
      */
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 27388e08b55..cc5052b517f 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
@@ -569,6 +569,17 @@ public class SimpleFunctionExpression extends LiteralExpression {
             return SimpleExpressionBuilder.uuidExpression(null);
         }
 
+        // empty function
+        remainder = ifStartsWithReturnRemainder("empty(", function);
+        if (remainder != null) {
+            String value = StringHelper.before(remainder, ")");
+            if (ObjectHelper.isEmpty(value)) {
+                throw new SimpleParserException(
+                        "Valid syntax: ${empty(<type>)} but was: " + function, token.getIndex());
+            }
+            return SimpleExpressionBuilder.newEmptyExpression(value);
+        }
+
         return null;
     }
 
diff --git a/core/camel-core/src/test/java/org/apache/camel/LanguageTestSupport.java b/core/camel-core/src/test/java/org/apache/camel/LanguageTestSupport.java
index 5b8a091cd01..ab1bb9377fe 100644
--- a/core/camel-core/src/test/java/org/apache/camel/LanguageTestSupport.java
+++ b/core/camel-core/src/test/java/org/apache/camel/LanguageTestSupport.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel;
 
+import java.util.function.Predicate;
+
 import org.apache.camel.spi.Language;
 
 import static org.junit.jupiter.api.Assertions.assertNotNull;
@@ -63,6 +65,16 @@ public abstract class LanguageTestSupport extends ExchangeTestSupport {
         assertExpression(exchange, getLanguageName(), expressionText, expectedValue);
     }
 
+    /**
+     * Asserts that this language expression evaluates in a way that the handed over predicate is true
+     */
+    protected void assertExpression(String expressionText, Predicate<Object> assertion) {
+
+        Object value = evaluateExpression(expressionText, null);
+
+        assertTrue(assertion.test(value));
+    }
+
     /**
      * Asserts that this language expression evaluates to the given value on the current exchange
      */
@@ -74,7 +86,7 @@ public abstract class LanguageTestSupport extends ExchangeTestSupport {
      * Asserts that the expression evaluates to one of the two given values
      */
     protected void assertExpression(String expressionText, String expectedValue, String orThisExpectedValue) {
-        Object value = evaluateExpression(expressionText, expectedValue);
+        Object value = evaluateExpression(expressionText, expectedValue.getClass());
 
         assertTrue(expectedValue.equals(value) || orThisExpectedValue.equals(value),
                 "Expression: " + expressionText + " on Exchange: " + exchange);
@@ -83,15 +95,15 @@ public abstract class LanguageTestSupport extends ExchangeTestSupport {
     /**
      * Evaluates the expression
      */
-    protected Object evaluateExpression(String expressionText, String expectedValue) {
+    protected Object evaluateExpression(String expressionText, Class<?> expectedType) {
         Language language = assertResolveLanguage(getLanguageName());
 
         Expression expression = language.createExpression(expressionText);
         assertNotNull(expression, "No Expression could be created for text: " + expressionText + " language: " + language);
 
         Object value;
-        if (expectedValue != null) {
-            value = expression.evaluate(exchange, expectedValue.getClass());
+        if (expectedType != null) {
+            value = expression.evaluate(exchange, expectedType);
         } else {
             value = expression.evaluate(exchange, Object.class);
         }
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 669425d0786..48631240d84 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
@@ -49,7 +49,15 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.parallel.ResourceLock;
 import org.junit.jupiter.api.parallel.Resources;
 
-import static org.junit.jupiter.api.Assertions.*;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+>>>>>>> 7ca0064683f (CAMEL-18904:  Add functions to simple language to create empty map/li… (#9770))
 
 public class SimpleTest extends LanguageTestSupport {
 
@@ -644,7 +652,7 @@ public class SimpleTest extends LanguageTestSupport {
 
     @Test
     public void testDateExchangeCreated() throws Exception {
-        Object out = evaluateExpression("${date:exchangeCreated:hh:mm:ss a}", "" + exchange.getCreated());
+        Object out = evaluateExpression("${date:exchangeCreated:hh:mm:ss a}", ("" + exchange.getCreated()).getClass());
         assertNotNull(out);
     }
 
@@ -2042,6 +2050,33 @@ public class SimpleTest extends LanguageTestSupport {
         assertExpression("${uuid(mygen)}", "1234");
     }
 
+    @Test
+    public void testNewEmpty() {
+        assertExpressionCreateNewEmpty("list", List.class, v -> ((List) v).isEmpty());
+        assertExpressionCreateNewEmpty("LIST", List.class, v -> ((List) v).isEmpty());
+        assertExpressionCreateNewEmpty("List", List.class, v -> ((List) v).isEmpty());
+        assertExpressionCreateNewEmpty("map", Map.class, v -> ((Map) v).isEmpty());
+        assertExpressionCreateNewEmpty("MAP", Map.class, v -> ((Map) v).isEmpty());
+        assertExpressionCreateNewEmpty("Map", Map.class, v -> ((Map) v).isEmpty());
+        assertExpressionCreateNewEmpty("string", String.class, v -> ((String) v).isEmpty());
+        assertExpressionCreateNewEmpty("STRING", String.class, v -> ((String) v).isEmpty());
+        assertExpressionCreateNewEmpty("String", String.class, v -> ((String) v).isEmpty());
+
+        assertThrows(SimpleIllegalSyntaxException.class, () -> evaluateExpression("${empty(falseSyntax}", null));
+        assertThrows(SimpleIllegalSyntaxException.class, () -> evaluateExpression("${empty()}", null));
+        assertThrows(SimpleIllegalSyntaxException.class, () -> evaluateExpression("${empty(}", null));
+        assertThrows(SimpleIllegalSyntaxException.class, () -> evaluateExpression("${empty}", null));
+        assertThrows(IllegalArgumentException.class, () -> evaluateExpression("${empty(unknownType)}", null));
+    }
+
+    private void assertExpressionCreateNewEmpty(
+            String type, Class<?> expectedClass, java.util.function.Predicate<Object> isEmptyAssertion) {
+        Object value = evaluateExpression("${empty(%s)}".formatted(type), null);
+        assertNotNull(value);
+        assertIsInstanceOf(expectedClass, value);
+        assertTrue(isEmptyAssertion.test(value));
+    }
+
     @Override
     protected String getLanguageName() {
         return "simple";