The Mule Expression Language (MEL) is based on the MVFLEX Expression Language (MVEL; see http://mvel.codehaus.org/), a hybrid dynamic/statically typed language. We strongly recommend you get acquainted with MVEL by reading its online documentation (http://mvel.codehaus.org/Language+Guide+for+2.0). MEL itself is also extensively documented online (http://mng.bz/g8sM). This appendix is a quick reference guide to Mule-specific features of MEL. It also provides a quick overview on how to customize MEL to implement custom needs.
Mule binds custom objects, variables, and functions within the MEL context to facilitate accessing Mule resources, processing messages, and so on.
The four main context objects exposed by MEL are server, mule, app, and message. Additionally, payload is available as a shortcut to message.payload, flowVars and sessionVars are maps that give access to flow and session variables, and exception is bound if the current event carries an exception.
Before looking in detail at these context helpers, let’s take a quick peek at MVEL. Take a look at this sample script from MVEL’s documentation (http://mvel.codehaus.org/Sample+Scripts):
colors = {'red', 'green', 'blue'}; foreach (c : colors) { System.out.println(c + "!"); }
What should strike you is the following:
Of all the goodness MVEL provides, its unified support for property navigation (including null-safe navigation) is one of the most convenient features. For example, in the following snippet,
user.name
name can refer to either a getName accessor on a user JavaBean or the name key in a user hashmap.
Without further ado, let’s go through the context objects Mule gives you access to.
There are four context objects available: server, mule, app, and message. We’ll review them in detail.
The server context gives access to the properties of the hardware, operating system, virtual machine, user and network interface, and time-related functions. See table A.1.
Name |
Description |
---|---|
dateTime | Current system time via the org.mule.el.datetime.DateTime utility object, whose complete documentation is available online (http://mng.bz/LT3q). This object supports date and time zone manipulation methods as well as comparison and formatting ones. |
fileSeparator | Character that separates components of a file path (/ on Unix and on Windows). |
host | Fully qualified domain name of the server. |
ip | The IP address of the server. |
locale | Default locale (of type java.util.Locale) of the JRE (can access server.locale.language and server.locale.country). |
javaVersion | JRE version. |
javaVendor | JRE vendor name. |
nanoTime | Current system time in nanoseconds. |
osName | Operating system name. |
osArch | Operating system architecture. |
osVersion | Operating system version. |
systemProperties | Map of Java system properties. |
timeZone | Default TimeZone (java.util.TimeZone) of the JRE. |
tmpDir | Temporary directory for use by the JRE. |
userName | Username. |
userHome | User home directory. |
userDir | User working directory. |
The mule context allows you to retrieve the properties of the Mule instance, which is either the standalone broker instance or the instance that’s embedded in an application (for example, in a web application). See table A.2.
Name |
Description |
---|---|
clusterId | Cluster ID |
home | Filesystem path to the home directory of the Mule server installation |
nodeId | Cluster node ID |
version | Mule version |
The app context exposes the properties of the Mule application that the current expression is evaluated into. See table A.3.
Name |
Description |
---|---|
encoding | Application default encoding (read-only) |
name | Application name (read-only) |
standalone | True if Mule is running standalone (read-only) |
workdir | Application work directory (read-only) |
registry | Map representing the Mule registry (read/write) |
The message context gives access to the payload, attachments, and properties of the Mule message that’s under processing. This context isn’t available if the expression is evaluated outside the context of a Mule event. See table A.4.
Name |
Permissions |
---|---|
id | Read-only |
rootId | Read-only |
correlationId | Read-only |
correlationSequence | Read-only |
correlationGroupSize | Read-only |
replyTo | Read/write |
dataType | Read-only |
payload | Read/write |
inboundProperties | Map (read-only) |
inboundAttachments | Map (read-only) |
outboundProperties | Map (read/write) |
outboundAttachments | Map (read/write) |
Mule binds extra context entries that are similar to the objects we’ve just described but specific to the in-flight message flow and session variables (that is, respectively, invocation- and session-scoped message properties; refer to section 2.3.2 for more on this).
These entries are as follows:
If, for any reason, you don’t want MEL to bind all flow variables as top-level variables in the evaluation context, add the following configuration element to your Mule configuration:
<configuration> <expression-language autoResolveVariables="false" /> <configuration>
Mule binds helper functions in the MEL context. These functions simplify using XPath and regular expressions.
Be aware that the xpath function returns DOM nodes (elements and attributes, but also node lists). If you want to get the node string content instead, you’ll need to specifically get it; for example, like this for an attribute:
xpath('/book/@id').value
Or like this for a text element:
path('/book/name').text
The regex function returns null if no match has been found and an array of results if more than one match was found. Otherwise, it returns the single matching value.
MEL automatically imports the following Java classes, so you can use them without using their fully qualified names:
MEL supports multiple configuration-based customizations. For example, it is possible to do the following:
Take a look at the following Mule configuration fragment:
<configuration> <expression-language autoResolveVariables="false"> <import class="org.mule.util.StringUtils" /> <import name="rsu" class="org.apache.commons.lang.RandomStringUtils" /> <alias name="appName" expression="app.name" /> <global-functions> def reversePayload() { StringUtils.reverse(payload) } def randomString(size) { rsu.randomAlphanumeric(size) } </global-functions> </expression-language> </configuration>
The noticeable aspects of this configuration are
Optionally, you can also specify a file attribute on the global-functions configuration element should you want to store your custom MEL functions in an external file. With this configuration in place, it’s possible to use the declared global functions and variables, as shown in the following example:
<set-property propertyName="random-app-property" value="#[appName + ':' + randomString(20)]" /> <set-payload value="#[reversePayload()]" />
It’s also possible to programmatically extend MEL by coding custom language extensions. This is beyond the scope of this appendix, but if you want to get started with that approach, take a look at org.mule.module.xml.el.XMLExpressionLanguageExtension from the mule-module-xml to have an idea of how to achieve this. Also take a look at META-INF/services/org/mule/config/registry-bootstrap.properties to see how the XMLExpression-LanguageExtension is globally registered so that it can be used throughout Mule.