一、流程设计模型验证
如果自己手写对流程模型bpmn xml验证的话,需要验证的逻辑有点多,可以将flowable源码中对流程的验证移植过来。
例如:
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.converter.BpmnXMLConverter;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.validation.ProcessValidator;
import org.flowable.validation.ProcessValidatorFactory;
import org.flowable.validation.ValidationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.List;
@Slf4j
public class ValidTest {
public static void main(String[] args) {
String flowDefXmlStr="<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><definitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:custom=\"http://xx.com.cn\" xmlns:flowable=\"http://flowable.org/bpmn\" xmlns:omgdc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:omgdi=\"http://www.omg.org/spec/DD/20100524/DI\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" expressionLanguage=\"http://www.w3.org/1999/XPath\" targetNamespace=\"http://xx.com.cn\" typeLanguage=\"http://www.w3.org/2001/XMLSchema\"><process id=\"F_ab6c15bec8cc48088c10ac1452ab0ad3\" isExecutable=\"true\" name=\"var2\"><sequenceFlow id=\"flow-f79c47d0-02f0-45d6-81c2-3786a6332602\" name=\"\" sourceRef=\"flow-9ba9ea5a-fb8c-48d7-adf0-ea9910895864\" targetRef=\"flow-c494fc41-cbac-4248-b936-df3254b92b88\"/><startEvent flowable:formKey=\"\" id=\"flow-9ba9ea5a-fb8c-48d7-adf0-ea9910895864\" name=\"开始\"><documentation/></startEvent><userTask flowable:candidateUsers=\"admin\" flowable:formKey=\"testform\" id=\"flow-c494fc41-cbac-4248-b936-df3254b92b88\" name=\"用户任务\"><documentation/></userTask><endEvent id=\"flow-6bfea0fc-0fad-47e4-aeef-b35fcad239ba\" name=\"结束\"><documentation/></endEvent></process></definitions>";
try {
validateProcess(flowDefXmlStr);
}catch (Exception e){
log.error("error info is :{}", e.getMessage());
}
}
private static void validateProcess(String flowDefXmlStr) throws UnsupportedEncodingException, XMLStreamException {
// xml转bpmnModel,取bpmn2.0规范的xml
InputStream bpmnStream = new ByteArrayInputStream(flowDefXmlStr.getBytes());
XMLInputFactory xif = XMLInputFactory.newInstance();
InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8");
XMLStreamReader xtr = xif.createXMLStreamReader(in);
// 然后转为bpmnModel
BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);
ProcessValidator validator = new ProcessValidatorFactory().createDefaultProcessValidator();
List<ValidationError> errors = validator.validate(bpmnModel);
System.out.println(errors);
}
}
flowable 自身对模型的验证也是有局限的,更多的是对排他网关的流设计条件后是否有多条输出流,这样的错误能验证出来,其他的一些类型错误不识别,所以不是万能的。
二、对?UEL 表达式、表达式函数进行分解
Flowable 使用 UEL 进行表达式解析。UEL 代表统一表达式语言,是 EE6 规范的一部分。6.4.0版本增加了表达式函数。更多使用说明参考官方文档:https://www.flowable.com/open-source/docs/bpmn/ch04-API/#expression-functions
import org.apache.commons.lang3.StringUtils;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.List;
public class TestParseExpression {
public static void main(String[] args) {
String expression ="${vars:getOrDefault(user1, '1')},${vars:getOrDefault(user2, '19')},${vars:getOrDefault(user3, '22')}";
List<String> result=TestParseExpression.parseDelimitedList(expression);
System.out.println(result);
}
public static List<String> parseDelimitedList(String s) {
List<String> result = new ArrayList<>();
if (StringUtils.isNotEmpty(s)) {
StringCharacterIterator iterator = new StringCharacterIterator(s);
char c = iterator.first();
StringBuilder strb = new StringBuilder();
boolean insideExpression = false;
while (c != StringCharacterIterator.DONE) {
if (c == '{' || c == '$') {
insideExpression = true;
} else if (c == '}') {
insideExpression = false;
} else if (c == ',' && !insideExpression) {
result.add(strb.toString().trim());
strb.delete(0, strb.length());
}
if (c != ',' || insideExpression) {
strb.append(c);
}
c = iterator.next();
}
if (strb.length() > 0) {
result.add(strb.toString().trim());
}
}
return result;
}
}
|