ACTIVITI 5.22.0 流程退回上一节点,实现多实例串行与并行退回

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.HistoricActivityInstanceQueryImpl;
import org.activiti.engine.impl.HistoricTaskInstanceQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.cmd.GetDeploymentProcessDefinitionCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandContext;
import org.activiti.engine.impl.persistence.entity.ExecutionEntity;
import org.activiti.engine.impl.persistence.entity.HistoricActivityInstanceEntity;
import org.activiti.engine.impl.persistence.entity.HistoricTaskInstanceEntity;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
import org.activiti.engine.impl.persistence.entity.VariableInstanceEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.impl.variable.VariableType;
import org.activiti.engine.impl.variable.VariableTypes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.activiti.core.service.workflow.entity.graph.ActivitiHistoryGraphBuilder;
import com.activiti.core.service.workflow.entity.graph.Edge;
import com.activiti.core.service.workflow.entity.graph.Graph;
import com.activiti.core.service.workflow.entity.graph.Node;
import com.activiti.core.utils.common.StringTools;

/**
 * 退回任务.
 */
public class RollbackTaskCmd implements Command<Object> {
    /** logger. */
    private static Logger logger = LoggerFactory
            .getLogger(RollbackTaskCmd.class);

    /** task id. */
    private String taskId;

    /** activity id. */
    private String activityId;

    /** user id. */
    private String userId;

    /** use last assignee. */
    private boolean useLastAssignee = false;

    /** 需要处理的多实例节点. */
    private Set<String> multiInstanceExecutionIds = new HashSet<String>();
    
    private boolean isParallel = true;
    
    /**
     * 指定taskId和跳转到的activityId,自动使用最后的assignee.
     */
    public RollbackTaskCmd(String taskId, String activityId) {
        this.taskId = taskId;
        this.activityId = activityId;
        this.useLastAssignee = true;
    }

    /**
     * 指定taskId和跳转到的activityId, userId.
     */
    public RollbackTaskCmd(String taskId, String activityId, String userId) {
        this.taskId = taskId;
        this.activityId = activityId;
        this.userId = userId;
    }

    /**
     * 退回流程.
     * 
     * @return 0-退回成功 1-流程结束 2-下一结点已经通过,不能退回
     */
    public Integer execute(CommandContext commandContext) {
        // 获得任务
        TaskEntity taskEntity = this.findTask(commandContext);

        // 找到想要回退到的节点
        ActivityImpl targetActivity = this.findTargetActivity(commandContext,
                taskEntity);
        logger.info("rollback to {}", this.activityId);
        logger.info("{}", targetActivity.getProperties());

        String type = (String) targetActivity.getProperty("type");

        if ("userTask".equals(type)) {
            logger.info("rollback to userTask");
            this.rollbackUserTask(commandContext, taskEntity, targetActivity);
        } else if ("startEvent".equals(type)) {
            logger.info("rollback to startEvent");
            this.rollbackStartEvent(commandContext);
        } else {
            throw new IllegalStateException("cannot rollback " + type);
        }

        return 0;
    }

    /**
     * 回退到userTask.
     */
    public Integer rollbackUserTask(CommandContext commandContext, TaskEntity taskEntity, ActivityImpl targetActivity) {

        // 找到想要回退对应的节点历史
        HistoricActivityInstanceEntity historicActivityInstanceEntity = this
                .findTargetHistoricActivity(commandContext, taskEntity,
                        targetActivity);

        // 找到想要回退对应的任务历史
        HistoricTaskInstanceEntity historicTaskInstanceEntity = this
                .findTargetHistoricTask(commandContext, taskEntity,
                        targetActivity);

        logger.info("historic activity instance is : {}",
                historicActivityInstanceEntity.getId());

        Graph graph = new ActivitiHistoryGraphBuilder(
                historicTaskInstanceEntity.getProcessInstanceId()).build();

        Node node = graph.findById(historicActivityInstanceEntity.getId());

        if (!checkCouldRollback(node, taskEntity.getProcessInstanceId())) {
            logger.info("cannot rollback {}", taskId);

            return 2;
        }

        if (this.isSameBranch(historicTaskInstanceEntity)) {
            // 如果退回的目标节点的executionId与当前task的executionId一样,说明是同一个分支
            // 只删除当前分支的task
            TaskEntity targetTaskEntity = Context.getCommandContext()
                    .getTaskEntityManager().findTaskById(this.taskId);
            this.deleteActiveTask(targetTaskEntity);
        } else {
            // 否则认为是从分支跳回主干
            // 删除所有活动中的task
            this.deleteActiveTasks(historicTaskInstanceEntity.getProcessInstanceId());

            // 获得期望退回的节点后面的所有节点历史
            List<String> historyNodeIds = new ArrayList<String>();
            collectNodes(node, historyNodeIds);
//            this.deleteHistoryActivities(historyNodeIds);
        }

        Map<String, Object> map = targetActivity.getProperties();
        if (map.containsKey("multiInstance")) {
            this.rollbackProcessMultiInstance(commandContext, taskEntity, historicTaskInstanceEntity, historicActivityInstanceEntity, targetActivity);
        } else {
            // 恢复期望退回的任务和历史
            this.processHistoryTask(commandContext, taskEntity, historicTaskInstanceEntity, historicActivityInstanceEntity, targetActivity);
        }
        logger.info("activiti is rollback {}",
                historicTaskInstanceEntity.getName());

        return 0;
    }
    
