flowable使用extensionElements自定义节点
发布日期:2021-06-29 11:46:53 浏览次数:2 分类:技术文章

本文共 45942 字,大约阅读时间需要 153 分钟。

flowable在extensionElements自定义节点,可以用作表单全局设置等

流程xml的结构如下

代码方面,自定义解析器 继承BpmnJsonConverter,重写convertToJson、convertToBpmnModel等方法

convertToJson增加以下内容:

convertToBpmnModel增加以下内容:

自定义解析器代码如下:

package com.hnac.hzinfo.flowable.utils;import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.node.ArrayNode;import com.fasterxml.jackson.databind.node.ObjectNode;import org.apache.commons.lang3.StringUtils;import org.flowable.bpmn.model.*;import org.flowable.bpmn.model.Process;import org.flowable.editor.language.json.converter.BpmnJsonConverter;import org.flowable.editor.language.json.converter.BpmnJsonConverterUtil;import org.flowable.editor.language.json.converter.SequenceFlowJsonConverter;import org.flowable.editor.language.json.converter.util.CollectionUtils;import org.flowable.editor.language.json.converter.util.JsonConverterUtil;import org.flowable.editor.language.json.model.ModelInfo;import java.awt.geom.Area;import java.util.*;/** * 自定义BpmnJsonConverter * @Date 2020/2/26 **/public class CustomBpmnJsonConverter extends BpmnJsonConverter {    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 { convertersToBpmnMap.put(STENCIL_TASK_USER,CustomUserTaskJsonConverter.class); } @Override public ObjectNode convertToJson(BpmnModel model, Map
formKeyMap, Map
decisionTableKeyMap) { 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.set("bounds", BpmnJsonConverterUtil.createBoundsNode(maxX, maxY, 0, 0)); modelNode.put("resourceId", "canvas"); ObjectNode stencilNode = objectMapper.createObjectNode(); stencilNode.put("id", "BPMNDiagram"); modelNode.set("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.set("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()) { propertiesNode.put(PROPERTY_IS_EXECUTABLE, "false"); } if (StringUtils.isNoneEmpty(model.getTargetNamespace())) { propertiesNode.put(PROPERTY_PROCESS_NAMESPACE, model.getTargetNamespace()); } if (CollectionUtils.isNotEmpty(mainProcess.getCandidateStarterGroups())) { propertiesNode.put(PROPERTY_PROCESS_POTENTIALSTARTERGROUP, StringUtils.join(mainProcess.getCandidateStarterGroups(), ",")); } if (CollectionUtils.isNotEmpty(mainProcess.getCandidateStarterUsers())) { propertiesNode.put(PROPERTY_PROCESS_POTENTIALSTARTERUSER, StringUtils.join(mainProcess.getCandidateStarterUsers(), ",")); } if (mainProcess.getExtensionElements().containsKey("historyLevel")) { List
historyExtensionElements = mainProcess.getExtensionElements().get("historyLevel"); if (historyExtensionElements != null && historyExtensionElements.size() > 0) { String historyLevel = historyExtensionElements.get(0).getElementText(); if (StringUtils.isNotEmpty(historyLevel)) { propertiesNode.put(PROPERTY_PROCESS_HISTORYLEVEL, historyLevel); } } } //自定义扩展节点 if (mainProcess.getExtensionElements().containsKey("customSetting")) { List
historyExtensionElements = mainProcess.getExtensionElements().get("customSetting"); if (historyExtensionElements != null && historyExtensionElements.size() > 0) { String customSetting = historyExtensionElements.get(0).getElementText(); if (StringUtils.isNotEmpty(customSetting)) { propertiesNode.put("customSetting", customSetting); } } } propertiesNode.put(PROPERTY_IS_EAGER_EXECUTION_FETCHING, Boolean.valueOf(mainProcess.isEnableEagerExecutionTreeFetching())); BpmnJsonConverterUtil.convertMessagesToJson(model.getMessages(), propertiesNode); BpmnJsonConverterUtil.convertListenersToJson(mainProcess.getExecutionListeners(), true, propertiesNode); BpmnJsonConverterUtil.convertEventListenersToJson(mainProcess.getEventListeners(), propertiesNode); BpmnJsonConverterUtil.convertSignalDefinitionsToJson(model, propertiesNode); BpmnJsonConverterUtil.convertMessagesToJson(model, propertiesNode); BpmnJsonConverterUtil.convertEscalationDefinitionsToJson(model, propertiesNode); if (CollectionUtils.isNotEmpty(mainProcess.getDataObjects())) { BpmnJsonConverterUtil.convertDataPropertiesToJson(mainProcess.getDataObjects(), propertiesNode); } modelNode.set(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 poolGraphicInfo = model.getGraphicInfo(pool.getId()); if (poolGraphicInfo == null) continue; ObjectNode poolNode = BpmnJsonConverterUtil.createChildShape(pool.getId(), STENCIL_POOL, poolGraphicInfo.getX() + poolGraphicInfo.getWidth(), poolGraphicInfo.getY() + poolGraphicInfo.getHeight(), poolGraphicInfo.getX(), poolGraphicInfo.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()) { poolPropertiesNode.put(PROPERTY_IS_EXECUTABLE, "false"); } if (StringUtils.isNotEmpty(pool.getName())) { poolPropertiesNode.put(PROPERTY_NAME, pool.getName()); } poolNode.set(EDITOR_SHAPE_PROPERTIES, poolPropertiesNode); ArrayNode laneShapesArrayNode = objectMapper.createArrayNode(); poolNode.set(EDITOR_CHILD_SHAPES, laneShapesArrayNode); ArrayNode outgoingArrayNode = objectMapper.createArrayNode(); poolNode.set("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() - poolGraphicInfo.getX(), laneGraphicInfo.getY() + laneGraphicInfo.getHeight() - poolGraphicInfo.getY(), laneGraphicInfo.getX() - poolGraphicInfo.getX(), laneGraphicInfo.getY() - poolGraphicInfo.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.set(EDITOR_SHAPE_PROPERTIES, lanePropertiesNode); ArrayNode elementShapesArrayNode = objectMapper.createArrayNode(); laneNode.set(EDITOR_CHILD_SHAPES, elementShapesArrayNode); laneNode.set("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()), formKeyMap, decisionTableKeyMap, 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, formKeyMap, decisionTableKeyMap, 0.0, 0.0); processMessageFlows(model, shapesArrayNode); } modelNode.set(EDITOR_CHILD_SHAPES, shapesArrayNode); return modelNode; } @Override public BpmnModel convertToBpmnModel(JsonNode modelNode, Map
formKeyMap, Map
decisionTableKeyMap) { BpmnModel bpmnModel = new BpmnModel(); bpmnModel.setTargetNamespace("http://flowable.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_IS_EXECUTABLE, shapeNode, true)); bpmnModel.getPools().add(pool); Process process = new Process(); process.setId(pool.getProcessRef()); process.setName(pool.getName()); process.setExecutable(pool.isExecutable()); process.setEnableEagerExecutionTreeFetching(JsonConverterUtil.getPropertyValueAsBoolean(PROPERTY_IS_EAGER_EXECUTION_FETCHING, shapeNode, false)); 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); } 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, formKeyMap, decisionTableKeyMap, 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(); if (StringUtils.isNotEmpty(signalId) && StringUtils.isNotEmpty(signalName)) { 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); } } } } // Escalation Definitions exist on the root level JsonNode escalationDefinitionNode = BpmnJsonConverterUtil.getProperty(PROPERTY_ESCALATION_DEFINITIONS, modelNode); escalationDefinitionNode = BpmnJsonConverterUtil.validateIfNodeIsTextual(escalationDefinitionNode); escalationDefinitionNode = BpmnJsonConverterUtil.validateIfNodeIsTextual(escalationDefinitionNode); // no idea why this needs to be done twice .. if (escalationDefinitionNode != null) { if (escalationDefinitionNode instanceof ArrayNode) { ArrayNode escalationDefinitionArrayNode = (ArrayNode) escalationDefinitionNode; for (JsonNode signalDefinitionJsonNode : escalationDefinitionArrayNode) { String escalationId = signalDefinitionJsonNode.get(PROPERTY_ESCALATION_DEFINITION_ID).asText(); String escalationName = signalDefinitionJsonNode.get(PROPERTY_ESCALATION_DEFINITION_NAME).asText(); if (StringUtils.isNotEmpty(escalationId) && StringUtils.isNotEmpty(escalationName)) { Escalation escalation = new Escalation(); escalation.setId(escalationId); escalation.setEscalationCode(escalationId); escalation.setName(escalationName); bpmnModel.addEscalation(escalation); } } } } if (!nonEmptyPoolFound) { 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_IS_EXECUTABLE, modelNode); if (processExecutableNode != null && StringUtils.isNotEmpty(processExecutableNode.asText())) { process.setExecutable(JsonConverterUtil.getPropertyValueAsBoolean(PROPERTY_IS_EXECUTABLE, modelNode)); } String historyLevel = BpmnJsonConverterUtil.getPropertyValueAsString(PROPERTY_PROCESS_HISTORYLEVEL, modelNode); if (StringUtils.isNotEmpty(historyLevel)) { ExtensionElement historyExtensionElement = new ExtensionElement(); historyExtensionElement.setName("historyLevel"); historyExtensionElement.setNamespace("http://flowable.org/bpmn"); historyExtensionElement.setNamespacePrefix("flowable"); historyExtensionElement.setElementText(historyLevel); process.addExtensionElement(historyExtensionElement); } //自定义节点 String customSetting = BpmnJsonConverterUtil.getPropertyValueAsString("customSetting", modelNode); if (StringUtils.isNotEmpty(customSetting)) { ExtensionElement customSettingExtensionElement = new ExtensionElement(); customSettingExtensionElement.setName("customSetting"); customSettingExtensionElement.setNamespace("http://flowable.org/bpmn"); customSettingExtensionElement.setNamespacePrefix("flowable"); customSettingExtensionElement.setElementText(customSetting); process.addExtensionElement(customSettingExtensionElement); } 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); } String userStarterValue = BpmnJsonConverterUtil.getPropertyValueAsString(PROPERTY_PROCESS_POTENTIALSTARTERUSER, modelNode); String groupStarterValue = BpmnJsonConverterUtil.getPropertyValueAsString(PROPERTY_PROCESS_POTENTIALSTARTERGROUP, modelNode); if (StringUtils.isNotEmpty(userStarterValue)) { String userStartArray[] = userStarterValue.split(","); List
userStarters = new ArrayList<>(Arrays.asList(userStartArray)); process.setCandidateStarterUsers(userStarters); } if (StringUtils.isNotEmpty(groupStarterValue)) { String groupStarterArray[] = groupStarterValue.split(","); List
groupStarters = new ArrayList<>(Arrays.asList(groupStarterArray)); process.setCandidateStarterGroups(groupStarters); } process.setEnableEagerExecutionTreeFetching(JsonConverterUtil.getPropertyValueAsBoolean(PROPERTY_IS_EAGER_EXECUTION_FETCHING, modelNode, false)); processJsonElements(shapesArrayNode, modelNode, process, shapeMap, formKeyMap, decisionTableKeyMap, 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()); } } } List
collapsedSubProcess = new ArrayList<>(); for (SubProcess subProcess : subShapesMap.values()) { // determine if its a collapsed subprocess GraphicInfo graphicInfo = bpmnModel.getGraphicInfo(subProcess.getId()); if (graphicInfo != null && Boolean.FALSE.equals(graphicInfo.getExpanded())){ collapsedSubProcess.add(subProcess); } } for (String flowId : removeSubFlowsList) { process.removeFlowElement(flowId); // check if the sequenceflow to remove is not assigned to a collapsed subprocess. for (SubProcess subProcess : collapsedSubProcess) { subProcess.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 = 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; } private void postProcessElements(FlowElementsContainer parentContainer, Collection
flowElementList, Map
edgeMap, BpmnModel bpmnModel, Map
allFlowMap, List
gatewayWithOrderList) { for (FlowElement flowElement : flowElementList) { parentContainer.addFlowElementToMap(flowElement); 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 {} is not attached to any activity", boundaryEvent.getId()); } 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 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(PROPERTY_SEQUENCEFLOW_DEFAULT, 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 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)) { GraphicInfo graphicInfo = new GraphicInfo(); JsonNode boundsNode = jsonChildNode.get(EDITOR_BOUNDS); ObjectNode upperLeftNode = (ObjectNode) boundsNode.get(EDITOR_BOUNDS_UPPER_LEFT); ObjectNode lowerRightNode = (ObjectNode) boundsNode.get(EDITOR_BOUNDS_LOWER_RIGHT); graphicInfo.setX(upperLeftNode.get(EDITOR_BOUNDS_X).asDouble() + parentX); graphicInfo.setY(upperLeftNode.get(EDITOR_BOUNDS_Y).asDouble() + parentY); 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); } } } //The graphic info of the collapsed subprocess is relative to its parent. //But the children of the collapsed subprocess are relative to the canvas upper corner. (always 0,0) if (STENCIL_COLLAPSED_SUB_PROCESS.equals(stencilId)) { readShapeDI(jsonChildNode, 0,0, shapeMap, sourceRefMap, bpmnModel); } else { 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) || STENCIL_POOL.equals(stencilId) || STENCIL_LANE.equals(stencilId) || STENCIL_COLLAPSED_SUB_PROCESS.equals(stencilId) || STENCIL_EVENT_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()) { 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(); } java.awt.geom.Line2D firstLine = new java.awt.geom.Line2D.Double(sourceRefLineX, sourceRefLineY, nextPointInLineX, nextPointInLineY); String sourceRefStencilId = BpmnJsonConverterUtil.getStencilId(sourceRefNode); String targetRefStencilId = BpmnJsonConverterUtil.getStencilId(targetRefNode); List
graphicInfoList = new ArrayList<>(); Area source2D = null; if (DI_CIRCLES.contains(sourceRefStencilId)) { source2D = createEllipse(sourceInfo, sourceDockersX, sourceDockersY); } else if (DI_RECTANGLES.contains(sourceRefStencilId)) { source2D = createRectangle(sourceInfo); } else if (DI_GATEWAY.contains(sourceRefStencilId)) { source2D = createGateway(sourceInfo); } if (source2D != null) { Collection
intersections = getIntersections(firstLine, source2D); if (intersections != null && intersections.size() > 0) { java.awt.geom.Point2D intersection = intersections.iterator().next(); graphicInfoList.add(createGraphicInfo(intersection.getX(), intersection.getY())); } else { graphicInfoList.add(createGraphicInfo(sourceRefLineX, sourceRefLineY)); } } java.awt.geom.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 java.awt.geom.Line2D.Double(startLastLineX, startLastLineY, endLastLineX, endLastLineY); } else { lastLine = firstLine; } Area 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 = createEllipse(targetInfo, targetDockersX, targetDockersY); } else if (DI_GATEWAY.contains(targetRefStencilId)) { target2D = createGateway(targetInfo); } if (target2D != null) { Collection
intersections = getIntersections(lastLine, target2D); if (intersections != null && intersections.size() > 0) { java.awt.geom.Point2D intersection = intersections.iterator().next(); graphicInfoList.add(createGraphicInfo(intersection.getX(), intersection.getY())); } else { graphicInfoList.add(createGraphicInfo(lastLine.getX2(), lastLine.getY2())); } } bpmnModel.addFlowGraphicInfoList(edgeId, graphicInfoList); } } private GraphicInfo createGraphicInfo(double x, double y) { GraphicInfo graphicInfo = new GraphicInfo(); graphicInfo.setX(x); graphicInfo.setY(y); return graphicInfo; } 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); } } } static 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; } }}
CustomUserTaskJsonConverter:
import com.fasterxml.jackson.databind.JsonNode;import com.fasterxml.jackson.databind.node.ArrayNode;import com.fasterxml.jackson.databind.node.ObjectNode;import org.apache.commons.collections.MapUtils;import org.apache.commons.lang3.StringUtils;import org.flowable.bpmn.model.*;import org.flowable.editor.constants.StencilConstants;import org.flowable.editor.language.json.converter.ActivityProcessor;import org.flowable.editor.language.json.converter.BaseBpmnJsonConverter;import org.flowable.editor.language.json.converter.UserTaskJsonConverter;import org.flowable.editor.language.json.converter.util.CollectionUtils;import org.flowable.editor.language.json.model.ModelInfo;import java.util.List;import java.util.Map;public class CustomUserTaskJsonConverter extends UserTaskJsonConverter {    public static final String IS_EDITDATA = "iseditdata";    public static final String NODE_TYPE = "nodetype";    public static void fillTypes(Map
> convertersToBpmnMap, Map
, Class
> convertersToJsonMap) { fillJsonTypes(convertersToBpmnMap); fillBpmnTypes(convertersToJsonMap); } public static void setCustomTypes(Map
> convertersToBpmnMap, Map
, Class
> convertersToJsonMap) { removeTypes(convertersToBpmnMap,convertersToJsonMap); fillTypes(convertersToBpmnMap,convertersToJsonMap); } public static void removeTypes(Map
> convertersToBpmnMap, Map
, Class
> convertersToJsonMap) { convertersToJsonMap.remove(UserTask.class); convertersToBpmnMap.remove(StencilConstants.STENCIL_TASK_USER); } public static void fillJsonTypes(Map
> convertersToBpmnMap) { convertersToBpmnMap.put(STENCIL_TASK_USER, CustomUserTaskJsonConverter.class); } public static void fillBpmnTypes( Map
, Class
> convertersToJsonMap) { convertersToJsonMap.put(UserTask.class, CustomUserTaskJsonConverter.class); } @Override public void convertToJson(BaseElement baseElement, ActivityProcessor processor, BpmnModel model, FlowElementsContainer container, ArrayNode shapesArrayNode, double subProcessX, double subProcessY){ super.convertToJson(baseElement, processor, model, container, shapesArrayNode, subProcessX, subProcessY); } @Override protected void convertElementToJson(ObjectNode propertiesNode, BaseElement baseElement) { UserTask userTask = (UserTask) baseElement; String assignee = userTask.getAssignee(); if (StringUtils.isNotEmpty(assignee) || CollectionUtils.isNotEmpty(userTask.getCandidateUsers()) || CollectionUtils.isNotEmpty(userTask.getCandidateGroups())) { ObjectNode assignmentNode = objectMapper.createObjectNode(); ObjectNode assignmentValuesNode = objectMapper.createObjectNode(); List
idmAssigneeList = userTask.getExtensionElements().get("activiti-idm-assignee"); List
idmAssigneeFieldList = userTask.getExtensionElements().get("activiti-idm-assignee-field"); if (CollectionUtils.isNotEmpty(idmAssigneeList) || CollectionUtils.isNotEmpty(idmAssigneeFieldList) || CollectionUtils.isNotEmpty(userTask.getExtensionElements().get("activiti-idm-candidate-user")) || CollectionUtils.isNotEmpty(userTask.getExtensionElements().get("activiti-idm-candidate-group"))) { assignmentValuesNode.put("type", "idm"); ObjectNode idmNode = objectMapper.createObjectNode(); assignmentValuesNode.set("idm", idmNode); List
canCompleteList = userTask.getExtensionElements().get("initiator-can-complete"); if (CollectionUtils.isNotEmpty(canCompleteList)) { assignmentValuesNode.put("initiatorCanCompleteTask", Boolean.valueOf(canCompleteList.get(0).getElementText())); } if (StringUtils.isNotEmpty(userTask.getAssignee())) { ObjectNode assigneeNode = objectMapper.createObjectNode(); assigneeNode.put("id", userTask.getAssignee()); idmNode.set("assignee", assigneeNode); idmNode.put("type", "user"); fillProperty("email", "assignee-info-email", assigneeNode, userTask); fillProperty("firstName", "assignee-info-firstname", assigneeNode, userTask); fillProperty("lastName", "assignee-info-lastname", assigneeNode, userTask); } List
idmCandidateUserList = userTask.getExtensionElements().get("activiti-idm-candidate-user"); if (CollectionUtils.isNotEmpty(userTask.getCandidateUsers()) && CollectionUtils.isNotEmpty(idmCandidateUserList)) { if (userTask.getCandidateUsers().size() > 0) { ArrayNode candidateUsersNode = objectMapper.createArrayNode(); idmNode.set("candidateUsers", candidateUsersNode); idmNode.put("type", "users"); for (String candidateUser : userTask.getCandidateUsers()) { ObjectNode candidateUserNode = objectMapper.createObjectNode(); candidateUserNode.put("id", candidateUser); candidateUsersNode.add(candidateUserNode); fillProperty("email", "user-info-email-" + candidateUser, candidateUserNode, userTask); fillProperty("firstName", "user-info-firstname-" + candidateUser, candidateUserNode, userTask); fillProperty("lastName", "user-info-lastname-" + candidateUser, candidateUserNode, userTask); } } } List
idmCandidateGroupList = userTask.getExtensionElements().get("activiti-idm-candidate-group"); if (CollectionUtils.isNotEmpty(userTask.getCandidateGroups()) && CollectionUtils.isNotEmpty(idmCandidateGroupList)) { if (userTask.getCandidateGroups().size() > 0) { ArrayNode candidateGroupsNode = objectMapper.createArrayNode(); idmNode.set("candidateGroups", candidateGroupsNode); idmNode.put("type", "groups"); for (String candidateGroup : userTask.getCandidateGroups()) { ObjectNode candidateGroupNode = objectMapper.createObjectNode(); candidateGroupNode.put("id", candidateGroup); candidateGroupsNode.add(candidateGroupNode); fillProperty("name", "group-info-name-" + candidateGroup, candidateGroupNode, userTask); } } } } else { assignmentValuesNode.put("type", "static"); if (StringUtils.isNotEmpty(assignee)) { assignmentValuesNode.put(PROPERTY_USERTASK_ASSIGNEE, assignee); } if (CollectionUtils.isNotEmpty(userTask.getCandidateUsers())) { ArrayNode candidateArrayNode = objectMapper.createArrayNode(); for (String candidateUser : userTask.getCandidateUsers()) { ObjectNode candidateNode = objectMapper.createObjectNode(); candidateNode.put("value", candidateUser); candidateArrayNode.add(candidateNode); } assignmentValuesNode.set(PROPERTY_USERTASK_CANDIDATE_USERS, candidateArrayNode); } if (CollectionUtils.isNotEmpty(userTask.getCandidateGroups())) { ArrayNode candidateArrayNode = objectMapper.createArrayNode(); for (String candidateGroup : userTask.getCandidateGroups()) { ObjectNode candidateNode = objectMapper.createObjectNode(); candidateNode.put("value", candidateGroup); candidateArrayNode.add(candidateNode); } assignmentValuesNode.set(PROPERTY_USERTASK_CANDIDATE_GROUPS, candidateArrayNode); } } assignmentNode.set("assignment", assignmentValuesNode); propertiesNode.set(PROPERTY_USERTASK_ASSIGNMENT, assignmentNode); } if (userTask.getPriority() != null) { setPropertyValue(PROPERTY_USERTASK_PRIORITY, userTask.getPriority(), propertiesNode); } setPropertyValue(PROPERTY_SKIP_EXPRESSION, userTask.getSkipExpression(), propertiesNode); if (StringUtils.isNotEmpty(userTask.getFormKey())) { if (formKeyMap != null && formKeyMap.containsKey(userTask.getFormKey())) { ObjectNode formRefNode = objectMapper.createObjectNode(); ModelInfo modelInfo = formKeyMap.get(userTask.getFormKey()); formRefNode.put("id", modelInfo.getId()); formRefNode.put("name", modelInfo.getName()); formRefNode.put("key", modelInfo.getKey()); propertiesNode.set(PROPERTY_FORM_REFERENCE, formRefNode); } else { setPropertyValue(PROPERTY_FORMKEY, userTask.getFormKey(), propertiesNode); } } setPropertyValue(PROPERTY_FORM_FIELD_VALIDATION, userTask.getValidateFormFields(), propertiesNode); setPropertyValue(PROPERTY_USERTASK_DUEDATE, userTask.getDueDate(), propertiesNode); setPropertyValue(PROPERTY_USERTASK_CATEGORY, userTask.getCategory(), propertiesNode); //自定义节点属性 List
customSetting = userTask.getExtensionElements().get("customSetting"); if(CollectionUtils.isNotEmpty(customSetting)){ setPropertyValue("customSetting", userTask.getExtensionElements().get("customSetting").get(0).getElementText(), propertiesNode); }else{ String attrValue = ""; Map
> attributeMap = userTask.getAttributes(); if (MapUtils.isNotEmpty(attributeMap)) { List
values = attributeMap.get("customSetting"); if (CollectionUtils.isNotEmpty(values)) { attrValue = values.get(0).getValue(); } } setPropertyValue("customSetting", attrValue, propertiesNode); } addFormProperties(userTask.getFormProperties(), propertiesNode); } @Override protected FlowElement convertJsonToElement(JsonNode elementNode, JsonNode modelNode, Map
shapeMap) { UserTask flowElement = (UserTask) super.convertJsonToElement(elementNode, modelNode, shapeMap); // 自定义属性扩展// List
customProperties = new ArrayList<>();// String customSetting = getPropertyValueAsString("customSetting", elementNode);// if (StringUtils.isNotBlank(customSetting)) {// CustomProperty editData = this.createProperty("customSetting", customSetting);// customProperties.add(editData);// }// if (CollectionUtils.isNotEmpty(customProperties)) {// flowElement.setCustomProperties(customProperties);// } LOGGER.info("进入自定义属性解析"); if(flowElement instanceof UserTask){ String customSetting = getPropertyValueAsString("customSetting",elementNode); if(StringUtils.isNotBlank(customSetting)){ LOGGER.info("新增自定义属性[customSetting]="+customSetting); ExtensionAttribute ea1 = generateExtensionAttribute("customSetting",customSetting); flowElement.addAttribute(ea1); }// addExtensionElement("customSetting", customSetting, flowElement); } return flowElement; } public static ExtensionAttribute generateExtensionAttribute(String key, String val){ ExtensionAttribute ea = new ExtensionAttribute(); ea.setNamespace("http://flowable.org/bpmn"); ea.setName(key); ea.setNamespacePrefix("flowable"); ea.setValue(val); return ea; }// public static ExtensionAttribute generateExtensionAttribute(String key, String val){// ExtensionAttribute ea = new ExtensionAttribute();// ea.setNamespace("http://flowable.org/bpmn");// ea.setName(key);// ea.setNamespacePrefix("flowable");// ea.setValue(val);// return ea;// } /** * 创建自定义属性 * * @param propertyName 属性名称 * @param propertyValue 属性值 */ private CustomProperty createProperty(String propertyName, String propertyValue) { CustomProperty customProperty = new CustomProperty(); customProperty.setId(propertyName); customProperty.setName(propertyName); customProperty.setSimpleValue(propertyValue); return customProperty; }}

 

转载地址:https://blog.csdn.net/zzchances/article/details/104700242 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:flowable自定义节点属性
下一篇:高可用 Redis 服务架构分析与搭建

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月28日 12时01分05秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章