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 180fce530a80 camel-core - Add isAlpha/isNumeric/isAlphaNumeric 
function to simple language
180fce530a80 is described below

commit 180fce530a803ead752afc14f836cedf35d4983a
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Jan 21 10:20:07 2026 +0100

    camel-core - Add isAlpha/isNumeric/isAlphaNumeric function to simple 
language
---
 .../org/apache/camel/catalog/languages/simple.json |  99 ++++++++-------
 .../language/csimple/joor/OriginalSimpleTest.java  | 117 ++++++++++++++++-
 .../org/apache/camel/language/simple/simple.json   |  99 ++++++++-------
 .../modules/languages/pages/simple-language.adoc   |   6 +
 .../camel/language/csimple/CSimpleHelper.java      |  42 +++++++
 .../camel/language/simple/SimpleConstants.java     |  12 ++
 .../language/simple/SimpleExpressionBuilder.java   | 138 +++++++++++++++++++++
 .../simple/ast/SimpleFunctionExpression.java       | 103 +++++++++++++++
 .../apache/camel/language/simple/SimpleTest.java   | 115 +++++++++++++++++
 9 files changed, 634 insertions(+), 97 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
index 805956ebdb9a..88730ad5a56f 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/languages/simple.json
@@ -67,53 +67,56 @@
     "hostName": { "index": 41, "kind": "function", "displayName": "Host Name", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the local hostname 
(may be empty if not possible to resolve).", "ognl": false, "suffix": "}" },
     "id": { "index": 42, "kind": "function", "displayName": "Id", "group": 
"function", "label": "function", "required": false, "javaType": "String", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The message id", "ognl": false, "suffix": "}" 
},
     "iif(predicate,trueExp,falseExp)": { "index": 43, "kind": "function", 
"displayName": "If Then Else", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Evaluates the predicate and returns the value of trueExp or falseExp. This 
function is similar to the ternary operator in Java.", "ognl": false, "suffix": 
"}" },
-    "isEmpty(exp)": { "index": 44, "kind": "function", "displayName": "Is 
Empty", "group": "function", "label": "function", "required": false, 
"javaType": "boolean", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Whether the message 
body (or expression) is null or empty (list\/map types are tested if they have 
0 elements).", "ognl": false, "suffix": "}" },
-    "jq(input,exp)": { "index": 45, "kind": "function", "displayName": "JQ", 
"group": "function", "label": "function", "required": false, "javaType": 
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "When working with JSon 
data, then this allows using the JQ language, for example, to extract data from 
the message body (in JSon format). This requires having camel-jq JAR on the 
classpath. For input (optional), you can [...]
-    "jsonpath(input,exp)": { "index": 46, "kind": "function", "displayName": 
"JSonPath", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "When working with JSon 
data, then this allows using the JSonPath language, for example, to extract 
data from the message body (in JSon format). This requires having 
camel-jsonpath JAR on the classpath. For i [...]
-    "join(separator,prefix,exp)": { "index": 47, "kind": "function", 
"displayName": "Join", "group": "function", "label": "function", "required": 
false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
join function iterates the message body\/expression and joins the data into a 
string. The separator is by default a comma. The prefix is optional. The join 
uses the message body as source by default.  [...]
-    "length(exp)": { "index": 48, "kind": "function", "displayName": "Length", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The payload length (number of bytes) of the 
message body (or expression).", "ognl": false, "suffix": "}" },
-    "list(val...)": { "index": 49, "kind": "function", "displayName": "Create 
List of values", "group": "function", "label": "function", "required": false, 
"javaType": "java.util.ArrayList", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
list function creates an ArrayList with the given set of values.", "ognl": 
false, "suffix": "}" },
-    "lowercase(exp)": { "index": 50, "kind": "function", "displayName": 
"Lowercase", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Lowercases the message 
body (or expression)", "ognl": false, "suffix": "}" },
-    "mandatoryBodyAs(type)": { "index": 51, "kind": "function", "displayName": 
"Mandatory Body As", "group": "function", "label": "function", "required": 
false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Converts the message body to the given type (classname). If the body is null 
then the function will fail with an exception", "ognl": true, "suffix": "}" },
-    "map(key1,value1,...)": { "index": 52, "kind": "function", "displayName": 
"Create Map of pairs", "group": "function", "label": "function", "required": 
false, "javaType": "java.util.LinkedHashMap", "prefix": "${", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "The map function creates a LinkedHashMap with the given set of 
pairs.", "ognl": false, "suffix": "}" },
-    "max(val...)": { "index": 53, "kind": "function", "displayName": "Maximum 
Number", "group": "function", "label": "function", "required": false, 
"javaType": "long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the maximum number 
from all the values", "ognl": false, "suffix": "}" },
-    "messageAs(type)": { "index": 54, "kind": "function", "displayName": 
"Message As", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the message 
to the given type (classname).", "ognl": true, "suffix": "}" },
-    "messageHistory(boolean)": { "index": 55, "kind": "function", 
"displayName": "Print Message History", "group": "function", "label": 
"function", "required": false, "javaType": "String", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message history of the current exchange (how it has 
been routed). This is similar to the route stack-trace message history the 
error handler logs in case of an unhandled exception. The b [...]
-    "messageTimestamp": { "index": 56, "kind": "function", "displayName": 
"Message Timestamp", "group": "function", "label": "function", "required": 
false, "javaType": "long", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
message timestamp (millis since epoc) that this message originates from. Some 
systems like JMS, Kafka, AWS have a timestamp on the event\/message that Camel 
received. This method returns the timestam [...]
-    "min(val...)": { "index": 57, "kind": "function", "displayName": "Minimum 
Number", "group": "function", "label": "function", "required": false, 
"javaType": "long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the minimum number 
from all the values", "ognl": false, "suffix": "}" },
-    "null": { "index": 58, "kind": "function", "displayName": "Null", "group": 
"function", "label": "function", "required": false, "javaType": "Object", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Represents a null value", "ognl": false, 
"suffix": "}" },
-    "originalBody": { "index": 59, "kind": "function", "displayName": 
"Original Body", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The original incoming 
body (only available if allowUseOriginalMessage=true).", "ognl": false, 
"suffix": "}" },
-    "pad(exp,width,separator)": { "index": 60, "kind": "function", 
"displayName": "Pad String", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Pads the expression with extra padding if necessary, according the the total 
width. The separator is by default a space. If the width is negative then 
padding to the right, otherwise to the left.", "o [...]
-    "pretty(exp)": { "index": 61, "kind": "function", "displayName": "Pretty 
Print", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the 
expression to a String, and attempts to pretty print if JSon or XML, otherwise 
the expression is returned as the String value.", "ognl": false, "suffix": "}" 
},
-    "prettyBody": { "index": 62, "kind": "function", "displayName": "Pretty 
Body", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Converts the body to a 
String, and attempts to pretty print if JSon or XML; otherwise the body is 
returned as the String value.", "ognl": false, "suffix": "}" },
-    "properties:key:default": { "index": 63, "kind": "function", 
"displayName": "Property Placeholder", "group": "function", "label": 
"function", "required": false, "javaType": "String", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Lookup a property placeholder with the given key. If the 
key does not exist nor has a value, then an optional default value can be 
specified.", "ognl": false, "suffix": "}" },
-    "propertiesExist:key": { "index": 64, "kind": "function", "displayName": 
"Property Placeholder Exists", "group": "function", "label": "function", 
"required": false, "javaType": "boolean", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Checks whether a property placeholder with the given key exists or not. The 
result can be negated by prefixing the key with !", "ognl": false, "suffix": 
"}" },
-    "random(min,max)": { "index": 65, "kind": "function", "displayName": 
"Random", "group": "function", "label": "function", "required": false, 
"javaType": "int", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns a random number 
between min and max (exclusive)", "ognl": false, "suffix": "}" },
-    "ref:name": { "index": 66, "kind": "function", "displayName": "Bean By 
Id", "group": "function", "label": "function", "required": false, "javaType": 
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "To look up a bean from the 
Registry with the given name.", "ognl": false, "suffix": "}" },
-    "replace(from,to,exp)": { "index": 67, "kind": "function", "displayName": 
"Replace String Values", "group": "function", "label": "function", "required": 
false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Replace all the string values in the message body\/expression. To make it 
easier to replace single and double quotes, then you can use XML escaped values 
`\\&quot;` as double quote, `\\&apos;`  [...]
-    "routeGroup": { "index": 68, "kind": "function", "displayName": "Route 
Group", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The route group of the 
current route the Exchange is being routed. Not all routes have a group 
assigned, so this may be null.", "ognl": false, "suffix": "}" },
-    "routeId": { "index": 69, "kind": "function", "displayName": "Route Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The route id of the 
current route the Exchange is being routed", "ognl": false, "suffix": "}" },
-    "setHeader(name,type,exp)": { "index": 70, "kind": "function", 
"displayName": "Set Header", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sets a message header with the given expression (optional converting to the 
given type)", "ognl": false, "suffix": "}" },
-    "setVariable(name,type,exp)": { "index": 71, "kind": "function", 
"displayName": "Set Variable", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sets a variable with the given expression (optional converting to the given 
type)", "ognl": false, "suffix": "}" },
-    "size(exp)": { "index": 72, "kind": "function", "displayName": "Size", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The size of the message body (or expression). 
If the payload is java.util.Collection or java.util.Map based then the size is 
the number of elements; otherwise the payload size in bytes.", "ognl": false, 
"suffix": "}" },
-    "skip(num)": { "index": 73, "kind": "function", "displayName": "Skip First 
Items from the Message Body", "group": "function", "label": "function", 
"required": false, "javaType": "java.util.Iterator", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The skip function iterates the message body and skips 
the first number of items. This can be used with the Splitter EIP to split a 
message body and skip the first N number of  [...]
-    "split(exp,separator)": { "index": 74, "kind": "function", "displayName": 
"Split String Values", "group": "function", "label": "function", "required": 
false, "javaType": "String[]", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Splits the message body\/expression as a String value using the separator into 
a String array", "ognl": false, "suffix": "}" },
-    "stepId": { "index": 75, "kind": "function", "displayName": "Step Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the id of the 
current step the Exchange is being routed.", "ognl": false, "suffix": "}" },
-    "substring(head,tail)": { "index": 76, "kind": "function", "displayName": 
"Substring", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Returns a substring of 
the message body\/expression. If only one positive number, then the returned 
string is clipped from the beginning. If only one negative number, then the 
returned string is clipped fr [...]
-    "substringAfter(exp,before)": { "index": 77, "kind": "function", 
"displayName": "Substring After", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that comes after. Returns 
null if nothing comes after.", "ognl": false, "suffix": "}" },
-    "substringBefore(exp,before)": { "index": 78, "kind": "function", 
"displayName": "Substring Before", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that comes before. Returns 
null if nothing comes before.", "ognl": false, "suffix": "}" },
-    "substringBetween(exp,after,before)": { "index": 79, "kind": "function", 
"displayName": "Substring Between", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that are between after and 
before. Returns null if nothing comes between.", "ognl": false, "suffix": "}" },
-    "sum(val...)": { "index": 80, "kind": "function", "displayName": 
"Calculate Sum Number", "group": "function", "label": "function", "required": 
false, "javaType": "long", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sums together all the values as integral numbers. This function can also be 
used to subtract by using negative numbers.", "ognl": false, "suffix": "}" },
-    "sys.name": { "index": 81, "kind": "function", "displayName": "JVM System 
Property", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The JVM system 
property with the given name", "ognl": false, "suffix": "}" },
-    "threadId": { "index": 82, "kind": "function", "displayName": "Thread Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the id of the 
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
-    "threadName": { "index": 83, "kind": "function", "displayName": "Thread 
Name", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the name of the 
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
-    "trim(exp)": { "index": 84, "kind": "function", "displayName": "Trim", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The trim function trims 
the message body (or expression) by removing all leading and trailing white 
spaces.", "ognl": false, "suffix": "}" },
-    "type:name.field": { "index": 85, "kind": "function", "displayName": "Java 
Field Value", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "To refer to a type or 
field by its classname. To refer to a field, you can append .FIELD_NAME. For 
example, you can refer to the constant field from Exchange as: 
`org.apache.camel.Exchange.FILE_NAME`", " [...]
-    "uppercase(exp)": { "index": 86, "kind": "function", "displayName": 
"Uppercase", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Uppercases the message 
body (or expression)", "ognl": false, "suffix": "}" },
-    "uuid(type)": { "index": 87, "kind": "function", "displayName": "Generate 
UUID", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns a UUID using the 
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and 
`simple` as the type. If no type is given, the default is used. It is also 
possible to use a custom `UuidG [...]
-    "variable.name": { "index": 88, "kind": "function", "displayName": 
"Variable", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The variable with the 
given name", "ognl": true, "suffix": "}" },
-    "variableAs(key,type)": { "index": 89, "kind": "function", "displayName": 
"Variable As", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the variable 
to the given type (classname).", "ognl": false, "suffix": "}" },
-    "variables": { "index": 90, "kind": "function", "displayName": 
"Variables", "group": "function", "label": "function", "required": false, 
"javaType": "java.util.Map", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns all the variables from the current Exchange in a Map", "ognl": false, 
"suffix": "}" },
-    "xpath(input,exp)": { "index": 91, "kind": "function", "displayName": 
"XPath", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "When working with XML 
data, then this allows using the XPath language, for example, to extract data 
from the message body (in XML format). This requires having camel-xpath JAR on 
the classpath. For input (optional [...]
+    "isAlpha(exp)": { "index": 44, "kind": "function", "displayName": "Is 
Alphabetic Value", "group": "function", "label": "function", "required": false, 
"javaType": "boolean", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Whether the message 
body (or expression) is alphabetic value (A..Z). For more advanced checks use 
the `regex` operator.", "ognl": false, "suffix": "}" },
+    "isAlphaNumeric(exp)": { "index": 45, "kind": "function", "displayName": 
"Is Alphabetic-Numeric Value", "group": "function", "label": "function", 
"required": false, "javaType": "boolean", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Whether the message body (or expression) is alphanumeric value (A..Z0-9). For 
more advanced checks use the `regex` operator.", "ognl": false, "suffix": "}" },
+    "isEmpty(exp)": { "index": 46, "kind": "function", "displayName": "Is 
Empty", "group": "function", "label": "function", "required": false, 
"javaType": "boolean", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Whether the message 
body (or expression) is null or empty (list\/map types are tested if they have 
0 elements).", "ognl": false, "suffix": "}" },
+    "isNumeric(exp)": { "index": 47, "kind": "function", "displayName": "Is 
Numeric Value", "group": "function", "label": "function", "required": false, 
"javaType": "boolean", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Whether the message 
body (or expression) is numeric value (0..9). For more advanced checks use the 
`regex` operator.", "ognl": false, "suffix": "}" },
+    "jq(input,exp)": { "index": 48, "kind": "function", "displayName": "JQ", 
"group": "function", "label": "function", "required": false, "javaType": 
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "When working with JSon 
data, then this allows using the JQ language, for example, to extract data from 
the message body (in JSon format). This requires having camel-jq JAR on the 
classpath. For input (optional), you can [...]
+    "jsonpath(input,exp)": { "index": 49, "kind": "function", "displayName": 
"JSonPath", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "When working with JSon 
data, then this allows using the JSonPath language, for example, to extract 
data from the message body (in JSon format). This requires having 
camel-jsonpath JAR on the classpath. For i [...]
+    "join(separator,prefix,exp)": { "index": 50, "kind": "function", 
"displayName": "Join", "group": "function", "label": "function", "required": 
false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
join function iterates the message body\/expression and joins the data into a 
string. The separator is by default a comma. The prefix is optional. The join 
uses the message body as source by default.  [...]
+    "length(exp)": { "index": 51, "kind": "function", "displayName": "Length", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The payload length (number of bytes) of the 
message body (or expression).", "ognl": false, "suffix": "}" },
+    "list(val...)": { "index": 52, "kind": "function", "displayName": "Create 
List of values", "group": "function", "label": "function", "required": false, 
"javaType": "java.util.ArrayList", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
list function creates an ArrayList with the given set of values.", "ognl": 
false, "suffix": "}" },
+    "lowercase(exp)": { "index": 53, "kind": "function", "displayName": 
"Lowercase", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Lowercases the message 
body (or expression)", "ognl": false, "suffix": "}" },
+    "mandatoryBodyAs(type)": { "index": 54, "kind": "function", "displayName": 
"Mandatory Body As", "group": "function", "label": "function", "required": 
false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Converts the message body to the given type (classname). If the body is null 
then the function will fail with an exception", "ognl": true, "suffix": "}" },
+    "map(key1,value1,...)": { "index": 55, "kind": "function", "displayName": 
"Create Map of pairs", "group": "function", "label": "function", "required": 
false, "javaType": "java.util.LinkedHashMap", "prefix": "${", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "The map function creates a LinkedHashMap with the given set of 
pairs.", "ognl": false, "suffix": "}" },
+    "max(val...)": { "index": 56, "kind": "function", "displayName": "Maximum 
Number", "group": "function", "label": "function", "required": false, 
"javaType": "long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the maximum number 
from all the values", "ognl": false, "suffix": "}" },
+    "messageAs(type)": { "index": 57, "kind": "function", "displayName": 
"Message As", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the message 
to the given type (classname).", "ognl": true, "suffix": "}" },
+    "messageHistory(boolean)": { "index": 58, "kind": "function", 
"displayName": "Print Message History", "group": "function", "label": 
"function", "required": false, "javaType": "String", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message history of the current exchange (how it has 
been routed). This is similar to the route stack-trace message history the 
error handler logs in case of an unhandled exception. The b [...]
+    "messageTimestamp": { "index": 59, "kind": "function", "displayName": 
"Message Timestamp", "group": "function", "label": "function", "required": 
false, "javaType": "long", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
message timestamp (millis since epoc) that this message originates from. Some 
systems like JMS, Kafka, AWS have a timestamp on the event\/message that Camel 
received. This method returns the timestam [...]
+    "min(val...)": { "index": 60, "kind": "function", "displayName": "Minimum 
Number", "group": "function", "label": "function", "required": false, 
"javaType": "long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the minimum number 
from all the values", "ognl": false, "suffix": "}" },
+    "null": { "index": 61, "kind": "function", "displayName": "Null", "group": 
"function", "label": "function", "required": false, "javaType": "Object", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Represents a null value", "ognl": false, 
"suffix": "}" },
+    "originalBody": { "index": 62, "kind": "function", "displayName": 
"Original Body", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The original incoming 
body (only available if allowUseOriginalMessage=true).", "ognl": false, 
"suffix": "}" },
+    "pad(exp,width,separator)": { "index": 63, "kind": "function", 
"displayName": "Pad String", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Pads the expression with extra padding if necessary, according the the total 
width. The separator is by default a space. If the width is negative then 
padding to the right, otherwise to the left.", "o [...]
+    "pretty(exp)": { "index": 64, "kind": "function", "displayName": "Pretty 
Print", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the 
expression to a String, and attempts to pretty print if JSon or XML, otherwise 
the expression is returned as the String value.", "ognl": false, "suffix": "}" 
},
+    "prettyBody": { "index": 65, "kind": "function", "displayName": "Pretty 
Body", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Converts the body to a 
String, and attempts to pretty print if JSon or XML; otherwise the body is 
returned as the String value.", "ognl": false, "suffix": "}" },
+    "properties:key:default": { "index": 66, "kind": "function", 
"displayName": "Property Placeholder", "group": "function", "label": 
"function", "required": false, "javaType": "String", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Lookup a property placeholder with the given key. If the 
key does not exist nor has a value, then an optional default value can be 
specified.", "ognl": false, "suffix": "}" },
+    "propertiesExist:key": { "index": 67, "kind": "function", "displayName": 
"Property Placeholder Exists", "group": "function", "label": "function", 
"required": false, "javaType": "boolean", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Checks whether a property placeholder with the given key exists or not. The 
result can be negated by prefixing the key with !", "ognl": false, "suffix": 
"}" },
+    "random(min,max)": { "index": 68, "kind": "function", "displayName": 
"Random", "group": "function", "label": "function", "required": false, 
"javaType": "int", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns a random number 
between min and max (exclusive)", "ognl": false, "suffix": "}" },
+    "ref:name": { "index": 69, "kind": "function", "displayName": "Bean By 
Id", "group": "function", "label": "function", "required": false, "javaType": 
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "To look up a bean from the 
Registry with the given name.", "ognl": false, "suffix": "}" },
+    "replace(from,to,exp)": { "index": 70, "kind": "function", "displayName": 
"Replace String Values", "group": "function", "label": "function", "required": 
false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Replace all the string values in the message body\/expression. To make it 
easier to replace single and double quotes, then you can use XML escaped values 
`\\&quot;` as double quote, `\\&apos;`  [...]
+    "routeGroup": { "index": 71, "kind": "function", "displayName": "Route 
Group", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The route group of the 
current route the Exchange is being routed. Not all routes have a group 
assigned, so this may be null.", "ognl": false, "suffix": "}" },
+    "routeId": { "index": 72, "kind": "function", "displayName": "Route Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The route id of the 
current route the Exchange is being routed", "ognl": false, "suffix": "}" },
+    "setHeader(name,type,exp)": { "index": 73, "kind": "function", 
"displayName": "Set Header", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sets a message header with the given expression (optional converting to the 
given type)", "ognl": false, "suffix": "}" },
+    "setVariable(name,type,exp)": { "index": 74, "kind": "function", 
"displayName": "Set Variable", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sets a variable with the given expression (optional converting to the given 
type)", "ognl": false, "suffix": "}" },
+    "size(exp)": { "index": 75, "kind": "function", "displayName": "Size", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The size of the message body (or expression). 
If the payload is java.util.Collection or java.util.Map based then the size is 
the number of elements; otherwise the payload size in bytes.", "ognl": false, 
"suffix": "}" },
+    "skip(num)": { "index": 76, "kind": "function", "displayName": "Skip First 
Items from the Message Body", "group": "function", "label": "function", 
"required": false, "javaType": "java.util.Iterator", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The skip function iterates the message body and skips 
the first number of items. This can be used with the Splitter EIP to split a 
message body and skip the first N number of  [...]
+    "split(exp,separator)": { "index": 77, "kind": "function", "displayName": 
"Split String Values", "group": "function", "label": "function", "required": 
false, "javaType": "String[]", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Splits the message body\/expression as a String value using the separator into 
a String array", "ognl": false, "suffix": "}" },
+    "stepId": { "index": 78, "kind": "function", "displayName": "Step Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the id of the 
current step the Exchange is being routed.", "ognl": false, "suffix": "}" },
+    "substring(head,tail)": { "index": 79, "kind": "function", "displayName": 
"Substring", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Returns a substring of 
the message body\/expression. If only one positive number, then the returned 
string is clipped from the beginning. If only one negative number, then the 
returned string is clipped fr [...]
+    "substringAfter(exp,before)": { "index": 80, "kind": "function", 
"displayName": "Substring After", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that comes after. Returns 
null if nothing comes after.", "ognl": false, "suffix": "}" },
+    "substringBefore(exp,before)": { "index": 81, "kind": "function", 
"displayName": "Substring Before", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that comes before. Returns 
null if nothing comes before.", "ognl": false, "suffix": "}" },
+    "substringBetween(exp,after,before)": { "index": 82, "kind": "function", 
"displayName": "Substring Between", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that are between after and 
before. Returns null if nothing comes between.", "ognl": false, "suffix": "}" },
+    "sum(val...)": { "index": 83, "kind": "function", "displayName": 
"Calculate Sum Number", "group": "function", "label": "function", "required": 
false, "javaType": "long", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sums together all the values as integral numbers. This function can also be 
used to subtract by using negative numbers.", "ognl": false, "suffix": "}" },
+    "sys.name": { "index": 84, "kind": "function", "displayName": "JVM System 
Property", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The JVM system 
property with the given name", "ognl": false, "suffix": "}" },
+    "threadId": { "index": 85, "kind": "function", "displayName": "Thread Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the id of the 
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
+    "threadName": { "index": 86, "kind": "function", "displayName": "Thread 
Name", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the name of the 
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
+    "trim(exp)": { "index": 87, "kind": "function", "displayName": "Trim", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The trim function trims 
the message body (or expression) by removing all leading and trailing white 
spaces.", "ognl": false, "suffix": "}" },
+    "type:name.field": { "index": 88, "kind": "function", "displayName": "Java 
Field Value", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "To refer to a type or 
field by its classname. To refer to a field, you can append .FIELD_NAME. For 
example, you can refer to the constant field from Exchange as: 
`org.apache.camel.Exchange.FILE_NAME`", " [...]
+    "uppercase(exp)": { "index": 89, "kind": "function", "displayName": 
"Uppercase", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Uppercases the message 
body (or expression)", "ognl": false, "suffix": "}" },
+    "uuid(type)": { "index": 90, "kind": "function", "displayName": "Generate 
UUID", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns a UUID using the 
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and 
`simple` as the type. If no type is given, the default is used. It is also 
possible to use a custom `UuidG [...]
+    "variable.name": { "index": 91, "kind": "function", "displayName": 
"Variable", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The variable with the 
given name", "ognl": true, "suffix": "}" },
+    "variableAs(key,type)": { "index": 92, "kind": "function", "displayName": 
"Variable As", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the variable 
to the given type (classname).", "ognl": false, "suffix": "}" },
+    "variables": { "index": 93, "kind": "function", "displayName": 
"Variables", "group": "function", "label": "function", "required": false, 
"javaType": "java.util.Map", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns all the variables from the current Exchange in a Map", "ognl": false, 
"suffix": "}" },
+    "xpath(input,exp)": { "index": 94, "kind": "function", "displayName": 
"XPath", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "When working with XML 
data, then this allows using the XPath language, for example, to extract data 
from the message body (in XML format). This requires having camel-xpath JAR on 
the classpath. For input (optional [...]
   }
 }
diff --git 
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
 
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
index 375cdbe280e7..dc6641b4a84f 100644
--- 
a/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
+++ 
b/components/camel-csimple-joor/src/test/java/org/apache/camel/language/csimple/joor/OriginalSimpleTest.java
@@ -2568,7 +2568,7 @@ public class OriginalSimpleTest extends 
LanguageTestSupport {
         expression = 
context.resolveLanguage("csimple").createExpression("${isEmpty('Hello 
World')}");
         assertFalse(expression.evaluate(exchange, Boolean.class));
 
-        expression = 
context.resolveLanguage("simple").createExpression("${isEmpty(${empty(map)})}");
+        expression = 
context.resolveLanguage("csimple").createExpression("${isEmpty(${empty(map)})}");
         assertTrue(expression.evaluate(exchange, Boolean.class));
 
         exchange.getMessage().setBody(Collections.EMPTY_MAP);
@@ -2580,6 +2580,121 @@ public class OriginalSimpleTest extends 
LanguageTestSupport {
         assertFalse(expression.evaluate(exchange, Boolean.class));
     }
 
+    @Test
+    public void testIsAlpha() {
+        exchange.getMessage().setBody("HelloWorld");
+
+        Expression expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha(${body})}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha(3)}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha('')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha(' ')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha('HiIamHere')}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha('Hi_I_am_here')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha('Hi I am 
here!')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello".getBytes());
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello123".getBytes());
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlpha()}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+    }
+
+    @Test
+    public void testIsAlphaNumeric() {
+        exchange.getMessage().setBody("Hello123");
+
+        Expression expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric(${body})}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric(3)}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric('A')}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric('')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric('!')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric('HiIamHere')}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric('Hi_I_am_here')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric('Hi I am 
here!')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello".getBytes());
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello123".getBytes());
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello123!".getBytes());
+        expression = 
context.resolveLanguage("csimple").createExpression("${isAlphaNumeric()}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+    }
+
+    @Test
+    public void testIsNumeric() {
+        exchange.getMessage().setBody(123L);
+
+        Expression expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric(${body})}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric(3)}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric('-4')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric('1.99')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric('')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric('Hello')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello".getBytes());
+        expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric()}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("123".getBytes());
+        expression = 
context.resolveLanguage("csimple").createExpression("${isNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+    }
+
     @Test
     public void testTrim() {
         exchange.getMessage().setBody("   Hello World ");
diff --git 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
index 805956ebdb9a..88730ad5a56f 100644
--- 
a/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
+++ 
b/core/camel-core-languages/src/generated/resources/META-INF/org/apache/camel/language/simple/simple.json
@@ -67,53 +67,56 @@
     "hostName": { "index": 41, "kind": "function", "displayName": "Host Name", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the local hostname 
(may be empty if not possible to resolve).", "ognl": false, "suffix": "}" },
     "id": { "index": 42, "kind": "function", "displayName": "Id", "group": 
"function", "label": "function", "required": false, "javaType": "String", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The message id", "ognl": false, "suffix": "}" 
},
     "iif(predicate,trueExp,falseExp)": { "index": 43, "kind": "function", 
"displayName": "If Then Else", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Evaluates the predicate and returns the value of trueExp or falseExp. This 
function is similar to the ternary operator in Java.", "ognl": false, "suffix": 
"}" },
-    "isEmpty(exp)": { "index": 44, "kind": "function", "displayName": "Is 
Empty", "group": "function", "label": "function", "required": false, 
"javaType": "boolean", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Whether the message 
body (or expression) is null or empty (list\/map types are tested if they have 
0 elements).", "ognl": false, "suffix": "}" },
-    "jq(input,exp)": { "index": 45, "kind": "function", "displayName": "JQ", 
"group": "function", "label": "function", "required": false, "javaType": 
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "When working with JSon 
data, then this allows using the JQ language, for example, to extract data from 
the message body (in JSon format). This requires having camel-jq JAR on the 
classpath. For input (optional), you can [...]
-    "jsonpath(input,exp)": { "index": 46, "kind": "function", "displayName": 
"JSonPath", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "When working with JSon 
data, then this allows using the JSonPath language, for example, to extract 
data from the message body (in JSon format). This requires having 
camel-jsonpath JAR on the classpath. For i [...]
-    "join(separator,prefix,exp)": { "index": 47, "kind": "function", 
"displayName": "Join", "group": "function", "label": "function", "required": 
false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
join function iterates the message body\/expression and joins the data into a 
string. The separator is by default a comma. The prefix is optional. The join 
uses the message body as source by default.  [...]
-    "length(exp)": { "index": 48, "kind": "function", "displayName": "Length", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The payload length (number of bytes) of the 
message body (or expression).", "ognl": false, "suffix": "}" },
-    "list(val...)": { "index": 49, "kind": "function", "displayName": "Create 
List of values", "group": "function", "label": "function", "required": false, 
"javaType": "java.util.ArrayList", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
list function creates an ArrayList with the given set of values.", "ognl": 
false, "suffix": "}" },
-    "lowercase(exp)": { "index": 50, "kind": "function", "displayName": 
"Lowercase", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Lowercases the message 
body (or expression)", "ognl": false, "suffix": "}" },
-    "mandatoryBodyAs(type)": { "index": 51, "kind": "function", "displayName": 
"Mandatory Body As", "group": "function", "label": "function", "required": 
false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Converts the message body to the given type (classname). If the body is null 
then the function will fail with an exception", "ognl": true, "suffix": "}" },
-    "map(key1,value1,...)": { "index": 52, "kind": "function", "displayName": 
"Create Map of pairs", "group": "function", "label": "function", "required": 
false, "javaType": "java.util.LinkedHashMap", "prefix": "${", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "The map function creates a LinkedHashMap with the given set of 
pairs.", "ognl": false, "suffix": "}" },
-    "max(val...)": { "index": 53, "kind": "function", "displayName": "Maximum 
Number", "group": "function", "label": "function", "required": false, 
"javaType": "long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the maximum number 
from all the values", "ognl": false, "suffix": "}" },
-    "messageAs(type)": { "index": 54, "kind": "function", "displayName": 
"Message As", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the message 
to the given type (classname).", "ognl": true, "suffix": "}" },
-    "messageHistory(boolean)": { "index": 55, "kind": "function", 
"displayName": "Print Message History", "group": "function", "label": 
"function", "required": false, "javaType": "String", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message history of the current exchange (how it has 
been routed). This is similar to the route stack-trace message history the 
error handler logs in case of an unhandled exception. The b [...]
-    "messageTimestamp": { "index": 56, "kind": "function", "displayName": 
"Message Timestamp", "group": "function", "label": "function", "required": 
false, "javaType": "long", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
message timestamp (millis since epoc) that this message originates from. Some 
systems like JMS, Kafka, AWS have a timestamp on the event\/message that Camel 
received. This method returns the timestam [...]
-    "min(val...)": { "index": 57, "kind": "function", "displayName": "Minimum 
Number", "group": "function", "label": "function", "required": false, 
"javaType": "long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the minimum number 
from all the values", "ognl": false, "suffix": "}" },
-    "null": { "index": 58, "kind": "function", "displayName": "Null", "group": 
"function", "label": "function", "required": false, "javaType": "Object", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Represents a null value", "ognl": false, 
"suffix": "}" },
-    "originalBody": { "index": 59, "kind": "function", "displayName": 
"Original Body", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The original incoming 
body (only available if allowUseOriginalMessage=true).", "ognl": false, 
"suffix": "}" },
-    "pad(exp,width,separator)": { "index": 60, "kind": "function", 
"displayName": "Pad String", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Pads the expression with extra padding if necessary, according the the total 
width. The separator is by default a space. If the width is negative then 
padding to the right, otherwise to the left.", "o [...]
-    "pretty(exp)": { "index": 61, "kind": "function", "displayName": "Pretty 
Print", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the 
expression to a String, and attempts to pretty print if JSon or XML, otherwise 
the expression is returned as the String value.", "ognl": false, "suffix": "}" 
},
-    "prettyBody": { "index": 62, "kind": "function", "displayName": "Pretty 
Body", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Converts the body to a 
String, and attempts to pretty print if JSon or XML; otherwise the body is 
returned as the String value.", "ognl": false, "suffix": "}" },
-    "properties:key:default": { "index": 63, "kind": "function", 
"displayName": "Property Placeholder", "group": "function", "label": 
"function", "required": false, "javaType": "String", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Lookup a property placeholder with the given key. If the 
key does not exist nor has a value, then an optional default value can be 
specified.", "ognl": false, "suffix": "}" },
-    "propertiesExist:key": { "index": 64, "kind": "function", "displayName": 
"Property Placeholder Exists", "group": "function", "label": "function", 
"required": false, "javaType": "boolean", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Checks whether a property placeholder with the given key exists or not. The 
result can be negated by prefixing the key with !", "ognl": false, "suffix": 
"}" },
-    "random(min,max)": { "index": 65, "kind": "function", "displayName": 
"Random", "group": "function", "label": "function", "required": false, 
"javaType": "int", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns a random number 
between min and max (exclusive)", "ognl": false, "suffix": "}" },
-    "ref:name": { "index": 66, "kind": "function", "displayName": "Bean By 
Id", "group": "function", "label": "function", "required": false, "javaType": 
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "To look up a bean from the 
Registry with the given name.", "ognl": false, "suffix": "}" },
-    "replace(from,to,exp)": { "index": 67, "kind": "function", "displayName": 
"Replace String Values", "group": "function", "label": "function", "required": 
false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Replace all the string values in the message body\/expression. To make it 
easier to replace single and double quotes, then you can use XML escaped values 
`\\&quot;` as double quote, `\\&apos;`  [...]
-    "routeGroup": { "index": 68, "kind": "function", "displayName": "Route 
Group", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The route group of the 
current route the Exchange is being routed. Not all routes have a group 
assigned, so this may be null.", "ognl": false, "suffix": "}" },
-    "routeId": { "index": 69, "kind": "function", "displayName": "Route Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The route id of the 
current route the Exchange is being routed", "ognl": false, "suffix": "}" },
-    "setHeader(name,type,exp)": { "index": 70, "kind": "function", 
"displayName": "Set Header", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sets a message header with the given expression (optional converting to the 
given type)", "ognl": false, "suffix": "}" },
-    "setVariable(name,type,exp)": { "index": 71, "kind": "function", 
"displayName": "Set Variable", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sets a variable with the given expression (optional converting to the given 
type)", "ognl": false, "suffix": "}" },
-    "size(exp)": { "index": 72, "kind": "function", "displayName": "Size", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The size of the message body (or expression). 
If the payload is java.util.Collection or java.util.Map based then the size is 
the number of elements; otherwise the payload size in bytes.", "ognl": false, 
"suffix": "}" },
-    "skip(num)": { "index": 73, "kind": "function", "displayName": "Skip First 
Items from the Message Body", "group": "function", "label": "function", 
"required": false, "javaType": "java.util.Iterator", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The skip function iterates the message body and skips 
the first number of items. This can be used with the Splitter EIP to split a 
message body and skip the first N number of  [...]
-    "split(exp,separator)": { "index": 74, "kind": "function", "displayName": 
"Split String Values", "group": "function", "label": "function", "required": 
false, "javaType": "String[]", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Splits the message body\/expression as a String value using the separator into 
a String array", "ognl": false, "suffix": "}" },
-    "stepId": { "index": 75, "kind": "function", "displayName": "Step Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the id of the 
current step the Exchange is being routed.", "ognl": false, "suffix": "}" },
-    "substring(head,tail)": { "index": 76, "kind": "function", "displayName": 
"Substring", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Returns a substring of 
the message body\/expression. If only one positive number, then the returned 
string is clipped from the beginning. If only one negative number, then the 
returned string is clipped fr [...]
-    "substringAfter(exp,before)": { "index": 77, "kind": "function", 
"displayName": "Substring After", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that comes after. Returns 
null if nothing comes after.", "ognl": false, "suffix": "}" },
-    "substringBefore(exp,before)": { "index": 78, "kind": "function", 
"displayName": "Substring Before", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that comes before. Returns 
null if nothing comes before.", "ognl": false, "suffix": "}" },
-    "substringBetween(exp,after,before)": { "index": 79, "kind": "function", 
"displayName": "Substring Between", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that are between after and 
before. Returns null if nothing comes between.", "ognl": false, "suffix": "}" },
-    "sum(val...)": { "index": 80, "kind": "function", "displayName": 
"Calculate Sum Number", "group": "function", "label": "function", "required": 
false, "javaType": "long", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sums together all the values as integral numbers. This function can also be 
used to subtract by using negative numbers.", "ognl": false, "suffix": "}" },
-    "sys.name": { "index": 81, "kind": "function", "displayName": "JVM System 
Property", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The JVM system 
property with the given name", "ognl": false, "suffix": "}" },
-    "threadId": { "index": 82, "kind": "function", "displayName": "Thread Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the id of the 
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
-    "threadName": { "index": 83, "kind": "function", "displayName": "Thread 
Name", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the name of the 
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
-    "trim(exp)": { "index": 84, "kind": "function", "displayName": "Trim", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The trim function trims 
the message body (or expression) by removing all leading and trailing white 
spaces.", "ognl": false, "suffix": "}" },
-    "type:name.field": { "index": 85, "kind": "function", "displayName": "Java 
Field Value", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "To refer to a type or 
field by its classname. To refer to a field, you can append .FIELD_NAME. For 
example, you can refer to the constant field from Exchange as: 
`org.apache.camel.Exchange.FILE_NAME`", " [...]
-    "uppercase(exp)": { "index": 86, "kind": "function", "displayName": 
"Uppercase", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Uppercases the message 
body (or expression)", "ognl": false, "suffix": "}" },
-    "uuid(type)": { "index": 87, "kind": "function", "displayName": "Generate 
UUID", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns a UUID using the 
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and 
`simple` as the type. If no type is given, the default is used. It is also 
possible to use a custom `UuidG [...]
-    "variable.name": { "index": 88, "kind": "function", "displayName": 
"Variable", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The variable with the 
given name", "ognl": true, "suffix": "}" },
-    "variableAs(key,type)": { "index": 89, "kind": "function", "displayName": 
"Variable As", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the variable 
to the given type (classname).", "ognl": false, "suffix": "}" },
-    "variables": { "index": 90, "kind": "function", "displayName": 
"Variables", "group": "function", "label": "function", "required": false, 
"javaType": "java.util.Map", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns all the variables from the current Exchange in a Map", "ognl": false, 
"suffix": "}" },
-    "xpath(input,exp)": { "index": 91, "kind": "function", "displayName": 
"XPath", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "When working with XML 
data, then this allows using the XPath language, for example, to extract data 
from the message body (in XML format). This requires having camel-xpath JAR on 
the classpath. For input (optional [...]
+    "isAlpha(exp)": { "index": 44, "kind": "function", "displayName": "Is 
Alphabetic Value", "group": "function", "label": "function", "required": false, 
"javaType": "boolean", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Whether the message 
body (or expression) is alphabetic value (A..Z). For more advanced checks use 
the `regex` operator.", "ognl": false, "suffix": "}" },
+    "isAlphaNumeric(exp)": { "index": 45, "kind": "function", "displayName": 
"Is Alphabetic-Numeric Value", "group": "function", "label": "function", 
"required": false, "javaType": "boolean", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Whether the message body (or expression) is alphanumeric value (A..Z0-9). For 
more advanced checks use the `regex` operator.", "ognl": false, "suffix": "}" },
+    "isEmpty(exp)": { "index": 46, "kind": "function", "displayName": "Is 
Empty", "group": "function", "label": "function", "required": false, 
"javaType": "boolean", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Whether the message 
body (or expression) is null or empty (list\/map types are tested if they have 
0 elements).", "ognl": false, "suffix": "}" },
+    "isNumeric(exp)": { "index": 47, "kind": "function", "displayName": "Is 
Numeric Value", "group": "function", "label": "function", "required": false, 
"javaType": "boolean", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Whether the message 
body (or expression) is numeric value (0..9). For more advanced checks use the 
`regex` operator.", "ognl": false, "suffix": "}" },
+    "jq(input,exp)": { "index": 48, "kind": "function", "displayName": "JQ", 
"group": "function", "label": "function", "required": false, "javaType": 
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "When working with JSon 
data, then this allows using the JQ language, for example, to extract data from 
the message body (in JSon format). This requires having camel-jq JAR on the 
classpath. For input (optional), you can [...]
+    "jsonpath(input,exp)": { "index": 49, "kind": "function", "displayName": 
"JSonPath", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "When working with JSon 
data, then this allows using the JSonPath language, for example, to extract 
data from the message body (in JSon format). This requires having 
camel-jsonpath JAR on the classpath. For i [...]
+    "join(separator,prefix,exp)": { "index": 50, "kind": "function", 
"displayName": "Join", "group": "function", "label": "function", "required": 
false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
join function iterates the message body\/expression and joins the data into a 
string. The separator is by default a comma. The prefix is optional. The join 
uses the message body as source by default.  [...]
+    "length(exp)": { "index": 51, "kind": "function", "displayName": "Length", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The payload length (number of bytes) of the 
message body (or expression).", "ognl": false, "suffix": "}" },
+    "list(val...)": { "index": 52, "kind": "function", "displayName": "Create 
List of values", "group": "function", "label": "function", "required": false, 
"javaType": "java.util.ArrayList", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
list function creates an ArrayList with the given set of values.", "ognl": 
false, "suffix": "}" },
+    "lowercase(exp)": { "index": 53, "kind": "function", "displayName": 
"Lowercase", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Lowercases the message 
body (or expression)", "ognl": false, "suffix": "}" },
+    "mandatoryBodyAs(type)": { "index": 54, "kind": "function", "displayName": 
"Mandatory Body As", "group": "function", "label": "function", "required": 
false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Converts the message body to the given type (classname). If the body is null 
then the function will fail with an exception", "ognl": true, "suffix": "}" },
+    "map(key1,value1,...)": { "index": 55, "kind": "function", "displayName": 
"Create Map of pairs", "group": "function", "label": "function", "required": 
false, "javaType": "java.util.LinkedHashMap", "prefix": "${", "deprecated": 
false, "deprecationNote": "", "autowired": false, "secret": false, 
"description": "The map function creates a LinkedHashMap with the given set of 
pairs.", "ognl": false, "suffix": "}" },
+    "max(val...)": { "index": 56, "kind": "function", "displayName": "Maximum 
Number", "group": "function", "label": "function", "required": false, 
"javaType": "long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the maximum number 
from all the values", "ognl": false, "suffix": "}" },
+    "messageAs(type)": { "index": 57, "kind": "function", "displayName": 
"Message As", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the message 
to the given type (classname).", "ognl": true, "suffix": "}" },
+    "messageHistory(boolean)": { "index": 58, "kind": "function", 
"displayName": "Print Message History", "group": "function", "label": 
"function", "required": false, "javaType": "String", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The message history of the current exchange (how it has 
been routed). This is similar to the route stack-trace message history the 
error handler logs in case of an unhandled exception. The b [...]
+    "messageTimestamp": { "index": 59, "kind": "function", "displayName": 
"Message Timestamp", "group": "function", "label": "function", "required": 
false, "javaType": "long", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": "The 
message timestamp (millis since epoc) that this message originates from. Some 
systems like JMS, Kafka, AWS have a timestamp on the event\/message that Camel 
received. This method returns the timestam [...]
+    "min(val...)": { "index": 60, "kind": "function", "displayName": "Minimum 
Number", "group": "function", "label": "function", "required": false, 
"javaType": "long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the minimum number 
from all the values", "ognl": false, "suffix": "}" },
+    "null": { "index": 61, "kind": "function", "displayName": "Null", "group": 
"function", "label": "function", "required": false, "javaType": "Object", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "Represents a null value", "ognl": false, 
"suffix": "}" },
+    "originalBody": { "index": 62, "kind": "function", "displayName": 
"Original Body", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The original incoming 
body (only available if allowUseOriginalMessage=true).", "ognl": false, 
"suffix": "}" },
+    "pad(exp,width,separator)": { "index": 63, "kind": "function", 
"displayName": "Pad String", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Pads the expression with extra padding if necessary, according the the total 
width. The separator is by default a space. If the width is negative then 
padding to the right, otherwise to the left.", "o [...]
+    "pretty(exp)": { "index": 64, "kind": "function", "displayName": "Pretty 
Print", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the 
expression to a String, and attempts to pretty print if JSon or XML, otherwise 
the expression is returned as the String value.", "ognl": false, "suffix": "}" 
},
+    "prettyBody": { "index": 65, "kind": "function", "displayName": "Pretty 
Body", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Converts the body to a 
String, and attempts to pretty print if JSon or XML; otherwise the body is 
returned as the String value.", "ognl": false, "suffix": "}" },
+    "properties:key:default": { "index": 66, "kind": "function", 
"displayName": "Property Placeholder", "group": "function", "label": 
"function", "required": false, "javaType": "String", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "Lookup a property placeholder with the given key. If the 
key does not exist nor has a value, then an optional default value can be 
specified.", "ognl": false, "suffix": "}" },
+    "propertiesExist:key": { "index": 67, "kind": "function", "displayName": 
"Property Placeholder Exists", "group": "function", "label": "function", 
"required": false, "javaType": "boolean", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Checks whether a property placeholder with the given key exists or not. The 
result can be negated by prefixing the key with !", "ognl": false, "suffix": 
"}" },
+    "random(min,max)": { "index": 68, "kind": "function", "displayName": 
"Random", "group": "function", "label": "function", "required": false, 
"javaType": "int", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns a random number 
between min and max (exclusive)", "ognl": false, "suffix": "}" },
+    "ref:name": { "index": 69, "kind": "function", "displayName": "Bean By 
Id", "group": "function", "label": "function", "required": false, "javaType": 
"Object", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "To look up a bean from the 
Registry with the given name.", "ognl": false, "suffix": "}" },
+    "replace(from,to,exp)": { "index": 70, "kind": "function", "displayName": 
"Replace String Values", "group": "function", "label": "function", "required": 
false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Replace all the string values in the message body\/expression. To make it 
easier to replace single and double quotes, then you can use XML escaped values 
`\\&quot;` as double quote, `\\&apos;`  [...]
+    "routeGroup": { "index": 71, "kind": "function", "displayName": "Route 
Group", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The route group of the 
current route the Exchange is being routed. Not all routes have a group 
assigned, so this may be null.", "ognl": false, "suffix": "}" },
+    "routeId": { "index": 72, "kind": "function", "displayName": "Route Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The route id of the 
current route the Exchange is being routed", "ognl": false, "suffix": "}" },
+    "setHeader(name,type,exp)": { "index": 73, "kind": "function", 
"displayName": "Set Header", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sets a message header with the given expression (optional converting to the 
given type)", "ognl": false, "suffix": "}" },
+    "setVariable(name,type,exp)": { "index": 74, "kind": "function", 
"displayName": "Set Variable", "group": "function", "label": "function", 
"required": false, "javaType": "Object", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sets a variable with the given expression (optional converting to the given 
type)", "ognl": false, "suffix": "}" },
+    "size(exp)": { "index": 75, "kind": "function", "displayName": "Size", 
"group": "function", "label": "function", "required": false, "javaType": "int", 
"prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, 
"secret": false, "description": "The size of the message body (or expression). 
If the payload is java.util.Collection or java.util.Map based then the size is 
the number of elements; otherwise the payload size in bytes.", "ognl": false, 
"suffix": "}" },
+    "skip(num)": { "index": 76, "kind": "function", "displayName": "Skip First 
Items from the Message Body", "group": "function", "label": "function", 
"required": false, "javaType": "java.util.Iterator", "prefix": "${", 
"deprecated": false, "deprecationNote": "", "autowired": false, "secret": 
false, "description": "The skip function iterates the message body and skips 
the first number of items. This can be used with the Splitter EIP to split a 
message body and skip the first N number of  [...]
+    "split(exp,separator)": { "index": 77, "kind": "function", "displayName": 
"Split String Values", "group": "function", "label": "function", "required": 
false, "javaType": "String[]", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Splits the message body\/expression as a String value using the separator into 
a String array", "ognl": false, "suffix": "}" },
+    "stepId": { "index": 78, "kind": "function", "displayName": "Step Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the id of the 
current step the Exchange is being routed.", "ognl": false, "suffix": "}" },
+    "substring(head,tail)": { "index": 79, "kind": "function", "displayName": 
"Substring", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Returns a substring of 
the message body\/expression. If only one positive number, then the returned 
string is clipped from the beginning. If only one negative number, then the 
returned string is clipped fr [...]
+    "substringAfter(exp,before)": { "index": 80, "kind": "function", 
"displayName": "Substring After", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that comes after. Returns 
null if nothing comes after.", "ognl": false, "suffix": "}" },
+    "substringBefore(exp,before)": { "index": 81, "kind": "function", 
"displayName": "Substring Before", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that comes before. Returns 
null if nothing comes before.", "ognl": false, "suffix": "}" },
+    "substringBetween(exp,after,before)": { "index": 82, "kind": "function", 
"displayName": "Substring Between", "group": "function", "label": "function", 
"required": false, "javaType": "String", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns a substring of the message body\/expression that are between after and 
before. Returns null if nothing comes between.", "ognl": false, "suffix": "}" },
+    "sum(val...)": { "index": 83, "kind": "function", "displayName": 
"Calculate Sum Number", "group": "function", "label": "function", "required": 
false, "javaType": "long", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Sums together all the values as integral numbers. This function can also be 
used to subtract by using negative numbers.", "ognl": false, "suffix": "}" },
+    "sys.name": { "index": 84, "kind": "function", "displayName": "JVM System 
Property", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The JVM system 
property with the given name", "ognl": false, "suffix": "}" },
+    "threadId": { "index": 85, "kind": "function", "displayName": "Thread Id", 
"group": "function", "label": "function", "required": false, "javaType": 
"long", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the id of the 
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
+    "threadName": { "index": 86, "kind": "function", "displayName": "Thread 
Name", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns the name of the 
current thread. Can be used for logging.", "ognl": false, "suffix": "}" },
+    "trim(exp)": { "index": 87, "kind": "function", "displayName": "Trim", 
"group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "The trim function trims 
the message body (or expression) by removing all leading and trailing white 
spaces.", "ognl": false, "suffix": "}" },
+    "type:name.field": { "index": 88, "kind": "function", "displayName": "Java 
Field Value", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "To refer to a type or 
field by its classname. To refer to a field, you can append .FIELD_NAME. For 
example, you can refer to the constant field from Exchange as: 
`org.apache.camel.Exchange.FILE_NAME`", " [...]
+    "uppercase(exp)": { "index": 89, "kind": "function", "displayName": 
"Uppercase", "group": "function", "label": "function", "required": false, 
"javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Uppercases the message 
body (or expression)", "ognl": false, "suffix": "}" },
+    "uuid(type)": { "index": 90, "kind": "function", "displayName": "Generate 
UUID", "group": "function", "label": "function", "required": false, "javaType": 
"String", "prefix": "${", "deprecated": false, "deprecationNote": "", 
"autowired": false, "secret": false, "description": "Returns a UUID using the 
Camel `UuidGenerator`. You can choose between `default`, `classic`, `short` and 
`simple` as the type. If no type is given, the default is used. It is also 
possible to use a custom `UuidG [...]
+    "variable.name": { "index": 91, "kind": "function", "displayName": 
"Variable", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "The variable with the 
given name", "ognl": true, "suffix": "}" },
+    "variableAs(key,type)": { "index": 92, "kind": "function", "displayName": 
"Variable As", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "Converts the variable 
to the given type (classname).", "ognl": false, "suffix": "}" },
+    "variables": { "index": 93, "kind": "function", "displayName": 
"Variables", "group": "function", "label": "function", "required": false, 
"javaType": "java.util.Map", "prefix": "${", "deprecated": false, 
"deprecationNote": "", "autowired": false, "secret": false, "description": 
"Returns all the variables from the current Exchange in a Map", "ognl": false, 
"suffix": "}" },
+    "xpath(input,exp)": { "index": 94, "kind": "function", "displayName": 
"XPath", "group": "function", "label": "function", "required": false, 
"javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": 
"", "autowired": false, "secret": false, "description": "When working with XML 
data, then this allows using the XPath language, for example, to extract data 
from the message body (in XML format). This requires having camel-xpath JAR on 
the classpath. For input (optional [...]
   }
 }
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 fa2ff756d5cb..94d6801aa19a 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
@@ -181,6 +181,12 @@ NOTE: Some functions take 1 or more arguments enclosed in 
parentheses, and argum
 |`iif(predicate,trueExp,falseExp`) | `Object` | The inlined if function 
evaluates the predicate expression and returns the value of _trueExp_ if the 
predicate is `true`, otherwise the value of `falseExp` is returned. This 
function is similar to the ternary operator in Java.
 |`isEmpty` | `boolean` | Whether the message body is `null` or empty (list/map 
types are tested if they have 0 elements).
 |`isEmpty(exp)` | `boolean` | Whether the expression is `null` or empty 
(list/map types are tested if they have 0 elements).
+|`isAlpha()` | `boolean` | Whether the message body is numeric value (A..Z). 
For more advanced checks use the `regex` operator.
+|`isAlpha(exp)` | `boolean` | Whether the expression is numeric value (A..Z). 
For more advanced checks use the `regex` operator.
+|`isAlphaNumeric()` | `boolean` | Whether the message body is alphanumeric 
value (A..Z0-9). For more advanced checks use the `regex` operator.
+|`isAlphaNumeric(exp)` | `boolean` | Whether the expression is alphanumeric 
value (A..Z0-9). For more advanced checks use the `regex` operator.
+|`isNumeric()` | `boolean` | Whether the message body is numeric value (0..9). 
For more advanced checks use the `regex` operator.
+|`isNumeric(exp)` | `boolean` | Whether the expression is numeric value 
(0..9). For more advanced checks use the `regex` operator.
 |`join(separator,prefix,exp` | `String` | The join function iterates the 
message body (by default) and joins the data into a `String`. The separator is 
by default a comma. The prefix is optional. The join uses the message body as 
source by default. It is possible to refer to another source (simple language) 
such as a header via the exp parameter. For example 
`join('&','id=','$\{header.ids}')`
 |`jq(exp)` | `Object` | When working with JSon data, then this allows using 
the JQ language, for example, to extract data from the message body (in JSon 
format). This requires having camel-jq JAR on the classpath.
 |`jq(input,exp)` | `Object` | Same as `jq(exp)` but to use the _input_ 
expression as the source of the JSon document.
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
index 3b97e58901eb..b414c5dc107d 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/csimple/CSimpleHelper.java
@@ -961,6 +961,48 @@ public final class CSimpleHelper {
         return null;
     }
 
+    public static boolean isAlpha(Exchange exchange, Object value) {
+        String body = convertTo(exchange, String.class, value);
+        if (body == null || body.isBlank()) {
+            return false;
+        }
+        for (int i = 0; i < body.length(); i++) {
+            char ch = body.charAt(i);
+            if (!Character.isLetter(ch)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean isAlphaNumeric(Exchange exchange, Object value) {
+        String body = convertTo(exchange, String.class, value);
+        if (body == null || body.isBlank()) {
+            return false;
+        }
+        for (int i = 0; i < body.length(); i++) {
+            char ch = body.charAt(i);
+            if (!Character.isLetterOrDigit(ch)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static boolean isNumeric(Exchange exchange, Object value) {
+        String body = convertTo(exchange, String.class, value);
+        if (body == null || body.isBlank()) {
+            return false;
+        }
+        for (int i = 0; i < body.length(); i++) {
+            char ch = body.charAt(i);
+            if (!Character.isDigit(ch)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     public static boolean isEmpty(Exchange exchange, Object value) {
         // this may be an object that we can iterate
         Iterable<?> it = 
org.apache.camel.support.ObjectHelper.createIterable(value);
diff --git 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
index 54c7b183ca26..5bdd8beb4ea7 100644
--- 
a/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
+++ 
b/core/camel-core-languages/src/main/java/org/apache/camel/language/simple/SimpleConstants.java
@@ -180,10 +180,22 @@ public final class SimpleConstants {
               label = "function", javaType = "Object", displayName = "If Then 
Else")
     public static final String IIF = "iif(predicate,trueExp,falseExp)";
 
+    @Metadata(description = "Whether the message body (or expression) is 
alphabetic value (A..Z). For more advanced checks use the `regex` operator.",
+              label = "function", javaType = "boolean", displayName = "Is 
Alphabetic Value")
+    public static final String IS_ALPHA = "isAlpha(exp)";
+
+    @Metadata(description = "Whether the message body (or expression) is 
alphanumeric value (A..Z0-9). For more advanced checks use the `regex` 
operator.",
+              label = "function", javaType = "boolean", displayName = "Is 
Alphabetic-Numeric Value")
+    public static final String IS_ALPHA_NUMERIC = "isAlphaNumeric(exp)";
+
     @Metadata(description = "Whether the message body (or expression) is null 
or empty (list/map types are tested if they have 0 elements).",
               label = "function", javaType = "boolean", displayName = "Is 
Empty")
     public static final String IS_EMPTY = "isEmpty(exp)";
 
+    @Metadata(description = "Whether the message body (or expression) is 
numeric value (0..9). For more advanced checks use the `regex` operator.",
+              label = "function", javaType = "boolean", displayName = "Is 
Numeric Value")
+    public static final String IS_NUMERIC = "isNumeric(exp)";
+
     @Metadata(description = "When working with JSon data, then this allows 
using the JQ language, for example, to extract data from the message body (in 
JSon format). This requires having camel-jq JAR on the classpath. For input 
(optional), you can choose `header:key`, `exchangeProperty:key` or 
`variable:key` to use as input for the JSon payload instead of the message 
body.",
               label = "function", javaType = "Object", displayName = "JQ")
     public static final String JQ = "jq(input,exp)";
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 a74df57f4e6c..48d46792aa54 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
@@ -419,6 +419,144 @@ public final class SimpleExpressionBuilder {
         };
     }
 
+    /**
+     * Whether the expression is an alphabetic String
+     */
+    public static Expression isAlphaExpression(final String expression) {
+        return new ExpressionAdapter() {
+            private Expression exp;
+
+            @Override
+            public void init(CamelContext context) {
+                if (expression != null) {
+                    exp = 
context.resolveLanguage("simple").createExpression(expression);
+                    exp.init(context);
+                }
+            }
+
+            @Override
+            public Object evaluate(Exchange exchange) {
+                String body;
+                if (exp != null) {
+                    body = exp.evaluate(exchange, String.class);
+                } else {
+                    body = exchange.getMessage().getBody(String.class);
+                }
+                if (body == null || body.isBlank()) {
+                    return false;
+                }
+                for (int i = 0; i < body.length(); i++) {
+                    char ch = body.charAt(i);
+                    if (!Character.isLetter(ch)) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            @Override
+            public String toString() {
+                if (expression != null) {
+                    return "isAlpha(" + expression + ")";
+                } else {
+                    return "isAlpha()";
+                }
+            }
+        };
+    }
+
+    /**
+     * Whether the expression is a number (integral or floating)
+     */
+    public static Expression isNumericExpression(final String expression) {
+        return new ExpressionAdapter() {
+            private Expression exp;
+
+            @Override
+            public void init(CamelContext context) {
+                if (expression != null) {
+                    exp = 
context.resolveLanguage("simple").createExpression(expression);
+                    exp.init(context);
+                }
+            }
+
+            @Override
+            public Object evaluate(Exchange exchange) {
+                String body;
+                if (exp != null) {
+                    body = exp.evaluate(exchange, String.class);
+                } else {
+                    body = exchange.getMessage().getBody(String.class);
+                }
+                if (body == null || body.isBlank()) {
+                    return false;
+                }
+                for (int i = 0; i < body.length(); i++) {
+                    char ch = body.charAt(i);
+                    if (!Character.isDigit(ch)) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            @Override
+            public String toString() {
+                if (expression != null) {
+                    return "isNumeric(" + expression + ")";
+                } else {
+                    return "isNumeric()";
+                }
+            }
+        };
+    }
+
+    /**
+     * Whether the expression is an alphabetic or numeric String
+     */
+    public static Expression isAlphaNumericExpression(final String expression) 
{
+        return new ExpressionAdapter() {
+            private Expression exp;
+
+            @Override
+            public void init(CamelContext context) {
+                if (expression != null) {
+                    exp = 
context.resolveLanguage("simple").createExpression(expression);
+                    exp.init(context);
+                }
+            }
+
+            @Override
+            public Object evaluate(Exchange exchange) {
+                String body;
+                if (exp != null) {
+                    body = exp.evaluate(exchange, String.class);
+                } else {
+                    body = exchange.getMessage().getBody(String.class);
+                }
+                if (body == null || body.isBlank()) {
+                    return false;
+                }
+                for (int i = 0; i < body.length(); i++) {
+                    char ch = body.charAt(i);
+                    if (!Character.isLetterOrDigit(ch)) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+
+            @Override
+            public String toString() {
+                if (expression != null) {
+                    return "isAlphaNumeric(" + expression + ")";
+                } else {
+                    return "isAlphaNumeric()";
+                }
+            }
+        };
+    }
+
     /**
      * Trims the given expressions (uses message body if expression is null)
      */
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 92c80dab720c..ac22e6d799b9 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
@@ -1056,6 +1056,36 @@ public class SimpleFunctionExpression extends 
LiteralExpression {
             return SimpleExpressionBuilder.isEmptyExpression(exp);
         }
 
+        // isAlpha function
+        remainder = ifStartsWithReturnRemainder("isAlpha(", function);
+        if (remainder != null) {
+            String exp = null;
+            String value = StringHelper.beforeLast(remainder, ")");
+            if (ObjectHelper.isNotEmpty(value)) {
+                exp = StringHelper.removeQuotes(value);
+            }
+            return SimpleExpressionBuilder.isAlphaExpression(exp);
+        }
+        remainder = ifStartsWithReturnRemainder("isAlphaNumeric(", function);
+        if (remainder != null) {
+            String exp = null;
+            String value = StringHelper.beforeLast(remainder, ")");
+            if (ObjectHelper.isNotEmpty(value)) {
+                exp = StringHelper.removeQuotes(value);
+            }
+            return SimpleExpressionBuilder.isAlphaNumericExpression(exp);
+        }
+        // isNumeric function
+        remainder = ifStartsWithReturnRemainder("isNumeric(", function);
+        if (remainder != null) {
+            String exp = null;
+            String value = StringHelper.beforeLast(remainder, ")");
+            if (ObjectHelper.isNotEmpty(value)) {
+                exp = StringHelper.removeQuotes(value);
+            }
+            return SimpleExpressionBuilder.isNumericExpression(exp);
+        }
+
         // trim function
         remainder = ifStartsWithReturnRemainder("trim(", function);
         if (remainder != null) {
@@ -2712,6 +2742,79 @@ public class SimpleFunctionExpression extends 
LiteralExpression {
             return "Object o = " + exp + ";\n        return isEmpty(exchange, 
o);";
         }
 
+        // isNumeric function
+        remainder = ifStartsWithReturnRemainder("isAlpha(", function);
+        if (remainder != null) {
+            String exp = null;
+            String values = StringHelper.beforeLast(remainder, ")");
+            if (ObjectHelper.isNotEmpty(values)) {
+                String[] tokens = codeSplitSafe(values, ',', true, true);
+                if (tokens.length != 1) {
+                    throw new SimpleParserException(
+                            "Valid syntax: ${isAlpha(exp)} was: " + function, 
token.getIndex());
+                }
+                // single quotes should be double quotes
+                String s = tokens[0];
+                if (StringHelper.isSingleQuoted(s)) {
+                    s = StringHelper.removeLeadingAndEndingQuotes(s);
+                    s = StringQuoteHelper.doubleQuote(s);
+                }
+                exp = s;
+            }
+            if (ObjectHelper.isEmpty(exp)) {
+                exp = "body";
+            }
+            return "Object o = " + exp + ";\n        return isAlpha(exchange, 
o);";
+        }
+        // isAlphaNumeric function
+        remainder = ifStartsWithReturnRemainder("isAlphaNumeric(", function);
+        if (remainder != null) {
+            String exp = null;
+            String values = StringHelper.beforeLast(remainder, ")");
+            if (ObjectHelper.isNotEmpty(values)) {
+                String[] tokens = codeSplitSafe(values, ',', true, true);
+                if (tokens.length != 1) {
+                    throw new SimpleParserException(
+                            "Valid syntax: ${isAlphaNumeric(exp)} was: " + 
function, token.getIndex());
+                }
+                // single quotes should be double quotes
+                String s = tokens[0];
+                if (StringHelper.isSingleQuoted(s)) {
+                    s = StringHelper.removeLeadingAndEndingQuotes(s);
+                    s = StringQuoteHelper.doubleQuote(s);
+                }
+                exp = s;
+            }
+            if (ObjectHelper.isEmpty(exp)) {
+                exp = "body";
+            }
+            return "Object o = " + exp + ";\n        return 
isAlphaNumeric(exchange, o);";
+        }
+        // isNumeric function
+        remainder = ifStartsWithReturnRemainder("isNumeric(", function);
+        if (remainder != null) {
+            String exp = null;
+            String values = StringHelper.beforeLast(remainder, ")");
+            if (ObjectHelper.isNotEmpty(values)) {
+                String[] tokens = codeSplitSafe(values, ',', true, true);
+                if (tokens.length != 1) {
+                    throw new SimpleParserException(
+                            "Valid syntax: ${isNumeric(exp)} was: " + 
function, token.getIndex());
+                }
+                // single quotes should be double quotes
+                String s = tokens[0];
+                if (StringHelper.isSingleQuoted(s)) {
+                    s = StringHelper.removeLeadingAndEndingQuotes(s);
+                    s = StringQuoteHelper.doubleQuote(s);
+                }
+                exp = s;
+            }
+            if (ObjectHelper.isEmpty(exp)) {
+                exp = "body";
+            }
+            return "Object o = " + exp + ";\n        return 
isNumeric(exchange, o);";
+        }
+
         // capitalize function
         remainder = ifStartsWithReturnRemainder("capitalize(", 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 971b4621a416..271ab904adce 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
@@ -2704,6 +2704,121 @@ public class SimpleTest extends LanguageTestSupport {
         assertFalse(expression.evaluate(exchange, Boolean.class));
     }
 
+    @Test
+    public void testIsAlpha() {
+        exchange.getMessage().setBody("HelloWorld");
+
+        Expression expression = 
context.resolveLanguage("simple").createExpression("${isAlpha()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha(${body})}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha(3)}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha('')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha(' ')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha('HiIamHere')}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha('Hi_I_am_here')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha('Hi I am 
here!')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello".getBytes());
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello123".getBytes());
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlpha()}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+    }
+
+    @Test
+    public void testIsAlphaNumeric() {
+        exchange.getMessage().setBody("Hello123");
+
+        Expression expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric(${body})}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric(3)}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric('A')}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric('')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric('!')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric('HiIamHere')}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric('Hi_I_am_here')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric('Hi I am 
here!')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello".getBytes());
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello123".getBytes());
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello123!".getBytes());
+        expression = 
context.resolveLanguage("simple").createExpression("${isAlphaNumeric()}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+    }
+
+    @Test
+    public void testIsNumeric() {
+        exchange.getMessage().setBody(123L);
+
+        Expression expression = 
context.resolveLanguage("simple").createExpression("${isNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isNumeric(${body})}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isNumeric(3)}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isNumeric('-4')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isNumeric('1.99')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isNumeric('')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        expression = 
context.resolveLanguage("simple").createExpression("${isNumeric('Hello')}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("Hello".getBytes());
+        expression = 
context.resolveLanguage("simple").createExpression("${isNumeric()}");
+        assertFalse(expression.evaluate(exchange, Boolean.class));
+
+        exchange.getMessage().setBody("123".getBytes());
+        expression = 
context.resolveLanguage("simple").createExpression("${isNumeric()}");
+        assertTrue(expression.evaluate(exchange, Boolean.class));
+    }
+
     @Test
     public void testTrim() {
         exchange.getMessage().setBody("   Hello World ");

Reply via email to