Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,12 @@
"trim(exp)": { "index": 101, "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": 102, "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`", "ognl": false, "suffix": "}" },
"kindOfType(exp)": { "index": 103, "kind": "function", "displayName": "Kind of Type", "group": "function", "label": "function", "required": false, "javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "What kind of type is the value (null,number,string,boolean,array,object)", "ognl": false, "suffix": "}" },
"uppercase(exp)": { "index": 104, "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": 105, "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 `UuidGenerator` and bind the bean to the Registry with an id. For example `${uuid(myGenerator)}` where the ID is _myGenerator_.", "ognl": false, "suffix": "}" },
"variable.name": { "index": 106, "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": 107, "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": 108, "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": 109, "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), you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the XML payload instead of the message body.", "ognl": false, "suffix": "}" }
"unquote(exp)": { "index": 104, "kind": "function", "displayName": "Unquote", "group": "function", "label": "function", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the message body (or expression) with any leading\/ending quotes removed", "ognl": false, "suffix": "}" },
"uppercase(exp)": { "index": 105, "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": 106, "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 `UuidGenerator` and bind the bean to the Registry with an id. For example `${uuid(myGenerator)}` where the ID is _myGenerator_.", "ognl": false, "suffix": "}" },
"variable.name": { "index": 107, "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": 108, "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": 109, "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": 110, "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), you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the XML payload instead of the message body.", "ognl": false, "suffix": "}" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2682,6 +2682,27 @@ public void testSafeQuote() {
assertEquals("\"{A=1, B=2}\"", s);
}

@Test
public void testUnquote() {
exchange.getMessage().setBody("\"Hello World\"");

Expression expression = context.resolveLanguage("csimple").createExpression("${unquote()}");
String s = expression.evaluate(exchange, String.class);
assertEquals("Hello World", s);

expression = context.resolveLanguage("csimple").createExpression("${unquote(${body})}");
s = expression.evaluate(exchange, String.class);
assertEquals("Hello World", s);

expression = context.resolveLanguage("csimple").createExpression("${unquote('\"Hi\"')}");
s = expression.evaluate(exchange, String.class);
assertEquals("Hi", s);

expression = context.resolveLanguage("csimple").createExpression("${unquote('Hi')}");
s = expression.evaluate(exchange, String.class);
assertEquals("Hi", s);
}

@Test
public void testTrim() {
exchange.getMessage().setBody(" Hello World ");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.camel.spi;

import java.util.Set;

import org.apache.camel.Expression;

/**
Expand Down Expand Up @@ -46,6 +48,11 @@ public interface SimpleFunctionRegistry {
*/
Expression getFunction(String name);

/**
* Returns a set with all the function names
*/
Set<String> getFunctionNames();

/**
* Number of custom functions
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package org.apache.camel.impl.engine;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.camel.CamelContext;
Expand Down Expand Up @@ -53,6 +54,11 @@ public Expression getFunction(String name) {
return functions.get(name);
}

@Override
public Set<String> getFunctionNames() {
return functions.keySet();
}

@Override
protected void doStop() throws Exception {
super.doShutdown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,12 @@
"trim(exp)": { "index": 101, "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": 102, "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`", "ognl": false, "suffix": "}" },
"kindOfType(exp)": { "index": 103, "kind": "function", "displayName": "Kind of Type", "group": "function", "label": "function", "required": false, "javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "What kind of type is the value (null,number,string,boolean,array,object)", "ognl": false, "suffix": "}" },
"uppercase(exp)": { "index": 104, "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": 105, "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 `UuidGenerator` and bind the bean to the Registry with an id. For example `${uuid(myGenerator)}` where the ID is _myGenerator_.", "ognl": false, "suffix": "}" },
"variable.name": { "index": 106, "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": 107, "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": 108, "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": 109, "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), you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the XML payload instead of the message body.", "ognl": false, "suffix": "}" }
"unquote(exp)": { "index": 104, "kind": "function", "displayName": "Unquote", "group": "function", "label": "function", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the message body (or expression) with any leading\/ending quotes removed", "ognl": false, "suffix": "}" },
"uppercase(exp)": { "index": 105, "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": 106, "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 `UuidGenerator` and bind the bean to the Registry with an id. For example `${uuid(myGenerator)}` where the ID is _myGenerator_.", "ognl": false, "suffix": "}" },
"variable.name": { "index": 107, "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": 108, "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": 109, "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": 110, "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), you can choose `header:key`, `exchangeProperty:key` or `variable:key` to use as input for the XML payload instead of the message body.", "ognl": false, "suffix": "}" }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ The generator supports different kinds `default`, `classic`, `short`, `simple` a
|`substringBetween(exp,after,before` | `String` | Returns a substring of the expression that are between before and after. Returns `null` if nothing comes between.
|`trim()` | `String` | The trim function trims the message body by removing all leading and trailing white spaces.
|`trim(exp)` | `String` | The trim function trims the expression by removing all leading and trailing white spaces.
|`unquote()` | `String` | Returns the message body with any leading/ending quotes removed
|`unquote(exp)` | `String` | Returns the expression with any leading/ending quotes removed
|`quote()` | `String` | Returns the message body as a double-quoted string
|`quote(exp)` | `String` | Returns the expression as a double-quoted string
|`uppercase()` | `String` | Uppercases the message body
Expand Down Expand Up @@ -1299,8 +1301,6 @@ $init{
}init$
----

NOTE: You cannot declare custom functions that call other function functions. This is currently not supported.

The function will by default use the message body as the input, such that the following:

[source,java]
Expand All @@ -1319,6 +1319,33 @@ simple("Incoming message: ${cleanUp(' Please clean this text for me ')}

Here the parameter is a fixed `String` but you can also pass in other type of value such as a number, boolean, or even a nested function.

==== Calling custom functions from custom functions

It is also possible to reuse custom functions from other functions using `${function(name)}`, such shown:

[source,text]
----
$init{
$cleanUp ~:= ${trim()} ~> ${normalizeWhitespace()} ~> ${uppercase()}
$count ~:= ${function(cleanUp)} ~> ${split(' ')} ~> ${size()}
}init$
----

Here the `$count` is declared as a function which calls the cleanUp function and then counts the words via split and size functions.

Instead of using `${function(name)}` you can also same syntax as the built-in functions, as follows:

[source,text]
----
$init{
$cleanUp ~:= ${trim()} ~> ${normalizeWhitespace()} ~> ${uppercase()}
$count ~:= ${cleanUp()} ~> ${split(' ')} ~> ${size()}
}init$
----

Notice how `${cleanUp()}` despite being a custom function is using the same syntax as all the built-in functions that are being used, for example:
`${trim()}`.


== OGNL Expression Support

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,19 @@ public static Object safeQuote(Exchange exchange, Object value) {
return value;
}

public static String unquote(Exchange exchange, Object value) {
String body;
if (value != null) {
body = exchange.getContext().getTypeConverter().tryConvertTo(String.class, exchange, value);
} else {
body = exchange.getMessage().getBody(String.class);
}
if (body != null) {
body = StringHelper.removeLeadingAndEndingQuotes(body);
}
return body;
}

public static String trim(Exchange exchange, Object value) {
String body;
if (value != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ public final class SimpleConstants {
label = "function", javaType = "Object", displayName = "Kind of Type")
public static final String KIND_OF_TYPE = "kindOfType(exp)";

@Metadata(description = "Returns the message body (or expression) with any leading/ending quotes removed",
label = "function", javaType = "String")
public static final String UNQUOTE = "unquote(exp)";

@Metadata(description = "Uppercases the message body (or expression)", label = "function", javaType = "String",
displayName = "Uppercase")
public static final String UPPERCASE = "uppercase(exp)";
Expand Down
Loading