    private VariableInstanceEntity insertVariableInstanceEntity(String name, Object value, String executionId, String processInstanceId) {
        VariableTypes variableTypes = Context.getProcessEngineConfiguration().getVariableTypes();
        VariableType newType = variableTypes.findVariableType(value);
        VariableInstanceEntity variableInstance = VariableInstanceEntity.create(name, newType, value);
        variableInstance.setExecutionId(executionId);
        variableInstance.setProcessInstanceId(processInstanceId);
        return variableInstance;
    }
    /**
     * 回退到startEvent.
     */
    public Integer rollbackStartEvent(CommandContext commandContext) {
        // 获得任务
        TaskEntity taskEntity = this.findTask(commandContext);

        // 找到想要回退到的节点
        ActivityImpl targetActivity = this.findTargetActivity(commandContext,
                taskEntity);

        if (taskEntity.getExecutionId().equals(
                taskEntity.getProcessInstanceId())) {
            // 如果退回的目标节点的executionId与当前task的executionId一样,说明是同一个分支
            // 只删除当前分支的task
            TaskEntity targetTaskEntity = Context.getCommandContext()
                    .getTaskEntityManager().findTaskById(this.taskId);
            this.deleteActiveTask(targetTaskEntity);
        } else {
            // 否则认为是从分支跳回主干
            // 删除所有活动中的task
            this.deleteActiveTasks(taskEntity.getProcessInstanceId());
        }

        // 把流程指向任务对应的节点
        ExecutionEntity executionEntity = Context.getCommandContext()
                .getExecutionEntityManager()
                .findExecutionById(taskEntity.getExecutionId());
        executionEntity.setActivity(targetActivity);

        // 创建HistoricActivityInstance
        Context.getCommandContext().getHistoryManager()
                .recordActivityStart(executionEntity);

        // 处理多实例
//        this.processMultiInstance();

        return 0;
    }

    /**
     * 获得当前任务.
     */
    public TaskEntity findTask(CommandContext commandContext) {
        TaskEntity taskEntity = commandContext.getTaskEntityManager()
                .findTaskById(taskId);

        return taskEntity;
    }

    /**
     * 查找回退的目的节点.
     */
    public ActivityImpl findTargetActivity(CommandContext commandContext,
            TaskEntity taskEntity) {
        if (activityId == null) {
            String historyTaskId = this.findNearestUserTask(commandContext);
            HistoricTaskInstanceEntity historicTaskInstanceEntity = commandContext
                    .getHistoricTaskInstanceEntityManager()
                    .findHistoricTaskInstanceById(historyTaskId);
            this.activityId = historicTaskInstanceEntity.getTaskDefinitionKey();
        }

        String processDefinitionId = taskEntity.getProcessDefinitionId();
        ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(
                processDefinitionId).execute(commandContext);

        return processDefinitionEntity.findActivity(activityId);
    }

    /**
     * 找到想要回退对应的节点历史.
     */
    public HistoricActivityInstanceEntity findTargetHistoricActivity(
            CommandContext commandContext, TaskEntity taskEntity,
            ActivityImpl activityImpl) {
        HistoricActivityInstanceQueryImpl historicActivityInstanceQueryImpl = new HistoricActivityInstanceQueryImpl();
        historicActivityInstanceQueryImpl.activityId(activityImpl.getId());
        historicActivityInstanceQueryImpl.processInstanceId(taskEntity
                .getProcessInstanceId());
        historicActivityInstanceQueryImpl
                .orderByHistoricActivityInstanceEndTime().desc();

        List<HistoricActivityInstance> list = commandContext
                .getHistoricActivityInstanceEntityManager()
                .findHistoricActivityInstancesByQueryCriteria(
                        historicActivityInstanceQueryImpl, new Page(0, 99));
        HistoricActivityInstanceEntity historicActivityInstanceEntity = new HistoricActivityInstanceEntity();
        for (HistoricActivityInstance historicActivityInstance : list) {
            if (StringTools.isValue(historicActivityInstance.getEndTime())) {
                historicActivityInstanceEntity = (HistoricActivityInstanceEntity) historicActivityInstance;
            }
        }
        return historicActivityInstanceEntity;
    }
    
    /**
     * 找到想要回退对应的节点历史.
     */
    public HistoricActivityInstanceEntity findTargetHistoricActivity(
            CommandContext commandContext, TaskEntity taskEntity,
            String taskDefKey) {
        HistoricActivityInstanceQueryImpl historicActivityInstanceQueryImpl = new HistoricActivityInstanceQueryImpl();
        historicActivityInstanceQueryImpl.activityId(taskDefKey);
        historicActivityInstanceQueryImpl.processInstanceId(taskEntity
                .getProcessInstanceId());
        historicActivityInstanceQueryImpl
                .orderByHistoricActivityInstanceEndTime().desc();

        return (HistoricActivityInstanceEntity) commandContext.getHistoricActivityInstanceEntityManager().findHistoricActivityInstancesByQueryCriteria(historicActivityInstanceQueryImpl, new Page(0, 99)).get(0);
    }
    
    public List<HistoricActivityInstance> findTargetHistoricActivityList(
            CommandContext commandContext, String activityId,
            String processInstanceId) {
        HistoricActivityInstanceQueryImpl historicActivityInstanceQueryImpl = new HistoricActivityInstanceQueryImpl();
        historicActivityInstanceQueryImpl.activityId(activityId);
        historicActivityInstanceQueryImpl.processInstanceId(processInstanceId);
        historicActivityInstanceQueryImpl.orderByHistoricActivityInstanceEndTime().desc();

        return commandContext
                .getHistoricActivityInstanceEntityManager()
                .findHistoricActivityInstancesByQueryCriteria(
                        historicActivityInstanceQueryImpl, new Page(0, 99));
    }
    
    /**
     * 找到想要回退对应的节点历史.
     */
    public List<HistoricActivityInstance> findTargetHistoricActivityList(
            CommandContext commandContext, TaskEntity taskEntity,
            ActivityImpl activityImpl) {
        HistoricActivityInstanceQueryImpl historicActivityInstanceQueryImpl = new HistoricActivityInstanceQueryImpl();
        historicActivityInstanceQueryImpl.activityId(activityImpl.getId());
        historicActivityInstanceQueryImpl.processInstanceId(taskEntity
                .getProcessInstanceId());
        historicActivityInstanceQueryImpl
                .orderByHistoricActivityInstanceEndTime().desc();

        return commandContext
                .getHistoricActivityInstanceEntityManager()
                .findHistoricActivityInstancesByQueryCriteria(
                        historicActivityInstanceQueryImpl, new Page(0, 99));
    }

