/** * Copyright 1996-2014 FoxBPM ORG. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @author ych */ package org.foxbpm.engine.impl.cmd; import java.util.List; import org.foxbpm.engine.impl.entity.ProcessDefinitionEntity; import org.foxbpm.engine.impl.entity.TaskEntity; import org.foxbpm.engine.impl.entity.TokenEntity; import org.foxbpm.engine.impl.identity.Authentication; import org.foxbpm.engine.impl.interceptor.Command; import org.foxbpm.engine.impl.interceptor.CommandContext; import org.foxbpm.engine.impl.persistence.TaskManager; import org.foxbpm.engine.impl.task.TaskCommandSystemType; import org.foxbpm.engine.impl.util.ExceptionUtil; import org.foxbpm.engine.impl.util.StringUtil; import org.foxbpm.kernel.process.impl.KernelFlowNodeImpl; /** * 追回任务 * 此命令要求: * 1.当前登陆人必须在目标节点(targetNodeId)处理过任务,处理多次则默认取最近的一条 * 2.主令牌经过的节点才能追回,也就是说主线上的节点 * 3.分支时,只有同一条分支上的节点之间才能追回操作 * 不满足上述条件时,则会抛出相应异常信息 * 如果从分支内追回到主线时,其他分支将被强制结束。 * @param taskId 要追回的任务编号 * @param targetNodeId 要追回到的目标节点编号 * */ public class RecoverTaskByIdCmd implements Command<List<Void>>{ private String taskId; private String targetNodeId; public RecoverTaskByIdCmd(String taskId,String targetNodeId) { this.taskId = taskId; this.targetNodeId = targetNodeId; } public List<Void> execute(CommandContext commandContext) { String userId = Authentication.getAuthenticatedUserId(); if(StringUtil.isEmpty(userId)){ //未设置当前登陆人 throw ExceptionUtil.getException("10601001"); } if(StringUtil.isEmpty(taskId)){ //追回的任务编号为空 throw ExceptionUtil.getException("10601201"); } if(StringUtil.isEmpty(targetNodeId)){ //追回的目标节点编号为空 throw ExceptionUtil.getException("10601011"); } TaskManager taskManager = commandContext.getTaskManager(); TaskEntity taskEntity = taskManager.findTaskById(taskId); if(taskEntity == null){ //追回的任务{0}不存在 throw ExceptionUtil.getException("10602201",taskId); } TaskEntity targetTaskEntity = taskManager.findLastEndTaskByProcessInstanceIdAndNodeId(taskEntity.getProcessInstanceId(), targetNodeId); if(targetTaskEntity == null){ //流程未经过{0}节点,无法追回 throw ExceptionUtil.getException("10603002",targetNodeId); } if(!targetTaskEntity.getAssignee().equals(Authentication.getAuthenticatedUserId())){ //任务最后处理人是{},当前登陆人为{},无权追回。 throw ExceptionUtil.getException("10603003",Authentication.getAuthenticatedUserId(),targetTaskEntity.getAssignee()); } TokenEntity targetTokenEntity = targetTaskEntity.getToken(); if(!targetTokenEntity.isRoot() && !targetTaskEntity.getTokenId().equals(taskEntity.getTokenId())){ //源节点{},目标节点{}不在统一分支,并且目标节点非主令牌处理 throw ExceptionUtil.getException("10603004",taskEntity.getNodeId(),targetNodeId); } ProcessDefinitionEntity processDefinitionEntity = taskEntity.getProcessDefinition(); KernelFlowNodeImpl findFlowNode = processDefinitionEntity.findFlowNode(targetNodeId); taskEntity.setCommandId(TaskCommandSystemType.RECOVER); taskEntity.setCommandType(TaskCommandSystemType.RECOVER); taskEntity.setCommandMessage("已追回"); taskEntity.setAssignee(userId); taskEntity.complete(findFlowNode,userId); return null; } }