<definitionsxmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns:flowable="http://flowable.org/bpmn"xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC"xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"typeLanguage="http://www.w3.org/2001/XMLSchema"expressionLanguage="http://www.w3.org/1999/XPath"targetNamespace="http://www.flowable.org/processdef"><!-- id:流程定义key name:流程定义名称 isExecutable:是否可执行--><!-- flowable:自定义属性名="自定义属性值" --><process id="test_bpmn" name="test BPMN" isExecutable="true"flowable:organizationCode="流程所属组织编码" >... ...<userTask id="test_usertask" name="用户任务测试"flowable:assignee="张三" flowable:owner="李四"flowable:formKey="表单地址"flowable:customArr="自定义属性"><!-- 监听器配置 --><extensionElements><!-- class类型 --><flowable:taskListener event="complete" class="com.flow.test.flowabledemo.service.MyListener.MyTaskListener"/><!-- 表达式类型 --><flowable:taskListener expression="${myExpressionExecutionListener.test(execution.eventName)}" event="complete" /><!-- 脚本类型类型 --><flowable:taskListener event="complete" class="org.flowable.engine.impl.bpmn.listener.ScriptTaskListener" ><flowable:field name="script"><flowable:string>def bar = "BAR"; // local variablefoo = "FOO"; // pushes variable to execution contexttask.setOwner("kermit"); // test access to task instancebar // implicit return value</flowable:string></flowable:field><flowable:field name="language" stringValue="groovy" /><flowable:field name="resultVariable" stringValue="myVar" /></flowable:taskListener></extensionElements></userTask>... ...</process>... ...</definitions>
调用BpmnXMLConverter convertToBpmnModel()方法可以实现将bpmn xml转换成BpmnModel内存模型对象,然后将flowable:customArr="自定义属性"映射到UserTask对象的attributes属性中,debug如下图所示:



/*** bpmn xml和BpmnModel 转换器*/private BpmnXMLConverter bpmnXMLConverter = new BpmnXMLConverter();/*** bpmn json和BpmnModel 转换器*/private BpmnJsonConverter bpmnJsonConverter = new BpmnJsonConverter();XMLStreamReader reader = null;InputStream inputStream = null;try {XMLInputFactory factory = XMLInputFactory.newInstance();inputStream = new FileInputStream(new File(filePath));reader = factory.createXMLStreamReader(inputStream);//校验bpmn xml文件是否异常BpmnModel bpmnModel = bpmnXMLConverter.convertToBpmnModel(reader);List<Process> processes = bpmnModel.getProcesses();if (CollectionUtils.isEmpty(processes)) {log.error("BPMN模型没有配置流程");return null;}/*** 获取流程定义信息*/Process mainProcess = bpmnModel.getMainProcess();//获取流程定义信息//获取流程keyString id = mainProcess.getId();//获取流程名称String name = mainProcess.getName();//获取流程描述String documentation = mainProcess.getDocumentation();//获取process节点中的扩展属性信息Map<String, List<ExtensionAttribute>> attributes = mainProcess.getAttributes();for (Map.Entry<String, List<ExtensionAttribute>> entry : attributes.entrySet()) {System.out.println("扩展属性key:" + entry.getKey() + ",对应的值:" + entry.getValue().get(0).getValue());}//保存或修改的流程模板信息Model newModel = new Model();// 查询是否已经存在流程模板 :即判断是修改还是新增List<Model> existModelList = modelRepository.findByKeyAndType(mainProcess.getId(), AbstractModel.MODEL_TYPE_BPMN);if (!existModelList.isEmpty()) {newModel.setId(existModelList.get(0).getId());}User userDo = new FlowUser();userDo.setId("aaaaaaaa");//设置流程名称newModel.setName(mainProcess.getName());//设置流程编码newModel.setKey(mainProcess.getId());//设置流程引擎类型newModel.setModelType(AbstractModel.MODEL_TYPE_BPMN);// newModel.setCreated(DateUtils.getCurrentTime());//设置流程描述newModel.setDescription(mainProcess.getDocumentation());//设置模板json格式ObjectNode bpmnJson = bpmnJsonConverter.convertToJson(bpmnModel);newModel.setModelEditorJson(bpmnJson.toString());if (StringUtils.isEmpty(newModel.getId())) {//修改newModel.setLastUpdated(Calendar.getInstance().getTime());newModel.setLastUpdatedBy(userDo.getId());} else {//新增newModel.setCreated(Calendar.getInstance().getTime());newModel.setCreatedBy(userDo.getId());}modelService.createModel(newModel, userDo);} catch (Exception e) {log.error("BPMN模型创建流程异常", e);return null;} finally {try {reader.close();} catch (XMLStreamException e) {log.error("关闭异常", e);}}}
我们看下flowable是如何实现UserTask元素的BpmnModel和bpmn Json转换的,如何是debug的一步步流程:







那么UserTaskJsonConverter是什么时候被加载的?我们看BpmnJsonConverter部分源码如下:
public class BpmnJsonConverter implements EditorJsonConstants, StencilConstants, ActivityProcessor {protected static Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap = new HashMap<>();protected static Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap = new HashMap<>();...static {...// task types...UserTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap);...}...}
debug如下在项目启动时,将UserTaskJsonConverter UserTask元素的转换器注入到BpmnModel和Bpmn Json相互转换的两个静态map中。



所以我们如何想要实现对UserTask元素进行扩展属性,重写UserTaskJsonConverter的BpmnModel和bpmn Json的转换方法即可,如下是扩展实现:
//自定义UserTaskJsonConverter:public class CustomUserTaskJsonConverter extends UserTaskJsonConverter {//注入自定义CustomUserTaskJsonConverterstatic void customFillTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap, Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {fillJsonTypes(convertersToBpmnMap);fillBpmnTypes(convertersToJsonMap);}public static void fillJsonTypes(Map<String, Class<? extends BaseBpmnJsonConverter>> convertersToBpmnMap) {convertersToBpmnMap.put(STENCIL_TASK_USER, CustomUserTaskJsonConverter.class);}public static void fillBpmnTypes(Map<Class<? extends BaseElement>, Class<? extends BaseBpmnJsonConverter>> convertersToJsonMap) {convertersToJsonMap.put(UserTask.class, CustomUserTaskJsonConverter.class);}//重写UserTask Element和Json转换方法@Overrideprotected void convertElementToJson(ObjectNode propertiesNode, BaseElement baseElement) {super.convertElementToJson(propertiesNode, baseElement);//获取扩展属性并进行设置UserTask userTask = (UserTask) baseElement;Map<String, List<ExtensionAttribute>> attributes = userTask.getAttributes();for (Map.Entry<String, List<ExtensionAttribute>> entry : attributes.entrySet()) {String key = entry.getKey();String value = entry.getValue().get(0).getValue();//自定义属性if (key.equalsIgnoreCase("customArr")) {propertiesNode.put("customArr", value);continue;}}}//重写Json和UserTask Element转换方法@Overrideprotected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode, Map<String, JsonNode> shapeMap) {return super.convertJsonToElement(elementNode, modelNode, shapeMap);}@Overrideprotected void convertJsonToFormProperties(JsonNode objectNode, BaseElement element) {super.convertJsonToFormProperties(objectNode, element);if (element instanceof UserTask) {UserTask userTask = (UserTask) element;//将Json转为UserTask中的ElementString customArr= BpmnJsonConverterUtil.getPropertyValueAsString("customArr", objectNode);if (StringUtils.isNotEmpty(customArr)) {ExtensionAttribute customArrExtensionAttribute = new ExtensionAttribute();customArrExtensionAttribute.setName("customArr");customArrExtensionAttribute.setValue(nodeClassType);customArrExtensionAttribute.setNamespace("http://flowable.org/bpmn");customArrExtensionAttribute.setNamespacePrefix("flowable");userTask.addAttribute(customArrExtensionAttribute);}}}}
长按二维码关注我们

ITSK
博客|yajing8
我知道你在看哟

文章转载自ITSK,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