    /**
     * 找到想要回退对应的任务历史.
     */
    public HistoricTaskInstanceEntity findTargetHistoricTask(
            CommandContext commandContext, TaskEntity taskEntity,
            ActivityImpl activityImpl) {
        HistoricTaskInstanceQueryImpl historicTaskInstanceQueryImpl = new HistoricTaskInstanceQueryImpl();
        historicTaskInstanceQueryImpl.taskDefinitionKey(activityImpl.getId());
        historicTaskInstanceQueryImpl.processInstanceId(taskEntity.getProcessInstanceId());
        historicTaskInstanceQueryImpl.setFirstResult(0);
        historicTaskInstanceQueryImpl.setMaxResults(1);
        historicTaskInstanceQueryImpl.orderByTaskCreateTime().asc();

        HistoricTaskInstanceEntity historicTaskInstanceEntity = (HistoricTaskInstanceEntity) commandContext
                .getHistoricTaskInstanceEntityManager()
                .findHistoricTaskInstancesByQueryCriteria(
                        historicTaskInstanceQueryImpl).get(0);
        
        return historicTaskInstanceEntity;
    }

    /**
     * 判断想要回退的目标节点和当前节点是否在一个分支上.
     */
    public boolean isSameBranch(
            HistoricTaskInstanceEntity historicTaskInstanceEntity) {
        TaskEntity taskEntity = Context.getCommandContext()
                .getTaskEntityManager().findTaskById(taskId);

        return taskEntity.getExecutionId().equals(
                historicTaskInstanceEntity.getExecutionId());
    }

    /**
     * 查找离当前节点最近的上一个userTask.
     */
    public String findNearestUserTask(CommandContext commandContext) {
        TaskEntity taskEntity = commandContext.getTaskEntityManager()
                .findTaskById(taskId);

        if (taskEntity == null) {
            logger.debug("cannot find task : {}", taskId);

            return null;
        }

        Graph graph = new ActivitiHistoryGraphBuilder(
                taskEntity.getProcessInstanceId()).build();
//        commandContext.getHistoricActivityInstanceEntityManager().findHistoricActivityInstancesByQueryCriteria(historicActivityInstanceQuery, page)
        HistoricActivityInstanceEntity hisActEntity = findTargetHistoricActivity(commandContext, taskEntity, taskEntity.getTaskDefinitionKey());
//        commandContext.getHistoricActivityInstanceEntityManager().findHistoricActivityInstance(taskEntity.getTaskDefinitionKey(), taskEntity.getProcessInstanceId());
        Node node = graph.findById(hisActEntity.getId());
        if (node == null)
            return null;
        String previousHistoricActivityInstanceId = this.findIncomingNode(
                graph, node, taskEntity.getProcessInstanceId());

        if (previousHistoricActivityInstanceId == null) {
            logger.debug(
                    "cannot find previous historic activity instance : {}",
                    taskEntity);

            return null;
        }
        List<HistoricActivityInstance> hisTaskList = findTargetHistoricActivityList(commandContext, previousHistoricActivityInstanceId, hisActEntity.getProcessInstanceId());
        for (HistoricActivityInstance historicActivityInstance : hisTaskList) {
            if(StringTools.isValue(historicActivityInstance.getEndTime())){
                return historicActivityInstance.getTaskId();
            }
        }
        return hisTaskList.get(0).getTaskId();
    }

    /**
     * 查找进入的连线.
     */
    public String findIncomingNode(Graph graph, Node node, String processInstanceId) {
        for (Edge edge : graph.getEdges()) {
            Node src = edge.getSrc();
            Node dest = edge.getDest();
            String srcType = src.getType();

            if (!dest.getId().equals(node.getId())) {
                continue;
            }

            if ("userTask".equals(srcType)) {
                boolean isSkip = isSkipActivity(src.getId(), processInstanceId);

                if (isSkip) {
                    return this.findIncomingNode(graph, src, processInstanceId);
                } else {
                    return src.getName();
                }
            } else if (srcType.endsWith("Gateway")) {
                return this.findIncomingNode(graph, src, processInstanceId);
            } else {
                logger.info("cannot rollback, previous node is not userTask : "
                        + src.getId() + " " + srcType + "(" + src.getName()
                        + ")");

                return null;
            }
        }

        logger.info("cannot rollback, this : " + node.getId() + " "
                + node.getType() + "(" + node.getName() + ")");

        return null;
    }


    /**
     * 判断是否可回退.
     */
    public boolean checkCouldRollback(Node node, String processInstanceId) {
        // TODO: 如果是catchEvent,也应该可以退回,到时候再说
        for (Edge edge : node.getOutgoingEdges()) {
            Node dest = edge.getDest();
            String type = dest.getType();

            if ("userTask".equals(type)) {
                if (!dest.isActive()) {
                    boolean isSkip = isSkipActivity(dest.getId(), processInstanceId);

                    if (isSkip) {
                        return checkCouldRollback(dest, processInstanceId);
                    } else {
                        // logger.info("cannot rollback, " + type + "("
                        // + dest.getName() + ") is complete.");
                        // return false;
                        return true;
                    }
                }
            } else if (type.endsWith("Gateway")) {
                return checkCouldRollback(dest, processInstanceId);
            } else {
                logger.info("cannot rollback, " + type + "(" + dest.getName()
                        + ") is complete.");

                return false;
            }
        }

        return true;
    }

    /**
     * 删除活动状态任务.
     */
    public void deleteActiveTasks(String processInstanceId) {
        List<TaskEntity> taskEntities = Context.getCommandContext()
                .getTaskEntityManager()
                .findTasksByProcessInstanceId(processInstanceId);

        for (TaskEntity taskEntity : taskEntities) {
            this.deleteActiveTask(taskEntity);
        }
    }

