Search in sources :

Example 1 with FlowNode

use of org.flowable.bpmn.model.FlowNode in project ox-data-cloud by ox-data.

the class BackUserTaskCmd method execute.

@Override
public String execute(CommandContext commandContext) {
    if (targetActivityId == null || targetActivityId.length() == 0) {
        throw new FlowableException("TargetActivityId cannot be empty");
    }
    // / TaskEntity task = CommandContextUtil.getTaskService().getTask(taskId);
    // / v6.5.1.28
    TaskEntity task = CommandContextUtil.getProcessEngineConfiguration().getTaskServiceConfiguration().getTaskService().getTask(taskId);
    if (task == null) {
        throw new FlowableObjectNotFoundException("task " + taskId + " doesn't exist", Task.class);
    }
    String sourceActivityId = task.getTaskDefinitionKey();
    String processInstanceId = task.getProcessInstanceId();
    String processDefinitionId = task.getProcessDefinitionId();
    Process process = ProcessDefinitionUtil.getProcess(processDefinitionId);
    FlowNode sourceFlowElement = (FlowNode) process.getFlowElement(sourceActivityId, true);
    // 只支持从用户任务退回
    if (!(sourceFlowElement instanceof UserTask)) {
        throw new FlowableException("Task with id:" + taskId + " is not a UserTask");
    }
    FlowNode targetFlowElement = (FlowNode) process.getFlowElement(targetActivityId, true);
    // 退回节点到当前节点不可达到,不允许退回
    if (!FlowableUtils.isReachable(process, targetFlowElement, sourceFlowElement)) {
        throw new FlowableException("Cannot back to [" + targetActivityId + "]");
    }
    // ps:目标节点如果相对当前节点是在子流程内部,则无法直接退回,目前处理是只能退回到子流程开始节点
    String[] sourceAndTargetRealActivityId = FlowableUtils.getSourceAndTargetRealActivityId(sourceFlowElement, targetFlowElement);
    // 实际应操作的当前节点ID
    String sourceRealActivityId = sourceAndTargetRealActivityId[0];
    // 实际应操作的目标节点ID
    String targetRealActivityId = sourceAndTargetRealActivityId[1];
    Map<String, Set<String>> specialGatewayNodes = FlowableUtils.getSpecialGatewayElements(process);
    // 当前节点处在的并行网关list
    List<String> sourceInSpecialGatewayList = new ArrayList<>();
    // 目标节点处在的并行网关list
    List<String> targetInSpecialGatewayList = new ArrayList<>();
    setSpecialGatewayList(sourceRealActivityId, targetRealActivityId, specialGatewayNodes, sourceInSpecialGatewayList, targetInSpecialGatewayList);
    // 实际应筛选的节点ID
    Set<String> sourceRealAcitivtyIds = null;
    // 若退回目标节点相对当前节点在并行网关中,则要找到相对当前节点最近的这个并行网关,后续做特殊处理
    String targetRealSpecialGateway = null;
    // 1.目标节点和当前节点都不在并行网关中
    if (targetInSpecialGatewayList.isEmpty() && sourceInSpecialGatewayList.isEmpty()) {
        sourceRealAcitivtyIds = Sets.newHashSet(sourceRealActivityId);
    } else // 2.目标节点不在并行网关中、当前节点在并行网关中
    if (targetInSpecialGatewayList.isEmpty() && !sourceInSpecialGatewayList.isEmpty()) {
        sourceRealAcitivtyIds = specialGatewayNodes.get(sourceInSpecialGatewayList.get(0));
    } else // 3.目标节点在并行网关中、当前节点不在并行网关中
    if (!targetInSpecialGatewayList.isEmpty() && sourceInSpecialGatewayList.isEmpty()) {
        sourceRealAcitivtyIds = Sets.newHashSet(sourceRealActivityId);
        targetRealSpecialGateway = targetInSpecialGatewayList.get(0);
    } else // 4.目标节点和当前节点都在并行网关中
    {
        int diffSpecialGatewayLevel = FlowableUtils.getDiffLevel(sourceInSpecialGatewayList, targetInSpecialGatewayList);
        // 在并行网关同一层且在同一分支
        if (diffSpecialGatewayLevel == -1) {
            sourceRealAcitivtyIds = Sets.newHashSet(sourceRealActivityId);
        } else {
            // 只筛选当前节点的execution
            if (sourceInSpecialGatewayList.size() == diffSpecialGatewayLevel) {
                sourceRealAcitivtyIds = Sets.newHashSet(sourceRealActivityId);
            } else // 当前节点相对目标节点在并行网关内,应筛选相对目标节点最近的并行网关的所有节点的execution
            {
                sourceRealAcitivtyIds = specialGatewayNodes.get(sourceInSpecialGatewayList.get(diffSpecialGatewayLevel));
            }
            // 不做处理
            if (targetInSpecialGatewayList.size() == diffSpecialGatewayLevel) {
            } else // 目标节点相对当前节点在并行网关内
            {
                targetRealSpecialGateway = targetInSpecialGatewayList.get(diffSpecialGatewayLevel);
            }
        }
    }
    // 筛选需要处理的execution
    List<ExecutionEntity> realExecutions = this.getRealExecutions(commandContext, processInstanceId, task.getExecutionId(), sourceRealActivityId, sourceRealAcitivtyIds);
    // 执行退回,直接跳转到实际的 targetRealActivityId
    List<String> realExecutionIds = realExecutions.stream().map(ExecutionEntity::getId).collect(Collectors.toList());
    runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId).moveExecutionsToSingleActivityId(realExecutionIds, targetRealActivityId).changeState();
    // 目标节点相对当前节点处于并行网关内,需要特殊处理,需要手动生成并行网关汇聚节点(_end)的execution数据
    if (targetRealSpecialGateway != null) {
        createTargetInSpecialGatewayEndExecutions(commandContext, realExecutions, process, targetInSpecialGatewayList, targetRealSpecialGateway);
    }
    return targetRealActivityId;
}
Also used : TaskEntity(org.flowable.task.service.impl.persistence.entity.TaskEntity) UserTask(org.flowable.bpmn.model.UserTask) Process(org.flowable.bpmn.model.Process) FlowableException(org.flowable.common.engine.api.FlowableException) FlowableObjectNotFoundException(org.flowable.common.engine.api.FlowableObjectNotFoundException) ExecutionEntity(org.flowable.engine.impl.persistence.entity.ExecutionEntity) FlowNode(org.flowable.bpmn.model.FlowNode)

