This document explains how to use Mule Expression Language (MEL).
This guide is for designers of Mule applications, which are collections of flows. The building blocks of flows often use information about Mule messages and their environment to make decisions about routing, filtering, and other common tasks. The logic of these decisions often relies on evaluating expressions. MEL is a simple, powerful tool for formulating such expressions. All features of MEL can be used in XML application configuration files, and a few require additional Java programming. All MEL features are available within the visual interface provided by Mule Studio.
The Mule enterprise service bus provides loose coupling between applications or other entities, generically known as endpoints, by passing payloads between them as messages. Each step on the path from the entering endpoint to the exiting endpoint is a message processor. Mule Application Architecture explains this architecture and its components.
Mule Expression Language (MEL) supports the work of message processors by providing a means of accessing, manipulating, and using information from the message and its environment.
While MEL is new in Mule 3.3, Mule has supported expressions since Mule 2.1. Prior to Mule 3.3, expression evaluators provided this functionality. Each expression evaluator has its own rules and syntax. They remain in place and are fully supported. With one set of rules and syntax, MEL provides a uniform way to achieve all of the functionality of expression evaluators and introduces new features as well. |
In most cases, Mule expressions work within message processors to modify the way those processors do their main jobs (for example, routing, filtering). Here are the principal use cases:
You can also use MEL in place of a programming language like Ruby, JavaScript, or Groovy for simple scripts. MEL can access the message and its environment more conveniently than those languages can.
The Using MEL section provides examples that implement the above use cases.
The functions, Xpath and Regex, provide ways of extracting information that doesn’t already exist as a single value within the context. By default they work on the payload, but you can pass them different arguments explicitly. Details appear in the Functions section.
Once you learn MEL, you can use it for many tasks in numerous situations and places to facilitate your use of Mule.
A typical MEL expression combines one or more operands with zero or more operators in a Java-like syntax and returns the resulting value.
At the heart of MEL are property expressions of the form contextObject.property. These provide easy access to properties of the Mule message and its environment. For example, the expressionmessage.payload represents the payload property of the message context object. Its value is the message payload.
Java method invocations and assignments are the other common MEL expressions.
In most cases, a MEL expression stands alone as the value of a configuration property of a message processor. MEL evaluates the expression at runtime, and the message processor uses the result.
The syntax of a MEL program largely follows Java, but MEL implements dynamic typing by performing type coercion at runtime. Semicolons follow each statement except the last, whether the statements are on one line or separate lines. Return statements are usually unnecessary, because a MEL program returns the value of the last MEL statement executed.
MEL operators and basic operands are conventional and predictable (for example, 2 + 2 == 4 returnstrue). Property expressions provide convenient access to information from the message and its environment (for example, server.fileSeparator returns "/" if the application is running on a Linux server, and "\" on a Windows server.). The remainder of this section summarizes the most important elements of MEL syntax.
An operand can be a literal, a variable, or a MEL expression. The Literals section describes the kinds of literals you can use in MEL. The Maps, Lists, and Arrays section describes data structures that are especially useful as operands in MEL expressions. The Assignments section discusses variables. In addition to using Java-style variables, you can use flow variables and session variables, which have more Mule-centric scopes. The Context and Functions section explains how to use variables.
The MEL expressions that most commonly appear as operands are property expressions and method invocations.
The Context and Functions section describes the context objects and their properties. The syntax of a property expression is contextObject.property. This can appear as an operand in most MEL expressions, including on the left side of an assignment if the property is writable from MEL. You can use the same syntax to refer to the properties of a Java bean as you can with a context object.
MEL uses standard Java method invocation. You can provide a fully qualified class name or import a class and use the unqualified name. MEL automatically imports a number of Java classes (see Appendix: Automatically Imported Java Classes).
The following examples illustrate Java method calls.
message.payload.getName()
If payload is a Java object—for example, representing a person—this code invokes its getNamemethod. The value of the expression is the value that getName returns—presumably a string representing the person’s name.
java.lang.System.currentTimeMillis()
The value is the current time in milliseconds, as returned by Java. Because MEL automatically imports java.lang.System (see Appendix: Automatically Imported Java Classes), you can also write this as:
System.currentTimeMillis()
MEL operators follow standard Java syntax, but operands are always by value, not by reference. For example, "A" == 'A' evaluates to true, whereas the same expression evaluates to false in Java.
Symbol | Definition | Example/Value |
---|---|---|
+ | Plus. For numbers, the value is the sum of the values of the operands. For strings, the value is the string formed by concatenating the values of the operands. | 2 + 4 6 'fu' + 'bar' The String "fubar" |
- | Minus. The value is the value of the first operand minus the value of the second. | 2 - 4 -2 |
/ | Over. The value is the value of the first operand divided by the value of the second. | 2 / 4 0.5 |
* | Times. The value is the product of the values of the operands. | 2 * 4 8 |
% | Modulo. The value is the remainder after dividing the value of the first operand by the value of the second. | 9 % 4 1 |
Symbol | Definition | Example/Value |
---|---|---|
== | Equal. True if and only if (iff) the values of the operands are equal. | 'A' == 'A' true |
!= | Not equal. True iff the values of the operands are unequal. | 'A' != 'B' true |
> | Greater than. True iff the value on the left is greater than the value on the right. | 7 > 5 true |
< | Less than. True iff the value on the left is less than the value on the right | 5 < 5 false |
>= | Greater than or equal. True iff the value on the left is greater than or equal to the value on the right. | 5 >= 7 false |
<= | Less than or equal. True iff the value on the left is less than or equal to the value on the right. | 5 <= 5 true |
contains | Contains. True iff the string on the right is a substring of the string on the left. | 'fubar' contains 'bar' true |
is, instance of |
Is an instance of. True iff the object on the left is an instance of the class on the right. | 'fubar' is String true |
strsim | Degree of similarity. The value of the expression is a number between 0 and 1 representing the degree of similarity between the two string arguments. | 'foo' strsim 'foo' 1.0 ‘foobar’ strsim ‘foo’ 0.5 |
soundslike | Sounds like. True iff the two string arguments sound alike according to a Soundex comparison. | 'Robert' soundslike 'Rupert' true |
Symbol | Definition | Example/Value |
---|---|---|
and | Logical AND. True iff both operands are true. (Don’t use &&) | (a == b) and (c != d) true iff a =b and c ≠ d |
|| | Logical OR. True iff at least one operand is true. | true ||anything Always true |
or | Chained OR. Scans left to right and returns the value of the first non-empty item | false or '' or ' ' or 'dog' The String "dog" |
An assignment is a MEL expression consisting of an identifier representing a mutable object to the left of an equal sign and a MEL expression to the right of the equal sign. For example,
message.payload = 'fu'
sets the payload of the current message to the string "fu". The Context and Functions section describes which elements of the message and its environment you can set with a MEL assignment.
MEL determines types dynamically, so declaring the type of a variable is optional. For example if, with no prior declarations, you write
number = 1; number == '1'
MEL assigns the expression the value true.
You can cast values to specific types. For example if you write
number = (String)1; number is String
MEL returns the value true for this expression.
Literals in MEL can be strings, numbers, Boolean values, types, and nulls. The Maps, Lists, and Arrays section shows how you can provide data structures as literals as well.
Numeric literals are integers and floating point numbers, with the same ranges of values as the underlying Java system.
Integers are assumed to be decimal unless they begin with 0. An integer consisting of 0 followed by digits ranging from 0 to 7 is interpreted as octal. An integer starting with 0x followed by digits ranging from 0 to 9 or letters ranging from a to f is interpreted as hexadecimal. An integer ending in an uppercase I is interpreted as a BigInteger.
MEL recognizes floating point numbers by the presence of a decimal point. Floating point numbers can optionally have suffixes of d, f, or B to represent double, float, or BigDecimal.
The following are examples of numeric literals: 255, 0377, 0xff (all represent 255); 3.14159, 3.14159f, 3.14159265358979d (all represent pi).
Literals that include alphabetic characters are case sensitive.
String literals are sequences of characters enclosed in single quotes.
You cannot use double quotes to express String literals as you can in Java, because MEL expressions appear within double quotes in configuration files. |
Within String literals you can use the following escape sequences to represent non-printable characters, Unicode characters, and the escape character.
Escape Sequence | Represents |
---|---|
\ \ | \ |
\n | Newline character |
\r | Return character |
\xxx | ASCII character represented by the octal number xxx |
\uyyyy | Unicode character represented by the hexadecimal number yyyy |
Boolean literals are the values true and false. These are case sensitive.
A null literal takes the form null or nil. These are case sensitive.
You can refer to any Java class by its fully qualified name or if it is one of the classes in the appendix (Appendix: Automatically Imported Java Classes), by its unqualified name. References use the same dot notation as in Java, except that you must use $ rather than a dot to refer to a nested class.
Maps are important in MEL because much of the context you can work with comes in the form of maps.
MEL uses a convenient syntax for maps and other data structures. It begins with map literals, and there is also a convenient way to access items in maps.
MEL provides a streamlined way to access map data. The Accessing Map Data section explains this.
Rather than constructing a map with a new statement, and then using its put method to populate it, you can simply write the following:
[key1 : value1, key2 : value2, . . .]
and use this literal form wherever you would otherwise use a map by name, including as a method argument.
You can use similar literal forms for lists ({item1, item2, . . .}) and arrays ([item1, item2, . . .]).
Arrays in Java must specify the type of their contents, but in MEL they are untyped. MEL supplies the correct type when you use them – either by determining it at compile time or coercing the array to the correct type at run time.
MEL provides a simpler way to refer to map items than java.util.Map provides. For example, Mule associates a map containing properties set by the inbound endpoint processor with each message. You can refer to this map as message.inboundProperties.
For example, to retrieve the inbound property with key name foo, write'message.inboundProperties[foo]'.
If that property can be set (never the case with inbound properties, but true of some properties in other maps), you can write message.inboundProperties[foo] on the left side of an assignment. The Context and Functions section explains which items in the context can be set and which cannot. If you try to set a property that cannot be set, Mule indicates failure by throwingorg.mvel2.PropertyAccessException.
MEL provides a full range of Java control flow statements. The most useful for typical MEL expressions are conditional operands (often called ternary statements).
A conditional operand has the form condition ? true value, false value.
For example, x = (name == 'Smith' ? 'Smith', 'Unknown') sets the variable x to the string "Smith" if the value of name is "Smith" and to the string "Unknown" if the value of name is not "Smith".