    /**
     * 遍历节点.
     */
    public void collectNodes(Node node, List<String> historyNodeIds) {
        logger.info("node : {}, {}, {}", node.getId(), node.getType(),
                node.getName());

        for (Edge edge : node.getOutgoingEdges()) {
            logger.info("edge : {}", edge.getName());

            Node dest = edge.getDest();
            historyNodeIds.add(dest.getId());
            collectNodes(dest, historyNodeIds);
        }
    }

    /**
     * 
     * <p>Title: 退回多实例环节  并行/串行</p>
     * <p>Description: </p>
     * @param commandContext
     * @param taskEntity
     * @param historicTaskInstanceEntity
     * @param historicActivityInstanceEntity
     * @param targetActivity
     * @date 2018年8月31日
     * @author zhuzubin
     */
    public void rollbackProcessMultiInstance (CommandContext commandContext,
            TaskEntity taskEntity,  HistoricTaskInstanceEntity historicTaskInstanceEntity,
            HistoricActivityInstanceEntity historicActivityInstanceEntity, ActivityImpl targetActivity) {

        //查找历史处理人
        HistoricTaskInstanceQueryImpl query = new HistoricTaskInstanceQueryImpl();
        query.taskDefinitionKey(targetActivity.getId());
        query.processInstanceId(historicTaskInstanceEntity.getProcessInstanceId());
        query.orderByHistoricTaskInstanceEndTime().desc();
        query.setFirstResult(0);
        query.setMaxResults(99);
        List<HistoricTaskInstance>  list = Context.getCommandContext().getHistoricTaskInstanceEntityManager().findHistoricTaskInstancesByQueryCriteria(query);
        //过虑重复退回任务
        for (int i = 0; i < list.size() - 1; i++) {
            for (int j = list.size() - 1; j > i; j--) {
                if (list.get(j).getTaskDefinitionKey().equals(list.get(i).getTaskDefinitionKey()) && list.get(j).getAssignee().equals(list.get(i).getAssignee())) {
                    list.remove(j);
                }
            }
        }
        // 删除旧的Execution
        String processDefinitionId = taskEntity.getProcessDefinitionId();
        ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(
                processDefinitionId).execute(commandContext);
        
        ExecutionEntity executionEntity = taskEntity.getExecution(); //taskEntity.getExecution();
        ActivityImpl activityImpl = processDefinitionEntity.findActivity(taskEntity.getTaskDefinitionKey());
        Map<String, Object> currMap = activityImpl.getProperties();
        if (currMap.containsKey("multiInstance")) { // 删除当前多实例任务
            executionEntity = taskEntity.getExecution().getParent().getParent(); //taskEntity.getExecution();
            this.deleteExecution(taskEntity);
        }
        executionEntity.setProcessInstance(executionEntity);
        executionEntity.setProcessDefinitionId(historicActivityInstanceEntity.getProcessDefinitionId());
        executionEntity.setActivity(targetActivity);
        executionEntity.setActive(false);
        executionEntity.setConcurrent(false);
        executionEntity.setCachedEntityState(0);
        // 创建HistoricActivityInstance
        if (currMap.containsKey("multiInstance")) {
            Context.getCommandContext().getHistoryManager().recordExecutionReplacedBy(taskEntity.getExecution().getParent().getParent(), executionEntity);
        } else {
            Context.getCommandContext().getHistoryManager().recordExecutionReplacedBy(taskEntity.getExecution(), executionEntity);
        }
        ExecutionEntity executionEntity_parent = new ExecutionEntity();
        executionEntity_parent.setParentId(executionEntity.getId());
        executionEntity_parent.setCachedEntityState(6);
        executionEntity_parent.setProcessDefinitionKey(historicActivityInstanceEntity.getProcessDefinitionKey());
        executionEntity_parent.setProcessInstance(executionEntity);
        executionEntity_parent.setProcessDefinitionId(historicActivityInstanceEntity.getProcessDefinitionId());
        executionEntity_parent.setActivity(targetActivity);
        if (targetActivity.getProperties().get("multiInstance").equals("sequential")) { // 串行任务
            this.isParallel = false;
            executionEntity_parent.setActive(true);
            executionEntity_parent.setConcurrent(false);
            executionEntity_parent.setScope(true);
            Context.getCommandContext().getExecutionEntityManager().insert(executionEntity_parent);   
            // 创建HistoricActivityInstance
            Context.getCommandContext().getHistoryManager().recordActivityStart(executionEntity_parent);
            TaskEntity task = TaskEntity.create(new Date());
            task.setExecutionId(executionEntity_parent.getId());
            this.setTaskEntity(task, historicTaskInstanceEntity, list.get(list.size()-1).getAssignee());
            Context.getCommandContext().getTaskEntityManager().insert(task);
            // 创建HistoricTaskInstance
            Context.getCommandContext().getHistoryManager().recordTaskCreated(task, executionEntity_parent);
            Context.getCommandContext().getHistoryManager().recordTaskId(task);
            // 更新ACT_HI_ACTIVITY里的assignee字段
            Context.getCommandContext().getHistoryManager().recordTaskAssignment(task);
            this.createVariable(list.size(), 1, executionEntity_parent.getId(), executionEntity.getProcessInstanceId(), list.get(list.size()-1).getAssignee());
        } else { //并行任务
            executionEntity_parent.setActive(false);
            executionEntity_parent.setConcurrent(false);
            executionEntity_parent.setScope(true);
            Context.getCommandContext().getExecutionEntityManager().insert(executionEntity_parent);   
            // 创建多实例任务
            this.createVariable(list.size(), list.size(), executionEntity_parent.getId(), executionEntity.getProcessInstanceId(), "");
            int i = 0;
            for (HistoricTaskInstance historicTaskInstance : list) {
                if(StringTools.isValue(historicTaskInstance.getAssignee())){
                    ExecutionEntity executionEntity_c = new ExecutionEntity();
                    executionEntity_c.setParentId(executionEntity_parent.getId());
                    executionEntity_c.setActive(true);
                    executionEntity_c.setScope(false);
                    executionEntity_c.setConcurrent(true);
                    executionEntity_c.setActivity(targetActivity);
                    executionEntity_c.setCachedEntityState(7);
                    executionEntity_c.setProcessDefinitionKey(historicActivityInstanceEntity.getProcessDefinitionKey());
                    executionEntity_c.setProcessInstance(executionEntity);
                    executionEntity_c.setProcessDefinitionId(historicActivityInstanceEntity.getProcessDefinitionId());
                    Context.getCommandContext().getExecutionEntityManager().insert(executionEntity_c);
                    // 创建HistoricActivityInstance
                    Context.getCommandContext().getHistoryManager().recordActivityStart(executionEntity_c);
                    TaskEntity task = TaskEntity.create(new Date());
                    task.setExecutionId(executionEntity_c.getId());
                    this.setTaskEntity(task, historicTaskInstanceEntity, historicTaskInstance.getAssignee());
                    Context.getCommandContext().getTaskEntityManager().insert(task);
                    // 创建HistoricTaskInstance
                    Context.getCommandContext().getHistoryManager().recordTaskCreated(task, executionEntity_c);
                    Context.getCommandContext().getHistoryManager().recordTaskId(task);
                    // 更新ACT_HI_ACTIVITY里的assignee字段
                    Context.getCommandContext().getHistoryManager().recordTaskAssignment(task);
                    String[] varName_ = {"loopCounter", "processUser"};
                    for (String name : varName_) {
                        VariableTypes variableTypes = Context.getProcessEngineConfiguration().getVariableTypes();
                        VariableInstanceEntity variableInstance = this.insertVariableInstanceEntity(name, i, executionEntity_c.getId(), historicTaskInstanceEntity.getProcessInstanceId());
                        switch (name) {
                            case "loopCounter":
                                variableInstance.setLongValue(Long.valueOf(i));
                                variableInstance.setTextValue(i+"");
                                break;
                            case "processUser":
                                VariableType newType = variableTypes.findVariableType(historicTaskInstance.getAssignee());
                                variableInstance.setType(newType);
                                variableInstance.setLongValue(null);
                                variableInstance.setTextValue(historicTaskInstance.getAssignee());
                                break;
                        }
                        Context.getCommandContext().getVariableInstanceEntityManager().insert(variableInstance);
                    }
                    i++;
                }
            }
        }
    }
    /**
     * 
     * <p>Title: 创建变量参数</p>
     * <p>Description: </p>
     * @param size
     * @param activeInstanceSize
     * @param executionEntityId
     * @param processInstanceId
     * @param userId
     * @date 2018年8月31日
     * @author zhuzubin
     */
    public void createVariable(int size, int activeInstanceSize, String executionEntityId, String processInstanceId, String userId) {
        List<String> varName = new ArrayList<String>();
        varName.add("nrOfInstances");
        varName.add("nrOfCompletedInstances");
        varName.add("nrOfActiveInstances");
        if (!this.isParallel) {
            varName.add("loopCounter");
            varName.add("processUser");
        }
        for (String name : varName) {
            VariableTypes variableTypes = Context.getProcessEngineConfiguration().getVariableTypes();
            VariableType newType = variableTypes.findVariableType(size);
            VariableInstanceEntity variableInstance = this.insertVariableInstanceEntity(name, size, executionEntityId, processInstanceId);
            switch (name) {
                case "nrOfInstances":
                    variableInstance.setLongValue(Long.valueOf(size));
                    break;
                case "nrOfCompletedInstances":
                    newType = variableTypes.findVariableType(0);
                    variableInstance.setType(newType);
                    variableInstance.setLongValue(0L);
                    variableInstance.setTextValue("0");
                    break;
                case "nrOfActiveInstances":
                    variableInstance.setLongValue(Long.valueOf(activeInstanceSize));
                    if (!this.isParallel) {
                        variableInstance.setTextValue(activeInstanceSize+"");
                    }
                    break;
                case "loopCounter":
                    variableInstance.setLongValue(0L);
                    variableInstance.setTextValue("0");
                    break;
                case "processUser":
                    newType = variableTypes.findVariableType(userId);
                    variableInstance.setType(newType);
                    variableInstance.setLongValue(null);
                    variableInstance.setTextValue(userId);
                    break;
            }
            Context.getCommandContext().getVariableInstanceEntityManager().insert(variableInstance);
        }
    }
    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);
    }
    
    /**
     * 根据任务历史,创建待办任务.
     */
    public void processHistoryTask(CommandContext commandContext,
            TaskEntity taskEntity,
            HistoricTaskInstanceEntity historicTaskInstanceEntity,
            HistoricActivityInstanceEntity historicActivityInstanceEntity, ActivityImpl targetActivity) {
        if (this.userId == null) {
            if (this.useLastAssignee) {
                this.userId = historicTaskInstanceEntity.getAssignee();
            } else {
                String processDefinitionId = taskEntity.getProcessDefinitionId();
                ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd( processDefinitionId).execute(commandContext);
                TaskDefinition taskDefinition = processDefinitionEntity
                        .getTaskDefinitions().get(
                                historicTaskInstanceEntity
                                        .getTaskDefinitionKey());

                if (taskDefinition == null) {
                    String message = "cannot find taskDefinition : "
                            + historicTaskInstanceEntity.getTaskDefinitionKey();
                    logger.info(message);
                    throw new IllegalStateException(message);
                }

                if (taskDefinition.getAssigneeExpression() != null) {
                    logger.info("assignee expression is null : {}",
                            taskDefinition.getKey());
                    this.userId = (String) taskDefinition
                            .getAssigneeExpression().getValue(taskEntity);
                }
            }
        }
        
        // 创建新任务
        TaskEntity task = TaskEntity.create(new Date());
        task.setExecutionId(taskEntity.getExecutionId());
        // 把流程指向任务对应的节点
        ExecutionEntity executionEntity = taskEntity.getExecution();
        String processDefinitionId = taskEntity.getProcessDefinitionId();
        ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(
                processDefinitionId).execute(commandContext);
        ActivityImpl activityImpl = processDefinitionEntity.findActivity(taskEntity.getTaskDefinitionKey());
        Map<String, Object> currMap = activityImpl.getProperties();
        if (currMap.containsKey("multiInstance")) { // 删除当前多实例任务
            if (currMap.get("multiInstance").equals("sequential")) {
                executionEntity = taskEntity.getExecution().getParent();
                // 获取删除当前任务 execution
                this.deleteExecution(taskEntity.getExecution());
            } else {
                executionEntity = taskEntity.getExecution().getParent().getParent(); //taskEntity.getExecution();
                this.deleteExecution(taskEntity);
            }
            task.setExecutionId(executionEntity.getId());
            
        }
        this.setTaskEntity(task, historicTaskInstanceEntity, this.userId);
        Context.getCommandContext().getTaskEntityManager().insert(task);
        executionEntity.setProcessInstance(executionEntity);
        executionEntity.setProcessDefinitionId(historicActivityInstanceEntity.getProcessDefinitionId());
        executionEntity.setActivity(targetActivity);
//        // 创建HistoricActivityInstance
//        if (currMap.containsKey("multiInstance")) {
//            if (currMap.get("multiInstance").equals("sequential")) {
//                Context.getCommandContext().getHistoryManager().recordExecutionReplacedBy(taskEntity.getExecution().getParent(), executionEntity);
//            } else {
//                Context.getCommandContext().getHistoryManager().recordExecutionReplacedBy(taskEntity.getExecution().getParent().getParent(), executionEntity);
//            }
//        } else {
//            Context.getCommandContext().getHistoryManager().recordExecutionReplacedBy(taskEntity.getExecution(), executionEntity);
//        }
        // 创建HistoricActivityInstance
        Context.getCommandContext().getHistoryManager().recordActivityStart(executionEntity);
        // 创建HistoricTaskInstance
        Context.getCommandContext().getHistoryManager().recordTaskCreated(task, executionEntity);
        Context.getCommandContext().getHistoryManager().recordTaskId(task);
        // 更新ACT_HI_ACTIVITY里的assignee字段
        Context.getCommandContext().getHistoryManager().recordTaskAssignment(task);
       
    }

    public void setTaskEntity(TaskEntity task, HistoricTaskInstanceEntity historicTaskInstanceEntity, String userId) {
        task.setProcessDefinitionId(historicTaskInstanceEntity.getProcessDefinitionId());
        task.setAssigneeWithoutCascade(userId);
        task.setParentTaskIdWithoutCascade(historicTaskInstanceEntity.getParentTaskId());
        task.setNameWithoutCascade(historicTaskInstanceEntity.getName());
        task.setTaskDefinitionKey(historicTaskInstanceEntity.getTaskDefinitionKey());
        task.setFormKey(historicTaskInstanceEntity.getFormKey());
        task.setPriority(historicTaskInstanceEntity.getPriority());
        task.setProcessInstanceId(historicTaskInstanceEntity.getProcessInstanceId());
        task.setDescriptionWithoutCascade(historicTaskInstanceEntity.getDescription());
        task.setTenantId(historicTaskInstanceEntity.getTenantId());
    }
    /**
     * 获得历史节点对应的节点信息.
     */
    public ActivityImpl getActivity(
            HistoricActivityInstanceEntity historicActivityInstanceEntity) {
        ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(
                historicActivityInstanceEntity.getProcessDefinitionId())
                .execute(Context.getCommandContext());

        return processDefinitionEntity
                .findActivity(historicActivityInstanceEntity.getActivityId());
    }

    /**
     * 删除未完成任务.
     */
    public void deleteActiveTask(TaskEntity taskEntity) {
        ProcessDefinitionEntity processDefinitionEntity = new GetDeploymentProcessDefinitionCmd(
                taskEntity.getProcessDefinitionId()).execute(Context
                .getCommandContext());

        ActivityImpl activityImpl = processDefinitionEntity
                .findActivity(taskEntity.getTaskDefinitionKey());

        if (this.isMultiInstance(activityImpl)) {
            logger.info("{} is multiInstance", taskEntity.getId());
            this.multiInstanceExecutionIds.add(taskEntity.getExecution()
                    .getParent().getId());
            logger.info("append : {}", taskEntity.getExecution().getParent()
                    .getId());
            List<VariableInstanceEntity> varLis = Context.getCommandContext().getVariableInstanceEntityManager().findVariableInstancesByExecutionId(taskEntity.getExecutionId());
            for (VariableInstanceEntity variableInstanceEntity : varLis) {
                Context.getCommandContext().getVariableInstanceEntityManager().delete(variableInstanceEntity);
            }
        }
        Context.getCommandContext().getTaskEntityManager().deleteTask(taskEntity, "回退", false);
    }

    /**
     * 判断跳过节点.
     */
    public boolean isSkipActivity(String historyActivityId, String processInstanceId) {
//        JdbcTemplate jdbcTemplate = ApplicationContextHelper
//                .getBean(JdbcTemplate.class);
//        String historyTaskId = jdbcTemplate.queryForObject(
//                "SELECT TASK_ID_ FROM ACT_HI_ACTINST WHERE ID_=?",
//                String.class, historyActivityId);
//        HistoricActivityInstanceEntity hisActivityEntity = Context.getCommandContext().getHistoricActivityInstanceEntityManager().findHistoricActivityInstance(historyActivityId, processInstanceId);
//        HistoricTaskInstanceEntity historicTaskInstanceEntity = Context
//                .getCommandContext().getHistoricTaskInstanceEntityManager()
//                .findHistoricTaskInstanceById(hisActivityEntity.getTaskId());
//        String deleteReason = historicTaskInstanceEntity.getDeleteReason();

        return false;
    }

    /**
     * 判断是否会签.
     */
    public boolean isMultiInstance(PvmActivity pvmActivity) {
        return pvmActivity.getProperty("multiInstance") != null;
    }
