暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Flowable 扩展流程定义属性

ITSK 2021-03-21
5298
多学习,多积累,多沉淀!解决问题的时学以致用,总会有一种豁然开朗的感觉!



我们在实际开发过程中,flowable官方提供的流程定义的属性可能无法满足实际需求,举个例子,比如像我们公司最近在开发的流程和组织有关系,所以流程定义中需要扩展组织相关属性等的。
流程图模板bpmn xml文件中flowable规范【xmlns:flowable】针对流程定义元素提供了基本属性及可扩展属性如下所示:
 <definitions 
 xmlns="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="流程所属组织编码" >
  <!-- documentation:流程描述 -->
<documentation>test BPMN</documentation>
</process>
... ...


</definitions>
本以为flowable框架也提供了针对扩展属性的处理,debug如下图:

我们可以看到flowable使用BpmnXMLConverter的convertToBpmnModel()方法可以将读取的bpmn xml文件中的扩展属性转到对应的Process类定义的扩展属性:Map<String, List<ExtensionAttribute>> attributes中,大家看下源码就知道了,这里不详细粘贴了。嗯哼太乐观了,将该流程图模板保存以后部署之前是插入到act_de_model表【流程模型信息表】,仅用于保存流程模板bpmn信息,只有在流程部署以后生成流程定义信息才能被流程引擎使用。

我们看到act_de_model表并没有存在bpmn xml文件而是转换成json格式进行存储的,代码实现如下:
/**
* 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();
//获取流程定义信息
//获取流程key
    String 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);
}
}
}
可以看到整个过程是将读取的bpmn xml文件先转换成BpmnModel对象,然后再将BpmnModel通过BpmnJsonConverter convertToJson(bpmnModel)转换成ObjectNode 存储到act_del_model表中,然而我们看convertToJson源码发现并没有对扩展属性做任何处理,所以说act_del_model表中的model_editor_json也没有保存我们自定义的属性,而后续流程引擎部署就是通过读取model_editor_json内容转换成bpmn xml资源文件保存到act_ge_bytearray【流程定义资源表】中拱后续流程引擎使用。所以我们要做的就是需要重写BpmnModel和bpmn Json相关转换的方法,支持bpmn xml文件中扩展属性的处理。
我们首先先看下BpmnJsonConverter convertToJson(bpmnModel)源码,然后我们自己实现将自定义属性转换到json文件中。
 自定义:CustomBpmnJsonConverter 类继承BpmnJsonConverter 
public class CustomBpmnJsonConverter extends BpmnJsonConverter {
    /**
     * 重写BpmnModel 和 bpmn Json转换方法:实现扩展属性转换
     */
@Override
public ObjectNode convertToJson(BpmnModel model, Map<String, ModelInfo> formKeyMap, Map<String, ModelInfo> decisionTableKeyMap) {
      ... ...
      if (mainProcess.getExtensionElements().containsKey("historyLevel")) {
... ...
       }
 
       //扩展process中自定义属性
Map<String, List<ExtensionAttribute>> extAttributes = mainProcess.getAttributes();
for (Map.Entry<String, List<ExtensionAttribute>> entry : extAttributes.entrySet()) {
String key = entry.getKey();
          String value = entry.getValue().get(0).getValue();
          //获取流程所属组织编码
if (key.equalsIgnoreCase("organizationCode")) {
propertiesNode.put("organizationCode", value);
continue;
          }
       }
       ... ...
    }
 }

然后再实现将Json中的扩展属性转换到BpmnModel对应属性中:如下为扩展代码:

 自定义:CustomBpmnJsonConverter 类继承BpmnJsonConverter 
public class CustomBpmnJsonConverter extends BpmnJsonConverter {
   /**
    * 重写bpmn Json和 BpmnModel转换方法:实现扩展属性转换
    */
@Override
public BpmnModel convertToBpmnModel(JsonNode modelNode, Map<String, String> formKeyMap, Map<String, String> decisionTableKeyMap) {
... ...
       if (!nonEmptyPoolFound) {
       String organizationCode = BpmnJsonConverterUtil.getPropertyValueAsString("organizationCode ", modelNode);
       if (StringUtils.isNotEmpty(organizationCode)) {
ExtensionAttribute organizationCodeExtensionAttribute = new ExtensionAttribute();
organizationCodeExtensionAttribute.setName("organizationCode ");
organizationCodeExtensionAttribute.setValue(organizationCode);
organizationCodeExtensionAttribute.setNamespace("http://flowable.org/bpmn");
organizationCodeExtensionAttribute.setNamespacePrefix("flowable");
process.addAttribute(organizationCodeExtensionAttribute);
}
       }
}
    ... ...
 }

如上重写源码对应实现方法即可,具体为什么这样写,我觉得没必要粘贴源码和debug图了,感兴趣小伙伴看下源码,debug跟一下就明白啦~

长按二维码关注我们

ITSK

博客|yajing8


我知道你在看


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

评论