| [[simple-language]] |
| = Simple Language |
| :page-source: core/camel-base/src/main/docs/simple-language.adoc |
| |
| *Available as of Camel version 1.1* |
| |
| The Simple Expression Language was a really simple language when it was |
| created, but has since grown more powerful. It is primarily intended for |
| being a really small and simple language for evaluating |
| Expressions and Predicates |
| without requiring any new dependencies or knowledge of |
| xref:components::xpath-language.adoc[XPath]; so it is ideal for testing in camel-core. The |
| idea was to cover 95% of the common use cases when you need a little bit |
| of expression based script in your Camel routes. |
| |
| However for much more complex use cases you are generally recommended to |
| choose a more expressive and powerful language such as: |
| |
| * xref:components::groovy-language.adoc[Groovy] |
| * xref:components::spel-language.adoc[SpEL] |
| * xref:components::mvel-component.adoc[MVEL] |
| * xref:components::ognl-language.adoc[OGNL] |
| |
| The simple language uses `${body`} placeholders for complex expressions |
| where the expression contains constant literals. The $\{ } placeholders |
| can be omitted if the expression is only the token itself. |
| |
| TIP: *Alternative syntax* You can also use the alternative syntax which |
| uses `$simple{ }` as placeholders. This can be used in situations to avoid clashes when using for example |
| Spring property placeholder together with Camel. |
| |
| |
| == Simple Language options |
| |
| // language options: START |
| The Simple language supports 2 options, which are listed below. |
| |
| |
| |
| [width="100%",cols="2,1m,1m,6",options="header"] |
| |=== |
| | Name | Default | Java Type | Description |
| | resultType | | String | Sets the class name of the result type (type from output) |
| | trim | true | Boolean | Whether to trim the value to remove leading and trailing whitespaces and line breaks |
| |=== |
| // language options: END |
| |
| == Variables |
| |
| [width="100%",cols="10%,10%,80%",options="header",] |
| |======================================================================= |
| |Variable |Type |Description |
| |
| |camelId |String |the CamelContext name |
| |
| |camelContext.*OGNL* |Object |the CamelContext invoked using a Camel OGNL expression. |
| |
| |exchange |Exchange |the Exchange |
| |
| |exchange.*OGNL* |Object |the Exchange invoked using a Camel |
| OGNL expression. |
| |
| |exchangeId |String |the exchange id |
| |
| |id |String |the input message id |
| |
| |body |Object |the input body |
| |
| |in.body |Object |*deprecated* the input body |
| |
| |body.*OGNL* |Object |the input body invoked using a Camel OGNL expression. |
| |
| |in.body.*OGNL* |Object |*deprecated* the input body invoked using a Camel OGNL expression. |
| |
| |bodyAs(_type_) |Type |Converts the body to the given type determined by its |
| classname. The converted body can be null. |
| |
| |bodyAs(_type_).*OGNL* |Object |Converts the body to the given type determined by its |
| classname and then invoke methods using a Camel OGNL expression. The |
| converted body can be null. |
| |
| |bodyOneLine | String | Converts the body to a String and removes all line-breaks so the string is in one line. |
| |
| |mandatoryBodyAs(_type_) |Type |Converts the body to the given type determined by its |
| classname, and expects the body to be not null. |
| |
| |mandatoryBodyAs(_type_).*OGNL* |Object |Converts the body to the given type determined by its |
| classname and then invoke methods using a Camel OGNL expression. |
| |
| |header.foo |Object |refer to the input foo header |
| |
| |header:foo |Object |refer to the input foo header |
| |
| |header[foo] |Object |refer to the input foo header |
| |
| |headers.foo |Object |refer to the input foo header |
| |
| |headers:foo |Object |refer to the input foo header |
| |
| |headers[foo] |Object |refer to the input foo header |
| |
| |in.header.foo |Object |*deprecated* refer to the input foo header |
| |
| |in.header:foo |Object |*deprecated* refer to the input foo header |
| |
| |in.header[foo] |Object |*deprecated* refer to the input foo header |
| |
| |in.headers.foo |Object |*deprecated* refer to the input foo header |
| |
| |in.headers:foo |Object |*deprecated* refer to the input foo header |
| |
| |in.headers[foo] |Object |*deprecated* refer to the input foo header |
| |
| |header.foo[bar] |Object |regard input foo header as a map and perform lookup on the |
| map with bar as key |
| |
| |in.header.foo[bar] |Object |*deprecated* regard input foo header as a map and perform lookup on the |
| map with bar as key |
| |
| |in.headers.foo[bar] |Object |*deprecated* regard input foo header as a map and perform lookup on the |
| map with bar as key |
| |
| |header.foo.*OGNL* |Object |refer to the input foo header and invoke its value using a |
| Camel OGNL expression. |
| |
| |in.header.foo.*OGNL* |Object |*deprecated* refer to the input foo header and invoke its value using a |
| Camel OGNL expression. |
| |
| |in.headers.foo.*OGNL* |Object |*deprecated* refer to the input foo header and invoke its value using a |
| Camel OGNL expression. |
| |
| |headerAs(_key_,_type_) |Type |converts the header to the given type determined by its |
| classname |
| |
| |headers |Map |refer to the input headers |
| |
| |in.headers |Map |*deprecated* refer to the input headers |
| |
| |exchangeProperty.foo |Object |refer to the foo property on the exchange |
| |
| |exchangeProperty[foo] |Object |refer to the foo property on the exchange |
| |
| |exchangeProperty.foo.*OGNL* |Object |refer to the foo property on the exchange and invoke its |
| value using a Camel OGNL expression. |
| |
| |sys.foo |String |refer to the JVM system property |
| |
| |sysenv.foo |String |refer to the system environment variable |
| |
| |env.foo |String |refer to the system environment variable |
| |
| |exception |Object |refer to the exception object on the exchange, is *null* if |
| no exception set on exchange. Will fallback and grab caught exceptions |
| (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any. |
| |
| |exception.*OGNL* |Object |refer to the exchange exception invoked using a Camel OGNL |
| expression object |
| |
| |exception.message |String |refer to the exception.message on the exchange, is *null* if no |
| exception set on exchange. Will fallback and grab caught exceptions |
| (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any. |
| |
| |exception.stacktrace |String |refer to the exception.stracktrace on the exchange, is |
| *null* if no exception set on exchange. Will fallback and grab caught |
| exceptions (`Exchange.EXCEPTION_CAUGHT`) if the Exchange has any. |
| |
| |date:_command_ |Date |evaluates to a Date object. |
| Supported commands are: *now* for current timestamp, *in.header.xxx* or |
| *header.xxx* to use the Date object header with the key xxx. |
| *exchangeProperty.xxx* to use the Date object in the exchange property with the key xxx. |
| *file* for the last modified timestamp of the file (available with a File consumer). |
| Command accepts offsets such as: *now-24h* or *in.header.xxx+1h* or even *now+1h30m-100*. |
| |
| |date:_command:pattern_ |String |Date formatting using `java.text.SimpleDataFormat` patterns. |
| |
| |date-with-timezone:_command:timezone:pattern_ |String |Date formatting using `java.text.SimpleDataFormat` timezones and patterns. |
| |
| |bean:_bean expression_ |Object |Invoking a bean expression using the xref:components::bean-component.adoc[Bean] language. |
| Specifying a method name you must use dot as separator. We also support |
| the ?method=methodname syntax that is used by the xref:components::bean-component.adoc[Bean] |
| component. |
| |
| |`properties:key:default` |String |Lookup a property with the given key. If the key does |
| not exists or has no value, then an optional default value can be |
| specified. |
| |
| |routeId |String |Returns the id of the current route the |
| Exchange is being routed. |
| |
| |stepId |String |Returns the id of the current step the |
| Exchange is being routed. |
| |
| |threadName |String |Returns the name of the current thread. Can be used for |
| logging purpose. |
| |
| |ref:xxx |Object |To lookup a bean from the Registry with |
| the given id. |
| |
| |type:name.field |Object |To refer to a type or field by its FQN name. 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` |
| |
| |null |null |represents a *null* |
| |
| |random_(value)_ |Integer |returns a random Integer between 0 (included) and _value_ |
| (excluded) |
| |
| |random_(min,max)_ |Integer |returns a random Integer between _min_ (included) and |
| _max_ (excluded) |
| |
| |collate(group) |List |The collate function iterates the message body and groups |
| the data into sub lists of specified size. This can be used with the |
| Splitter EIP to split a message body and group/batch |
| the splitted sub message into a group of N sub lists. This method works |
| similar to the collate method in Groovy. |
| |
| |skip(number) |Iterator |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 items. |
| |
| |messageHistory |String |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. |
| |
| |messageHistory(false) |String |As messageHistory but without the exchange details (only |
| includes the route strack-trace). This can be used if you do not want to |
| log sensitive data from the message itself. |
| |======================================================================= |
| |
| == OGNL expression support |
| |
| INFO:Camel's OGNL support is for invoking methods only. You cannot access |
| fields. Camel support accessing the length field of Java arrays. |
| |
| |
| The xref:simple-language.adoc[Simple] and xref:simple-language.adoc[Bean] language now |
| supports a Camel OGNL notation for invoking beans in a chain like |
| fashion. Suppose the Message IN body contains a POJO which has a `getAddress()` |
| method. |
| |
| Then you can use Camel OGNL notation to access the address object: |
| |
| [source,java] |
| -------------------------------- |
| simple("${body.address}") |
| simple("${body.address.street}") |
| simple("${body.address.zip}") |
| -------------------------------- |
| |
| Camel understands the shorthand names for getters, but you can invoke |
| any method or use the real name such as: |
| |
| [source,java] |
| -------------------------------------- |
| simple("${body.address}") |
| simple("${body.getAddress.getStreet}") |
| simple("${body.address.getZip}") |
| simple("${body.doSomething}") |
| -------------------------------------- |
| |
| You can also use the null safe operator (`?.`) to avoid NPE if for |
| example the body does NOT have an address |
| |
| [source,java] |
| ---------------------------------- |
| simple("${body?.address?.street}") |
| ---------------------------------- |
| |
| It is also possible to index in `Map` or `List` types, so you can do: |
| |
| [source,java] |
| --------------------------- |
| simple("${body[foo].name}") |
| --------------------------- |
| |
| To assume the body is `Map` based and lookup the value with `foo` as |
| key, and invoke the `getName` method on that value. |
| |
| If the key has space, then you *must* enclose the key with quotes, for |
| example 'foo bar': |
| |
| [source,java] |
| --------------------------------- |
| simple("${body['foo bar'].name}") |
| --------------------------------- |
| |
| You can access the `Map` or `List` objects directly using their key name |
| (with or without dots) : |
| |
| [source,java] |
| ------------------------------ |
| simple("${body[foo]}") |
| simple("${body[this.is.foo]}") |
| ------------------------------ |
| |
| Suppose there was no value with the key `foo` then you can use the null |
| safe operator to avoid the NPE as shown: |
| |
| [source,java] |
| ---------------------------- |
| simple("${body[foo]?.name}") |
| ---------------------------- |
| |
| You can also access `List` types, for example to get lines from the |
| address you can do: |
| |
| [source,java] |
| ---------------------------------- |
| simple("${body.address.lines[0]}") |
| simple("${body.address.lines[1]}") |
| simple("${body.address.lines[2]}") |
| ---------------------------------- |
| |
| There is a special `last` keyword which can be used to get the last |
| value from a list. |
| |
| [source,java] |
| ------------------------------------- |
| simple("${body.address.lines[last]}") |
| ------------------------------------- |
| |
| And to get the 2nd last you can subtract a number, so we can use |
| `last-1` to indicate this: |
| |
| [source,java] |
| --------------------------------------- |
| simple("${body.address.lines[last-1]}") |
| --------------------------------------- |
| |
| And the 3rd last is of course: |
| |
| [source,java] |
| --------------------------------------- |
| simple("${body.address.lines[last-2]}") |
| --------------------------------------- |
| |
| And you can call the size method on the list with |
| |
| [source,java] |
| ------------------------------------ |
| simple("${body.address.lines.size}") |
| ------------------------------------ |
| |
| Camel supports the length field for Java arrays as well, eg: |
| |
| [source,java] |
| --------------------------------------------------- |
| String[] lines = new String[]{"foo", "bar", "cat"}; |
| exchange.getIn().setBody(lines); |
| |
| simple("There are ${body.length} lines") |
| --------------------------------------------------- |
| |
| And yes you can combine this with the operator support as shown below: |
| |
| [source,java] |
| ------------------------------------ |
| simple("${body.address.zip} > 1000") |
| ------------------------------------ |
| |
| == Operator support |
| |
| The parser is limited to only support a single operator. |
| |
| To enable it the left value must be enclosed in $\{ }. The syntax is: |
| |
| [source] |
| -------------------------- |
| ${leftValue} OP rightValue |
| -------------------------- |
| |
| Where the `rightValue` can be a String literal enclosed in `' '`, |
| `null`, a constant value or another expression enclosed in $\{ }. |
| |
| IMPORTANT: There *must* be spaces around the operator. |
| |
| Camel will automatically type convert the rightValue type to the |
| leftValue type, so it is able to eg. convert a string into a numeric so |
| you can use > comparison for numeric values. |
| |
| The following operators are supported: |
| |
| [width="100%",cols="50%,50%",options="header",] |
| |=== |
| |Operator |Description |
| |
| |== |equals |
| |
| |=~ |equals ignore case (will ignore case when comparing String values) |
| |
| |> |greater than |
| |
| |>= |greater than or equals |
| |
| |< |less than |
| |
| |<= |less than or equals |
| |
| |!=~ |not equals |
| |
| |!=~ |not equals ignore case (will ignore case when comparing String values) |
| |
| |contains |For testing if contains in a string based value |
| |
| |!contains |For testing if not contains in a string based value |
| |
| |~~ |For testing if contains by ignoring case sensitivity in a string based value |
| |
| |!~~ |For testing if not contains by ignoring case sensitivity in a string based value |
| |
| |regex |For matching against a given regular expression pattern defined as a |
| String value |
| |
| |!regex |For not matching against a given regular expression pattern defined as a |
| String value |
| |
| |in |For matching if in a set of values, each element must be separated by |
| comma. If you want to include an empty value, then it must be defined using double comma, eg ',,bronze,silver,gold', which |
| is a set of four values with an empty value and then the three medals. |
| |
| |!in |For matching if not in a set of values, each element must be separated |
| by comma. If you want to include an empty value, then it must be defined using double comma, eg ',,bronze,silver,gold', which |
| is a set of four values with an empty value and then the three medals. |
| |
| |is |For matching if the left hand side type is an instanceof the value. |
| |
| |!is |For matching if the left hand side type is not an instanceof the value. |
| |
| |range |For matching if the left hand side is within a range of values defined |
| as numbers: `from..to`.. |
| |
| |!range |For matching if the left hand side is not within a range of values |
| defined as numbers: `from..to`. . |
| |
| |startsWith |For testing if the left hand side string starts |
| with the right hand string. |
| |
| |endsWith |For testing if the left hand side string ends with |
| the right hand string. |
| |=== |
| |
| And the following unary operators can be used: |
| |
| [width="100%",cols="50%,50%",options="header",] |
| |=== |
| |Operator |Description |
| |
| |++ |To increment a number by one. The left hand side must be a |
| function, otherwise parsed as literal. |
| |
| |-- |To decrement a number by one. The left hand side must be a |
| function, otherwise parsed as literal. |
| |
| |\ |To escape a value, eg \$, to indicate a $ sign. |
| Special: Use \n for new line, \t for tab, and \r for carriage return. |
| *Notice:* Escaping is *not* supported using the |
| xref:file-language.adoc[File Language]. *Notice:* The escape character is not supported, use the |
| following three special escaping instead. |
| |
| |\n |To use newline character. |
| |
| |\t |To use tab character. |
| |
| |\r |To use carriage return character. |
| |
| |\} |To use the } character as text |
| |=== |
| |
| And the following logical operators can be used to group expressions: |
| |
| [width="100%",cols="50%,50%",options="header",] |
| |=== |
| |Operator |Description |
| |
| |&& |The logical and operator is used to group two expressions. |
| |
| | \|\| |The logical or operator is used to group two expressions. |
| |=== |
| |
| The syntax for AND is: |
| |
| [source] |
| ---------------------------------------------------------- |
| ${leftValue} OP rightValue && ${leftValue} OP rightValue |
| ---------------------------------------------------------- |
| |
| And the syntax for OR is: |
| |
| [source] |
| --------------------------------------------------------- |
| ${leftValue} OP rightValue || ${leftValue} OP rightValue |
| --------------------------------------------------------- |
| |
| Some examples: |
| |
| [source,java] |
| ---- |
| // exact equals match |
| simple("${in.header.foo} == 'foo'") |
| |
| // ignore case when comparing, so if the header has value FOO this will match |
| simple("${in.header.foo} =~ 'foo'") |
| |
| // here Camel will type convert '100' into the type of in.header.bar and if it is an Integer '100' will also be converter to an Integer |
| simple("${in.header.bar} == '100'") |
| |
| simple("${in.header.bar} == 100") |
| |
| // 100 will be converter to the type of in.header.bar so we can do > comparison |
| simple("${in.header.bar} > 100") |
| ---- |
| |
| === Comparing with different types |
| |
| When you compare with different types such as String and int, then you |
| have to take a bit care. Camel will use the type from the left hand side |
| as 1st priority. And fallback to the right hand side type if both values |
| couldn't be compared based on that type. + |
| This means you can flip the values to enforce a specific type. Suppose |
| the bar value above is a String. Then you can flip the equation: |
| |
| [source,java] |
| ---- |
| simple("100 < ${in.header.bar}") |
| ---- |
| |
| which then ensures the int type is used as 1st priority. |
| |
| This may change in the future if the Camel team improves the binary |
| comparison operations to prefer numeric types over String based. It's |
| most often the String type which causes problem when comparing with |
| numbers. |
| |
| [source,java] |
| ---- |
| // testing for null |
| simple("${in.header.baz} == null") |
| |
| // testing for not null |
| simple("${in.header.baz} != null") |
| ---- |
| |
| And a bit more advanced example where the right value is another |
| expression |
| |
| [source,java] |
| ---- |
| simple("${in.header.date} == ${date:now:yyyyMMdd}") |
| |
| simple("${in.header.type} == ${bean:orderService?method=getOrderType}") |
| ---- |
| |
| And an example with contains, testing if the title contains the word |
| Camel |
| |
| [source,java] |
| ---- |
| simple("${in.header.title} contains 'Camel'") |
| ---- |
| |
| And an example with regex, testing if the number header is a 4 digit |
| value: |
| |
| [source,java] |
| ---- |
| simple("${in.header.number} regex '\\d{4}'") |
| ---- |
| |
| And finally an example if the header equals any of the values in the |
| list. Each element must be separated by comma, and no space around. + |
| This also works for numbers etc, as Camel will convert each element |
| into the type of the left hand side. |
| |
| [source,java] |
| ---- |
| simple("${in.header.type} in 'gold,silver'") |
| ---- |
| |
| And for all the last 3 we also support the negate test using not: |
| |
| [source,java] |
| ---- |
| simple("${in.header.type} !in 'gold,silver'") |
| ---- |
| |
| And you can test if the type is a certain instance, eg for instance a |
| String |
| |
| [source,java] |
| ---- |
| simple("${in.header.type} is 'java.lang.String'") |
| ---- |
| |
| We have added a shorthand for all `java.lang` types so you can write it |
| as: |
| |
| [source,java] |
| ---- |
| simple("${in.header.type} is 'String'") |
| ---- |
| |
| Ranges are also supported. The range interval requires numbers and both |
| from and end are inclusive. For instance to test whether a value is |
| between 100 and 199: |
| |
| [source,java] |
| ---- |
| simple("${in.header.number} range 100..199") |
| ---- |
| |
| Notice we use `..` in the range without spaces. It is based on the same |
| syntax as Groovy. |
| |
| From *Camel 2.9* onwards the range value must be in single quotes |
| |
| [source,java] |
| ---- |
| simple("${in.header.number} range '100..199'") |
| ---- |
| |
| === Using Spring XML |
| |
| As the Spring XML does not have all the power as the Java DSL with all |
| its various builder methods, you have to resort to use some other |
| languages for testing with simple operators. Now you can do this with the simple |
| language. In the sample below we want to test if the header is a widget |
| order: |
| |
| [source,xml] |
| ---- |
| <from uri="seda:orders"> |
| <filter> |
| <simple>${in.header.type} == 'widget'</simple> |
| <to uri="bean:orderService?method=handleWidget"/> |
| </filter> |
| </from> |
| ---- |
| |
| == Using and / or |
| |
| If you have two expressions you can combine them with the `&&` or `||` |
| operator. |
| |
| For instance: |
| |
| [source,java] |
| ----- |
| simple("${in.header.title} contains 'Camel' && ${in.header.type'} == 'gold'") |
| ----- |
| |
| And of course the `||` is also supported. The sample would be: |
| |
| [source,java] |
| ----- |
| simple("${in.header.title} contains 'Camel' || ${in.header.type'} == 'gold'") |
| ----- |
| |
| *Notice:* Currently `&&` or `||` can only be used *once* in a simple |
| language expression. This might change in the future. + |
| So you *cannot* do: |
| |
| [source,java] |
| ----- |
| simple("${in.header.title} contains 'Camel' && ${in.header.type'} == 'gold' && ${in.header.number} range 100..200") |
| ----- |
| |
| |
| == Samples |
| |
| In the Spring XML sample below we filter based on a header value: |
| |
| [source,xml] |
| -------------------------------------------- |
| <from uri="seda:orders"> |
| <filter> |
| <simple>${in.header.foo}</simple> |
| <to uri="mock:fooOrders"/> |
| </filter> |
| </from> |
| -------------------------------------------- |
| |
| The Simple language can be used for the predicate test above in the |
| Message Filter pattern, where we test if the |
| in message has a `foo` header (a header with the key `foo` exists). If |
| the expression evaluates to *true* then the message is routed to the |
| `mock:fooOrders` endpoint, otherwise the message is dropped. |
| |
| The same example in Java DSL: |
| |
| [source,java] |
| ---- |
| from("seda:orders") |
| .filter().simple("${in.header.foo}") |
| .to("seda:fooOrders"); |
| ---- |
| |
| You can also use the simple language for simple text concatenations such |
| as: |
| |
| [source,java] |
| ---- |
| from("direct:hello") |
| .transform().simple("Hello ${in.header.user} how are you?") |
| .to("mock:reply"); |
| ---- |
| |
| Notice that we must use $\{ } placeholders in the expression now to |
| allow Camel to parse it correctly. |
| |
| And this sample uses the date command to output current date. |
| |
| [source,java] |
| ---- |
| from("direct:hello") |
| .transform().simple("The today is ${date:now:yyyyMMdd} and it is a great day.") |
| .to("mock:reply"); |
| ---- |
| |
| And in the sample below we invoke the bean language to invoke a method |
| on a bean to be included in the returned string: |
| |
| [source,java] |
| ---- |
| from("direct:order") |
| .transform().simple("OrderId: ${bean:orderIdGenerator}") |
| .to("mock:reply"); |
| ---- |
| |
| Where `orderIdGenerator` is the id of the bean registered in the |
| Registry. If using Spring then it is the Spring bean |
| id. |
| |
| If we want to declare which method to invoke on the order id generator |
| bean we must prepend `.method name` such as below where we invoke the |
| `generateId` method. |
| |
| [source,java] |
| ---- |
| from("direct:order") |
| .transform().simple("OrderId: ${bean:orderIdGenerator.generateId}") |
| .to("mock:reply"); |
| ---- |
| |
| We can use the `?method=methodname` option that we are familiar with the |
| xref:components::bean-component.adoc[Bean] component itself: |
| |
| [source,java] |
| ---- |
| from("direct:order") |
| .transform().simple("OrderId: ${bean:orderIdGenerator?method=generateId}") |
| .to("mock:reply"); |
| ---- |
| |
| You can also convert the body to a given |
| type, for example to ensure that it is a String you can do: |
| |
| [source,xml] |
| ---- |
| <transform> |
| <simple>Hello ${bodyAs(String)} how are you?</simple> |
| </transform> |
| ---- |
| |
| There are a few types which have a shorthand notation, so we can use |
| `String` instead of `java.lang.String`. These are: |
| `byte[], String, Integer, Long`. All other types must use their FQN |
| name, e.g. `org.w3c.dom.Document`. |
| |
| It is also possible to lookup a value from a header `Map`: |
| |
| [source,xml] |
| ---- |
| <transform> |
| <simple>The gold value is ${header.type[gold]}</simple> |
| </transform> |
| ---- |
| |
| In the code above we lookup the header with name `type` and regard it as |
| a `java.util.Map` and we then lookup with the key `gold` and return the |
| value. If the header is not convertible to Map an exception is thrown. If the |
| header with name `type` does not exist `null` is returned. |
| |
| You can nest functions, such as shown below: |
| |
| [source,xml] |
| ---- |
| <setHeader name="myHeader"> |
| <simple>${properties:${header.someKey}}</simple> |
| </setHeader> |
| ---- |
| |
| == Referring to constants or enums |
| |
| Suppose you have an enum for customers |
| |
| And in a Content Based Router we can use |
| the xref:simple-language.adoc[Simple] language to refer to this enum, to check |
| the message which enum it matches. |
| |
| == Using new lines or tabs in XML DSLs |
| |
| It is easier to specify new lines or tabs in |
| XML DSLs as you can escape the value now |
| |
| [source,xml] |
| ---- |
| <transform> |
| <simple>The following text\nis on a new line</simple> |
| </transform> |
| ---- |
| |
| == Leading and trailing whitespace handling |
| |
| The trim attribute of the expression can be |
| used to control whether the leading and trailing whitespace characters |
| are removed or preserved. The default value is true, which removes the |
| whitespace characters. |
| |
| [source,xml] |
| ---- |
| <setBody> |
| <simple trim="false">You get some trailing whitespace characters. </simple> |
| </setBody> |
| ---- |
| |
| == Setting result type |
| |
| You can now provide a result type to the xref:simple-language.adoc[Simple] |
| expression, which means the result of the evaluation will be converted |
| to the desired type. This is most usable to define types such as |
| booleans, integers, etc. |
| |
| For example to set a header as a boolean type you can do: |
| |
| [source,java] |
| ---- |
| .setHeader("cool", simple("true", Boolean.class)) |
| ---- |
| |
| And in XML DSL |
| |
| [source,xml] |
| ---- |
| <setHeader name="cool"> |
| <!-- use resultType to indicate that the type should be a java.lang.Boolean --> |
| <simple resultType="java.lang.Boolean">true</simple> |
| </setHeader> |
| ---- |
| |
| == Loading script from external resource |
| |
| You can externalize the script and have Camel load it from a resource |
| such as `"classpath:"`, `"file:"`, or `"http:"`. + |
| This is done using the following syntax: `"resource:scheme:location"`, |
| eg to refer to a file on the classpath you can do: |
| |
| [source,java] |
| ---- |
| .setHeader("myHeader").simple("resource:classpath:mysimple.txt") |
| ---- |
| |
| == Setting Spring beans to Exchange properties |
| |
| You can set a spring bean into an exchange property as shown below: |
| |
| [source,xml] |
| ---- |
| <bean id="myBeanId" class="my.package.MyCustomClass" /> |
| ... |
| <route> |
| ... |
| <setProperty name="monitoring.message"> |
| <simple>ref:myBeanId</simple> |
| </setProperty> |
| ... |
| </route> |
| ---- |
| |