当遇到Activiti 5.22版本中官方Modeler的监听器丢失问题时,通过分析源码找到了解决方案。以下是具体的实现步骤和代码示例。
Model modelInfo = repositoryService.getModel(modelId);
repositoryService.saveModel(modelInfo);
ObjectNode modelJson = (ObjectNode) new ObjectMapper()
.readTree(repositoryService.getModelEditorSource(modelInfo.getId()));
BpmnModel bpmnModel = new BpmnJsonConverter().convertToBpmnModel(modelJson);
在`convertToBpmnModel`方法中的特定位置(例如386行),有如下代码片段:
// 仅包含边界事件的引用ID
for (Process process : bpmnModel.getProcesses()) {
postProcessElements(process, process.getFlowElements());
}
通过调试发现,在`process.getFlowElements()`调用时,监听器已经丢失。为了解决这个问题,需要手动解析并重新添加监听器。下面是一个自定义的方法,专门用于恢复`taskListeners`,可以根据需求进一步扩展。
private Collection<FlowElement> recoverListeners(Collection<FlowElement> elements, ArrayNode shapeNodes) {
List<FlowElement> updatedElements = new ArrayList<>();
for (FlowElement element : elements) {
JsonNode currentNode = null;
for (JsonNode node : shapeNodes) {
JsonNode properties = node.get("properties");
if (properties != null && properties.has("overrideId")) {
String overrideId = properties.get("overrideId").asText();
if (!overrideId.isEmpty() && overrideId.equals(element.getId())) {
currentNode = node;
break;
}
} else if (node.has("resourceId") && !node.get("resourceId").asText().isEmpty()) {
String resourceId = node.get("resourceId").asText();
if (resourceId.equals(element.getId())) {
currentNode = node;
break;
}
}
}
if (currentNode != null && element instanceof UserTask) {
FlowElement updatedElement = addTaskListener(element, currentNode);
updatedElements.add(updatedElement);
} else {
updatedElements.add(element);
}
}
return updatedElements;
}
接下来,修改原始代码段中的处理逻辑:
// 仅包含边界事件的引用ID
for (Process process : bpmnModel.getProcesses()) {
Collection<FlowElement> flowElements = process.getFlowElements();
Collection<FlowElement> updatedElements = recoverListeners(flowElements, shapeNodes);
postProcessElements(process, updatedElements);
}
这样就可以正确解析到监听器了。如果有更优的解决方案,欢迎交流讨论。