RollbackTaskCmd

package com.pty.workflow.service.extend;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.activiti.bpmn.model.ExclusiveGateway;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.bpmn.model.Process;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.StartEvent;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.HistoryService;
import org.activiti.engine.delegate.event.ActivitiEventDispatcher;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.delegate.event.impl.ActivitiEventBuilder;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.cmd.NeedsActiveTaskCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.HistoricIdentityLinkEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.task.Task;

import com.pty.workflow.api.RollbackPosition;

import lombok.extern.slf4j.Slf4j;

@Slf4j
/* @Service */
public class RollbackTaskCmd extends NeedsActiveTaskCmd<Void> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1264547749014497759L;

	private RollbackPosition _position;

	private String _designatedNodeId;
	
	private String _exeNodeId;

	public RollbackTaskCmd(String taskId, RollbackPosition position, String exeNodeId,String... designatedNodeId) {
		super(taskId);
		_position = position;
		_exeNodeId = exeNodeId;
		if (designatedNodeId.length > 0) {
			_designatedNodeId = designatedNodeId[0];
		}
	}

	@Override
	protected Void execute(CommandContext commandContext, TaskEntity task) {

		ActivitiEventDispatcher eventDispatcher = Context.getProcessEngineConfiguration().getEventDispatcher();
		// TODO(liubo): 增加退回的enum
		if (eventDispatcher.isEnabled()) {
			eventDispatcher
					.dispatchEvent(ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_COMPLETED, task));
		}

		if (task.getExecutionId() != null) {
			ExecutionEntity executionEntity = commandContext.getExecutionEntityManager()
					.findExecutionById(task.getExecutionId());
			if (_position.equals(RollbackPosition.START)) {
				rollback2Start(commandContext, task, executionEntity);
			} else if (_position.equals(RollbackPosition.PREVIOUS)) {
				rollback2Previous(commandContext, task, executionEntity);
			} else if (_position.equals(RollbackPosition.DESIGNATED)) {
				rollback2Designated(commandContext, task, executionEntity,_exeNodeId);
			}
			// Context.getAgenda().planTriggerExecutionOperation(executionEntity);
		}
		return null;
	}

	// 退回到流程初始的任务节点
	private void rollback2Start(CommandContext commandContext, TaskEntity task, ExecutionEntity executionEntity) {
		// TODO(liubo): 设置creator
		String creator=this.getProcessCreator(task, commandContext);
		task.setVariable("creator", this.getProcessCreator(task, commandContext));
		List<TaskEntity> tasks = commandContext.getTaskEntityManager().findTasksByExecutionId(task.getExecutionId());
		tasks.forEach(taskEntity -> {
			// commandContext.getTaskEntityManager().delete(taskEntity);
			commandContext.getTaskEntityManager().deleteTask(taskEntity, null, false);
		});
		Process process = Context.getProcessEngineConfiguration().getRepositoryService()
				.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
		String firstUserTaskNode = process.findFlowElementsOfType(StartEvent.class).get(0).getOutgoingFlows().get(0)
				.getTargetRef();
		task.fireEvent("rollback");
		executionEntity.removeTask(task);
		executionEntity.executeActivity(executionEntity.getProcessDefinition().findActivity(firstUserTaskNode));
	}

	// 退回到上一个任务节点
	private void rollback2Previous(CommandContext commandContext, TaskEntity task, ExecutionEntity executionEntity) {
		commandContext.getTaskEntityManager().deleteTask(task, null, false);
		// HistoryManager historyManager = commandContext.getHistoryManager();
		// historyManager.recordTaskEnd(taskId, "shareniu-jump");
		Process process = Context.getProcessEngineConfiguration().getRepositoryService()
				.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
		List<FlowElement> prevNode = getPrevousNode(task, process);
		
		
		List<Task> list = Context.getProcessEngineConfiguration().getTaskService().createTaskQuery()
				.processInstanceId(task.getProcessInstanceId()).list();
		if (list.size() >= 2) {
			for (Task task2 : list) {
				if (!task2.getId().equals(task.getId())) {
					commandContext.getTaskEntityManager().deleteTask((TaskEntity) task2, null, false);
				}
			}

		}
		prevNode.stream().forEach(node -> {
			if (node == null) {
				throw new RuntimeException("前置任务节点未找到");
			}
			if (((FlowNode) node).getIncomingFlows().stream().anyMatch(ele -> {
				String s=ele.getSourceRef();
				return StartEvent.class.isAssignableFrom(process.getFlowElement(ele.getSourceRef()).getClass());
			})) {
				task.setVariable("creator", this.getProcessCreator(task, commandContext));
			}
			// TODO(liubo):如果退回的是第一个任务节点,将creator注入
			task.fireEvent("rollback");
			executionEntity.removeTask(task);
			
	        /*String processDefinitionId = task.getProcessDefinitionId();
	        ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(processDefinitionId).execute(commandContext);
	        ActivityImpl activityImpl = processDefinitionEntity.findActivity(task.getTaskDefinitionKey());
	         Map<String, Object> currMap = activityImpl.getProperties();
	         if (currMap.containsKey("multiInstance")) { // 删除当前多实例任务
	        	// executionEntity= task.getExecution().getParent().getParent(); //taskEntity.getExecution();
	        this.deleteExecution(task);
	        }
	         
	         executionEntity.setProcessInstance(executionEntity);
	         executionEntity.setProcessDefinitionId(historicActivityInstanceEntity.getProcessDefinitionId());
	         executionEntity.setActivity(targetActivity);
	         executionEntity.setActive(false);
	         executionEntity.setConcurrent(false);
	         executionEntity.setCachedEntityState(0);*/

	        

			executionEntity.executeActivity(executionEntity.getProcessDefinition().findActivity(node.getId()));
		});
	}
	
	/*public void deleteExecution(TaskEntity taskEntity) {
		// 删除未处理任务信息
          List<TaskEntity> taskEntities = Context.getCommandContext().getTaskEntityManager().findTasksByProcessInstanceId(taskEntity.getProcessInstanceId());
		for (TaskEntity taskEntity2 : taskEntities) {
		List<VariableInstanceEntity> varLis = Context.getCommandContext().getVariableInstanceEntityManager().findVariableInstancesByExecutionId(taskEntity2.getExecutionId());
		for (VariableInstanceEntity variableInstanceEntity : varLis) {
		Context.getCommandContext().getVariableInstanceEntityManager().delete(variableInstanceEntity);
		}
		Context.getCommandContext().getExecutionEntityManager().delete(taskEntity2.getExecution());
		}
// 获取多实例同节点处理任务
		HistoricTaskInstanceQueryImpl historicTaskInstanceQueryImpl = new HistoricTaskInstanceQueryImpl();
		 historicTaskInstanceQueryImpl.taskDefinitionKey(taskEntity.getTaskDefinitionKey());
		 historicTaskInstanceQueryImpl.processInstanceId(taskEntity.getProcessInstanceId());
		 historicTaskInstanceQueryImpl.setFirstResult(0);
		 historicTaskInstanceQueryImpl.setMaxResults(999);
		 historicTaskInstanceQueryImpl.orderByTaskCreateTime().asc();
		 List<HistoricTaskInstance> historicTaskInstanceList = (List<HistoricTaskInstance>) Context.getCommandContext()
		 .getHistoricTaskInstanceEntityManager().findHistoricTaskInstancesByQueryCriteria(historicTaskInstanceQueryImpl);
		 if (historicTaskInstanceList != null && historicTaskInstanceList.size() > 0) {
		for (HistoricTaskInstance historicTaskInstance : historicTaskInstanceList) {
		ExecutionEntity executionEntity = Context.getCommandContext().getExecutionEntityManager().findExecutionById(historicTaskInstance.getExecutionId());
		if(executionEntity != null) { 
		List<VariableInstanceEntity> hisVarLis = Context.getCommandContext().getVariableInstanceEntityManager().findVariableInstancesByExecutionId(executionEntity.getId());
		for (VariableInstanceEntity variableInstanceEntity : hisVarLis) {
		Context.getCommandContext().getVariableInstanceEntityManager().delete(variableInstanceEntity);
}
		 Context.getCommandContext().getExecutionEntityManager().delete(executionEntity);
		}
		}
		 }
		// 删除多实例父节点信息
		ExecutionEntity parent = Context.getCommandContext().getExecutionEntityManager().findExecutionById(taskEntity.getExecution().getParentId());
		List<VariableInstanceEntity> varLis = Context.getCommandContext().getVariableInstanceEntityManager().findVariableInstancesByExecutionId(parent.getId());
		for (VariableInstanceEntity variableInstanceEntity : varLis) {
		Context.getCommandContext().getVariableInstanceEntityManager().delete(variableInstanceEntity);
		}
		Context.getCommandContext().getExecutionEntityManager().delete(parent);
		    }
		
		 public void deleteExecution(ExecutionEntity executionEntity) {
		Context.getCommandContext().getExecutionEntityManager().delete(executionEntity);
		    }
*/
	private void rollback2Designated(CommandContext commandContext, TaskEntity task, ExecutionEntity executionEntity, String _exeNodeId) {

		commandContext.getTaskEntityManager().deleteTask(task, null, false);
		// HistoryManager historyManager = commandContext.getHistoryManager();
		// historyManager.recordTaskEnd(taskId, "shareniu-jump");
		Process process = Context.getProcessEngineConfiguration().getRepositoryService()
				.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
		//List<FlowElement> prevNode = getPrevousNode(task, process);
		FlowNode sss = (FlowNode)process.getFlowElement(_exeNodeId);
		List<FlowNode> prevNode =new ArrayList<FlowNode>();
		prevNode.add(sss);
		prevNode.stream().forEach(node -> {
			if (node == null) {
				throw new RuntimeException("前置任务节点未找到");
			}
			if (((FlowNode) node).getIncomingFlows().stream().anyMatch(ele -> {
				String s=ele.getSourceRef();
				return StartEvent.class.isAssignableFrom(process.getFlowElement(ele.getSourceRef()).getClass());
			})) {
				task.setVariable("creator", this.getProcessCreator(task, commandContext));
			}
			// TODO(liubo):如果退回的是第一个任务节点,将creator注入
			task.fireEvent("rollback");
			executionEntity.removeTask(task);
			
	        /*String processDefinitionId = task.getProcessDefinitionId();
	        ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(processDefinitionId).execute(commandContext);
	        ActivityImpl activityImpl = processDefinitionEntity.findActivity(task.getTaskDefinitionKey());
	         Map<String, Object> currMap = activityImpl.getProperties();
	         if (currMap.containsKey("multiInstance")) { // 删除当前多实例任务
	        	// executionEntity= task.getExecution().getParent().getParent(); //taskEntity.getExecution();
	        this.deleteExecution(task);
	        }
	         
	         executionEntity.setProcessInstance(executionEntity);
	         executionEntity.setProcessDefinitionId(historicActivityInstanceEntity.getProcessDefinitionId());
	         executionEntity.setActivity(targetActivity);
	         executionEntity.setActive(false);
	         executionEntity.setConcurrent(false);
	         executionEntity.setCachedEntityState(0);*/
			executionEntity.executeActivity(executionEntity.getProcessDefinition().findActivity(node.getId()));
		});
		//throw new RuntimeException("暂不支持退回到任一指定节点");
	}

	/*private List<FlowNode> getPrevousNode(TaskEntity task, Process process) {
		
		ProcessDefinitionEntity processDefinitionEntity = null;

		String id = null;

		TaskDefinition taskDef = null;
		String type = null;
		Map<String, Object> map = new HashMap<String, Object>();
		// 获取流程实例Id信息
		TaskService taskService = Context.getProcessEngineConfiguration().getTaskService();
		Task Task = Context.getProcessEngineConfiguration().getTaskService().createTaskQuery().taskId(taskId)
				.singleResult();
		String processInstanceId = Context.getProcessEngineConfiguration().getTaskService().createTaskQuery()
				.taskId(taskId).singleResult().getProcessInstanceId();
		String executionId = Context.getProcessEngineConfiguration().getTaskService().createTaskQuery().taskId(taskId)
				.singleResult().getExecutionId();
		// 获取流程发布Id信息
		String definitionId = Context.getProcessEngineConfiguration().getRuntimeService().createProcessInstanceQuery()
				.processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();

		processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) Context
				.getProcessEngineConfiguration().getRepositoryService()).getDeployedProcessDefinition(definitionId);

		List<Execution> execution = Context.getProcessEngineConfiguration().getRuntimeService().createExecutionQuery()
				.executionId(executionId).list();
		if (execution.size() == 1) {
			// execution.getActivityId();
			// 当前流程节点Id信息
			String activitiId = execution.get(0).getActivityId();

			// 获取流程所有节点信息
			List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();

			// 遍历所有节点信息
			for (ActivityImpl activityImpl : activitiList) {
				id = activityImpl.getId();

				// 找到当前节点信息
				if (activitiId.equals(id)) {

					// 判断上一个节点信息是 什么类型
					map = lastNodeType(activityImpl, activityImpl.getId(), processInstanceId);

					break;
				}
			}
		} else {

		}

		if (map.get("type") != null && map.get("type").equals("parallelGateway")) {
			List<FlowNode> flowNodes = new ArrayList<FlowNode>();

			String activityId = (String) map.get("activityId");
			FlowNode node = (FlowNode) process.getFlowElement(activityId);
			List<SequenceFlow> list = node.getIncomingFlows();
			for (SequenceFlow sequenceFlow : list) {
				FlowElement flowElement = process.getFlowElement(sequenceFlow.getSourceRef());
				FlowNode flowNode = (FlowNode) flowElement;
				flowNodes.add(flowNode);
			}

			return flowNodes;
		} else if (map.get("type").equals("userTask")) {
			List<FlowNode> flowNodes = new ArrayList<FlowNode>();
			List<HistoricActivityInstance> taskHis = Context.getProcessEngineConfiguration().getHistoryService()
					.createHistoricActivityInstanceQuery().executionId(task.getExecutionId()).finished()
					.orderByHistoricActivityInstanceEndTime().desc().list();

			FlowNode flowNode = (FlowNode) process.getFlowElement(taskHis.get(0).getActivityId());
			flowNodes.add(flowNode);
			return flowNodes;
		} else{
			List<FlowNode> flowNodes = new ArrayList<FlowNode>();
			List<HistoricActivityInstance> taskHis3 = Context.getProcessEngineConfiguration().getHistoryService()
					.createHistoricActivityInstanceQuery().executionId(task.getExecutionId()).finished()
					.orderByHistoricActivityInstanceEndTime().desc().list();
			FlowNode flowNode = (FlowNode) process.getFlowElement(taskHis3.get(0).getActivityId());
			flowNodes.add(flowNode);
			return flowNodes;

		}

	}*/

	private List<FlowElement> getPrevousNode(TaskEntity task, Process process) {
		/*List<HistoricActivityInstance> historyActivitys = Context.getProcessEngineConfiguration().getHistoryService()
				.createNativeHistoricActivityInstanceQuery("").list();*/
		
		List<HistoricActivityInstance> taskHis = Context.getProcessEngineConfiguration().getHistoryService()
				.createHistoricActivityInstanceQuery().processInstanceId(task.getProcessInstanceId()).finished()
				.orderByHistoricActivityInstanceEndTime().desc().list();
		
		List<HistoricActivityInstance> taskHis1 = Context.getProcessEngineConfiguration().getHistoryService()
				.createHistoricActivityInstanceQuery().processInstanceId(task.getProcessInstanceId()).finished()
				.orderByHistoricActivityInstanceEndTime().desc().list();
		HistoricActivityInstance maxExecuteElement = taskHis.stream().filter(activity->{
			FlowElement ele = process.getFlowElement(activity.getActivityId());
			if (ele == null) {
				return false;
			}
			if (!(ele instanceof FlowNode)) {
				return false;
			}
			if (activity.getActivityType().equals("exclusiveGateway")) {
				return false;
			}
			return true;
		}).max((a, b)->{
			return a.getEndTime().compareTo(b.getEndTime());
		}).get();
		List<SequenceFlow> list2=new ArrayList<>();
		List<FlowElement> listFlowElement=new ArrayList<FlowElement>();
		if (maxExecuteElement.getActivityType().equals("userTask")) {
			FlowNode node = (FlowNode)process.getFlowElement(maxExecuteElement.getActivityId());
			List<SequenceFlow> list=node.getOutgoingFlows();
			
			for (SequenceFlow sequenceFlow : list) {
				
				String targetRef=sequenceFlow.getTargetRef();
				FlowNode node2 = (FlowNode) process.getFlowElement(targetRef);
				
				String name=node2.getName();
				/*if(name==null){
					list2=node2.getIncomingFlows();
					for (SequenceFlow sequenceFlow2 : list2) {
						FlowElement flowElement=process.getFlowElement(sequenceFlow2.getSourceRef());
						listFlowElement.add(flowElement);
					}
				}else{
					FlowElement  flowElement =process.getFlowElement(maxExecuteElement.getActivityId());
					listFlowElement.add(flowElement);
				}*/
				FlowElement  flowElement =process.getFlowElement(maxExecuteElement.getActivityId());
				listFlowElement.add(flowElement);
			}
			
			return listFlowElement;
			//return Arrays.asList(process.getFlowElement(maxExecuteElement.getActivityId()));
		} else if (maxExecuteElement.getActivityType().equals("parallelGateway")) {
			FlowNode node = (FlowNode)process.getFlowElement(maxExecuteElement.getActivityId());
			return node.getIncomingFlows().stream().map(sequence->{
				return process.getFlowElement(sequence.getSourceRef());
			}).collect(Collectors.toList());
		} else {
			return new ArrayList<FlowElement>();
		}
	}
	
	/*private List<FlowElement> getPrevousNode(TaskEntity task, Process process) {
		List<HistoricActivityInstance> historyActivitys = Context.getProcessEngineConfiguration().getHistoryService()
				.createNativeHistoricActivityInstanceQuery().list();
		HistoricActivityInstance maxExecuteElement = historyActivitys.stream().filter(activity->{
			FlowElement ele = process.getFlowElement(activity.getActivityId());
			if (ele == null) {
				return false;
			}
			if (!(ele instanceof FlowNode)) {
				return false;
			}
			if (activity.getActivityType().equals("exclusiveGateway")) {
				return false;
			}
			return true;
		}).max((a, b)->{
			return a.getEndTime().compareTo(b.getEndTime());
		}).get();
		if (maxExecuteElement.getActivityType().equals("userTask")) {
			return Arrays.asList(process.getFlowElement(maxExecuteElement.getActivityId()));
		} else if (maxExecuteElement.getActivityType().equals("parallelGateway")) {
			FlowNode node = (FlowNode)process.getFlowElement(maxExecuteElement.getActivityId());
			return node.getIncomingFlows().stream().map(sequence->{
				return process.getFlowElement(sequence.getSourceRef());
			}).collect(Collectors.toList());
		} else {
			return new ArrayList<FlowElement>();
		}
	}*/
	
	
	/*private Map<String, Object> lastNodeType(ActivityImpl activityImpl, String id, String processInstanceId) {
		PvmActivity ac = null;

		Object s = null;

		// 如果遍历节点为用户任务并且节点不是当前节点信息
		if ("userTask".equals(activityImpl.getProperty("type")) && !id.equals(activityImpl.getId())) {

		} else {
			// 获取节点所有流向线路信息
			List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
			List<PvmTransition> outTransitionsTemp = null;

			List<PvmTransition> incomings = activityImpl.getIncomingTransitions();
			List<PvmTransition> incomingsTemp = null;

			for (PvmTransition pvmTransition : incomings) {
				ac = pvmTransition.getDestination();
				PvmActivity source = pvmTransition.getSource();
				String a = (String) source.getProperty("type");
				if ("exclusiveGateway".equals(source.getProperty("type"))) {
					incomingsTemp = source.getIncomingTransitions();
					if (incomingsTemp.size() == 1) {
						String actId = source.getId();
						Map<String, Object> map = new HashMap<String, Object>();
						map.put("activityId", source.getId());
						map.put("type", "exclusiveGateway");
						return map;
					}

				} else if ("userTask".equals(source.getProperty("type"))) {
					String actId = source.getId();
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("activityId", source.getId());
					map.put("type", "userTask");
					return map;

				} else if ("parallelGateway".equals(source.getProperty("type"))) {
					String actId = source.getId();
					Map<String, Object> map = new HashMap<String, Object>();
					map.put("activityId", source.getId());
					map.put("type", "parallelGateway");
					return map;
				}

			}

		}
		return null;
	}*/

	private String getProcessCreator(TaskEntity task, CommandContext commandContext) {
		List<HistoricIdentityLinkEntity> links = commandContext.getHistoricIdentityLinkEntityManager().findHistoricIdentityLinksByProcessInstanceId(task.getProcessInstanceId());
		/*List<IdentityLinkEntity> links = commandContext.getIdentityLinkEntityManager()
				.findIdentityLinksByProcessInstanceId(task.getProcessInstanceId());*/
		return links.stream().filter(link -> {
			return "starter".equals(link.getType());
		}).findFirst().get().getUserId();
	}

	@Deprecated
	private FlowNode getPrevTaskNode(String processId, FlowElement curNode, Process process,
			HistoryService historyService) {
		if (curNode == null) {
			return null;
		}
		if (!FlowNode.class.isAssignableFrom(curNode.getClass())) {
			return null;
		}
		List<SequenceFlow> sequences = ((FlowNode) curNode).getIncomingFlows();
		for (SequenceFlow seq : sequences) {
			FlowElement ele = process.getFlowElement(seq.getSourceRef());
			if (UserTask.class.isAssignableFrom(ele.getClass())) {
				try {
					HistoricActivityInstance his = historyService.createHistoricActivityInstanceQuery()
							.processDefinitionId(processId).activityId(ele.getId())
							.orderByHistoricActivityInstanceEndTime().desc().singleResult();
					return (FlowNode) ele;
				} catch (Exception ex) {
					log.error("error", ex);
				}
			} else if (ExclusiveGateway.class.isAssignableFrom(ele.getClass())) {
				return getPrevTaskNode(processId, ele, process, historyService);
			}
		}
		return null;
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值