jBPM4靈活的臨時動態性需求小結

[b]靈活的臨時動態性需求,例如:任意回退、會籤(包括加、減籤,補籤)[/b]
關於名詞解釋參看這裏
[url]http://www.infoq.com/cn/articles/jbpm4-process-requirement[/url]

[b]回退:如果你有回退的路線,那麼completeTask後直接指定路線就可以。
任意回退:setActivity()[/b]

[b]會籤:這裏以單步會籤爲例[/b]
思想:活動中使用custom,調用用戶代碼,實現一個自定義的活動行爲。
使task處於等待狀態,生成幾個子任務,當所有子任務結束後查看會簽結果,最後進行走向。(不同的投票機制可以採取不同的方案,如果一票否決制,那麼就不必等所有人都審覈了再決定走向,所以具體還是要看投票的機制;投票的審覈方式可以放在signal方法裏,也可以放在signal方法外,即實際業務中,主要還是要看應用的場景)

public class CountersignCustom implements ExternalActivityBehaviour {
...
public void execute(ActivityExecution activityExecution) {
ExecutionImpl execution = (ExecutionImpl) activityExecution;

// 創建主任務
DbSession dbSession = EnvironmentImpl.getFromCurrent(DbSession.class);
TaskImpl task = (TaskImpl) dbSession.createTask();
task.setExecution(execution);
task.setProcessInstance((ExecutionImpl) execution.getProcessInstance());
task.setSignalling(true);
task.setName(taskName);
dbSession.save(task);
HistoryEvent.fire(new TaskActivityStart(task), (ExecutionImpl) execution);
//通過變量傳入會籤人員
String[] counters = (String[]) execution.getVariable(counterignVarName);
// 創建子任務
for (String countersigner : counters) {
TaskImpl subtask = (TaskImpl) dbSession.createTask();
task.addSubTask(subtask);
subtask.setAssignee(countersigner);
subtask.setName(taskName + "." + countersigner);
subtask.setProcessInstance((ExecutionImpl) execution.getProcessInstance());
subtask.setExecution(execution);
// 設置爲true時,completeTask 會觸發 signal
// 參見 TaskImpl.complete() 方法
subtask.setSignalling(false);
dbSession.save(subtask);
// 觸發事件
HistoryEvent.fire(new TaskActivityStart(subtask), (ExecutionImpl) execution);
}
execution.waitForSignal();
}
public void signal(ActivityExecution activityExecution, String signalName, Map<String, ?> parms) throws Exception {
...
if (會簽完成) {
Transition transition = null;
if(會籤不批准) {
ExecutionService executionService = processEngine.getExecutionService();
executionService.endProcessInstance(pi.getId(), Execution.STATE_ENDED);
}else {
transition = activity.findOutgoingTransition(countersignSuccess);
signalName = countersignSuccess;
executionImpl.historyActivityEnd(signalName);
executionImpl.take(transition);
}
} else {//會籤未完成繼續等待
executionImpl.waitForSignal();
}
...
}

以上怎麼來觸發呢?
// 設置爲true時,completeTask 會觸發 signal
subtask.setSignalling(false);
如果設置的是false
參考[url]http://www.family168.com/tutorial/jbpm4.0/html/services.html#singallingawaitingexecution[/url]
使用以下代碼即可
ExecutionService executionService = processEngine.getExecutionService();
executionService.signalExecutionById(id);

是不是很簡單?

[b]另外關於會籤中決策方式,比如一票否決,少數服從多數,N票認可,按比例通過等可以通過定義會簽結論接口,不同的實現來進行處理。[/b]

當我們的工作流和實際業務結合的很緊密,例如:我們必須知道一個人在一個項目中的任務,這個時候我們必須把工作流實例和項目進行綁定,這也是最簡單有效地方法。

獲取一個流程實例中的個人任務
ExecutionService executionService = processEngine.getExecutionService();  
ProcessInstance processInstance = executionService.startProcessInstanceByKey(key,variables);
TaskService taskService = processEngine.getTaskService();

//根據節點名取一流程實例下的任務
Task task1 = taskService.createTaskQuery().processInstanceId(processInstance.getId()).activityName("經理簽收").uniqueResult();

//根據任務分配者userId取一流程實例下的任務
Task task2 = taskService.createTaskQuery().processInstanceId(processInstance.getId()).assignee(userId).uniqueResult();


然後我們再回頭看下官方用戶手冊和demo中的實現方法
List<Task> taskList = taskService.findPersonalTasks("johndoe");
Task task = taskList.get(0);

這個時候,我們所取得的任務只是任務列表中的某個任務,而無法取得我們需要指定的任務,實用性顯而易見。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章