package org.jboss.seam.bpm;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.contexts.Lifecycle;
import org.jbpm.context.exe.ContextInstance;
import org.jbpm.graph.def.Action;
import org.jbpm.graph.exe.ExecutionContext;
import org.jbpm.graph.exe.Token;
import org.jbpm.instantiation.UserCodeInterceptor;
import org.jbpm.taskmgmt.def.AssignmentHandler;
import org.jbpm.taskmgmt.def.TaskControllerHandler;
import org.jbpm.taskmgmt.exe.Assignable;
import org.jbpm.taskmgmt.exe.TaskInstance;
/**
* Intercepts calls to user code coming from jBPM, sets up
* Seam contexts and associates the process and task instances
* with the contexts.
*
* @author Gavin King
*
*/
class SeamUserCodeInterceptor implements UserCodeInterceptor
{
abstract static class ContextualCall
{
abstract void process() throws Exception;
void run() throws Exception
{
if ( Contexts.isEventContextActive() || Contexts.isApplicationContextActive() ) //not sure about the second bit (only needed at init time!)
{
process();
}
else
{
Lifecycle.beginCall();
try
{
process();
}
finally
{
Lifecycle.endCall();
}
}
}
void runAndWrap()
{
try
{
run();
}
catch (RuntimeException re)
{
throw re;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
public void executeAction(final Action action, final ExecutionContext context) throws Exception
{
if ( isPageflow(context) )
{
action.execute(context);
}
else
{
new ContextualCall()
{
@Override
void process() throws Exception
{
initProcessAndTask(context);
action.execute(context);
}
}.run();
}
}
private boolean isPageflow(final ExecutionContext context)
{
return Contexts.isConversationContextActive() &&
Jbpm.instance().isPageflowProcessDefinition( context.getProcessDefinition().getName() );
}
public void executeAssignment(final AssignmentHandler handler, final Assignable assignable,
final ExecutionContext context)
throws Exception
{
new ContextualCall()
{
@Override
void process() throws Exception
{
initProcessAndTask(context);
handler.assign(assignable, context);
}
}.run();
}
public void executeTaskControllerInitialization(final TaskControllerHandler handler, final TaskInstance task,
final ContextInstance context, final Token token)
{
new ContextualCall()
{
@Override
void process() throws Exception
{
initProcessAndTask(task);
handler.initializeTaskVariables(task, context, token);
}
}.runAndWrap();
}
public void executeTaskControllerSubmission(final TaskControllerHandler handler, final TaskInstance task,
final ContextInstance context, final Token token)
{
new ContextualCall()
{
@Override
void process() throws Exception
{
initProcessAndTask(task);
handler.submitTaskVariables(task, context, token);
}
}.runAndWrap();
}
private static void initProcessAndTask(ExecutionContext context)
{
BusinessProcess businessProcess = BusinessProcess.instance();
businessProcess.setProcessId( context.getProcessInstance().getId() );
TaskInstance taskInstance = context.getTaskInstance();
if (taskInstance!=null)
{
businessProcess.setTaskId( taskInstance.getId() );
}
}
private static void initProcessAndTask(TaskInstance task)
{
BusinessProcess businessProcess = BusinessProcess.instance();
businessProcess.setProcessId( task.getProcessInstance().getId() );
businessProcess.setTaskId( task.getId() );
}
}