import java.util.HashSet;
import java.util.Set;

import org.activiti.engine.impl.cmd.GetDeploymentProcessDefinitionCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;

/**
 * 根据流程定义,构建设计阶段的图.
 */
public class ActivitiGraphBuilder {
    /**
     * 流程定义id.
     */
    private String processDefinitionId;

    /**
     * 流程定义.
     */
    private ProcessDefinitionEntity processDefinitionEntity;

    /**
     * 已访问的节点id.
     */
    private Set<String> visitedNodeIds = new HashSet<String>();

    /**
     * 构造方法.
     */
    public ActivitiGraphBuilder(String processDefinitionId) {
        this.processDefinitionId = processDefinitionId;
    }

    /**
     * 构建图.
     */
    public Graph build() {
        this.fetchProcessDefinitionEntity();

        Node initial = visitNode(processDefinitionEntity.getInitial());

        Graph graph = new Graph();
        graph.setInitial(initial);

        return graph;
    }

    /**
     * 获取流程定义.
     */
    public void fetchProcessDefinitionEntity() {
        GetDeploymentProcessDefinitionCmd cmd = new GetDeploymentProcessDefinitionCmd(
                processDefinitionId);
        processDefinitionEntity = cmd.execute(Context.getCommandContext());
    }

    /**
     * 遍历.
     */
    public Node visitNode(PvmActivity pvmActivity) {
        if (visitedNodeIds.contains(pvmActivity.getId())) {
            return null;
        }

        visitedNodeIds.add(pvmActivity.getId());

        Node currentNode = new Node();
        currentNode.setId(pvmActivity.getId());
        currentNode.setName(this.getString(pvmActivity.getProperty("name")));
        currentNode.setType(this.getString(pvmActivity.getProperty("type")));

        for (PvmTransition pvmTransition : pvmActivity.getOutgoingTransitions()) {
            PvmActivity destination = pvmTransition.getDestination();
            Node targetNode = this.visitNode(destination);

            if (targetNode == null) {
                continue;
            }

            Edge edge = new Edge();
            edge.setId(pvmTransition.getId());
            edge.setSrc(currentNode);
            edge.setDest(targetNode);
            currentNode.getOutgoingEdges().add(edge);
        }

        return currentNode;
    }

