天天看點

activity節點任意跳轉(包含單執行個體、多執行個體)前言任意跳轉(包含單執行個體、多執行個體)

前言

實作思路:

處理掉目前的代辦節點(也就是删除正在運作的該任務,更新維護曆史資料)

跳轉到目标節點,并把目标節點作為待辦任務節點

任意跳轉(包含單執行個體、多執行個體)

1.實作思路

處理掉目前的代辦節點(也就是删除正在運作的該任務,更新維護曆史資料)

跳轉到目标節點,并把目标節點作為待辦任務節點

activity節點任意跳轉(包含單執行個體、多執行個體)前言任意跳轉(包含單執行個體、多執行個體)

要繼續運轉流程,則向operations中壓入ContinueProcessOperation,

多執行個體壓入planContinueMultiInstanceOperation

要結束流程則壓入EndExecutionOperation。

在每一個操作完成的時候,将接下來要執行的操作壓入operations棧中,這樣就達到了流程運轉的效果

2.任意跳轉指令類

代碼如下(示例):

public class JumpTaskCmd implements Command<Void>, Serializable {
   /**
     * 目前流程執行個體的待辦節點
     * 當多執行個體節點為并行時,會有多個節點
     * 跳過多執行個體節點時,需要把它們都删除
     */
    private List<String> taskIds;

    /**
     * 以下兩個節點,targetNodeId跳過過去的節點,即将為代辦任務節點
     * var 是targetNodeId節點需要的參數,如:候選人、多執行個體完成率等等
     */
    private String targetNodeId;
    private Map<String, Object> vars;

    public JumpMultiCmd(List<String> taskIds, String targetNodeId, Map<String, Object> vars) {
        this.taskIds = taskIds;
        this.targetNodeId = targetNodeId;
        this.vars = vars;
    }

    @Override
    public Void execute(CommandContext commandContext) {
        //擷取其中一個代辦任務
        String taskId = taskIds.get(0);
        //任務執行管理器
        TaskEntityManager taskEntityManager = commandContext.getTaskEntityManager();
        ExecutionEntityManager executionEntityManager = commandContext.getExecutionEntityManager();
        TaskEntity taskEntity = taskEntityManager.findById(taskId);
        //流程定義對象資訊
        String processDefinitionId = taskEntity.getProcessDefinitionId();
        Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);
        //節點的元資訊對象,封裝了節點的中繼資料,如入線和出線
        Activity flowElement = (Activity) process.getFlowElement(taskEntity.getTaskDefinitionKey());

        // 執行執行個體對象
        String executionId = taskEntity.getExecutionId();
        ExecutionEntity currentExecutionEntity = executionEntityManager.findById(executionId);

        Object behavior = flowElement.getBehavior();
        //判斷目前節點的行為類,即是否多執行個體任務類型,主要做兩件事,删除2級執行個體下的三級執行個體,然後重新設定2級執行個體的資訊執行更新操作
        if (behavior instanceof MultiInstanceActivityBehavior) {
            HistoricTaskInstanceEntityManager historicTaskInstance = commandContext.getHistoricTaskInstanceEntityManager();
            this.taskIds.forEach(historicTaskInstance::delete);

            executionEntityManager.deleteChildExecutions(currentExecutionEntity, "jump task", false);
            currentExecutionEntity.setActive(true);
            currentExecutionEntity.setMultiInstanceRoot(false);
            executionEntityManager.update(currentExecutionEntity);
        } else {
            //不是多執行個體
            //删除曆史任務節點
            HistoricTaskInstanceEntityManager historicTaskInstance = commandContext.getHistoricTaskInstanceEntityManager();
            historicTaskInstance.delete(taskId);
            //删除目前的任務并把條件删掉
            IdentityLinkEntityManager identityLinkEntityManager = commandContext.getIdentityLinkEntityManager();
            identityLinkEntityManager.deleteIdentityLinksByTaskId(taskId);
            //taskEntityManager.delete(taskId); 報外鍵沖突,執行前面的代碼
            taskEntityManager.deleteTask(taskEntity, "jumpReason", false, false);
        }
        //使用agenda驅動執行個體的繼續運轉,即跳入到目标節點
        ActivitiEngineAgenda agenda = commandContext.getAgenda();

        // 如果目标節點為結束節點(不是使用者節點)
        if (FLOW_NODE_EVENT_END.equals(targetNodeId)) {
            FlowElement targetFlowElement = process.getFlowElement(targetNodeId);
            
            currentExecutionEntity.setCurrentFlowElement(targetFlowElement);
            agenda.planEndExecutionOperation(currentExecutionEntity);
            return null;
        }

        // 目标節點處理
        Activity targetFlowElement = (Activity) process.getFlowElement(targetNodeId);
        behavior = targetFlowElement.getBehavior();

        // 當目标節點為多執行個體節點時,需要從執行執行個體中擷取它們父執行個體對象
        if (behavior instanceof MultiInstanceActivityBehavior) {
            //待跳出節點的二級執行個體對象(多執行個體下的執行執行個體對象為三級執行個體對象)
            ExecutionEntity secondExecutionEntity = currentExecutionEntity.getParent();
            secondExecutionEntity.setCurrentFlowElement(targetFlowElement);
            if (!Objects.isNull(vars) && vars.size() > 0) {// 如需要提供的參數
                secondExecutionEntity.setVariables(vars);
            }
            agenda.planContinueMultiInstanceOperation(secondExecutionEntity);
            return null;
        }

        if (!Objects.isNull(vars) && vars.size() > 0) {
            currentExecutionEntity.setVariables(vars);
        }
        currentExecutionEntity.setCurrentFlowElement(targetFlowElement);
        agenda.planContinueProcessInCompensation(currentExecutionEntity);

        return null;
    }
 }
           

如果你對工作流感興趣,想了解更多,請點選

Java工作流管理系統(activity6.0)