throws EngineException, KernelException {
Activity thisActivity = workItem.getTaskInstance().getActivity();
TaskInstance thisTaskInstance = (TaskInstance) workItem
.getTaskInstance();
if (workItem.getState() < 5) {// 小于5的状态为活动状态
throw new EngineException(thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getWorkflowProcess(), thisTaskInstance
.getTaskId(),
"Withdraw operation is refused! Current workitem is in running state!!");
}
// 当前Activity只允许一个Form类型的Task
if (thisActivity.getTasks().size() > 1) {
throw new EngineException(thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getWorkflowProcess(), thisTaskInstance
.getTaskId(),
"Withdraw operation is refused! The activity[id="
+ thisActivity.getId() + "] has more than 1 tasks");
}
// 汇签Task不允许撤销
if (FormTask.ALL.equals(thisTaskInstance.getAssignmentStrategy())) {
throw new EngineException(thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getWorkflowProcess(), thisTaskInstance
.getTaskId(),
"Withdraw operation is refused! The assignment strategy for activity[id="
+ thisActivity.getId() + "] is 'ALL'");
}
IPersistenceService persistenceService = this.rtCtx
.getPersistenceService();
List<ITaskInstance> targetTaskInstancesList = null;
targetTaskInstancesList = persistenceService
.findTaskInstancesForProcessInstanceByStepNumber(
thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getStepNumber() + 1);
// 如果targetTaskInstancesList为空或size 等于0,则表示流程实例执行了汇聚操作。
if (targetTaskInstancesList == null
|| targetTaskInstancesList.size() == 0) {
throw new EngineException(
thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getWorkflowProcess(),
thisTaskInstance.getTaskId(),
"Withdraw operation is refused!Because the process instance has taken a join operation after this activity[id="
+ thisActivity.getId() + "].");
} else {
TaskInstance taskInstance = (TaskInstance) targetTaskInstancesList
.get(0);
if (!taskInstance.getFromActivityId().equals(
thisTaskInstance.getActivityId())) {
throw new EngineException(
thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getWorkflowProcess(),
thisTaskInstance.getTaskId(),
"Withdraw operation is refused!Because the process instance has taken a join operation after this activity[id="
+ thisActivity.getId() + "].");
}
}
for (int i = 0; targetTaskInstancesList != null
&& i < targetTaskInstancesList.size(); i++) {
TaskInstance targetTaskInstanceTmp = (TaskInstance) targetTaskInstancesList
.get(i);
if (!targetTaskInstanceTmp.getCanBeWithdrawn()) {
// 说明已经有某些WorkItem处于已签收状态,或者已经处于完毕状态,此时不允许退回
throw new EngineException(thisTaskInstance
.getProcessInstanceId(), thisTaskInstance
.getWorkflowProcess(), thisTaskInstance.getTaskId(),
"Withdraw operation is refused! Some task instances of the next activity[id="
+ targetTaskInstanceTmp.getActivityId()
+ "] are not in 'Initialized' state");
}
}
INetInstance netInstance = rtCtx.getKernelManager().getNetInstance(
thisTaskInstance.getProcessId(),
workItem.getTaskInstance().getVersion());
if (netInstance == null) {
throw new EngineException(thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getWorkflowProcess(), thisTaskInstance
.getTaskId(),
"Withdraw operation failed.Not find the net instance for workflow process [id="
+ thisTaskInstance.getProcessId() + ", version="
+ workItem.getTaskInstance().getVersion() + "]");
}
Object obj = netInstance.getWFElementInstance(thisTaskInstance
.getActivityId());
IActivityInstance thisActivityInstance = (IActivityInstance) obj;
// 一切检查通过之后进行“收回”处理
IWorkflowSession session = ((IWorkflowSessionAware) workItem)
.getCurrentWorkflowSession();
session.setWithdrawOrRejectOperationFlag(true);
int newStepNumber = thisTaskInstance.getStepNumber() + 2;
try {
DynamicAssignmentHandler dynamicAssignmentHandler = new DynamicAssignmentHandler();
List<String> actorIds = new ArrayList<String>();
actorIds.add(workItem.getActorId());
dynamicAssignmentHandler.setActorIdsList(actorIds);
((WorkflowSession) session)
.setCurrentDynamicAssignmentHandler(dynamicAssignmentHandler);
// 1、首先将后续环节的TaskInstance极其workItem变成Canceled状态
List<String> targetActivityIdList = new ArrayList<String>();
StringBuffer theFromActivityIds = new StringBuffer("");
for (int i = 0; i < targetTaskInstancesList.size(); i++) {
TaskInstance taskInstTemp = (TaskInstance) targetTaskInstancesList
.get(i);
persistenceService.abortTaskInstance(taskInstTemp);
if (!targetActivityIdList
.contains(taskInstTemp.getActivityId())) {
targetActivityIdList.add(taskInstTemp.getActivityId());
if (theFromActivityIds.length() == 0) {
theFromActivityIds.append(taskInstTemp.getActivityId());
} else {
theFromActivityIds.append(
IToken.FROM_ACTIVITY_ID_SEPARATOR).append(
taskInstTemp.getActivityId());
}
}
}
persistenceService.deleteTokensForNodes(thisTaskInstance
.getProcessInstanceId(), targetActivityIdList);
if (rtCtx.isEnableTrace()) {
for (int i = 0; targetActivityIdList != null
&& i < targetActivityIdList.size(); i++) {
String tmpActId = (String) targetActivityIdList.get(i);
ProcessInstanceTrace trace = new ProcessInstanceTrace();
trace.setProcessInstanceId(thisTaskInstance
.getProcessInstanceId());
trace.setStepNumber(newStepNumber);
trace.setType(ProcessInstanceTrace.WITHDRAW_TYPE);
trace.setFromNodeId(tmpActId);
trace.setToNodeId(thisActivity.getId());
trace.setEdgeId("");
rtCtx.getPersistenceService()
.saveOrUpdateProcessInstanceTrace(trace);
}
}
ITransitionInstance thisLeavingTransitionInstance = (ITransitionInstance) thisActivityInstance
.getLeavingTransitionInstances().get(0);
ISynchronizerInstance synchronizerInstance = (ISynchronizerInstance) thisLeavingTransitionInstance
.getLeavingNodeInstance();
if (synchronizerInstance.getEnteringTransitionInstances().size() > 1) {
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 withdraw)");
supplementToken.setStepNumber(newStepNumber);
supplementToken.setValue(synchronizerInstance.getVolume()
- thisLeavingTransitionInstance.getWeight());
persistenceService.saveOrUpdateToken(supplementToken);
}
Token newToken = new Token();
((Token) newToken).setAlive(true);
((Token) newToken).setNodeId(workItem.getTaskInstance()
.getActivityId());
newToken.setProcessInstanceId(thisTaskInstance
.getProcessInstanceId());
newToken.setProcessInstance(((TaskInstance) thisTaskInstance)
.getAliveProcessInstance());
newToken.setFromActivityId(theFromActivityIds.toString());
newToken.setStepNumber(newStepNumber);
newToken.setValue(0);
persistenceService.saveOrUpdateToken(newToken);
this.createTaskInstances(newToken, thisActivityInstance);
List<IWorkItem> workItems = persistenceService.findTodoWorkItems(workItem
.getActorId(), workItem.getTaskInstance().getProcessId(),
workItem.getTaskInstance().getTaskId());
if (workItems == null || workItems.size() == 0) {
throw new EngineException(thisTaskInstance
.getProcessInstanceId(), thisTaskInstance
.getWorkflowProcess(), thisTaskInstance.getTaskId(),
"Withdraw operation failed.No work item has been created for Task[id="
+ thisTaskInstance.getTaskId() + "]");
}
if (workItems.size() > 1) {
throw new EngineException(
thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getWorkflowProcess(),
thisTaskInstance.getTaskId(),
"Withdraw operation failed.More than one work item have been created for Task[id="
+ thisTaskInstance.getTaskId() + "]");