XML
|
Этот раздел перенесён из документации Camunda 7 и в дальнейшем будет доработан с учётом особенностей OpenBPM Engine |
Для работы с XML, в качестве точек вхождения могут использоваться функции Spin io.openbpm.spin.Spin.S и io.openbpm.spin.Spin.XML. Последняя предлагает строго типизированный доступ к XML API от Spin и является предпочтительным выбором при написании кода на Java code. В окружениях, предназначенных для написания скриптов, доступна только функция S. Возвращаемая Spin-обертка предлагает методы для манипуляции данными и их записи в XML, а также для маппинга XML на Java. Более того, функции для вхождений могут быть предоставлены с Java объектами, которые неявно преобразуются в промежуточный XML формат от Spin.
Далее приведены примеры того, как Camunda Spin может использоваться в движке обработки процессов для работы с XML данными. Для целей иллюстрации предположим, что существует процессная переменная типа String с именем customer, которая содержит XML. Ее содержимое выглядит следующим образом:
<?xml version="1.0" encoding="UTF-8"?>
<customer xmlns="http://camunda.org/example" name="Jonny">
<address>
<street>12 High Street</street>
<postCode>1234</postCode>
</address>
</customer>
Больше документация об использовании Spin можно найти в справочнике Camunda Spin по форматам данных.
Интеграция языка выражений
Функции вхождений от Spin можно использовать везде, где движок управления процессами позволяет использовать язык выражений. Следующий фрагмент BPMN показывает выражение последовательного алгоритма с условием, которое основано на почтовом коде клиента:
...
<sequenceFlow>
<conditionExpression xsi:type="tFormalExpression">
${XML(customer).xPath("/customer/address/postCode").element().textContent() == "1234"}
</conditionExpression>
</sequenceFlow>
...
Если ваша переменная уже входит в число link:{{< relref "#native-xml-variable-value" >}}[XML переменных] , а не является строкой, как в предыдущем примере, вы можете опустить вызов XML(…) и напрямую обратиться к переменной:
...
<sequenceFlow>
<conditionExpression xsi:type="tFormalExpression">
${customer.xPath("/customer/address/postCode").element().textContent() == "1234"}
</conditionExpression>
</sequenceFlow>
...
Интеграция механизма написания скриптов
Нижеприведенный пример — это скрипт, написанный на JavaScript. Скрипт использует Spin API для извлечения адреса объекта из переменной customer, добавления названия города и установки ее в качестве процессной переменной:
...
<scriptTask id="task" name="Script Task" scriptFormat="javascript">
<script>
<![CDATA[
var address = S(customer).element("address");
var city = XML("<city>New York</city>");
address.append(city);
execution.setVariable("address", address.toString());
]]>
</script>
</scriptTask>
...
Значения нативных переменных XML
Концепция значений нативных переменных для XML делает возможным ранний парсинг XML строки и ее оборачивание внутри объекта без необходимости наличия класса, представляющего XML. Допустим, мы хотим сохранить XML внутри процессной переменной для последующего использования; мы можем сделать следующее внутри JavaDelegate:
public class MyDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
String xml = "<customer xmlns=\"http:\\/\\/camunda.org/example\" name=\"Jonny\">"
+ "<address>"
+ "<street>12 High Street</street>"
+ "<postCode>1234</postCode>"
+ "</address>"
+ "</customer>";
XmlValue xmlValue = SpinValues.xmlValue(xml).create();
execution.setVariable("customerJonny", xmlValue);
}
}
Вызов SpinValues.xmlValue(…).create() преобразует строку в DomXML объект в обертке от Spin.
Если бы мы хотели извлечь XML в другом JavaDelegate и, например, добавить больше информации, мы могли бы легко сделать это:
public class AddDataDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
XmlValue customer = execution.getVariableTyped("customerJonny");
SpinXmlElement xmlElement = customer.getValue().append(Spin.XML("<creditLimit>1000.00</creditLimit>"));
customer = SpinValues.xmlValue(xmlElement).create();
execution.setVariable("customerJonny", customer);
//<?xml version="1.0" encoding="UTF-8"?><customer xmlns="http:\/\/camunda.org/example" name="Jonny"><address><street>12 High Street</street><postCode>1234</postCode></address><creditLimit xmlns="">1000.00</creditLimit></customer>
}
}
При извлечении XML-значения через execution.getVariableTyped() имеются две опции: сериализованное и десериализованное значение.
При извлечении десериализованной переменной через вызов либо getVariableTyped("name"), либо getVariableTyped("name", true) XmlValue будет содержать обернутый DomXML объект для представления XML данных. Вызов getVariableTyped("name", false) приведет к тому, что XmlValue будет содержать только сырую строку, что может быть преимуществом, если вам нужна только строка, например, чтобы передать ее в другой API.
Сериализация процессных переменных
Java объект можно сериализовать, используя встроенный формат данных от Spin. Предположим, что у нас есть только два Java класса, com.example.Customer и com.example.Address. XML формат по умолчанию от Spin полагается на JAXB, из-за чего JAXB аннотации типа @XmlRootElement, @XmlAttribute и @XmlElement могут использоваться для конфигурации процесса сериализации. Отметим, однако, что эти аннотации необязательны. Классы выглядят следующим образом:
@XmlRootElement(namespace = "http://camunda.org/example")
public class Customer {
protected String name;
protected Address address;
@XmlAttribute
public String getName() { .. }
@XmlElement(namespace = "http://camunda.org/example")
public Address getAddress() { .. }
/* constructor and setters omitted for brevity */
}
public class Address {
protected String street;
protected int postCode;
@XmlElement(namespace = "http://camunda.org/example")
public String getStreet() { .. }
@XmlElement(namespace = "http://camunda.org/example")
public int getPostCode() { .. }
/* constructor and setters omitted for brevity */
}
Следующий код на Java устанавливает процессную переменную на объект типа Customer, который сериализуется с использованием формата данных XML от Spin:
Address address = new Address("12 High Street", 1234);
Customer customer = new Customer("jonny", address);
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("aProcess");
ObjectValue typedCustomerValue =
Variables.objectValue(customer).serializationDataFormat("application/xml").create();
runtimeService.setVariable(processInstance.getId(), "customer", typedCustomerValue);
Определяющая команда здесь:
ObjectValue typedCustomerValue =
Variables.objectValue(customer).serializationDataFormat("application/xml").create();
Она создает значение переменной для объекта типа Customer. Вызов serializationDataFormat("application/xml") говорит движку управления процессами, в каком формате должна сериализоваться переменная. Это имя должно совпадать с именем формата данных, известного Spin. Например, application/xml это имя встроенного формата данных XML.
Как только переменная установлена, ее сериализованное значение может быть извлечено с использованием API типов переменных. Например:
ObjectValue customer = runtimeService.getVariableTyped(processInstance.getId(), "customer");
String customerXml = customer.getValueSerialized();
/*
customerXml matches:
<?xml version="1.0" encoding="UTF-8"?>
<customer xmlns="http://camunda.org/example" name="Jonny">
<address>
<street>12 High Street</street>
<postCode>1234</postCode>
</address>
</customer>
*/
Извлечение переменной произведет десериализацию сериализованного значения, если оно не было закешировано ранее. Пожалуйста, помните о том, что это может вызвать риск по безопасности, если источникам, не вызывающим доверия, разрешается хранить сериализованные значения в процессных переменных, которые могут вызвать выполнение вредоносного кода при десериализации. Обратитесь к инструкциям по безопасности, чтобы получить больше информации об этой проблеме.
|
Движок можно сконфигурировать таким образом, чтобы он сохранял в базе данных все объекты, для которых ни один из явно указанных форматов данных на задан как XML. Конфигурация движка управления процессами предлагает свойство |
Лицензия и атрибуция
Эта документация была создана на базе материала "Camunda 7 Docs" от Camunda, находится под лицензией Creative Commons Attribution-ShareAlike 3.0 Unported License .
Оригинал документации: https://docs.camunda.org