@Override
public BpmTask performAction(ProcessStateAction action, BpmTask task, ProcessToolContext ctx)
{
BpmTask bpmTask = getTaskData(task.getInternalTaskId(), ctx);
if (bpmTask == null || bpmTask.isFinished())
return bpmTask;
ProcessInstance processInstance = bpmTask.getProcessInstance();
ProcessInstanceLog log = addActionLogEntry(action, task, ctx);
Map<String, Object> vars = new HashMap<String, Object>();
vars.put("ACTION", action.getBpmName());
processInstance.setSimpleAttribute("ACTION", action.getBpmName());
List<String> outgoingTransitionNames = getOutgoingTransitionNames(task.getInternalTaskId(), ctx);
ProcessEngine processEngine = getProcessEngine(ctx);
Task bpmTaskInstance = processEngine.getTaskService().getTask(task.getInternalTaskId());
String executionId = bpmTaskInstance.getExecutionId();
Set<String> taskIdsBeforeCompletion = new HashSet<String>();
pl.net.bluesoft.util.lang.Collections.collect(findProcessTasksWithUser(processInstance, ctx), new Transformer<BpmTask, String>() {
@Override
public String transform(BpmTask obj) {
return obj.getInternalTaskId();
}
}, taskIdsBeforeCompletion);
if (outgoingTransitionNames.size() == 1)
processEngine.getTaskService().completeTask(task.getInternalTaskId(), outgoingTransitionNames.get(0), vars); //BPMN2.0 style, decision is taken on the XOR gateway
else
processEngine.getTaskService().completeTask(task.getInternalTaskId(), action.getBpmName(), vars);
broadcastEvent(ctx, new BpmEvent(BpmEvent.Type.TASK_FINISHED, task, user));
/* Inform queue manager about task finish and process state change */
ctx.getUserProcessQueueManager().onTaskFinished(task);
String processState = getProcessState(processInstance, ctx);
/* Check if new subProcess is created */
boolean startsSubprocess = updateSubprocess(processInstance, executionId, ctx);
fillProcessAssignmentData(processEngine, processInstance, ctx);
processInstance.setState(processState);
if (startsSubprocess == false && processState == null && processInstance.getRunning() && !isProcessRunning(processInstance.getInternalId(), ctx)) {
processInstance.setRunning(false);
}
if (log.getUserSubstitute() == null)
broadcastEvent(ctx, new BpmEvent(BpmEvent.Type.SIGNAL_PROCESS, bpmTask, user));
else
broadcastEvent(ctx, new BpmEvent(BpmEvent.Type.SIGNAL_PROCESS, bpmTask, log.getUserSubstitute()));
if (Strings.hasText(action.getAssignProcessStatus())) {
String processStatus = action.getAssignProcessStatus();
ProcessStatus ps = processStatus.length() == 1 ? ProcessStatus.fromChar(processStatus.charAt(0)) : ProcessStatus.fromString(processStatus);
processInstance.setStatus(ps);
}
else
{
boolean isProcessRunning = processInstance.isProcessRunning();
//boolean isProcessRunning = isProcessRunning(pi.getInternalId(), ctx);
/* Process is not running and no new suprocesses are created, so process should
* be finished by now
*/
if(!isProcessRunning && !startsSubprocess)
{
broadcastEvent(ctx, new BpmEvent(BpmEvent.Type.END_PROCESS, bpmTask, user));
/* Inform queue manager about process ending. Only main process is stored */
if(!processInstance.isSubprocess())
ctx.getUserProcessQueueManager().onProcessFinished(processInstance, bpmTask);
processInstance.setStatus(ProcessStatus.FINISHED);
}
/* Process is running or is halted, but new subprocess are created */
else if(!isProcessRunning && startsSubprocess)
{
broadcastEvent(ctx, new BpmEvent(BpmEvent.Type.PROCESS_HALTED, bpmTask, user));
/* Inform queue manager about process halt */
ctx.getUserProcessQueueManager().onProcessHalted(processInstance, bpmTask);
processInstance.setStatus(ProcessStatus.RUNNING);
}
else
{
processInstance.setStatus(ProcessStatus.RUNNING);
}
}
ctx.getProcessInstanceDAO().saveProcessInstance(processInstance);
BpmTask userTask = null;
BpmTask autoSkipTask = null;
/* Is process finished */
boolean isProcessFinished = processInstance.getStatus().equals(ProcessStatus.FINISHED);
boolean isSubProcess = processInstance.getParent() != null;