要了解拒收,看懂源代码,至少要先看几次作者的原文档说明,他对拒收的定义以及约束在哪里。
拒收的含义是:当前操作者因为某种原因拒绝接收工作项,将已经发生的流转退回到前
驱环节。
可以实现拒收的场景是:
/** *拒收工单 */ public void rejectWorkItem(IWorkItem workItem, String comments) throws EngineException, KernelException { //取到工单对应的Activity Activity thisActivity = workItem.getTaskInstance().getActivity(); //取到TaskInstance TaskInstance thisTaskInstance = (TaskInstance) workItem .getTaskInstance(); //如果工单处于非活动状态,或者被挂起,则不允许reject if (workItem.getState() > 5 || workItem.getTaskInstance().isSuspended()) { throw new EngineException( thisTaskInstance.getProcessInstanceId(), thisTaskInstance.getWorkflowProcess(), thisTaskInstance.getTaskId(), "Reject operation refused!Current work item is completed or the correspond task instance is suspended!!"); } // 拒收操作环节只可以含有一个task if (thisActivity.getTasks().size() > 1) { throw new EngineException(thisTaskInstance.getProcessInstanceId(), thisTaskInstance.getWorkflowProcess(), thisTaskInstance .getTaskId(), "Reject operation refused!The correspond activity has more than 1 tasks"); } // 汇签Task不允许Reject,因为你不确定其它的人是否完成。。。 if (FormTask.ALL.equals(thisTaskInstance.getAssignmentStrategy())) { throw new EngineException(thisTaskInstance.getProcessInstanceId(), thisTaskInstance.getWorkflowProcess(), thisTaskInstance .getTaskId(), "Reject operation refused!The assignment strategy is 'ALL'"); } //处理拒收的边界问题,不能退回到开始节点 if(thisTaskInstance.getFromActivityId().equals(IToken.FROM_START_NODE)){ throw new EngineException( thisTaskInstance.getProcessInstanceId(), thisTaskInstance.getWorkflowProcess(), thisTaskInstance.getTaskId(), "Reject operation refused!Because the from activityId equals "+IToken.FROM_START_NODE ); } //取到持久化处理器 IPersistenceService persistenceService = this.rtCtx .getPersistenceService(); List<ITaskInstance> siblingTaskInstancesList = null; siblingTaskInstancesList = persistenceService .findTaskInstancesForProcessInstanceByStepNumber(workItem .getTaskInstance().getProcessInstanceId(), thisTaskInstance.getStepNumber()); // split情况下,每个分支上的环节不可以执行拒收操作 if (siblingTaskInstancesList.size() > 1) { throw new EngineException( thisTaskInstance.getProcessInstanceId(), thisTaskInstance.getWorkflowProcess(), thisTaskInstance.getTaskId(), "Reject operation refused!Because the process instance has taken a split operation."); } // 检查From Activity中是否有ToolTask和SubflowTask,如果有tool或subflow也不允许拒收 //注意这里,为什么可以从fromActivityID得到它的多个前驱activity,这个要看之后的synchroinizerInstance之汇聚算法 List<String> fromActivityIdList = new ArrayList<String>(); StringTokenizer tokenizer = new StringTokenizer(thisTaskInstance .getFromActivityId(), IToken.FROM_ACTIVITY_ID_SEPARATOR); while (tokenizer.hasMoreTokens()) { fromActivityIdList.add(tokenizer.nextToken()); } WorkflowProcess workflowProcess = workItem.getTaskInstance() .getWorkflowProcess(); for (int i = 0; i < fromActivityIdList.size(); i++) { String fromActivityId = (String) fromActivityIdList.get(i); Activity fromActivity = (Activity) workflowProcess .findWFElementById(fromActivityId); List<Task> fromTaskList = fromActivity.getTasks(); for (int j = 0; j < fromTaskList.size(); j++) { Task task = fromTaskList.get(j); //前驱环节的task类型是tool或subflow,则不可能拒收 if (Task.TOOL.equals(task.getType()) || Task.SUBFLOW.equals(task.getType())) { throw new EngineException( thisTaskInstance.getProcessInstanceId(), thisTaskInstance.getWorkflowProcess(), thisTaskInstance.getTaskId(), "Reject operation refused!The previous activity contains tool-task or subflow-task"); } } } // 取到工个流网实例 INetInstance netInstance = rtCtx.getKernelManager().getNetInstance( workflowProcess.getId(), workItem.getTaskInstance().getVersion()); if (netInstance == null) { throw new EngineException(thisTaskInstance.getProcessInstanceId(), thisTaskInstance.getWorkflowProcess(), thisTaskInstance .getTaskId(), "Not find the net instance for workflow process [id=" + workflowProcess.getId() + ", version=" + workItem.getTaskInstance().getVersion() + "]"); } // 执行reject操作。 //取到当前流程会话session IWorkflowSession session = ((IWorkflowSessionAware) workItem) .getCurrentWorkflowSession(); //设置作了退回动作 session.setWithdrawOrRejectOperationFlag(true); //当前步骤加1 int newStepNumber = thisTaskInstance.getStepNumber() + 1; try { // 首先将本WorkItem和TaskInstance cancel掉。 workItem.setComments(comments); ((WorkItem) workItem).setState(IWorkItem.CANCELED); ((WorkItem) workItem).setEndTime(rtCtx.getCalendarService() .getSysDate()); rtCtx.getPersistenceService().saveOrUpdateWorkItem(workItem); //终止本任务 persistenceService.abortTaskInstance(thisTaskInstance); // 删除本环节的token persistenceService.deleteTokensForNode(thisTaskInstance .getProcessInstanceId(), thisTaskInstance.getActivityId()); IActivityInstance fromActivityInstance = null; for (int i = 0; i < fromActivityIdList.size(); i++) { String fromActivityId = (String) fromActivityIdList.get(i); Object obj = netInstance.getWFElementInstance(fromActivityId); fromActivityInstance = (IActivityInstance) obj; //生成一个新的token Token newToken = new Token(); //设置状态 ((Token) newToken).setAlive(true); //设置当前节点id ((Token) newToken).setNodeId(fromActivityId); //设置流程实例id newToken.setProcessInstanceId(thisTaskInstance .getProcessInstanceId()); newToken.setProcessInstance(((TaskInstance) thisTaskInstance) .getAliveProcessInstance()); newToken.setFromActivityId(thisTaskInstance.getActivityId()); newToken.setStepNumber(newStepNumber); newToken.setValue(0); persistenceService.saveOrUpdateToken(newToken); //生成一个新的任务 this.createTaskInstances(newToken, fromActivityInstance); //如果需要打印trance if (rtCtx.isEnableTrace()) { ProcessInstanceTrace trace = new ProcessInstanceTrace(); trace.setProcessInstanceId(thisTaskInstance .getProcessInstanceId()); trace.setStepNumber(newStepNumber); trace.setType(ProcessInstanceTrace.REJECT_TYPE); trace.setFromNodeId(thisActivity.getId()); trace.setToNodeId(fromActivityId); trace.setEdgeId(""); rtCtx.getPersistenceService() .saveOrUpdateProcessInstanceTrace(trace); } } //下面的这些代码我认为是没有意义的. //得到前一个activity的一条输出边 ITransitionInstance theLeavingTransitionInstance = (ITransitionInstance) fromActivityInstance .getLeavingTransitionInstances().get(0); //得到前一个同步器 ISynchronizerInstance synchronizerInstance = (ISynchronizerInstance) theLeavingTransitionInstance .getLeavingNodeInstance(); //if语句永远为真的,不会执行的。 if (synchronizerInstance.getEnteringTransitionInstances().size() > fromActivityIdList .size()) { Token supplementToken = new Token(); ((Token) supplementToken).setAlive(false); ((Token) supplementToken).setNodeId(synchronizerInstance .getSynchronizer().getId()); supplementToken.setProcessInstanceId(thisTaskInstance .getProcessInstanceId()); supplementToken .setProcessInstance(((TaskInstance) thisTaskInstance) .getAliveProcessInstance()); supplementToken.setFromActivityId("EMPTY(created by reject)"); supplementToken .setStepNumber(thisTaskInstance.getStepNumber() + 1); supplementToken.setValue(synchronizerInstance.getVolume() - theLeavingTransitionInstance.getWeight() * fromActivityIdList.size()); persistenceService.saveOrUpdateToken(supplementToken); } } finally { session.setWithdrawOrRejectOperationFlag(false); } }