/* (non-Javadoc)
* @see org.fireflow.engine.taskinstance.ITaskInstanceManager#withdrawWorkItem(org.fireflow.engine.IWorkItem)
*/
public IWorkItem withdrawWorkItem(IWorkItem workItem)
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);
}
}