* @see org.fireflow.engine.taskinstance.ITaskInstanceManager#rejectWorkItem(org.fireflow.engine.IWorkItem, java.lang.String)
*/
public void rejectWorkItem(IWorkItem workItem, String comments)
throws EngineException, KernelException {
Activity thisActivity = workItem.getTaskInstance().getActivity();
TaskInstance thisTaskInstance = (TaskInstance) workItem
.getTaskInstance();
if (workItem.getState() > 5 || workItem.getTaskInstance().isSuspended()) {// 处于非活动状态,或者被挂起,则不允许reject
throw new EngineException(
thisTaskInstance.getProcessInstanceId(),
thisTaskInstance.getWorkflowProcess(),
thisTaskInstance.getTaskId(),
"Reject operation refused!Current work item is completed or the correspond task instance is suspended!!");
}
// 当前Activity只允许一个Form类型的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'");
}
//----added by wmj2003 20090915 ---start---
//处理拒收的边界问题
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 );
}
//----added by wmj2003 20090915 ---end---
IPersistenceService persistenceService = this.rtCtx
.getPersistenceService();
List<ITaskInstance> siblingTaskInstancesList = null;
siblingTaskInstancesList = persistenceService
.findTaskInstancesForProcessInstanceByStepNumber(workItem
.getTaskInstance().getProcessInstanceId(),
thisTaskInstance.getStepNumber());
// 如果执行了split操作,则不允许reject
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
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);
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");
}
}
}
// 恢复所有的FromTaskInstance
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操作。
IWorkflowSession session = ((IWorkflowSessionAware) workItem)
.getCurrentWorkflowSession();
session.setWithdrawOrRejectOperationFlag(true);
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 newToken = new Token();
((Token) newToken).setAlive(true);
((Token) newToken).setNodeId(fromActivityId);
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);
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);
}
}
ITransitionInstance theLeavingTransitionInstance = (ITransitionInstance) fromActivityInstance
.getLeavingTransitionInstances().get(0);
ISynchronizerInstance synchronizerInstance = (ISynchronizerInstance) theLeavingTransitionInstance
.getLeavingNodeInstance();
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);
}