Example 2 with FlowNode

use of org.flowable.bpmn.model.FlowNode in project ox-data-cloud by ox-data.

the class BackUserTaskCmd method createTargetInSpecialGatewayEndExecutions.

private void createTargetInSpecialGatewayEndExecutions(CommandContext commandContext, List<ExecutionEntity> excutionEntitys, Process process, List<String> targetInSpecialGatewayList, String targetRealSpecialGateway) {
    // 目标节点相对当前节点处于并行网关,需要手动生成并行网关汇聚节点(_end)的execution数据
    String parentExecutionId = excutionEntitys.iterator().next().getParentId();
    ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
    ExecutionEntity parentExecutionEntity = executionEntityManager.findById(parentExecutionId);
    int index = targetInSpecialGatewayList.indexOf(targetRealSpecialGateway);
    for (; index < targetInSpecialGatewayList.size(); index++) {
        String targetInSpecialGateway = targetInSpecialGatewayList.get(index);
        String targetInSpecialGatewayEndId = targetInSpecialGateway + FlowableConstant.SPECIAL_GATEWAY_END_SUFFIX;
        FlowNode targetInSpecialGatewayEnd = (FlowNode) process.getFlowElement(targetInSpecialGatewayEndId, true);
        int nbrOfExecutionsToJoin = targetInSpecialGatewayEnd.getIncomingFlows().size();
        // 处理目标节点所处的分支以外的分支,即 总分枝数-1 = nbrOfExecutionsToJoin - 1
        for (int i = 0; i < nbrOfExecutionsToJoin - 1; i++) {
            ExecutionEntity childExecution = executionEntityManager.createChildExecution(parentExecutionEntity);
            childExecution.setCurrentFlowElement(targetInSpecialGatewayEnd);
            ActivityBehavior activityBehavior = (ActivityBehavior) targetInSpecialGatewayEnd.getBehavior();
            activityBehavior.execute(childExecution);
        }
    }
}
Also used : ExecutionEntity(org.flowable.engine.impl.persistence.entity.ExecutionEntity) ActivityBehavior(org.flowable.engine.impl.delegate.ActivityBehavior) ExecutionEntityManager(org.flowable.engine.impl.persistence.entity.ExecutionEntityManager) FlowNode(org.flowable.bpmn.model.FlowNode)

Aggregations

FlowNode (org.flowable.bpmn.model.FlowNode)2 ExecutionEntity (org.flowable.engine.impl.persistence.entity.ExecutionEntity)2 Process (org.flowable.bpmn.model.Process)1 UserTask (org.flowable.bpmn.model.UserTask)1 FlowableException (org.flowable.common.engine.api.FlowableException)1 FlowableObjectNotFoundException (org.flowable.common.engine.api.FlowableObjectNotFoundException)1 ActivityBehavior (org.flowable.engine.impl.delegate.ActivityBehavior)1 ExecutionEntityManager (org.flowable.engine.impl.persistence.entity.ExecutionEntityManager)1 TaskEntity (org.flowable.task.service.impl.persistence.entity.TaskEntity)1