解决activiti中由模板转换的流程图连线名称缺失问题

版本声明:Activiti 5.22.0
通常,由模板发布流程的代码大致如下:

private Deployment convertModelToProcess(String modelId) throws IOException, UnsupportedEncodingException { Deployment deployment = null; try { Model modelData = https://www.it610.com/article/repositoryService.getModel(modelId); ObjectNode modelNode = (ObjectNode) new ObjectMapper() .readTree(repositoryService.getModelEditorSource(modelData.getId())); byte[] bpmnBytes = null; BpmnModel model = new BpmnJsonConverter().convertToBpmnModel(modelNode); bpmnBytes = new BpmnXMLConverter().convertToXML(model); String processName = modelData.getName() +".bpmn20.xml"; deployment = repositoryService.createDeployment().name(modelData.getName()) .addString(processName, new String(bpmnBytes, "UTF-8")).deploy(); } catch (Exception e1) { throw new BizException("流程定义文件存在错误,请修改后重新部署!"); } return deployment; }

但在此版本的activiti中存在一个bug:由模板转换的流程定义,其流程图会丢失连线名称。
解决办法:重写BpmnJsonConverter类:
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.activiti.bpmn.model.Activity; import org.activiti.bpmn.model.Artifact; import org.activiti.bpmn.model.BaseElement; import org.activiti.bpmn.model.BoundaryEvent; import org.activiti.bpmn.model.BpmnModel; import org.activiti.bpmn.model.Event; import org.activiti.bpmn.model.EventDefinition; import org.activiti.bpmn.model.ExtensionElement; import org.activiti.bpmn.model.FlowElement; import org.activiti.bpmn.model.FlowElementsContainer; import org.activiti.bpmn.model.FlowNode; import org.activiti.bpmn.model.Gateway; import org.activiti.bpmn.model.GraphicInfo; import org.activiti.bpmn.model.Lane; import org.activiti.bpmn.model.Message; import org.activiti.bpmn.model.MessageEventDefinition; import org.activiti.bpmn.model.MessageFlow; import org.activiti.bpmn.model.Pool; import org.activiti.bpmn.model.Process; import org.activiti.bpmn.model.SequenceFlow; import org.activiti.bpmn.model.Signal; import org.activiti.bpmn.model.SignalEventDefinition; import org.activiti.bpmn.model.SubProcess; import org.activiti.bpmn.model.ValuedDataObject; import org.activiti.editor.constants.EditorJsonConstants; import org.activiti.editor.constants.StencilConstants; import org.activiti.editor.language.json.converter.ActivityProcessor; import org.activiti.editor.language.json.converter.AssociationJsonConverter; import org.activiti.editor.language.json.converter.BaseBpmnJsonConverter; import org.activiti.editor.language.json.converter.BoundaryEventJsonConverter; import org.activiti.editor.language.json.converter.BpmnJsonConverter; import org.activiti.editor.language.json.converter.BpmnJsonConverterUtil; import org.activiti.editor.language.json.converter.BusinessRuleTaskJsonConverter; import org.activiti.editor.language.json.converter.CallActivityJsonConverter; import org.activiti.editor.language.json.converter.CamelTaskJsonConverter; import org.activiti.editor.language.json.converter.CatchEventJsonConverter; import org.activiti.editor.language.json.converter.DataStoreJsonConverter; import org.activiti.editor.language.json.converter.EndEventJsonConverter; import org.activiti.editor.language.json.converter.EventGatewayJsonConverter; import org.activiti.editor.language.json.converter.EventSubProcessJsonConverter; import org.activiti.editor.language.json.converter.ExclusiveGatewayJsonConverter; import org.activiti.editor.language.json.converter.InclusiveGatewayJsonConverter; import org.activiti.editor.language.json.converter.MailTaskJsonConverter; import org.activiti.editor.language.json.converter.ManualTaskJsonConverter; import org.activiti.editor.language.json.converter.MessageFlowJsonConverter; import org.activiti.editor.language.json.converter.MuleTaskJsonConverter; import org.activiti.editor.language.json.converter.ParallelGatewayJsonConverter; import org.activiti.editor.language.json.converter.ReceiveTaskJsonConverter; import org.activiti.editor.language.json.converter.ScriptTaskJsonConverter; import org.activiti.editor.language.json.converter.SendTaskJsonConverter; import org.activiti.editor.language.json.converter.SequenceFlowJsonConverter; import org.activiti.editor.language.json.converter.ServiceTaskJsonConverter; import org.activiti.editor.language.json.converter.StartEventJsonConverter; import org.activiti.editor.language.json.converter.SubProcessJsonConverter; import org.activiti.editor.language.json.converter.TextAnnotationJsonConverter; import org.activiti.editor.language.json.converter.ThrowEventJsonConverter; import org.activiti.editor.language.json.converter.UserTaskJsonConverter; import org.activiti.editor.language.json.converter.util.JsonConverterUtil; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ObjectNode; import math.geom2d.Point2D; import math.geom2d.conic.Circle2D; import math.geom2d.curve.AbstractContinuousCurve2D; import math.geom2d.line.Line2D; import math.geom2d.polygon.Polyline2D; /** * @author Tijs Rademakers */ public class CustomBpmnJsonConverter implements EditorJsonConstants, StencilConstants, ActivityProcessor { protected static final Logger LOGGER = LoggerFactory .getLogger(BpmnJsonConverter.class); protected static Map, Class> convertersToJsonMap = new HashMap, Class>(); protected static Map> convertersToBpmnMap = new HashMap>(); public static final String MODELER_NAMESPACE = "http://activiti.com/modeler"; protected static final DateFormat defaultFormat = new SimpleDateFormat( "yyyyMMddHHmmss"); protected static final DateFormat entFormat = new SimpleDateFormat( "yyyyMMddHHmmssSSS"); static { // start and end events StartEventJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); EndEventJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); // connectors SequenceFlowJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); MessageFlowJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); AssociationJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); // task types BusinessRuleTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); MailTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); ManualTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); ReceiveTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); ScriptTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); ServiceTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); UserTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); CallActivityJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); CamelTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); MuleTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); SendTaskJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); // gateways ExclusiveGatewayJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); InclusiveGatewayJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); ParallelGatewayJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); EventGatewayJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); // scope constructs SubProcessJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); EventSubProcessJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); // catch events CatchEventJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); // throw events ThrowEventJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); // boundary events BoundaryEventJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); // artifacts TextAnnotationJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); DataStoreJsonConverter.fillTypes(convertersToBpmnMap, convertersToJsonMap); }private static final List DI_CIRCLES = new ArrayList(); private static final List DI_RECTANGLES = new ArrayList(); private static final List DI_GATEWAY = new ArrayList(); static { DI_CIRCLES.add(STENCIL_EVENT_START_ERROR); DI_CIRCLES.add(STENCIL_EVENT_START_MESSAGE); DI_CIRCLES.add(STENCIL_EVENT_START_NONE); DI_CIRCLES.add(STENCIL_EVENT_START_TIMER); DI_CIRCLES.add(STENCIL_EVENT_START_SIGNAL); DI_CIRCLES.add(STENCIL_EVENT_BOUNDARY_ERROR); DI_CIRCLES.add(STENCIL_EVENT_BOUNDARY_SIGNAL); DI_CIRCLES.add(STENCIL_EVENT_BOUNDARY_TIMER); DI_CIRCLES.add(STENCIL_EVENT_BOUNDARY_MESSAGE); DI_CIRCLES.add(STENCIL_EVENT_BOUNDARY_CANCEL); DI_CIRCLES.add(STENCIL_EVENT_BOUNDARY_COMPENSATION); DI_CIRCLES.add(STENCIL_EVENT_CATCH_MESSAGE); DI_CIRCLES.add(STENCIL_EVENT_CATCH_SIGNAL); DI_CIRCLES.add(STENCIL_EVENT_CATCH_TIMER); DI_CIRCLES.add(STENCIL_EVENT_THROW_NONE); DI_CIRCLES.add(STENCIL_EVENT_THROW_SIGNAL); DI_CIRCLES.add(STENCIL_EVENT_END_NONE); DI_CIRCLES.add(STENCIL_EVENT_END_ERROR); DI_CIRCLES.add(STENCIL_EVENT_END_CANCEL); DI_CIRCLES.add(STENCIL_EVENT_END_TERMINATE); DI_RECTANGLES.add(STENCIL_CALL_ACTIVITY); DI_RECTANGLES.add(STENCIL_SUB_PROCESS); DI_RECTANGLES.add(STENCIL_EVENT_SUB_PROCESS); DI_RECTANGLES.add(STENCIL_TASK_BUSINESS_RULE); DI_RECTANGLES.add(STENCIL_TASK_MAIL); DI_RECTANGLES.add(STENCIL_TASK_MANUAL); DI_RECTANGLES.add(STENCIL_TASK_RECEIVE); DI_RECTANGLES.add(STENCIL_TASK_SCRIPT); DI_RECTANGLES.add(STENCIL_TASK_SEND); DI_RECTANGLES.add(STENCIL_TASK_SERVICE); DI_RECTANGLES.add(STENCIL_TASK_USER); DI_RECTANGLES.add(STENCIL_TASK_CAMEL); DI_RECTANGLES.add(STENCIL_TASK_MULE); DI_RECTANGLES.add(STENCIL_TEXT_ANNOTATION); DI_GATEWAY.add(STENCIL_GATEWAY_EVENT); DI_GATEWAY.add(STENCIL_GATEWAY_EXCLUSIVE); DI_GATEWAY.add(STENCIL_GATEWAY_INCLUSIVE); DI_GATEWAY.add(STENCIL_GATEWAY_PARALLEL); }protected ObjectMapper objectMapper = new ObjectMapper(); public ObjectNode convertToJson(BpmnModel model) { ObjectNode modelNode = objectMapper.createObjectNode(); double maxX = 0.0; double maxY = 0.0; for (GraphicInfo flowInfo : model.getLocationMap().values()) { if ((flowInfo.getX() + flowInfo.getWidth()) > maxX) { maxX = flowInfo.getX() + flowInfo.getWidth(); }if ((flowInfo.getY() + flowInfo.getHeight()) > maxY) { maxY = flowInfo.getY() + flowInfo.getHeight(); } }maxX += 50; maxY += 50; if (maxX < 1485) { maxX = 1485; }if (maxY < 700) { maxY = 700; }modelNode.put("bounds", BpmnJsonConverterUtil.createBoundsNode(maxX, maxY, 0, 0)); modelNode.put("resourceId", "canvas"); ObjectNode stencilNode = objectMapper.createObjectNode(); stencilNode.put("id", "BPMNDiagram"); modelNode.put("stencil", stencilNode); ObjectNode stencilsetNode = objectMapper.createObjectNode(); stencilsetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#"); stencilsetNode.put("url", "../editor/stencilsets/bpmn2.0/bpmn2.0.json"); modelNode.put("stencilset", stencilsetNode); ArrayNode shapesArrayNode = objectMapper.createArrayNode(); Process mainProcess = null; if (model.getPools().size() > 0) { mainProcess = model.getProcess(model.getPools().get(0).getId()); } else { mainProcess = model.getMainProcess(); }ObjectNode propertiesNode = objectMapper.createObjectNode(); if (StringUtils.isNotEmpty(mainProcess.getId())) { propertiesNode.put(PROPERTY_PROCESS_ID, mainProcess.getId()); }if (StringUtils.isNotEmpty(mainProcess.getName())) { propertiesNode.put(PROPERTY_NAME, mainProcess.getName()); }if (StringUtils.isNotEmpty(mainProcess.getDocumentation())) { propertiesNode.put(PROPERTY_DOCUMENTATION, mainProcess.getDocumentation()); }if (mainProcess.isExecutable() == false) { propertiesNode.put(PROPERTY_PROCESS_EXECUTABLE, "No"); }if (StringUtils.isNoneEmpty(model.getTargetNamespace())) { propertiesNode.put(PROPERTY_PROCESS_NAMESPACE, model.getTargetNamespace()); }BpmnJsonConverterUtil.convertMessagesToJson(model.getMessages(), propertiesNode); BpmnJsonConverterUtil.convertListenersToJson( mainProcess.getExecutionListeners(), true, propertiesNode); BpmnJsonConverterUtil.convertEventListenersToJson( mainProcess.getEventListeners(), propertiesNode); BpmnJsonConverterUtil.convertSignalDefinitionsToJson(model, propertiesNode); BpmnJsonConverterUtil.convertMessagesToJson(model, propertiesNode); if (CollectionUtils.isNotEmpty(mainProcess.getDataObjects())) { BpmnJsonConverterUtil.convertDataPropertiesToJson( mainProcess.getDataObjects(), propertiesNode); }modelNode.put(EDITOR_SHAPE_PROPERTIES, propertiesNode); boolean poolHasDI = false; if (model.getPools().size() > 0) { for (Pool pool : model.getPools()) { GraphicInfo graphicInfo = model.getGraphicInfo(pool.getId()); if (graphicInfo != null) { poolHasDI = true; break; } } }if ((model.getPools().size() > 0) && poolHasDI) { for (Pool pool : model.getPools()) { GraphicInfo graphicInfo = model.getGraphicInfo(pool.getId()); if (graphicInfo == null) { continue; }ObjectNode poolNode = BpmnJsonConverterUtil.createChildShape( pool.getId(), STENCIL_POOL, graphicInfo.getX() + graphicInfo.getWidth(), graphicInfo.getY() + graphicInfo.getHeight(), graphicInfo.getX(), graphicInfo.getY()); shapesArrayNode.add(poolNode); ObjectNode poolPropertiesNode = objectMapper.createObjectNode(); poolPropertiesNode.put(PROPERTY_OVERRIDE_ID, pool.getId()); poolPropertiesNode.put(PROPERTY_PROCESS_ID, pool.getProcessRef()); if (pool.isExecutable() == false) { poolPropertiesNode.put(PROPERTY_PROCESS_EXECUTABLE, PROPERTY_VALUE_NO); }if (StringUtils.isNotEmpty(pool.getName())) { poolPropertiesNode.put(PROPERTY_NAME, pool.getName()); }poolNode.put(EDITOR_SHAPE_PROPERTIES, poolPropertiesNode); ArrayNode laneShapesArrayNode = objectMapper.createArrayNode(); poolNode.put(EDITOR_CHILD_SHAPES, laneShapesArrayNode); ArrayNode outgoingArrayNode = objectMapper.createArrayNode(); poolNode.put("outgoing", outgoingArrayNode); Process process = model.getProcess(pool.getId()); if (process != null) { Map laneMap = new HashMap(); for (Lane lane : process.getLanes()) { GraphicInfo laneGraphicInfo = model.getGraphicInfo(lane .getId()); if (laneGraphicInfo == null) { continue; }ObjectNode laneNode = BpmnJsonConverterUtil .createChildShape(lane.getId(), STENCIL_LANE, laneGraphicInfo.getX() + laneGraphicInfo.getWidth(), laneGraphicInfo.getY() + laneGraphicInfo.getHeight(), laneGraphicInfo.getX(), laneGraphicInfo.getY()); laneShapesArrayNode.add(laneNode); ObjectNode lanePropertiesNode = objectMapper .createObjectNode(); lanePropertiesNode.put(PROPERTY_OVERRIDE_ID, lane.getId()); if (StringUtils.isNotEmpty(lane.getName())) { lanePropertiesNode.put(PROPERTY_NAME, lane.getName()); }laneNode.put(EDITOR_SHAPE_PROPERTIES, lanePropertiesNode); ArrayNode elementShapesArrayNode = objectMapper .createArrayNode(); laneNode.put(EDITOR_CHILD_SHAPES, elementShapesArrayNode); laneNode.put("outgoing", objectMapper.createArrayNode()); laneMap.put(lane.getId(), elementShapesArrayNode); }for (FlowElement flowElement : process.getFlowElements()) { Lane laneForElement = null; GraphicInfo laneGraphicInfo = null; FlowElement lookForElement = null; if (flowElement instanceof SequenceFlow) { SequenceFlow sequenceFlow = (SequenceFlow) flowElement; lookForElement = model.getFlowElement(sequenceFlow .getSourceRef()); } else { lookForElement = flowElement; }for (Lane lane : process.getLanes()) { if (lane.getFlowReferences().contains( lookForElement.getId())) { laneGraphicInfo = model.getGraphicInfo(lane .getId()); if (laneGraphicInfo != null) { laneForElement = lane; }break; } }if (flowElement instanceof SequenceFlow || (laneForElement != null)) { processFlowElement(flowElement, process, model, laneMap.get(laneForElement.getId()), laneGraphicInfo.getX(), laneGraphicInfo.getY()); } }processArtifacts(process, model, shapesArrayNode, 0.0, 0.0); }for (MessageFlow messageFlow : model.getMessageFlows().values()) { if (messageFlow.getSourceRef().equals(pool.getId())) { outgoingArrayNode.add(BpmnJsonConverterUtil .createResourceNode(messageFlow.getId())); } } }processMessageFlows(model, shapesArrayNode); } else { processFlowElements(model.getMainProcess(), model, shapesArrayNode, 0.0, 0.0); processMessageFlows(model, shapesArrayNode); }modelNode.put(EDITOR_CHILD_SHAPES, shapesArrayNode); return modelNode; }public void processFlowElements(FlowElementsContainer container, BpmnModel model, ArrayNode shapesArrayNode, double subProcessX, double subProcessY) { for (FlowElement flowElement : container.getFlowElements()) { processFlowElement(flowElement, container, model, shapesArrayNode, subProcessX, subProcessY); }processArtifacts(container, model, shapesArrayNode, subProcessX, subProcessY); }protected void processFlowElement(FlowElement flowElement, FlowElementsContainer container, BpmnModel model, ArrayNode shapesArrayNode, double containerX, double containerY) { Class converter = convertersToJsonMap .get(flowElement.getClass()); if (converter != null) { try { converter.newInstance().convertToJson(flowElement, this, model, container, shapesArrayNode, containerX, containerY); } catch (Exception e) { LOGGER.error("Error converting {}", flowElement, e); } } }protected void processArtifacts(FlowElementsContainer container, BpmnModel model, ArrayNode shapesArrayNode, double containerX, double containerY) { for (Artifact artifact : container.getArtifacts()) { Class converter = convertersToJsonMap .get(artifact.getClass()); if (converter != null) { try { converter.newInstance().convertToJson(artifact, this, model, container, shapesArrayNode, containerX, containerY); } catch (Exception e) { LOGGER.error("Error converting {}", artifact, e); } } } }protected void processMessageFlows(BpmnModel model, ArrayNode shapesArrayNode) { for (MessageFlow messageFlow : model.getMessageFlows().values()) { MessageFlowJsonConverter jsonConverter = new MessageFlowJsonConverter(); jsonConverter.convertToJson(messageFlow, this, model, null, shapesArrayNode, 0.0, 0.0); } }public BpmnModel convertToBpmnModel(JsonNode modelNode) { BpmnModel bpmnModel = new BpmnModel(); bpmnModel.setTargetNamespace("http://activiti.org/test"); Map shapeMap = new HashMap(); Map sourceRefMap = new HashMap(); Map edgeMap = new HashMap(); Map> sourceAndTargetMap = new HashMap>(); readShapeDI(modelNode, 0, 0, shapeMap, sourceRefMap, bpmnModel); filterAllEdges(modelNode, edgeMap, sourceAndTargetMap, shapeMap, sourceRefMap); readEdgeDI(edgeMap, sourceAndTargetMap, bpmnModel); ArrayNode shapesArrayNode = (ArrayNode) modelNode .get(EDITOR_CHILD_SHAPES); if ((shapesArrayNode == null) || (shapesArrayNode.size() == 0)) { return bpmnModel; }boolean nonEmptyPoolFound = false; Map elementInLaneMap = new HashMap(); // first create the pool structure for (JsonNode shapeNode : shapesArrayNode) { String stencilId = BpmnJsonConverterUtil.getStencilId(shapeNode); if (STENCIL_POOL.equals(stencilId)) { Pool pool = new Pool(); pool.setId(BpmnJsonConverterUtil.getElementId(shapeNode)); pool.setName(JsonConverterUtil.getPropertyValueAsString( PROPERTY_NAME, shapeNode)); pool.setProcessRef(JsonConverterUtil.getPropertyValueAsString( PROPERTY_PROCESS_ID, shapeNode)); pool.setExecutable(JsonConverterUtil.getPropertyValueAsBoolean( PROPERTY_PROCESS_EXECUTABLE, shapeNode, true)); bpmnModel.getPools().add(pool); Process process = new Process(); process.setId(pool.getProcessRef()); process.setName(pool.getName()); process.setExecutable(pool.isExecutable()); bpmnModel.addProcess(process); ArrayNode laneArrayNode = (ArrayNode) shapeNode .get(EDITOR_CHILD_SHAPES); for (JsonNode laneNode : laneArrayNode) { // should be a lane, but just check to be certain String laneStencilId = BpmnJsonConverterUtil .getStencilId(laneNode); if (STENCIL_LANE.equals(laneStencilId)) { nonEmptyPoolFound = true; Lane lane = new Lane(); lane.setId(BpmnJsonConverterUtil.getElementId(laneNode)); lane.setName(JsonConverterUtil .getPropertyValueAsString(PROPERTY_NAME, laneNode)); lane.setParentProcess(process); process.getLanes().add(lane); processJsonElements(laneNode.get(EDITOR_CHILD_SHAPES), modelNode, lane, shapeMap, bpmnModel); if (CollectionUtils .isNotEmpty(lane.getFlowReferences())) { for (String elementRef : lane.getFlowReferences()) { elementInLaneMap.put(elementRef, lane); } } } } } }// Signal Definitions exist on the root level JsonNode signalDefinitionNode = BpmnJsonConverterUtil.getProperty( PROPERTY_SIGNAL_DEFINITIONS, modelNode); signalDefinitionNode = BpmnJsonConverterUtil .validateIfNodeIsTextual(signalDefinitionNode); signalDefinitionNode = BpmnJsonConverterUtil .validateIfNodeIsTextual(signalDefinitionNode); // no idea why this needs to be done twice ..if (signalDefinitionNode != null) { if (signalDefinitionNode instanceof ArrayNode) { ArrayNode signalDefinitionArrayNode = (ArrayNode) signalDefinitionNode; Iterator signalDefinitionIterator = signalDefinitionArrayNode .iterator(); while (signalDefinitionIterator.hasNext()) { JsonNode signalDefinitionJsonNode = signalDefinitionIterator .next(); String signalId = signalDefinitionJsonNode.get( PROPERTY_SIGNAL_DEFINITION_ID).asText(); String signalName = signalDefinitionJsonNode.get( PROPERTY_SIGNAL_DEFINITION_NAME).asText(); String signalScope = signalDefinitionJsonNode.get( PROPERTY_SIGNAL_DEFINITION_SCOPE).asText(); Signal signal = new Signal(); signal.setId(signalId); signal.setName(signalName); signal.setScope((signalScope.toLowerCase() .equals("processinstance")) ? Signal.SCOPE_PROCESS_INSTANCE : Signal.SCOPE_GLOBAL); bpmnModel.addSignal(signal); } } }if (nonEmptyPoolFound == false) { Process process = new Process(); bpmnModel.getProcesses().add(process); process.setId(BpmnJsonConverterUtil.getPropertyValueAsString( PROPERTY_PROCESS_ID, modelNode)); process.setName(BpmnJsonConverterUtil.getPropertyValueAsString( PROPERTY_NAME, modelNode)); String namespace = BpmnJsonConverterUtil.getPropertyValueAsString( PROPERTY_PROCESS_NAMESPACE, modelNode); if (StringUtils.isNotEmpty(namespace)) { bpmnModel.setTargetNamespace(namespace); }process.setDocumentation(BpmnJsonConverterUtil .getPropertyValueAsString(PROPERTY_DOCUMENTATION, modelNode)); JsonNode processExecutableNode = JsonConverterUtil.getProperty( PROPERTY_PROCESS_EXECUTABLE, modelNode); if ((processExecutableNode != null) && StringUtils.isNotEmpty(processExecutableNode.asText())) { process.setExecutable(JsonConverterUtil .getPropertyValueAsBoolean(PROPERTY_PROCESS_EXECUTABLE, modelNode)); }BpmnJsonConverterUtil.convertJsonToMessages(modelNode, bpmnModel); BpmnJsonConverterUtil.convertJsonToListeners(modelNode, process); JsonNode eventListenersNode = BpmnJsonConverterUtil.getProperty( PROPERTY_EVENT_LISTENERS, modelNode); if (eventListenersNode != null) { eventListenersNode = BpmnJsonConverterUtil .validateIfNodeIsTextual(eventListenersNode); BpmnJsonConverterUtil.parseEventListeners( eventListenersNode.get(PROPERTY_EVENTLISTENER_VALUE), process); }JsonNode processDataPropertiesNode = modelNode.get( EDITOR_SHAPE_PROPERTIES).get(PROPERTY_DATA_PROPERTIES); if (processDataPropertiesNode != null) { List dataObjects = BpmnJsonConverterUtil .convertJsonToDataProperties(processDataPropertiesNode, process); process.setDataObjects(dataObjects); process.getFlowElements().addAll(dataObjects); }processJsonElements(shapesArrayNode, modelNode, process, shapeMap, bpmnModel); } else { // sequence flows are on root level so need additional parsing for pools for (JsonNode shapeNode : shapesArrayNode) { if (STENCIL_SEQUENCE_FLOW .equalsIgnoreCase(BpmnJsonConverterUtil .getStencilId(shapeNode)) || STENCIL_ASSOCIATION .equalsIgnoreCase(BpmnJsonConverterUtil .getStencilId(shapeNode))) { String sourceRef = BpmnJsonConverterUtil.lookForSourceRef( shapeNode.get(EDITOR_SHAPE_ID).asText(), modelNode.get(EDITOR_CHILD_SHAPES)); if (sourceRef != null) { Lane lane = elementInLaneMap.get(sourceRef); SequenceFlowJsonConverter flowConverter = new SequenceFlowJsonConverter(); if (lane != null) { flowConverter.convertToBpmnModel(shapeNode, modelNode, this, lane, shapeMap, bpmnModel); } else { flowConverter.convertToBpmnModel(shapeNode, modelNode, this, bpmnModel.getProcesses() .get(0), shapeMap, bpmnModel); } } } } }// sequence flows are now all on root level Map subShapesMap = new HashMap(); for (Process process : bpmnModel.getProcesses()) { for (FlowElement flowElement : process .findFlowElementsOfType(SubProcess.class)) { SubProcess subProcess = (SubProcess) flowElement; fillSubShapes(subShapesMap, subProcess); }if (subShapesMap.size() > 0) { List removeSubFlowsList = new ArrayList(); for (FlowElement flowElement : process .findFlowElementsOfType(SequenceFlow.class)) { SequenceFlow sequenceFlow = (SequenceFlow) flowElement; if (subShapesMap.containsKey(sequenceFlow.getSourceRef())) { SubProcess subProcess = subShapesMap.get(sequenceFlow .getSourceRef()); if (subProcess.getFlowElement(sequenceFlow.getId()) == null) { subProcess.addFlowElement(sequenceFlow); removeSubFlowsList.add(sequenceFlow.getId()); } } }for (String flowId : removeSubFlowsList) { process.removeFlowElement(flowId); } } }Map allFlowMap = new HashMap(); List gatewayWithOrderList = new ArrayList(); // post handling of process elements for (Process process : bpmnModel.getProcesses()) { postProcessElements(process, process.getFlowElements(), edgeMap, bpmnModel, allFlowMap, gatewayWithOrderList); }// sort the sequence flows for (Gateway gateway : gatewayWithOrderList) { List orderList = gateway.getExtensionElements() .get("EDITOR_FLOW_ORDER"); if (CollectionUtils.isNotEmpty(orderList)) { for (ExtensionElement orderElement : orderList) { String flowValue = https://www.it610.com/article/orderElement.getElementText(); if (StringUtils.isNotEmpty(flowValue)) { if (allFlowMap.containsKey(flowValue)) { FlowWithContainer flowWithContainer = allFlowMap .get(flowValue); flowWithContainer.getFlowContainer() .removeFlowElement( flowWithContainer.getSequenceFlow() .getId()); flowWithContainer .getFlowContainer() .addFlowElement( flowWithContainer.getSequenceFlow()); } } } }gateway.getExtensionElements().remove("EDITOR_FLOW_ORDER"); }return bpmnModel; }public void processJsonElements(JsonNode shapesArrayNode, JsonNode modelNode, BaseElement parentElement, Map shapeMap, BpmnModel bpmnModel) { for (JsonNode shapeNode : shapesArrayNode) { String stencilId = BpmnJsonConverterUtil.getStencilId(shapeNode); Class converter = convertersToBpmnMap .get(stencilId); try { BaseBpmnJsonConverter converterInstance = converter .newInstance(); converterInstance.convertToBpmnModel(shapeNode, modelNode, this, parentElement, shapeMap, bpmnModel); } catch (Exception e) { LOGGER.error("Error converting {}", BpmnJsonConverterUtil.getStencilId(shapeNode), e); } } }private void fillSubShapes(Map subShapesMap, SubProcess subProcess) { for (FlowElement flowElement : subProcess.getFlowElements()) { if (flowElement instanceof SubProcess) { SubProcess childSubProcess = (SubProcess) flowElement; subShapesMap.put(childSubProcess.getId(), subProcess); fillSubShapes(subShapesMap, childSubProcess); } else { subShapesMap.put(flowElement.getId(), subProcess); } } }private void postProcessElements(FlowElementsContainer parentContainer, Collection flowElementList, Map edgeMap, BpmnModel bpmnModel, Map allFlowMap, List gatewayWithOrderList) { for (FlowElement flowElement : flowElementList) { if (flowElement instanceof Event) { Event event = (Event) flowElement; if (CollectionUtils.isNotEmpty(event.getEventDefinitions())) { EventDefinition eventDef = event.getEventDefinitions().get( 0); if (eventDef instanceof SignalEventDefinition) { SignalEventDefinition signalEventDef = (SignalEventDefinition) eventDef; if (StringUtils.isNotEmpty(signalEventDef .getSignalRef())) { if (bpmnModel.getSignal(signalEventDef .getSignalRef()) == null) { bpmnModel.addSignal(new Signal(signalEventDef .getSignalRef(), signalEventDef .getSignalRef())); } } } else if (eventDef instanceof MessageEventDefinition) { MessageEventDefinition messageEventDef = (MessageEventDefinition) eventDef; if (StringUtils.isNotEmpty(messageEventDef .getMessageRef())) { if (bpmnModel.getMessage(messageEventDef .getMessageRef()) == null) { bpmnModel.addMessage(new Message( messageEventDef.getMessageRef(), messageEventDef.getMessageRef(), null)); } } } } }if (flowElement instanceof BoundaryEvent) { BoundaryEvent boundaryEvent = (BoundaryEvent) flowElement; Activity activity = retrieveAttachedRefObject( boundaryEvent.getAttachedToRefId(), parentContainer.getFlowElements()); if (activity == null) { LOGGER.warn("Boundary event " + boundaryEvent.getId() + " is not attached to any activity"); } else { boundaryEvent.setAttachedToRef(activity); activity.getBoundaryEvents().add(boundaryEvent); } } else if (flowElement instanceof Gateway) { if (flowElement.getExtensionElements().containsKey( "EDITOR_FLOW_ORDER")) { gatewayWithOrderList.add((Gateway) flowElement); } } else if (flowElement instanceof SubProcess) { SubProcess subProcess = (SubProcess) flowElement; postProcessElements(subProcess, subProcess.getFlowElements(), edgeMap, bpmnModel, allFlowMap, gatewayWithOrderList); } else if (flowElement instanceof SequenceFlow) { SequenceFlow sequenceFlow = (SequenceFlow) flowElement; FlowElement sourceFlowElement = parentContainer .getFlowElement(sequenceFlow.getSourceRef()); if ((sourceFlowElement != null) && sourceFlowElement instanceof FlowNode) { FlowWithContainer flowWithContainer = new FlowWithContainer( sequenceFlow, parentContainer); if ((sequenceFlow.getExtensionElements().get( "EDITOR_RESOURCEID") != null) && (sequenceFlow.getExtensionElements() .get("EDITOR_RESOURCEID").size() > 0)) { allFlowMap.put( sequenceFlow.getExtensionElements() .get("EDITOR_RESOURCEID").get(0) .getElementText(), flowWithContainer); sequenceFlow.getExtensionElements().remove( "EDITOR_RESOURCEID"); }((FlowNode) sourceFlowElement).getOutgoingFlows().add( sequenceFlow); JsonNode edgeNode = edgeMap.get(sequenceFlow.getId()); if (edgeNode != null) { boolean isDefault = JsonConverterUtil .getPropertyValueAsBoolean("defaultflow", edgeNode); if (isDefault) { if (sourceFlowElement instanceof Activity) { ((Activity) sourceFlowElement) .setDefaultFlow(sequenceFlow.getId()); } else if (sourceFlowElement instanceof Gateway) { ((Gateway) sourceFlowElement) .setDefaultFlow(sequenceFlow.getId()); } } } }FlowElement targetFlowElement = parentContainer .getFlowElement(sequenceFlow.getTargetRef()); if ((targetFlowElement != null) && targetFlowElement instanceof FlowNode) { ((FlowNode) targetFlowElement).getIncomingFlows().add( sequenceFlow); } } } }private Activity retrieveAttachedRefObject(String attachedToRefId, Collection flowElementList) { Activity activity = null; if (StringUtils.isNotEmpty(attachedToRefId)) { for (FlowElement flowElement : flowElementList) { if (attachedToRefId.equals(flowElement.getId())) { activity = (Activity) flowElement; break; } else if (flowElement instanceof SubProcess) { SubProcess subProcess = (SubProcess) flowElement; Activity retrievedActivity = retrieveAttachedRefObject( attachedToRefId, subProcess.getFlowElements()); if (retrievedActivity != null) { activity = retrievedActivity; break; } } } }return activity; }private void readShapeDI(JsonNode objectNode, double parentX, double parentY, Map shapeMap, Map sourceRefMap, BpmnModel bpmnModel) { if (objectNode.get(EDITOR_CHILD_SHAPES) != null) { for (JsonNode jsonChildNode : objectNode.get(EDITOR_CHILD_SHAPES)) { String stencilId = BpmnJsonConverterUtil .getStencilId(jsonChildNode); if (STENCIL_SEQUENCE_FLOW.equals(stencilId) == false) { GraphicInfo graphicInfo = new GraphicInfo(); JsonNode boundsNode = jsonChildNode.get(EDITOR_BOUNDS); ObjectNode upperLeftNode = (ObjectNode) boundsNode .get(EDITOR_BOUNDS_UPPER_LEFT); graphicInfo.setX(upperLeftNode.get(EDITOR_BOUNDS_X) .asDouble() + parentX); graphicInfo.setY(upperLeftNode.get(EDITOR_BOUNDS_Y) .asDouble() + parentY); ObjectNode lowerRightNode = (ObjectNode) boundsNode .get(EDITOR_BOUNDS_LOWER_RIGHT); graphicInfo.setWidth(lowerRightNode.get(EDITOR_BOUNDS_X) .asDouble() - graphicInfo.getX() + parentX); graphicInfo.setHeight(lowerRightNode.get(EDITOR_BOUNDS_Y) .asDouble() - graphicInfo.getY() + parentY); String childShapeId = jsonChildNode.get(EDITOR_SHAPE_ID) .asText(); bpmnModel.addGraphicInfo( BpmnJsonConverterUtil.getElementId(jsonChildNode), graphicInfo); shapeMap.put(childShapeId, jsonChildNode); ArrayNode outgoingNode = (ArrayNode) jsonChildNode .get("outgoing"); if ((outgoingNode != null) && (outgoingNode.size() > 0)) { for (JsonNode outgoingChildNode : outgoingNode) { JsonNode resourceNode = outgoingChildNode .get(EDITOR_SHAPE_ID); if (resourceNode != null) { sourceRefMap.put(resourceNode.asText(), jsonChildNode); } } }readShapeDI(jsonChildNode, graphicInfo.getX(), graphicInfo.getY(), shapeMap, sourceRefMap, bpmnModel); } } } }private void filterAllEdges(JsonNode objectNode, Map edgeMap, Map> sourceAndTargetMap, Map shapeMap, Map sourceRefMap) { if (objectNode.get(EDITOR_CHILD_SHAPES) != null) { for (JsonNode jsonChildNode : objectNode.get(EDITOR_CHILD_SHAPES)) { ObjectNode childNode = (ObjectNode) jsonChildNode; String stencilId = BpmnJsonConverterUtil .getStencilId(childNode); if (STENCIL_SUB_PROCESS.equals(stencilId)) { filterAllEdges(childNode, edgeMap, sourceAndTargetMap, shapeMap, sourceRefMap); } else if (STENCIL_SEQUENCE_FLOW.equals(stencilId) || STENCIL_ASSOCIATION.equals(stencilId)) { String childEdgeId = BpmnJsonConverterUtil .getElementId(childNode); JsonNode targetNode = childNode.get("target"); if ((targetNode != null) && (targetNode.isNull() == false)) { String targetRefId = targetNode.get(EDITOR_SHAPE_ID) .asText(); List sourceAndTargetList = new ArrayList(); sourceAndTargetList.add(sourceRefMap.get(childNode.get( EDITOR_SHAPE_ID).asText())); sourceAndTargetList.add(shapeMap.get(targetRefId)); sourceAndTargetMap .put(childEdgeId, sourceAndTargetList); }edgeMap.put(childEdgeId, childNode); } } } }private void readEdgeDI(Map edgeMap, Map> sourceAndTargetMap, BpmnModel bpmnModel) { for (String edgeId : edgeMap.keySet()) { JsonNode edgeNode = edgeMap.get(edgeId); List sourceAndTargetList = sourceAndTargetMap.get(edgeId); JsonNode sourceRefNode = null; JsonNode targetRefNode = null; if ((sourceAndTargetList != null) && (sourceAndTargetList.size() > 1)) { sourceRefNode = sourceAndTargetList.get(0); targetRefNode = sourceAndTargetList.get(1); }if (sourceRefNode == null) { LOGGER.info("Skipping edge {} because source ref is null", edgeId); continue; }if (targetRefNode == null) { LOGGER.info("Skipping edge {} because target ref is null", edgeId); continue; }JsonNode dockersNode = edgeNode.get(EDITOR_DOCKERS); double sourceDockersX = dockersNode.get(0).get(EDITOR_BOUNDS_X) .asDouble(); double sourceDockersY = dockersNode.get(0).get(EDITOR_BOUNDS_Y) .asDouble(); GraphicInfo sourceInfo = bpmnModel .getGraphicInfo(BpmnJsonConverterUtil .getElementId(sourceRefNode)); GraphicInfo targetInfo = bpmnModel .getGraphicInfo(BpmnJsonConverterUtil .getElementId(targetRefNode)); double sourceRefLineX = sourceInfo.getX() + sourceDockersX; double sourceRefLineY = sourceInfo.getY() + sourceDockersY; double nextPointInLineX; double nextPointInLineY; nextPointInLineX = dockersNode.get(1).get(EDITOR_BOUNDS_X) .asDouble(); nextPointInLineY = dockersNode.get(1).get(EDITOR_BOUNDS_Y) .asDouble(); if (dockersNode.size() == 2) { nextPointInLineX += targetInfo.getX(); nextPointInLineY += targetInfo.getY(); }Line2D firstLine = new Line2D(sourceRefLineX, sourceRefLineY, nextPointInLineX, nextPointInLineY); String sourceRefStencilId = BpmnJsonConverterUtil .getStencilId(sourceRefNode); String targetRefStencilId = BpmnJsonConverterUtil .getStencilId(targetRefNode); List graphicInfoList = new ArrayList(); AbstractContinuousCurve2D source2D = null; if (DI_CIRCLES.contains(sourceRefStencilId)) { source2D = new Circle2D(sourceInfo.getX() + sourceDockersX, sourceInfo.getY() + sourceDockersY, sourceDockersX); } else if (DI_RECTANGLES.contains(sourceRefStencilId)) { source2D = createRectangle(sourceInfo); } else if (DI_GATEWAY.contains(sourceRefStencilId)) { source2D = createGateway(sourceInfo); }if (source2D != null) { Collection intersections = source2D .intersections(firstLine); if ((intersections != null) && (intersections.size() > 0)) { Point2D intersection = intersections.iterator().next(); graphicInfoList.add(createGraphicInfo(intersection.x(), intersection.y())); } else { graphicInfoList.add(createGraphicInfo(sourceRefLineX, sourceRefLineY)); } }Line2D lastLine = null; if (dockersNode.size() > 2) { for (int i = 1; i < (dockersNode.size() - 1); i++) { double x = dockersNode.get(i).get(EDITOR_BOUNDS_X) .asDouble(); double y = dockersNode.get(i).get(EDITOR_BOUNDS_Y) .asDouble(); graphicInfoList.add(createGraphicInfo(x, y)); }double startLastLineX = dockersNode.get(dockersNode.size() - 2) .get(EDITOR_BOUNDS_X).asDouble(); double startLastLineY = dockersNode.get(dockersNode.size() - 2) .get(EDITOR_BOUNDS_Y).asDouble(); double endLastLineX = dockersNode.get(dockersNode.size() - 1) .get(EDITOR_BOUNDS_X).asDouble(); double endLastLineY = dockersNode.get(dockersNode.size() - 1) .get(EDITOR_BOUNDS_Y).asDouble(); endLastLineX += targetInfo.getX(); endLastLineY += targetInfo.getY(); lastLine = new Line2D(startLastLineX, startLastLineY, endLastLineX, endLastLineY); } else { lastLine = firstLine; }AbstractContinuousCurve2D target2D = null; if (DI_RECTANGLES.contains(targetRefStencilId)) { target2D = createRectangle(targetInfo); } else if (DI_CIRCLES.contains(targetRefStencilId)) { double targetDockersX = dockersNode.get(dockersNode.size() - 1) .get(EDITOR_BOUNDS_X).asDouble(); double targetDockersY = dockersNode.get(dockersNode.size() - 1) .get(EDITOR_BOUNDS_Y).asDouble(); target2D = new Circle2D(targetInfo.getX() + targetDockersX, targetInfo.getY() + targetDockersY, targetDockersX); } else if (DI_GATEWAY.contains(targetRefStencilId)) { target2D = createGateway(targetInfo); }if (target2D != null) { Collection intersections = target2D .intersections(lastLine); if ((intersections != null) && (intersections.size() > 0)) { Point2D intersection = intersections.iterator().next(); graphicInfoList.add(createGraphicInfo(intersection.x(), intersection.y())); } else { graphicInfoList.add(createGraphicInfo(lastLine.getPoint2() .x(), lastLine.getPoint2().y())); } }bpmnModel.addFlowGraphicInfoList(edgeId, graphicInfoList); // if sequence has a name, just add a label graphic info if (!"".equals(edgeNode.get("properties").get("name"))) { bpmnModel.addLabelGraphicInfo( edgeId, createGraphicInfo(graphicInfoList.get(0).getX(), graphicInfoList.get(0).getY())); } } }private Polyline2D createRectangle(GraphicInfo graphicInfo) { Polyline2D rectangle = new Polyline2D(new Point2D(graphicInfo.getX(), graphicInfo.getY()), new Point2D(graphicInfo.getX() + graphicInfo.getWidth(), graphicInfo.getY()), new Point2D( graphicInfo.getX() + graphicInfo.getWidth(), graphicInfo.getY() + graphicInfo.getHeight()), new Point2D( graphicInfo.getX(), graphicInfo.getY() + graphicInfo.getHeight()), new Point2D( graphicInfo.getX(), graphicInfo.getY())); return rectangle; }private Polyline2D createGateway(GraphicInfo graphicInfo) { double middleX = graphicInfo.getX() + (graphicInfo.getWidth() / 2); double middleY = graphicInfo.getY() + (graphicInfo.getHeight() / 2); Polyline2D gatewayRectangle = new Polyline2D(new Point2D( graphicInfo.getX(), middleY), new Point2D(middleX, graphicInfo.getY()), new Point2D(graphicInfo.getX() + graphicInfo.getWidth(), middleY), new Point2D(middleX, graphicInfo.getY() + graphicInfo.getHeight()), new Point2D( graphicInfo.getX(), middleY)); return gatewayRectangle; }private GraphicInfo createGraphicInfo(double x, double y) { GraphicInfo graphicInfo = new GraphicInfo(); graphicInfo.setX(x); graphicInfo.setY(y); return graphicInfo; }class FlowWithContainer { protected SequenceFlow sequenceFlow; protected FlowElementsContainer flowContainer; public FlowWithContainer(SequenceFlow sequenceFlow, FlowElementsContainer flowContainer) { this.sequenceFlow = sequenceFlow; this.flowContainer = flowContainer; }public SequenceFlow getSequenceFlow() { return sequenceFlow; }public void setSequenceFlow(SequenceFlow sequenceFlow) { this.sequenceFlow = sequenceFlow; }public FlowElementsContainer getFlowContainer() { return flowContainer; }public void setFlowContainer(FlowElementsContainer flowContainer) { this.flowContainer = flowContainer; } } }

重新转换模板再查看流程图进行验证。
注:这样解决虽然能显示连线名称了,但是会出现连线名称显示位置不准确的问题。解决办法:重写DefaultProcessDiagramGenerator类的generateProcessDiagram方法:
public CustomProcessDiagramCanvas generateProcessDiagram(BpmnModel bpmnModel, String imageType, List highLightedActivities, List highLightedFlows, String activityFontName, String labelFontName, String annotationFontName, ClassLoader customClassLoader, double scaleFactor, Color [] colors) { prepareBpmnModel(bpmnModel); CustomProcessDiagramCanvas processDiagramCanvas = initProcessDiagramCanvas(bpmnModel, imageType, activityFontName, labelFontName, annotationFontName, customClassLoader); // Draw pool shape, if process is participant in collaboration for (Pool pool : bpmnModel.getPools()) { GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(pool.getId()); processDiagramCanvas.drawPoolOrLane(pool.getName(), graphicInfo); }// Draw lanes for (Process process : bpmnModel.getProcesses()) { for (Lane lane : process.getLanes()) { GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(lane.getId()); processDiagramCanvas.drawPoolOrLane(lane.getName(), graphicInfo); } }// Draw activities and their sequence-flows for (Process process: bpmnModel.getProcesses()) { List flowNodeList= process.findFlowElementsOfType(FlowNode.class); for (FlowNode flowNode : flowNodeList) { drawActivity(processDiagramCanvas, bpmnModel, flowNode, highLightedActivities, highLightedFlows, scaleFactor, colors); } }// Draw artifacts for (Process process : bpmnModel.getProcesses()) {for (Artifact artifact : process.getArtifacts()) { drawArtifact(processDiagramCanvas, bpmnModel, artifact); }List subProcesses = process.findFlowElementsOfType(SubProcess.class, true); if (subProcesses != null) { for (SubProcess subProcess : subProcesses) { for (Artifact subProcessArtifact : subProcess.getArtifacts()) { drawArtifact(processDiagramCanvas, bpmnModel, subProcessArtifact); } } } }return processDiagramCanvas; }protected void drawActivity(CustomProcessDiagramCanvas processDiagramCanvas, BpmnModel bpmnModel, FlowNode flowNode, List highLightedActivities, List highLightedFlows, double scaleFactor, Color[] colors) { ActivityDrawInstruction drawInstruction = activityDrawInstructions.get(flowNode.getClass()); if (drawInstruction != null) {drawInstruction.draw(processDiagramCanvas, bpmnModel, flowNode); // Gather info on the multi instance marker boolean multiInstanceSequential = false, multiInstanceParallel = false, collapsed = false; if (flowNode instanceof Activity) { Activity activity = (Activity) flowNode; MultiInstanceLoopCharacteristics multiInstanceLoopCharacteristics = activity.getLoopCharacteristics(); if (multiInstanceLoopCharacteristics != null) { multiInstanceSequential = multiInstanceLoopCharacteristics.isSequential(); multiInstanceParallel = !multiInstanceSequential; } }// Gather info on the collapsed marker GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(flowNode.getId()); if (flowNode instanceof SubProcess) { collapsed = graphicInfo.getExpanded() != null && !graphicInfo.getExpanded(); } else if (flowNode instanceof CallActivity) { collapsed = true; }if (scaleFactor == 1.0) { // Actually draw the markers processDiagramCanvas.drawActivityMarkers((int) graphicInfo.getX(), (int) graphicInfo.getY(),(int) graphicInfo.getWidth(), (int) graphicInfo.getHeight(), multiInstanceSequential, multiInstanceParallel, collapsed); }// Draw highlighted activities if (highLightedActivities.contains(flowNode.getId())) { if(flowNode.getId().equals(highLightedActivities.get(highLightedActivities.size()-1)) && !(flowNode instanceof EndEvent)) {//非结束节点,并且是当前节点 drawHighLight((flowNode instanceof StartEvent), processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[1]); }else {//普通节点 drawHighLight((flowNode instanceof StartEvent)||(flowNode instanceof EndEvent),processDiagramCanvas, bpmnModel.getGraphicInfo(flowNode.getId()), colors[0]); } }}// Outgoing transitions of activity for (SequenceFlow sequenceFlow : flowNode.getOutgoingFlows()) { boolean highLighted = (highLightedFlows.contains(sequenceFlow.getId())); String defaultFlow = null; if (flowNode instanceof Activity) { defaultFlow = ((Activity) flowNode).getDefaultFlow(); } else if (flowNode instanceof Gateway) { defaultFlow = ((Gateway) flowNode).getDefaultFlow(); }boolean isDefault = false; if (defaultFlow != null && defaultFlow.equalsIgnoreCase(sequenceFlow.getId())) { isDefault = true; } //boolean drawConditionalIndicator = sequenceFlow.getConditionExpression() != null && !(flowNode instanceof Gateway); String sourceRef = sequenceFlow.getSourceRef(); String targetRef = sequenceFlow.getTargetRef(); FlowElement sourceElement = bpmnModel.getFlowElement(sourceRef); FlowElement targetElement = bpmnModel.getFlowElement(targetRef); List graphicInfoList = bpmnModel.getFlowLocationGraphicInfo(sequenceFlow.getId()); if (graphicInfoList != null && graphicInfoList.size() > 0) { graphicInfoList = connectionPerfectionizer(processDiagramCanvas, bpmnModel, sourceElement, targetElement, graphicInfoList); int xPoints[]= new int[graphicInfoList.size()]; int yPoints[]= new int[graphicInfoList.size()]; for (int i=1; i= 5); //} } }

【解决activiti中由模板转换的流程图连线名称缺失问题】重点修改之处在注释的几行代码上,请读者自己查看思考。

    推荐阅读