condition ? true-branch : false-branch
MidPoint Expression Language Tips and Recommendations
|
MidPoint Expression Language feature
This page describes configuration of MidPoint Expression Language midPoint feature.
Please see the feature page for more details.
|
MidPoint Expression Language (MEL) is an expression language, designed to support customization of midPoint functionality in an easy-to-use and secure way. This page lists miscellaneous tips and recommendations for writing MEL expressions.
Conditions
MEL as well as CEL are expression languages with distinct functional character.
There are no commands in such expression languages.
Every clause is an operator or a function.
Therefore, the classic if-then-else construct does not exist in a form of command.
Conditional operator (?:) is used instead.
Short MEL expressions are usually written on a single line. However, complicated expressions can be very long. The expression can be split to several lines in MEL. This can be used to the advantage, especially when the expression contains conditionals:
condition
? true-branch
: false-branch
While the practice of indenting the code can bring clarity, the indents are still considered just an ordinary white space and have no special semantic meaning. This can become slightly confusing especially when nested conditional operators are used.
condition-A
? condition-B
? true-branch-B
: false-branch-B
: false-branch-A
The CEL engine cannot compile such code. Nested conditionals have to be enclosed in parentheses:
condition-A
? ( condition-B
? true-branch-B
: false-branch-B
)
: false-branch-A
CEL conditionals tend to be quite strict. Strictly speaking, the conditional operator expects the same data types in both branches. This can be painful especially when strings are combined with polystrings:
fullName == null ? 'John Doe' : fullName
Such expression leads to an error, as the data types in the branches do not match.
While 'John Doe' is a string, the value of fullName variable is polystring.
Quick fix would be to explicitly convert polystring to string:
fullName == null ? 'John Doe' : stringify(fullName)
However, the best approach is to avoid using conditionals whenever possible.
For example, function default() provides very elegant way to specify default value:
default(fullName, 'John Doe')
The default() function takes care of everything, null checks, data conversion and all other details.
Formatting
Use format() function for advanced string formatting:
'%s:%s'.format([foo, bar])
When formatting timestamps, use specialized timestamp functions, such as format.strftime():
// Returns formatted time, e.g. `11/02/26 09:32:15`
format.strftime(ts, '%d/%m/%Y %H:%M:%S')
Overall, the format extension of MEL provides may useful functions for string formatting and parsing.
Single-Valued and Multi-Valued Data
CEL and therefore MEL makes a strict distinction between single-valued (scalar) and multi-valued (list/array) data. Functions often require multi-valued (list) arguments. Also, some functions return list values. Therefore, it is often necessary to convert single-valued and multi-valued (list) data.
Correct method to convert list (multi-valued data) to a single value is to use single() function:
single(['foo']) // Returns 'foo'
Primary purpose of single() function is conversion of list to single value.
Moreover, it does the conversion in a safe way.
Error is raised in case that the argument is a list with more than one value.
The single() function returns null value in a robust way, handling all the valid argument values such as empty list, null and empty optional.
On the other hand, other methods (such as x[0]) does not provide such robustness.
Correct method to convert single value to list (multi-valued data) is use of list() function:
list('foo') // Returns ['foo']
list(['foo']) // Returns ['foo']
The list() function always returns list.
If a single-valued (scalar_ argument is provided, it returns a single-element list containing that argument.
If a list is provided as argument, the same list is returned.
Hence, the list() function can be used to make sure that list is provided in context where list arguments are required.