Unified Expression Language (EL)
|
Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine |
Camunda 7 поддерживает Unified Expression Language (EL, "Унифицированный язык выражений"), описываемый стандартом Jakarta Expression Language 4.0 . Для этого она поддерживает кастомизированную версию open source реализации JUEL.
Отметим, что по сравнению с EL 4.0, эта реализация JUEL имеет следующие ограничения:
-
Инициализация коллекций напрямую внутри выражений (например,
${[1,2,3]}) НЕ поддерживается. -
Лямбда-выражения (например, инлайн функции
${((x,y)→x+y)(3,4)}) НЕ поддерживаются. -
Возможность ссылаться на статические поля (например,
${Boolean.TRUE}), статические функции (например,${Integer.parseInt("123")})и на enum-ы (например,${Thread.State.TERMINATED}) НЕ поддерживается. -
Оператор присвоения
(A=B), оператор строковой конкатенации(A+=B)и оператор точки с запятой(A ; B)НЕ поддерживаются.
Чтобы получить больше общей информации об использовании языка выражений, см. официальную документацию. Она предоставляет примеры, которые дают хороший обзор синтаксиса выражений.
В пределах Camunda 7 данный язык выражений может использоваться в самых азных обстоятельствах для вычисления небольших скриптовых выражений. Следующая таблица предоставляет обзор BPMN элементов, поддерживающих использование EL.
| BPMN элемент | Поддержка EL |
|---|---|
Язык выражений как код делегации |
|
Язык выражений как условное выражение |
|
Язык выражений внутри маппинга параметра |
|
Язык выражений как значение атрибута или элемента |
|
Язык выражений используется для определения приоритета джобы |
Использование языка выражений
Код делегации
Помимо Java кода, Camunda 7 также поддерживает вычисление выражений как кода делегации. Чтобы получить общую информацию по коду делегации, см. соответствующий раздел.
В настоящее время поддерживается два типа выражений: camunda:expression и camunda:delegateExpression.
Используя camunda:expression, можно вычислить выражение-значение или вызвать выражение-метод. Вы можете использовать специальные переменные, доступные внутри выражения или внутри Spring и CDI бинов. Чтобы получить больше информации о переменных и Spring, соответственно, а также о CDI бинах,
см. соответствующие разделы.
<process id="process">
<extensionElements>
<!-- execution listener which uses an expression to set a process variable -->
<camunda:executionListener event="start" expression="${execution.setVariable('test', 'foo')}" />
</extensionElements>
<!-- ... -->
<userTask id="userTask">
<extensionElements>
<!-- task listener which calls a method of a bean with current task as parameter -->
<camunda:taskListener event="complete" expression="${myBean.taskDone(task)}" />
</extensionElements>
</userTask>
<!-- ... -->
<!-- service task which evaluates an expression and saves it in a result variable -->
<serviceTask id="serviceTask"
camunda:expression="${myBean.ready}" camunda:resultVariable="myVar" />
<!-- ... -->
</process>
Атрибут camunda:delegateExpression используется для выражений, которые вычисляются в объект делегации. Этот объект делегации должен реализовывать либо интерфейс JavaDelegate, либо ActivityBehavior.
<!-- service task which calls a bean implementing the JavaDelegate interface -->
<serviceTask id="task1" camunda:delegateExpression="${myBean}" />
<!-- service task which calls a method which returns delegate object -->
<serviceTask id="task2" camunda:delegateExpression="${myBean.createDelegate()}" />
Условия
Язык выражений обычно используется с уловными потоками последовательностей или с условными событиями. Для условных потоков последовательностей должен использоваться элемент conditionExpression потока последовательности. Для условных событий должен использоваться элемент condition условного события. Оба элемента принадлежат к типу tFormalExpression. Текстовый контент элемента является выражением, которое требуется вычислить.
В пределах выражения доступны некоторые специальные переменные, дающие доступ к текущему контексту. Чтобы найти больше информации о доступных переменных, см. соответствующий раздел.
Следующий пример показывает, как использовать язык выражений в качестве условия для потока последовательности:
<sequenceFlow>
<conditionExpression xsi:type="tFormalExpression">
${test == 'foo'}
</conditionExpression>
</sequenceFlow>
Для понимания способа использования языка выражений на условных событиях см. следующий пример:
<conditionalEventDefinition>
<condition type="tFormalExpression">${var1 == 1}</condition>
</conditionalEventDefinition>
Параметры inputOutput
Используя элемент расширения Camunda inputOutput, вы можете осуществить маппинг inputParameter или outputParameter через язык выражений.
Внутри выражения доступны некоторые специальные переменные, которые дают доступ к текущему контексту. Чтобьы найти больше информации о доступных переменных, см. соответствующий раздел: переменные.
Следующий пример демонстрирует inputParameter, который использует язык выражений для вызова метода бина.
<serviceTask id="task" camunda:class="io.openbpm.bpm.example.SumDelegate">
<extensionElements>
<camunda:inputOutput>
<camunda:inputParameter name="x">
${myBean.calculateX()}
</camunda:inputParameter>
</camunda:inputOutput>
</extensionElements>
</serviceTask>
Управление ошибками во внешних задачах
Для внешних задач есть возможность определить элементы camunda:errorEventDefinition, которые можно предоставлять вместе с выражением на JUEL. Выражение вычисляется на ExternalTaskService#complete и ExternalTaskService#handleFailure. Если выражение вычисляется в true, выбрасывается BPMN-ошибка, которую можно поймать при помощи события границ ошибки.
Внутри скоупа внешней задачи выражения могут получать доступ к {{< javadocref page="org/camunda/bpm/engine/externaltask/ExternalTask.html" text="ExternalTaskEntity" >}} объекту через ключ externalTask, который предоставляет getter-методы для errorMessage, errorDetails, workerId, retries и т.д.
Примеры:
Как получить доступ к объекту внешней задачи:
<bpmn:serviceTask id="myExternalTaskId" name="myExternalTask" camunda:type="external" camunda:topic="myTopic">
<bpmn:extensionElements>
<camunda:errorEventDefinition id="myErrorEventDefinition" errorRef="myError" expression="${externalTask.getWorkerId() == 'myWorkerId'}" />
</bpmn:extensionElements>
</bpmn:serviceTask>
Как произвести матчинг сообщения об ошибке:
<bpmn:serviceTask id="myExternalTaskId" name="myExternalTask" camunda:type="external" camunda:topic="myTopic">
<bpmn:extensionElements>
<camunda:errorEventDefinition id="myErrorEventDefinition" errorRef="myError" expression="${externalTask.getErrorDetails().contains('myErrorMessage')}" />
</bpmn:extensionElements>
</bpmn:serviceTask>
Чтобы узнать больше подробностей по функциональности определения события ошибки в контекйте внешних задач, проконсультируйтесь с Руководством по внешним задачам.
Доступность переменных и функций внутри фзыка выражений
Процессные переменные
Вск процессные переменные в текущем скоупе доступны напрямую внутри выражения. Поэтому условныя поток последовательности может напрямую проверить значение переменной:
<sequenceFlow>
<conditionExpression xsi:type="tFormalExpression">
${test == 'start'}
</conditionExpression>
</sequenceFlow>
Переменные внутреннего контекста
В зависимости от текущего контекста выполнения, при вычислении выражений бывают доступны специальные встроенные контекстные переменные:
| Переменная | Java-тип | Контекст |
|---|---|---|
execution |
Доступна в контексте BPMN-выполнения, например, в сервисной задаче, в слушателе выполнения или в потоке последовательности. |
|
task |
Доступна в контексте задачи, например, в слушателе задачи. |
|
externalTask |
Доступна во время выполнения активностей контекста задачи (например, в выражениях camunda:errorEventDefinition). |
|
caseExecution |
Доступна в контексте CMMN выполнения. |
|
authenticatedUserId |
String |
Переменная id пользователя, аутентифицированного в данный момент. Аозвращает значение, только если id аутентифицированного пользователя было установлено через соответствующие методы IdentityService. В противном случае возвращает |
В следующем примере приведено выражение, которое кустанавливает переменную test в имя текущего события в слушателе выполнения.
<camunda:executionListener event="start"
expression="${execution.setVariable('test', execution.eventName)}" />
Переменные внешнего контекста со Spring и CDI
Если движок управления процессами интегрирован со Spring или CDI, можно получить доступ к бинам Spring и CDI внутри выражений. См. соответствующий раздел для Spring и CDI, чтобы получить больше информации. Следующий пример демонстрирует использование бина, который реализует интерфейс JavaDelegate как delegateExecution.
<serviceTask id="task1" camunda:delegateExpression="${myBean}" />
Любой метод бина может быть вызван через атрибут выражения.
<serviceTask id="task2" camunda:expression="${myBean.myMethod(execution)}" />
Функции внутреннего контекста
Специальные встроенные функции контекста доступны при вычислении выражений:
| Функция | Возвращаемый тип | Описание |
|---|---|---|
currentUser() |
String |
Возвращает user id аутентифицированного в настоящий момент пользователя или null, если ни один пользователь не аутентифицирован в настоящий момент. |
currentUserGroups() |
List of Strings |
Возвращает список group группы аутентифицированного в настоящий момент пользователя или null, если ни один пользователь в настоящий момент не авторизован. |
now() |
Date |
Возвращает текущую дату как объект типа Java Date. |
dateTime() |
DateTime |
Возвращает объект типа Joda-Time DateTime от текущей даты. См. документацию Joda-Time, чтобы найти все доступные функции . |
Следующий пример устанавливает дату окончания для пользовательской задачи в три дня после создания задачи.
<userTask id="theTask" name="Important task" camunda:dueDate="${dateTime().plusDays(3).toDate()}"/>
Встроенные функции Camunda Spin
Если активирован плагин двидка управления процессами Camunda Spin, функции Spin, такие как S, XML и JSON, тоже становятся доступными внутри выражения. См. Форматы данных (XML, JSON и др.)[раздел о форматах данных], чтобы найти подробное объяснение.
<serviceTask id="task" camunda:expression="${XML(xml).attr('test').value()}" resultVariable="test" />
Лицензия и атрибуция
Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .
Оригинал документации: https://docs.camunda.org