    /**
     * 把object转换为string.
     */
    public String getString(Object object) {
        if (object == null) {
            return null;
        } else if (object instanceof String) {
            return (String) object;
        } else {
            return object.toString();
        }
    }
}


import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.impl.HistoricActivityInstanceQueryImpl;
import org.activiti.engine.impl.Page;
import org.activiti.engine.impl.cmd.GetDeploymentProcessDefinitionCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 根据历史,生成实时运行阶段的子图.
 */
public class ActivitiHistoryGraphBuilder {
    /**
     * logger.
     */
    private static Logger logger = LoggerFactory
            .getLogger(ActivitiHistoryGraphBuilder.class);
    private String processInstanceId;
    private ProcessDefinitionEntity processDefinitionEntity;
    private List<HistoricActivityInstance> historicActivityInstances;
    private List<HistoricActivityInstance> visitedHistoricActivityInstances = new ArrayList<HistoricActivityInstance>();
    private Map<String, Node> nodeMap = new HashMap<String, Node>();

    public ActivitiHistoryGraphBuilder(String processInstanceId) {
        this.processInstanceId = processInstanceId;
    }

    public Graph build() {
        this.fetchProcessDefinitionEntity();
        this.fetchHistoricActivityInstances();

        Graph graph = new Graph();

        for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
            Node currentNode = new Node();
            currentNode.setId(historicActivityInstance.getId());
            currentNode.setName(historicActivityInstance.getActivityId());
            currentNode.setType(historicActivityInstance.getActivityType());
            currentNode
                    .setActive(historicActivityInstance.getEndTime() == null);
            logger.debug("currentNode : {}:{}", currentNode.getName(),
                    currentNode.getId());

            Edge previousEdge = this.findPreviousEdge(currentNode,
                    historicActivityInstance.getStartTime().getTime());

            if (previousEdge == null) {
                if (graph.getInitial() != null) {
                    throw new IllegalStateException("already set an initial.");
                }

                graph.setInitial(currentNode);
            } else {
                logger.debug("previousEdge : {}", previousEdge.getName());
            }

            nodeMap.put(currentNode.getId(), currentNode);
            visitedHistoricActivityInstances.add(historicActivityInstance);
        }

