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!
Comments