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

Сервисная задача, задача с бизнес-правилом, задача отправки, событие выбрасывания промежуточного сообщения, событие конца сообщения, слушатель выполнений и слушатель задач

Язык выражений как код делегации

Последовательные потоки, условные события

Язык выражений как условное выражение

Все задачи, все события, транзакции, подпроцесс и коннектор

Язык выражений внутри маппинга параметра inputOutput

Различные элементы

Язык выражений как значение атрибута или элемента

Все узлы потока, определение процесса

Язык выражений используется для определения приоритета джобы

Использование языка выражений

Код делегации

Помимо 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>

Чтобы узнать больше подробностей по функциональности определения события ошибки в контекйте внешних задач, проконсультируйтесь с Руководством по внешним задачам.

Значение

Различные BPMN и CMMN элементы позволяют задавать их содержимое или значение атрибута по выражению. См. соответствующие разделы для BPMN и CMMN в справочниках, чтобы найти более подробные примеры.

Доступность переменных и функций внутри фзыка выражений

Процессные переменные

Вск процессные переменные в текущем скоупе доступны напрямую внутри выражения. Поэтому условныя поток последовательности может напрямую проверить значение переменной:

  <sequenceFlow>
    <conditionExpression xsi:type="tFormalExpression">
      ${test == 'start'}
    </conditionExpression>
  </sequenceFlow>

Переменные внутреннего контекста

В зависимости от текущего контекста выполнения, при вычислении выражений бывают доступны специальные встроенные контекстные переменные:

Переменная Java-тип Контекст

execution

DelegateExecution

Доступна в контексте BPMN-выполнения, например, в сервисной задаче, в слушателе выполнения или в потоке последовательности.

task

DelegateTask

Доступна в контексте задачи, например, в слушателе задачи.

externalTask

ExternalTask

Доступна во время выполнения активностей контекста задачи (например, в выражениях camunda:errorEventDefinition).

caseExecution

DelegateCaseExecution

Доступна в контексте CMMN выполнения.

authenticatedUserId

String

Переменная id пользователя, аутентифицированного в данный момент. Аозвращает значение, только если id аутентифицированного пользователя было установлено через соответствующие методы IdentityService. В противном случае возвращает null.

В следующем примере приведено выражение, которое кустанавливает переменную 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