Version 16

    Often times there is a need that just isn't covered by jBPM out of the box.  Recently I received some business requirements that required me to either fix our current WFMS or look into a new solution.  We decided to go with jBPM, but like most third party solutions, it doesn't fit all your needs - so we had to customize.

     

    In this case, there was a need to be able to plan users' time according to how many tasks are scheduled at any given time.  So, basically, this information would be used to help in deciding which user to assign a particular task to within a particular swimlane (workload balancing).  In essence, it required us to add a field in the  for .

     

    Of course, other fields are often required, but I want to keep this example as simple as possible, so here are the steps involved in making the customization:

     

    1. First, do the obvious.  Open up  and add in the field and the getter/setter pair:

     

    private double estimatedManHours;
    
    ...
    
    public double getEstimatedManHours() {
       return estimatedManHours;
    }
    
    public void setEstimatedManHours(double estimatedManHours){
       this.estimatedManHours = estimatedManHours;
    }
    
    

     

    2. Next, you have to update the  so that hibernate can map the new property to the database and back.

     

    <property name="estimatedManHours" column="ESTIMATEDMANHOURS_" ></property>
    

     

    3. Then, we'll want to modify the  to be able to read in our new property from a  (here, I place the new code just after where date/priorty are handled):

     

          // duedate and priority
          String duedateText = taskElement.attributeValue("duedate");
          if (duedateText==null) {
             duedateText = taskElement.attributeValue("dueDate");
          }
          task.setDueDate(duedateText);
          String priorityText = taskElement.attributeValue("priority");
          if (priorityText!=null) {
             task.setPriority(Task.parsePriority(priorityText));
          }
    
          /*
           * custom attributes here
           *
           */
          String estimatedManHoursText = taskElement.attributeValue("estimatedmanhours");
          if (estimatedManHoursText==null) {
             estimatedManHoursText = taskElement.attributeValue("estimatedManHours");
          }
        
          if(estimatedManHoursText != null){
              task.setEstimatedManHours(Double.parseDouble(estimatedManHoursText));
          }
        
          // if this task is in the context of a taskNode, associate them
          if (taskNode!=null) {
             taskNode.addTask(task);
          }
    
    

     

     

    4.  After doing all that, you should be able to produce new  documents where tasks have an  attribute, like so:

     

    <process-definition name="sequential">
    
      <start-state name="start">
        <transition to="firstStep" ></transition>
      </start-state>
    
      <task-node name="firstStep">
        <task name="firstStep" description="this is the very first step" estimatedManHours="7.5">
          <assignment pooled-actors="user"></assignment>
        </task>
        <transition to="secondStep" ></transition>
      </task-node>
    
      <task-node name="secondStep">
        <task name="secondStep" description="this is the second step" estimatedmanhours="15.0">
          <assignment pooled-actors="admin" ></assignment>
        </task>
        <transition to="thirdStep" ></transition>
      </task-node>
         
      <task-node name="thirdStep">
        <task name="thirdStep" description="third step" estimatedManHours="1.0">
          <assignment pooled-actors="user" ></assignment>
        </task>
        <transition to="done" ></transition>
      </task-node>     
    
      <end-state name="done" ></end-state>
    
    </process-definition>
    

     

    5.  Finally, just rebuild the source and drop in your new  into your project!