Встроенные операторы
Simple поддерживает операторы, которые используются в предикатах для оценки того, является ли условие true или false.
Операторы Simple требуют, чтобы левое значение было заключено в ${ }. Синтаксис:
${leftValue} OP rightValue
Где rightValue может быть строковым литералом, заключенным в ' ', null, константным значением или другим выражением, заключенным в ${ }.
Вокруг оператора должны быть пробелы.
Тип rightValue автоматически преобразуется в тип leftValue, поэтому, например, строка может быть преобразована в число, чтобы можно было использовать сравнение > для числовых значений.
Операторы сравнения
Поддерживаются следующие операторы сравнения:
| Оператор | Описание |
|---|---|
== | равно |
=~ | равно без учета регистра (игнорирует регистр при сравнении строковых значений) |
> | больше |
>= | больше или равно |
< | меньше |
<= | меньше или равно |
!= | не равно |
!=~ | не равно без учета регистра (игнорирует регистр при сравнении строковых значений) |
~~ | Проверяет содержит ли строка подстроку (без учета регистра) |
!~~ | Проверяет то, что строка не содержит подстроку (без учета регистра) |
contains | Проверяет содержит ли строка подстроку |
!contains | Проверяет то, что строка не содержит подстроку |
endsWith | Проверяет заканчивается ли строка слева строкой справа |
!endsWith | Проверяет то, что строка слева не заканчивается строкой справа |
in | Проверяет вхождение в набор значений, элементы которого разделены запятыми. |
!in | Проверяет отсутствие в наборе значений, элементы которого разделены запятыми. |
is | Проверяет является ли тип левой части экземпляром значения. |
!is | Проверяет то, что тип левой части не является экземпляром значения. |
range | Проверяет находится ли левая часть в диапазоне значений, определенных как числа: from..to. |
!range | проверяет то, что левая часть не находится в диапазоне значений, определенных как числа: from..to. |
regex | Проверяет соответствие заданному шаблону регулярного выражения, определенному как строковое значение. |
!regex | Проверяет отсутствие соответствия заданному шаблону регулярного выражения, определенному как строковое значение. |
startsWith | Проверяет начинается ли строка слева со строки справа |
!startsWith | Проверяет то, что строка слева не начинается со строки справа |
Числовые операторы
В Simple можно использовать следующие числовые операторы:
| Оператор | Описание |
|---|---|
++ | Увеличивает число на единицу. Левая часть должна быть функцией. |
-- | Уменьшает число на единицу. Левая часть должна быть функцией. |
Эти операторы являются унарными и должны примыкать непосредственно к функции:
${function}OP
Например, для увеличения результата функции:
simple("${header.myNumber}++ > 10");
И то же самое для уменьшения:
simple("${header.myNumber}-- < 10");
Условные операторы
В Simple можно использовать следующие условные операторы:
| Оператор | Описание |
|---|---|
? : | Тернарный оператор вычисляет условие и возвращает значение на основе результата. Если условие истинно, возвращается первое значение (после ?); в противном случае возвращается второе значение (после :). Вокруг ? и : должны быть пробелы. Это похоже на тернарный оператор в Java. |
?: | Оператор elvis возвращает левую часть, если она имеет логическое значение true, в противном случае возвращает правую часть. Это полезно для предоставления резервных значений, когда выражение может иметь значение с логическим значением false (например, null, false, 0, пустая/пустая строка). |
~> | Оператор цепочки используется в ситуациях, когда к значению нужно применить несколько вложенных функций, при этом не усложняя код. Значение в левой части вычисляется и устанавливается в качестве нового тела сообщения до вычисления функции в правой части. |
?~> | Оператор цепочки с нулевой безопасностью, где цепочка не продолжается, если функция вернула null. |
Тернарный оператор
Синтаксис тернарного оператора: ${leftValue} OP rightValue ? trueValue : falseValue
Например, следующий тернарный оператор вернет positive, если заголовок foo больше 0, в противном случае negative:
simple("${header.foo > 0 ? 'positive' : 'negative'}");
Тернарные операторы могут быть вложенными для обработки нескольких условий:
simple("${header.score >= 90 ? 'A' : ${header.score >= 80 ? 'B' : 'C'}}");
Оператор Elvis
Например, следующий оператор elvis вернет заголовок username, если он не равен null и не пуст, в противном случае будет возвращено значение по умолчанию Guest:
simple("${header.username} ?: 'Guest'");
Оператор chain
Синтаксис оператора chain (цепочки): ${leftValue} ~> ${rightValue}
Цепочек может быть любое количество: ${leftValue} ~> ${midValue} ~> ${midValue} ~> ${rightValue}
Например, если тело сообщения содержит Hello World, то следующее выражение вернет WORLD:
simple("${substringAfter('Hello')} ~> ${trim()} ~> ${uppercase()}");
Вариант null-safe (?~>) можно использовать для избежания NullPointerException, если нужно не продолжать цепочку, когда какая-то функция вернула null. Однако многие простые функции имеют встроенную защиту от NPE (NullPointerException), поэтому этот вариант необходим только в особых ситуациях.
Использование $param в качестве значения входного параметра
Оператор цепочки по умолчанию передает результаты через тело сообщения. Обычно это хорошо работает с большинством функций. Однако, когда вам нужен полный контроль, используйте $param в качестве параметра, который представляет переданное значение от предыдущей функции в цепочке.
Предположим, тело сообщения содержит " Hello World from the Center ", тогда следующая цепочка работает без дополнительных настроек:
simple("${trim()} ~> ${replace('Hello','Hi')} ~> ${split(' ')} ~> ${size()}");
А вот тот же пример, где мы явно используем $param в параметрах, где нам нужны входные данные:
simple("${trim()} ~> ${replace('Hello','Hi',$param)} ~> ${split($param,' ')} ~> ${size($param)}");
Логические операторы
Следующие логические операторы можно использовать для группировки выражений:
| Оператор | Описание |
|---|---|
&& | Оператор И используется для группировки двух выражений, если оба имеют значение true. |
|| | Оператор ИЛИ используется для группировки двух выражений, если хотя бы одно имеет значение true. |
Синтаксис для AND: ${leftValue} OP rightValue && ${leftValue} OP rightValue
Синтаксис для OR: ${leftValue} OP rightValue \|\| ${leftValue} OP rightValue
Объединения нескольких выражений
Если у вас есть два выражения, вы можете объединить их с помощью оператора && (и) или || (или).
simple("${header.title} contains 'Center' && ${header.type'} == 'gold'")
simple("${header.title} contains 'Center' || ${header.type'} == 'gold'")
Примеры:
// exact equals match
simple("${header.foo} == 'foo'")
// ignore case when comparing, so if the header has value FOO, this will match
simple("${header.foo} =~ 'foo'")
// here there will be type convert of '100' into the type of header.bar and if it is an Integer '100' will also be converter to an Integer
simple("${header.bar} == '100'")
simple("${header.bar} == 100")
// 100 will be converted to the type of header.bar, so we can do > comparison
simple("${header.bar} > 100")
// if the value of header.bar was 100, value returned will be 101. header.bar itself will not be changed.
simple("${header.bar}++")
Использование операторов с разными типами объектов Java
При сравнении с разными типами, такими как String и int, нужно быть внимательным. Тип левой части будет использоваться в качестве приоритетного и вернется к типу правой части, если оба значения не могут быть сравнены на основе этого типа. Это означает, что вы можете поменять местами значения, чтобы принудительно использовать определенный тип. Предположим, что значение bar выше является строкой.
Тогда вы можете изменить уравнение:
simple("100 < ${header.bar}")
что гарантирует, что тип int будет использоваться в качестве приоритетного.
И более сложный пример, где правильное значение является другим выражением:
simple("${header.date} == ${date:now:yyyyMMdd}")
simple("${header.type} == ${bean:orderService?method=getOrderType}")
И пример с contains, проверяющим, содержит ли заголовок title слово Center:
simple("${header.title} contains 'Center'")
И пример с regex, проверяющим, является ли заголовок number четырехзначным значением:
simple("${header.number} regex '\\d{4}'")
И, наконец, пример, где заголовок равен любому из значений в списке. Элементы должны быть разделены запятыми, без пробелов вокруг. Это также работает для чисел и т.д., так как каждый элемент преобразуется в тип левой части.
simple("${header.type} in 'gold,silver'")
И для всех трех последних тестов мы также поддерживаем отрицание с помощью not:
simple("${header.type} !in 'gold,silver'")
Вы можете проверить, является ли тип определенным экземпляром, например, экземпляром String:
simple("${header.type} is 'java.lang.String'")
Для всех типов java.lang можно применять сокращение, так что вы можете написать это как:
simple("${header.type} is 'String'")
Диапазоны также поддерживаются. Интервал диапазона требует чисел, и оба значения from и end включительно. Например, чтобы проверить, находится ли значение между 100 и 199:
simple("${header.number} range 100..199")
Обратите внимание, что .. используется в диапазоне без пробелов. Оно основано на том же синтаксисе, что и Groovy.
simple("${header.number} range '100..199'")
В приведенном ниже примере нужно проверить является ли заголовок заказом на виджет:
<from uri="seda:orders"/>
<filter>
<simple>${header.type} == 'widget'</simple>
<to uri="bean:orderService?method=handleWidget"/>
</filter>
</from>