        if (graph.getInitial() == null) {
            throw new IllegalStateException("cannot find initial.");
        }

        return graph;
    }

    /**
     * 根据流程实例id获取对应的流程定义.
     */
    public void fetchProcessDefinitionEntity() {
        String processDefinitionId = Context.getCommandContext()
                .getHistoricProcessInstanceEntityManager()
                .findHistoricProcessInstance(processInstanceId)
                .getProcessDefinitionId();
        GetDeploymentProcessDefinitionCmd cmd = new GetDeploymentProcessDefinitionCmd(
                processDefinitionId);
        processDefinitionEntity = cmd.execute(Context.getCommandContext());
    }

    public void fetchHistoricActivityInstances() {
        HistoricActivityInstanceQueryImpl historicActivityInstanceQueryImpl = new HistoricActivityInstanceQueryImpl();
        // historicActivityInstanceQueryImpl.processInstanceId(processInstanceId)
        // .orderByHistoricActivityInstanceStartTime().asc();
        // TODO: 如果用了uuid会造成这样排序出问题
        // 但是如果用startTime,可能出现因为处理速度太快,时间一样,导致次序颠倒的问题
        historicActivityInstanceQueryImpl.processInstanceId(processInstanceId)
                .orderByHistoricActivityInstanceId().asc();

        Page page = new Page(0, 100);
        historicActivityInstances = Context
                .getCommandContext()
                .getHistoricActivityInstanceEntityManager()
                .findHistoricActivityInstancesByQueryCriteria(
                        historicActivityInstanceQueryImpl, page);
    }

    /**
     * 找到这个节点前面的连线.
     */
    public Edge findPreviousEdge(Node currentNode, long currentStartTime) {
        String activityId = currentNode.getName();
        ActivityImpl activityImpl = processDefinitionEntity
                .findActivity(activityId);
        HistoricActivityInstance nestestHistoricActivityInstance = null;
        String temporaryPvmTransitionId = null;

        // 遍历进入当前节点的所有连线
        for (PvmTransition pvmTransition : activityImpl
                .getIncomingTransitions()) {
            PvmActivity source = pvmTransition.getSource();

            String previousActivityId = source.getId();

            HistoricActivityInstance visitiedHistoryActivityInstance = this
                    .findVisitedHistoricActivityInstance(previousActivityId);

            if (visitiedHistoryActivityInstance == null) {
                continue;
            }

            // 如果上一个节点还未完成,说明不可能是从这个节点过来的,跳过
            if (visitiedHistoryActivityInstance.getEndTime() == null) {
                continue;
            }

            logger.debug("current activity start time : {}", new Date(
                    currentStartTime));
            logger.debug("nestest activity end time : {}",
                    visitiedHistoryActivityInstance.getEndTime());

            // 如果当前节点的开始时间,比上一个节点的结束时间要早,跳过
            if (currentStartTime < visitiedHistoryActivityInstance.getEndTime()
                    .getTime()) {
                continue;
            }

            if (nestestHistoricActivityInstance == null) {
                nestestHistoricActivityInstance = visitiedHistoryActivityInstance;
                temporaryPvmTransitionId = pvmTransition.getId();
            } else if ((currentStartTime - nestestHistoricActivityInstance
                    .getEndTime().getTime()) > (currentStartTime - visitiedHistoryActivityInstance
                    .getEndTime().getTime())) {
                // 寻找离当前节点最近的上一个节点
                // 比较上一个节点的endTime与当前节点startTime的差
                nestestHistoricActivityInstance = visitiedHistoryActivityInstance;
                temporaryPvmTransitionId = pvmTransition.getId();
            }
        }

        // 没找到上一个节点,就返回null
        if (nestestHistoricActivityInstance == null) {
            return null;
        }

        Node previousNode = nodeMap
                .get(nestestHistoricActivityInstance.getId());

        if (previousNode == null) {
            return null;
        }

        logger.debug("previousNode : {}:{}", previousNode.getName(),
                previousNode.getId());

        Edge edge = new Edge();
        edge.setName(temporaryPvmTransitionId);
        previousNode.getOutgoingEdges().add(edge);
        edge.setSrc(previousNode);
        edge.setDest(currentNode);

        return edge;
    }

    public HistoricActivityInstance findVisitedHistoricActivityInstance(
            String activityId) {
        for (int i = visitedHistoricActivityInstances.size() - 1; i >= 0; i--) {
            HistoricActivityInstance historicActivityInstance = visitedHistoricActivityInstances
                    .get(i);

            if (activityId.equals(historicActivityInstance.getActivityId())) {
                return historicActivityInstance;
            }
        }

        return null;
    }
}

