Variable missing in assignment handler
lpiccoli Jul 14, 2009 5:39 AMhi all,
my swimlane assignment handler is unable to retrieve variables that have been previous set in both root token and local token.
the test involves a forkhandler, sub process and swimlane assignment handler.
When inside the SwimlaneAssignmentHandler getVariable() returns null which is not what i was expecting
public void assign(Assignable assignable, ExecutionContext executionContext) {
assertNotNull("shouldnt be null", executionContext.getVariable(IDENTIFIER));
String expression = (String)executionContext.getVariable(EXPRESSION);
assertNotNull( "shouldnt be null", expression );
as it was set in the previous ActivityForkActionHandler.execute()
public void execute(final ExecutionContext executionContext) throws Exception {
.....stuff
Token(rootToken, "ITP" + item.getId()); //TODO -lp
newToken.setTerminationImplicit(true);
executionContext.getJbpmContext().getSession().save(newToken);
final ExecutionContext newExecutionContext = new ExecutionContext(newToken);
newExecutionContext.getContextInstance().createVariable(
EXPRESSION,
item.getResponsibleExpression(),
newToken);
I am not sure if the problem is with my process definition of the swimlan assignment
<swimlane name='responsible' > <assignment class='com.asteriski.itpflow.action.ActivityForkActionHandlerTest$SwimlaneAssignmentHandler'/> </swimlane>
or with how i am setting the local variables against token in the forkHandler above
i have a attached the entire test case below. It is a bit tedious but i needed to include all the handler code.
any help is most appreciated.
public class ActivityForkActionHandlerTest extends AbstractJbpmTestCase {
static JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance("jbpm.test.cfg.xml");
public void testForkHandlerAndSubProcess() throws Exception {
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
ProcessDefinition subProcessDefinition = ProcessDefinition.parseXmlString(
"<process-definition name='sub'>" +
" <start-state>" +
" <transition to='wait' />" +
" </start-state>" +
" <swimlane name='responsible' >" +
" <assignment class='com.asteriski.itpflow.action.ActivityForkActionHandlerTest$SwimlaneAssignmentHandler' />" +
" </swimlane>" +
" <task-node name='wait' >" +
" <description>'just waiting'</description>" +
" <task name='task-waiting' signal='block' swimlane='responsible'>"+
" </task>" +
" <transition to='end_sub'></transition>" +
" </task-node>" +
" <end-state name='end_sub' />" +
"</process-definition>"
);
jbpmContext.deployProcessDefinition(subProcessDefinition);
ProcessDefinition superProcessDefinition = ProcessDefinition.parseXmlString(
"<process-definition" +
" name='super'>" +
"<start-state name='start'> " +
"<transition name='to_state' to='forkActivities'>" +
"</transition>" +
"</start-state>" +
" <node name='forkActivities'>" +
" <action class='com.asteriski.itpflow.action.ActivityForkActionHandlerTest$ActivityForkActionHandler' config-type='bean' name='ActivityForkActionHandler'></action>" +
" <description>" +
" find all activities that have no blocking state and generate a testign request"+
" </description>" +
" <transition to='Sub Process'></transition>" +
" </node>" +
"<process-state name='Sub Process'>" +
"<sub-process name='sub'/>" +
"<transition to='task-node1'></transition>" +
"</process-state>" +
"<task-node name='task-node1'> " +
" <task name='task1'>" +
" </task>" +
" <transition to='end' name='to_end'> " +
" </transition>" +
"</task-node>" +
"<end-state name='end'></end-state> " +
"</process-definition>");
jbpmContext.deployProcessDefinition(superProcessDefinition);
ProcessInstance processInstance = jbpmContext.newProcessInstance("super");
ProcessState processState = (ProcessState) superProcessDefinition.getNode("Sub Process");
processState.setSubProcessDefinition(subProcessDefinition);
processInstance.getContextInstance().createVariable(Constant.ITP_ID_JBPM_CONTEXT_IDENTIFIER, 1);
// After construction, the process execution has one main path
// of execution (=the root token).
Token rootToken = processInstance.getRootToken();
assertEquals(
"start",
rootToken.getNode().getName());
// Move the process instance to the task
rootToken.signal();
assertEquals(
"Sub Process",
rootToken.getNode().getName());
//get the sub process
ProcessInstance subProcessInstance = rootToken.getSubProcessInstance();
assertSame(subProcessDefinition, subProcessInstance.getProcessDefinition());
Token subToken = subProcessInstance.getRootToken();
// Move the process instance to the task
subToken.signal();
assertEquals(
"end_sub",
subToken.getNode().getName());
}
public static class SwimlaneAssignmentHandler implements AssignmentHandler {
Logger log = Logger.getLogger(ResponsibleSwimlaneAssignmentHandler.class);
private static final long serialVersionUID = 1L;
public void assign(Assignable assignable, ExecutionContext executionContext) {
assertNotNull("shouldnt be null", executionContext.getVariable(Constant.ITP_ID_JBPM_CONTEXT_IDENTIFIER));
String expression = (String)executionContext.getVariable(Constant.ASSIGNMENT_RESPONSIBLE_EXPRESSION_JBPM_CONTEXT_IDENTIFIER);
assertNotNull( "shouldnt be null", expression );
assignable.setPooledActors( expression );
}
}
public static class ActivityForkActionHandler implements ActionHandler, Constant {
Logger log = Logger.getLogger( ActivityForkActionHandler.class );
/**
* Create a new child token for each item in list.
*
* @param executionContext
* @throws Exception
*/
@SuppressWarnings("unchecked")
public void execute(final ExecutionContext executionContext) throws Exception {
log.debug("execute");
long id =Long.valueOf( executionContext.getContextInstance().getVariable(ITP_ID_JBPM_CONTEXT_IDENTIFIER).toString() );
log.debug("execute itp d:" + id);
Collection<ITPItem> activities = getActivities( id );
if( activities != null ){
final Token rootToken = executionContext.getToken();
final Node node = executionContext.getNode();
log.debug( "node name:" + node.getName() );
log.debug( "node getDescription:" + node.getDescription() );
log.debug( "node getDefaultLeavingTransition:" + node.getDefaultLeavingTransition().getName() );
final Transition transition = (Transition) node.getLeavingTransitions().get(0); //TODO must work out which transition to use
log.debug( "transition name:" + transition.getName() );
Collection<ExecutionContext> newContextList = new ArrayList<ExecutionContext>();
//newExecutionContext.getContextInstance().createVariable(as, item, newToken);
//
for (Iterator iterator = activities.iterator(); iterator.hasNext();) {
ITPItem item = (ITPItem) iterator.next();
log.debug( "item id:" + item.getId() );
final Token newToken = new Token(rootToken, "ITP" + item.getId()); //TODO -lp
newToken.setTerminationImplicit(true);
executionContext.getJbpmContext().getSession().save(newToken);
final ExecutionContext newExecutionContext = new ExecutionContext(newToken);
newExecutionContext.getContextInstance().createVariable(
ASSIGNMENT_RESPONSIBLE_EXPRESSION_JBPM_CONTEXT_IDENTIFIER,
item.getResponsibleExpression(),
newToken);
log.debug("execute getVariable:" + newExecutionContext.getVariable(ASSIGNMENT_RESPONSIBLE_EXPRESSION_JBPM_CONTEXT_IDENTIFIER));
newContextList.add(newExecutionContext);
}
// Now, let each new token leave the node.
//
for (Iterator<ExecutionContext> iterator = newContextList.iterator(); iterator.hasNext();) {
ExecutionContext context = iterator.next();
//go via transition
node.leave(context, transition);
}
}
log.debug("leaving node" );
executionContext.leaveNode();
}
/**
* TODO the test version needs to be mocked somehow
* @param id
* @return
*/
public Collection<ITPItem> getActivities( long id) {
log.trace("getActivities");
Collection<ITPItem> items = new ArrayList<ITPItem>();
ITPItem itp1 = new ITPItem();
itp1.setId(1);
itp1.setResponsibleExpression("hello1");
ITPItem itp2 = new ITPItem();
itp2.setId(2);
itp2.setResponsibleExpression("hello2");
ITPItem itp3 = new ITPItem();
itp3.setId(3);
itp3.setResponsibleExpression("hello3");
items.add(itp1);
items.add(itp2);
items.add(itp3);
return items;
}
}
}
-lp