Adding Custom Events
Goal: Provide a mechanism to suspend a task for a period of time, and automatically resume the task after the time period is up.
Solution: Add custom Events for task suspend and task resume, override the suspend and resume methods in a custom task instance to fire the suspend and resume events.
1) Optional - Add two new EVENTTYPEs for suspend and resume to the org.jbpm.graph.def.Event class. (not necessary however, just a convenience)
 public static final String EVENTTYPE_TASK_SUSPEND = "task-suspend";
  public static final String EVENTTYPE_TASK_RESUME = "task-resume";
2) Optional - Add these to the supported EventTypes in the org.jbpm.graph.def.Task class. (not necessary since jBPM determines event-types dynamically).
static final String[] supportedEventTypes = new String[]{
   Event.EVENTTYPE_TASK_CREATE,
   Event.EVENTTYPE_TASK_ASSIGN,
   Event.EVENTTYPE_TASK_START,
   Event.EVENTTYPE_TASK_END,
   Event.EVENTTYPE_TASK_SUSPEND,
   Event.EVENTTYPE_TASK_RESUME
2) Subclass .jbpm.graph.exe.TaskInstance
Override Suspend and Resume
 public void suspend(String date) {
  super.suspend();
     if ( (task!=null)
             && (token!=null)
           ) {
          ExecutionContext executionContext = new ExecutionContext(token);
           // the TASK_SUSPEND event is fired
          executionContext.setTaskInstance(this);
          executionContext.setTask(task);
          executionContext.getTaskInstance().setVariable("suspendUntilDate", date);
          task.fireEvent(Event.EVENTTYPE_TASK_SUSPEND, executionContext);
        }
 }
 
 public void resume() {
  super.resume();
     if ( (task!=null)
             && (token!=null)
           ) {
          ExecutionContext executionContext = new ExecutionContext(token);
           // the TASK_RESUME event is fired
          executionContext.setTaskInstance(this);
          executionContext.setTask(task);
          task.fireEvent(Event.EVENTTYPE_TASK_RESUME, executionContext);
        }
 } 
3) Configure the timer on the task
<process-definition
 xmlns="urn:jbpm.org:jpdl-3.1"
 name="simple">
  <action name="resume" class="com.sample.action.ResumeActionHander" />
  <start-state name="start">
     <transition name="" to="Create Order"></transition>
  </start-state>
  <end-state name="end"></end-state>
    <task-node name="Approve Order" create-tasks="true">
       <task name="approve" description="Review order">
          <assignment class="com.sample.assignment.SomeAssignmentHandler"
  </assignment>    
         <event type='task-suspend'>
   <action name="Suspend Timer" class="com.sample.action.CreateTimerActionHandler">
             <action>resume</action>
           </action>
   </event>
   <event type="task-resume">
   <action name="SendMessage" class="com.sample.action.MessageActionHandler">
   <message>resumed the task instance</message>
    </action> 
    </event>
        <controller class="com.sample.taskinstance.CustomTaskControllerHandler"></controller>
      </task>
      <transition name="" to="end"></transition>
    </task-node>
  ...
</process-definition>
4) Implement CreateTimerActionHandler
public class CreateTimerActionHandler implements ActionHandler {
 private String action;
 private static final long serialVersionUID = 1L;
 /** {@inheritDoc} */
 public void execute(ExecutionContext executionContext) throws Exception {
  Timer timer = new Timer(executionContext.getToken());
  timer.setName(executionContext.getAction().getName());
  TaskInstance taskInstance = executionContext.getTaskInstance();
  String dueDate = (String)taskInstance.getVariable("suspendUntilDate");
  // parse the due date
  DateFormat format = DateFormat.getDateTimeInstance(DateFormat.SHORT,
    DateFormat.SHORT);
  Date date = format.parse(dueDate);
  timer.setDueDate(date);
  // retrieve a named action from the process definition
  Action action = executionContext.getProcessDefinition().getAction(
    this.action);
  timer.setAction(action);
  // set the TaskInstance so the resume action knows what taskInstance to resume
  timer.setTaskInstance(taskInstance);
  SchedulerService schedulerService = (SchedulerService) Services
    .getCurrentService(Services.SERVICENAME_SCHEDULER);
  schedulerService.createTimer(timer);
 }
}
5) Implement ResumeActionHandler
public class Resume implements ActionHandler {
public class ResumeActionHandler implements ActionHandler {
 private static final long serialVersionUID = 1L;
 public void execute(ExecutionContext executionContext) throws Exception {
   System.out.println("resuming taskInstance");
   TaskInstance taskInstance = executionContext.getTaskInstance();
   System.out.println("TaskInstance is " + taskInstance);
  
   CustomTaskInstance cti = (CustomTaskInstance) executionContext.getJbpmContext().getSession().load(CustomTaskInstance.class, new Long(taskInstance.getId()));
   cti.resume();
 }
}
Wednesday, February 18, 2009
Adding Custom Events using JBoss JBPM - JPDL
Subscribe to:
Post Comments (Atom)










 
 
 digg
 digg reddit
 reddit del.icio.us
 del.icio.us 





 
0 comments:
Post a Comment