/**
 * 连线.
 */
public class Edge extends GraphElement {
    /**
     * 起点.
     */
    private Node src;

    /**
     * 终点.
     */
    private Node dest;

    /**
     * 循环.
     */
    private boolean cycle;

    public Node getSrc() {
        return src;
    }

    public void setSrc(Node src) {
        this.src = src;
    }

    public Node getDest() {
        return dest;
    }

    public void setDest(Node dest) {
        this.dest = dest;
    }

    public boolean isCycle() {
        return cycle;
    }

    public void setCycle(boolean cycle) {
        this.cycle = cycle;
    }
}


import java.util.ArrayList;
import java.util.List;

public class Graph {
    private Node initial;

    public Node getInitial() {
        return initial;
    }

    public void setInitial(Node initial) {
        this.initial = initial;
    }

    public List<Node> getNodes() {
        List<Node> nodes = new ArrayList<Node>();
        visitNode(initial, nodes);

        return nodes;
    }

    public void visitNode(Node node, List<Node> nodes) {
        nodes.add(node);

        for (Edge edge : node.getOutgoingEdges()) {
            Node nextNode = edge.getDest();
            visitNode(nextNode, nodes);
        }
    }

    public List<Edge> getEdges() {
        List<Edge> edges = new ArrayList<Edge>();
        visitEdge(initial, edges);

        return edges;
    }

    public void visitEdge(Node node, List<Edge> edges) {
        for (Edge edge : node.getOutgoingEdges()) {
            edges.add(edge);

            Node nextNode = edge.getDest();
            visitEdge(nextNode, edges);
        }
    }

    public Node findById(String id) {
        for (Node node : this.getNodes()) {
            if (id.equals(node.getId())) {
                return node;
            }
        }

        return null;
    }
}


/**
 * 节点和连线的父类.
 */
public class GraphElement {
    /**
     * 实例id,历史的id.
     */
    private String id;

    /**
     * 节点名称,bpmn图形中的id.
     */
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
import java.util.ArrayList;
import java.util.List;

/**
 * 节点.
 */
public class Node extends GraphElement {
    /**
     * 类型,比如userTask,startEvent.
     */
    private String type;

    /**
     * 是否还未完成.
     */
    private boolean active;

    /**
     * 进入这个节点的所有连线.
     */
    private List<Edge> incomingEdges = new ArrayList<Edge>();

    /**
     * 外出这个节点的所有连线.
     */
    private List<Edge> outgoingEdges = new ArrayList<Edge>();

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }

    public List<Edge> getIncomingEdges() {
        return incomingEdges;
    }

    public void setIncomingEdges(List<Edge> incomingEdges) {
        this.incomingEdges = incomingEdges;
    }

    public List<Edge> getOutgoingEdges() {
        return outgoingEdges;
    }

    public void setOutgoingEdges(List<Edge> outgoingEdges) {
        this.outgoingEdges = outgoingEdges;
    }
}

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值