This is an automated email from the ASF dual-hosted git repository. gnodet pushed a commit to branch CAMEL-23053/simple-tojson in repository https://gitbox.apache.org/repos/asf/camel.git
commit 7ac5e13a50f2b0ebe607b2e8b3e3fee914d041a3 Author: Guillaume Nodet <[email protected]> AuthorDate: Fri Mar 6 14:10:46 2026 +0100 CAMEL-23053: Add toJson functions to Simple language --- .../org/apache/camel/language/simple/simple.json | 80 +++++++++++----------- .../camel/language/csimple/CSimpleHelper.java | 11 +++ .../camel/language/simple/SimpleConstants.java | 8 +++ .../simple/ast/SimpleFunctionExpression.java | 16 +++++ .../apache/camel/language/simple/SimpleTest.java | 20 ++++++ .../camel/support/builder/ExpressionBuilder.java | 48 +++++++++++++ 6 files changed, 144 insertions(+), 39 deletions(-) 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 e8afbc37b6a8..d466c04146e7 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 @@ -102,44 +102,46 @@ "pad(exp,width,separator)": { "index": 74, "kind": "function", "displayName": "Pad String", "group": "string", "label": "string", "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.", "ognl" [...] "pretty(exp)": { "index": 75, "kind": "function", "displayName": "Pretty Print", "group": "xml", "label": "json,xml", "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": 76, "kind": "function", "displayName": "Pretty Body", "group": "xml", "label": "json,xml", "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": 77, "kind": "function", "displayName": "Property Placeholder", "group": "core", "label": "core", "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": 78, "kind": "function", "displayName": "Property Placeholder Exists", "group": "core", "label": "core", "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": "}" }, - "quote(exp)": { "index": 79, "kind": "function", "displayName": "Quote", "group": "string", "label": "string", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the message body (or expression) as a double quoted string", "ognl": false, "suffix": "}" }, - "random(min,max)": { "index": 80, "kind": "function", "displayName": "Random", "group": "number", "label": "number", "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": "}" }, - "range(min,max)": { "index": 81, "kind": "function", "displayName": "Range", "group": "number", "label": "number", "required": false, "javaType": "List", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns a list of increasing integers between the given interval (exclusive)", "ognl": false, "suffix": "}" }, - "ref:name": { "index": 82, "kind": "function", "displayName": "Bean By Id", "group": "core", "label": "core", "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": 83, "kind": "function", "displayName": "Replace String Values", "group": "string", "label": "string", "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 `\\"` as double quote, `\\'` as s [...] - "reverse(val...)": { "index": 84, "kind": "function", "displayName": "Reverse Values", "group": "collection", "label": "collection", "required": false, "javaType": "List", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns a list of all the values, but in reverse order", "ognl": false, "suffix": "}" }, - "routeGroup": { "index": 85, "kind": "function", "displayName": "Route Group", "group": "core", "label": "core", "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": 86, "kind": "function", "displayName": "Route Id", "group": "core", "label": "core", "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": "}" }, - "safeQuote(exp)": { "index": 87, "kind": "function", "displayName": "Safe Quote", "group": "string", "label": "string", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the message body (or expression) safely quoted if needed", "ognl": false, "suffix": "}" }, - "setVariable(key,exp)": { "index": 88, "kind": "function", "displayName": "Set Variable", "group": "attachment", "label": "attachment", "required": false, "javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Sets an attachment with payload from the message body\/expression.", "ognl": false, "suffix": "}" }, - "setHeader(name,type,exp)": { "index": 89, "kind": "function", "displayName": "Set Header", "group": "core", "label": "core", "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": 90, "kind": "function", "displayName": "Set Variable", "group": "core", "label": "core", "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": "}" }, - "shuffle(val...)": { "index": 91, "kind": "function", "displayName": "Shuffle Values", "group": "collection", "label": "collection", "required": false, "javaType": "List", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns a list of all the values shuffled in random order", "ognl": false, "suffix": "}" }, - "size(exp)": { "index": 92, "kind": "function", "displayName": "Size", "group": "collection", "label": "collection", "required": false, "javaType": "int", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the number of elements in collection or array based payloads. If the value is null then 0 is returned, otherwise 1.", "ognl": false, "suffix": "}" }, - "skip(num)": { "index": 93, "kind": "function", "displayName": "Skip First Items from the Message Body", "group": "collection", "label": "collection", "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 [...] - "split(exp,separator)": { "index": 94, "kind": "function", "displayName": "Split String Values", "group": "collection", "label": "collection", "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": 95, "kind": "function", "displayName": "Step Id", "group": "core", "label": "core", "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": 96, "kind": "function", "displayName": "Substring", "group": "string", "label": "string", "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 from t [...] - "substringAfter(exp,before)": { "index": 97, "kind": "function", "displayName": "Substring After", "group": "string", "label": "string", "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": 98, "kind": "function", "displayName": "Substring Before", "group": "string", "label": "string", "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": 99, "kind": "function", "displayName": "Substring Between", "group": "string", "label": "string", "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": 100, "kind": "function", "displayName": "Calculate Sum Number", "group": "number", "label": "number", "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": 101, "kind": "function", "displayName": "JVM System Property", "group": "other", "label": "other", "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": 102, "kind": "function", "displayName": "Thread Id", "group": "other", "label": "other", "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": 103, "kind": "function", "displayName": "Thread Name", "group": "other", "label": "other", "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": "}" }, - "throwException(type,msg)": { "index": 104, "kind": "function", "displayName": "Throw Exception", "group": "core", "label": "core", "required": false, "javaType": "java.lang.Exception", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deliberately throws an error. Uses IllegalArgumentException by default if no type is specified (use fully qualified classname).", "ognl": false, "suffix": "}" }, - "trim(exp)": { "index": 105, "kind": "function", "displayName": "Trim", "group": "string", "label": "string", "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": 106, "kind": "function", "displayName": "Java Field Value", "group": "core", "label": "core", "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": [...] - "kindOfType(exp)": { "index": 107, "kind": "function", "displayName": "Kind of Type", "group": "core", "label": "core", "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": "}" }, - "unquote(exp)": { "index": 108, "kind": "function", "displayName": "Unquote", "group": "string", "label": "string", "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": 109, "kind": "function", "displayName": "Uppercase", "group": "string", "label": "string", "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": 110, "kind": "function", "displayName": "Generate UUID", "group": "other", "label": "other", "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 `UuidGenera [...] - "val(exp)": { "index": 111, "kind": "function", "displayName": "Value", "group": "core", "label": "core", "required": false, "javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the expression as a constant value", "ognl": false, "suffix": "}" }, - "variable.name": { "index": 112, "kind": "function", "displayName": "Variable", "group": "core", "label": "core", "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": 113, "kind": "function", "displayName": "Variable As", "group": "core", "label": "core", "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": 114, "kind": "function", "displayName": "Variables", "group": "core", "label": "core", "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": 115, "kind": "function", "displayName": "XPath", "group": "xml", "label": "xml", "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 ca [...] + "toJson(exp)": { "index": 77, "kind": "function", "displayName": "To JSon", "group": "json", "label": "json", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Converts the expression to JSon String representation.", "ognl": false, "suffix": "}" }, + "toJsonBody": { "index": 78, "kind": "function", "displayName": "To Json Body", "group": "json", "label": "json", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Converts the body to JSon String representation.", "ognl": false, "suffix": "}" }, + "properties:key:default": { "index": 79, "kind": "function", "displayName": "Property Placeholder", "group": "core", "label": "core", "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": 80, "kind": "function", "displayName": "Property Placeholder Exists", "group": "core", "label": "core", "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": "}" }, + "quote(exp)": { "index": 81, "kind": "function", "displayName": "Quote", "group": "string", "label": "string", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the message body (or expression) as a double quoted string", "ognl": false, "suffix": "}" }, + "random(min,max)": { "index": 82, "kind": "function", "displayName": "Random", "group": "number", "label": "number", "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": "}" }, + "range(min,max)": { "index": 83, "kind": "function", "displayName": "Range", "group": "number", "label": "number", "required": false, "javaType": "List", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns a list of increasing integers between the given interval (exclusive)", "ognl": false, "suffix": "}" }, + "ref:name": { "index": 84, "kind": "function", "displayName": "Bean By Id", "group": "core", "label": "core", "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": 85, "kind": "function", "displayName": "Replace String Values", "group": "string", "label": "string", "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 `\\"` as double quote, `\\'` as s [...] + "reverse(val...)": { "index": 86, "kind": "function", "displayName": "Reverse Values", "group": "collection", "label": "collection", "required": false, "javaType": "List", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns a list of all the values, but in reverse order", "ognl": false, "suffix": "}" }, + "routeGroup": { "index": 87, "kind": "function", "displayName": "Route Group", "group": "core", "label": "core", "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": 88, "kind": "function", "displayName": "Route Id", "group": "core", "label": "core", "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": "}" }, + "safeQuote(exp)": { "index": 89, "kind": "function", "displayName": "Safe Quote", "group": "string", "label": "string", "required": false, "javaType": "String", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the message body (or expression) safely quoted if needed", "ognl": false, "suffix": "}" }, + "setVariable(key,exp)": { "index": 90, "kind": "function", "displayName": "Set Variable", "group": "attachment", "label": "attachment", "required": false, "javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Sets an attachment with payload from the message body\/expression.", "ognl": false, "suffix": "}" }, + "setHeader(name,type,exp)": { "index": 91, "kind": "function", "displayName": "Set Header", "group": "core", "label": "core", "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": 92, "kind": "function", "displayName": "Set Variable", "group": "core", "label": "core", "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": "}" }, + "shuffle(val...)": { "index": 93, "kind": "function", "displayName": "Shuffle Values", "group": "collection", "label": "collection", "required": false, "javaType": "List", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns a list of all the values shuffled in random order", "ognl": false, "suffix": "}" }, + "size(exp)": { "index": 94, "kind": "function", "displayName": "Size", "group": "collection", "label": "collection", "required": false, "javaType": "int", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the number of elements in collection or array based payloads. If the value is null then 0 is returned, otherwise 1.", "ognl": false, "suffix": "}" }, + "skip(num)": { "index": 95, "kind": "function", "displayName": "Skip First Items from the Message Body", "group": "collection", "label": "collection", "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 [...] + "split(exp,separator)": { "index": 96, "kind": "function", "displayName": "Split String Values", "group": "collection", "label": "collection", "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": 97, "kind": "function", "displayName": "Step Id", "group": "core", "label": "core", "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": 98, "kind": "function", "displayName": "Substring", "group": "string", "label": "string", "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 from t [...] + "substringAfter(exp,before)": { "index": 99, "kind": "function", "displayName": "Substring After", "group": "string", "label": "string", "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": 100, "kind": "function", "displayName": "Substring Before", "group": "string", "label": "string", "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": 101, "kind": "function", "displayName": "Substring Between", "group": "string", "label": "string", "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": 102, "kind": "function", "displayName": "Calculate Sum Number", "group": "number", "label": "number", "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": 103, "kind": "function", "displayName": "JVM System Property", "group": "other", "label": "other", "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": 104, "kind": "function", "displayName": "Thread Id", "group": "other", "label": "other", "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": 105, "kind": "function", "displayName": "Thread Name", "group": "other", "label": "other", "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": "}" }, + "throwException(type,msg)": { "index": 106, "kind": "function", "displayName": "Throw Exception", "group": "core", "label": "core", "required": false, "javaType": "java.lang.Exception", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deliberately throws an error. Uses IllegalArgumentException by default if no type is specified (use fully qualified classname).", "ognl": false, "suffix": "}" }, + "trim(exp)": { "index": 107, "kind": "function", "displayName": "Trim", "group": "string", "label": "string", "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": 108, "kind": "function", "displayName": "Java Field Value", "group": "core", "label": "core", "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": [...] + "kindOfType(exp)": { "index": 109, "kind": "function", "displayName": "Kind of Type", "group": "core", "label": "core", "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": "}" }, + "unquote(exp)": { "index": 110, "kind": "function", "displayName": "Unquote", "group": "string", "label": "string", "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": 111, "kind": "function", "displayName": "Uppercase", "group": "string", "label": "string", "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": 112, "kind": "function", "displayName": "Generate UUID", "group": "other", "label": "other", "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 `UuidGenera [...] + "val(exp)": { "index": 113, "kind": "function", "displayName": "Value", "group": "core", "label": "core", "required": false, "javaType": "Object", "prefix": "${", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Returns the expression as a constant value", "ognl": false, "suffix": "}" }, + "variable.name": { "index": 114, "kind": "function", "displayName": "Variable", "group": "core", "label": "core", "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": 115, "kind": "function", "displayName": "Variable As", "group": "core", "label": "core", "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": 116, "kind": "function", "displayName": "Variables", "group": "core", "label": "core", "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": 117, "kind": "function", "displayName": "XPath", "group": "xml", "label": "xml", "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 ca [...] } } 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 810c998e5f4d..398a57d184b6 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 @@ -252,6 +252,17 @@ public final class CSimpleHelper { return body; } + public static String toJsonBody(Exchange exchange) { + Object body = exchange.getIn().getBody(); + if (body == null) { + return null; + } + if (body instanceof String) { + return (String) body; + } + return Jsoner.serialize(body); + } + private static String prettyXml(String rawXml) { try { boolean includeDeclaration = rawXml.startsWith("<?xml"); 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 5d2accbbdefa..30db651968f0 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 @@ -314,6 +314,14 @@ public final class SimpleConstants { javaType = "String", label = "json,xml") public static final String PRETTY_BODY = "prettyBody"; + @Metadata(description = "Converts the expression to JSon String representation.", + label = "json", javaType = "String", displayName = "To JSon") + public static final String TO_JSON = "toJson(exp)"; + + @Metadata(description = "Converts the body to JSon String representation.", + javaType = "String", label = "json") + public static final String TO_JSON_BODY = "toJsonBody"; + @Metadata(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.", label = "core", javaType = "String", displayName = "Property Placeholder") public static final String PROPERTIES = "properties:key:default"; 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 b906b2fe758f..5ab85cba6f8a 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 @@ -203,6 +203,18 @@ public class SimpleFunctionExpression extends LiteralExpression { return ExpressionBuilder.prettyExpression(inlined); } + // toJson + remainder = ifStartsWithReturnRemainder("toJson(", function); + if (remainder != null) { + String exp = StringHelper.beforeLast(remainder, ")"); + if (exp == null) { + throw new SimpleParserException("Valid syntax: ${toJson(exp)} was: " + function, token.getIndex()); + } + exp = StringHelper.removeLeadingAndEndingQuotes(exp); + Expression inlined = camelContext.resolveLanguage("simple").createExpression(exp); + return ExpressionBuilder.toJsonExpression(inlined); + } + // file: prefix remainder = ifStartsWithReturnRemainder("file:", function); if (remainder != null) { @@ -719,6 +731,8 @@ public class SimpleFunctionExpression extends LiteralExpression { return ExpressionBuilder.bodyTypeExpression(); } else if (ObjectHelper.equal(expression, "prettyBody")) { return ExpressionBuilder.prettyBodyExpression(); + } else if (ObjectHelper.equal(expression, "toJsonBody")) { + return ExpressionBuilder.toJsonBodyExpression(); } else if (ObjectHelper.equal(expression, "bodyOneLine")) { return ExpressionBuilder.bodyOneLine(); } else if (ObjectHelper.equal(expression, "originalBody")) { @@ -1987,6 +2001,8 @@ public class SimpleFunctionExpression extends LiteralExpression { return "bodyType(exchange)"; } else if (ObjectHelper.equal(expression, "prettyBody")) { return "prettyBody(exchange)"; + } else if (ObjectHelper.equal(expression, "toJsonBody")) { + return "toJsonBody(exchange)"; } else if (ObjectHelper.equal(expression, "bodyOneLine")) { return "bodyOneLine(exchange)"; } else if (ObjectHelper.equal(expression, "id")) { 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 cc92d6dfc9ac..c0fdacd56787 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 @@ -3290,6 +3290,26 @@ public class SimpleTest extends LanguageTestSupport { assertExpression(exchange, "${pretty(${body})}", "{\n\t\"name\": \"Jack\",\n\t\"id\": 123\n}\n"); } + @Test + public void testToJson() { + // string body is returned as-is + exchange.getMessage().setBody("Hello"); + assertExpression(exchange, "${toJson(${body})}", "Hello"); + assertExpression(exchange, "${toJsonBody}", "Hello"); + + // map body is serialized to JSON + Map<String, Object> map = new LinkedHashMap<>(); + map.put("name", "Jack"); + map.put("id", 123); + exchange.getMessage().setBody(map); + assertExpression(exchange, "${toJson(${body})}", "{\"name\":\"Jack\",\"id\":123}"); + assertExpression(exchange, "${toJsonBody}", "{\"name\":\"Jack\",\"id\":123}"); + + // null body + exchange.getMessage().setBody(null); + assertExpression(exchange, "${toJsonBody}", null); + } + @Test public void testTrimResult() { exchange.getMessage().setBody("Camel "); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java index bd5fd489eb37..771026893e17 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/builder/ExpressionBuilder.java @@ -2741,6 +2741,54 @@ public class ExpressionBuilder { }; } + /** + * Returns the expression result serialized as a JSON string + */ + public static Expression toJsonExpression(final Expression expression) { + return new ExpressionAdapter() { + @Override + public Object evaluate(Exchange exchange) { + Object value = expression.evaluate(exchange, Object.class); + if (value == null) { + return null; + } + if (value instanceof String) { + return value; + } + return Jsoner.serialize(value); + } + + @Override + public String toString() { + return "toJson(" + expression + ")"; + } + }; + } + + /** + * Returns the message body serialized as a JSON string + */ + public static Expression toJsonBodyExpression() { + return new ExpressionAdapter() { + @Override + public Object evaluate(Exchange exchange) { + Object body = exchange.getIn().getBody(); + if (body == null) { + return null; + } + if (body instanceof String) { + return body; + } + return Jsoner.serialize(body); + } + + @Override + public String toString() { + return "toJsonBody"; + } + }; + } + /** * Returns the expression for the message body as pretty formatted string */
