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;
}
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);
}
}
}
Aggregations