Before you can use a particular expression language, you must ensure that the required JAR files are available on the classpath. If the language you want to use is not included in the Apache Camel core, you must add the relevant JARs to your classpath.
If you are using the Maven build system, you can modify the build-time classpath simply by adding the relevant dependency to your POM file. For example, if you want to use the Ruby language, add the following dependency to your POM file:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-script</artifactId> <!-- Use the same version as your Camel core version --> <version>${camel.version}</version> </dependency>
If you are going to deploy your application in a Fuse ESB OSGi container, you also
need to ensure that the relevant language features are installed (features are named
after the corresponding Maven artifact). For example, to use the Groovy language in
the OSGi container, you must first install the camel-groovy
feature by
entering the following OSGi console command:
karaf@root> features:install camel-groovy
As shown in Table 1.1, there are several different syntaxes for invoking an expression language, depending on the context in which it is used. You can invoke an expression language:
Most of the languages define a static method that can be used in
any context where an
org.apache.camel.Expression
type or an
org.apache.camel.Predicate
type is expected. The static method
takes a string expression (or predicate) as its argument and returns an
Expression
object (which is usually also a Predicate
object).
For example, to implement a content-based router that processes messages in XML
format, you could route messages based on the value of the
/order/address/countryCode
element, as follows:
from("SourceURL
") .choice .when(xpath("/order/address/countryCode = 'us'")) .to("file://countries/us/") .when(xpath("/order/address/countryCode = 'uk'")) .to("file://countries/uk/") .otherwise() .to("file://countries/other/") .to("TargetURL
");
The Java fluent DSL supports another style of invoking expression languages.
Instead of providing the expression as an argument to an Enterprise Integration
Pattern (EIP), you can provide the expression as a sub-clause of the DSL command.
For example, instead of invoking an XPath expression as
filter(xpath("
, you can
invoke the expression as,
Expression
"))filter().xpath("
.Expression
")
For example, the preceding content-based router can be re-implemented in this style of invocation, as follows:
from("SourceURL
") .choice .when().xpath("/order/address/countryCode = 'us'") .to("file://countries/us/") .when().xpath("/order/address/countryCode = 'uk'") .to("file://countries/uk/") .otherwise() .to("file://countries/other/") .to("TargetURL
");
You can also invoke an expression language in XML, by putting the expression string inside the relevant XML element.
For example, the XML element for invoking XPath in XML is xpath
(which belongs to the standard Apache Camel namespace). You can use XPath expressions in
a XML DSL content-based router, as follows:
<from uri="file://input/orders"/> <choice> <when> <xpath>/order/address/countryCode = 'us'</xpath> <to uri="file://countries/us/"/> </when> <when> <xpath>/order/address/countryCode = 'uk'</xpath> <to uri="file://countries/uk/"/> </when> <otherwise> <to uri="file://countries/other/"/> </otherwise> </choice>
Alternatively, you can specify a language expression using the
language
element, where you specify the name of the language in the
language
attribute. For example, you can define an XPath expression
using the language
element as follows:
<language language="xpath">/order/address/countryCode = 'us'</language>
Language annotations are used in the context of bean integration (see Bean Integration in Implementing Enterprise Integration Patterns). The annotations provide a convenient way of extracting information from a message or header and then injecting the extracted data into a bean's method parameters.
For example, consider the bean, myBeanProc
, which is invoked as a
predicate of the filter()
EIP. If the bean's
checkCredentials
method returns true
, the message is
allowed to proceed; but if the method returns false
, the message is
blocked by the filter. The filter pattern is implemented as follows:
// Java MyBeanProcessor myBeanProc = new MyBeanProcessor(); from("SourceURL
") .filter().method(myBeanProc, "checkCredentials") .to("TargetURL
");
The implementation of the MyBeanProcessor
class exploits the
@XPath
annotation to extract the username
and
password
from the underlying XML message, as follows:
// Java import org.apache.camel.language.XPath; public class MyBeanProcessor { boolean void checkCredentials( @XPath("/credentials/username/text()") String user, @XPath("/credentials/password/text()") String pass ) { // Check the user/pass credentials... ... } }
The @XPath
annotation is placed just before the parameter into which
it gets injected. Notice how the XPath expression explicitly
selects the text node, by appending /text()
to the path, which ensures
that just the content of the element is selected, not the enclosing tags.