开源工作流Fireflow源码分析之拒收

   要了解拒收,看懂源代码,至少要先看几次作者的原文档说明,他对拒收的定义以及约束在哪里。

   拒收的含义是:当前操作者因为某种原因拒绝接收工作项,将已经发生的流转退回到前

驱环节。

   可以实现拒收的场景是:

开源工作流Fireflow源码分析之拒收

开源工作流Fireflow源码分析之拒收

开源工作流Fireflow源码分析之拒收

开源工作流Fireflow源码分析之拒收

开源工作流Fireflow源码分析之拒收

开源工作流Fireflow源码分析之拒收

/**

	 *拒收工单 

	 */

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

		}

	}

你可能感兴趣的:(源码分析)