jBPM4.4: 动态创建执行路径 -- 类似与会签等

工作场景: 有一项任务需要完成,不同的部门领导根据实际情况,有的交给一个人完成,有的会交给2、3甚至更多的人完成,这个时候,流程就是由程序进行设置了,而无法在画流程图的时候写死了。

 

找到了一些资料:

如:

http://yy629.iteye.com/blog/660701 --- 比较全面

http://phoenix-clt.iteye.com/blog/428242

 

做了一下,可以通过设置subtask来创建会签流程,有问题正在解决:

1. 如果会签中的一员已经signal了,而其他人还没有完成,怎么把这个subtask complete掉,否则只要其他人没有结束,这个人就是signal了,还是看到这个任务;

   在signal中,把ActivityExecution转成ExecutionImpl,调用其getExecution().end即可,这样这个人的会签就结束了;

2. 在例子中,加入的subtask,都需要在HistoryTaskImpl中进行addsubtask,现在一到这里就会发生Exception;

3. 还没有做回退的功能

4.

 

 

 

http://yy629.iteye.com/blog/660701 --- 比较全面

 

一些说明:

 

创建流程

 

在execute方法中,创建subTask

1. 首先创建一个task,将这个task存盘(通过DbSession)

//创建会签任务  

// DBSession: DbSession dbsession = EnvironmentImpl.getFromCurrent(DbSession.class);  
// execution: execute方法的参数

private TaskImpl createCounterSignTask(DbSession dbsession,  ExecutionImpl execution) {  
   // 创建一个新Task
  TaskImpl task = dbsession.createTask();  
  task.setName(execution.getActivityName() + "_会签");  

  // 设置了type, 便于以后做流程展示时区别   -- 暂时没有清楚作用
  execution.getActivity().setType(COUNTER_SIGN_TASK_TYPE);   

  task.setExecution(execution);  
  task.setProcessInstance(execution.getProcessInstance());  

  task.setSignalling(false); //  false, 自己手工处理execution的跳转  
  task.setFormResourceName(form);  
  task.setDescription(description);  

  // 存盘,非常重要,获取到task的id
  dbsession.save(task);  

  // 这个应该和历史事件等相关,目前还不清楚
  HistoryEvent.fire(new TaskActivityStart(task), execution);  
  return task;  
}  
 

2. 创建这个task的subTask,根据人数,每个人一个subtask

 

// 创建会签子任务 这里才是真正的会签任务..  

// 函数参数中的execution:是execute方法中的execution

private void newCounterSignSubTask(DbSession dbsession, ExecutionImpl execution,   
       TaskImpl task, String user, HistoryTaskImpl ht) {  
  // 开始创建sub task
  TaskImpl subtask = task.createSubTask();  
   // 设置一些属性
  subtask.setName(execution.getActivityName() + "$" + user);  
  subtask.setAssignee(user);  
  subtask.setSignalling(false); //  false, 自己手工处理execution的跳转  

  // 这里用的都是父execution,自己写的时候曾经搞错过,错误查都查不出来
  ExecutionImpl exec = execution.createExecution(); // 创建子Execution  
  ActivityImpl activity = execution.getActivity();  
  activity.setType(COUNTER_SIGN_SUB_TASK_TYPE); // 设置类型, 便于区别  
  exec.setActivity(activity);  
  exec.setState(Execution.STATE_ACTIVE_CONCURRENT); // 再设置原来的type  
  exec.setHistoryActivityStart(Clock.getCurrentTime());  

  // sub task对应的是 子execution
  subtask.setExecution(exec);  
  
  subtask.setFormResourceName(form);  
  subtask.setDescription(description);  
  
  // 也是需要持久化的,存盘
  dbsession.save(subtask);  
  
  // 下面的这些暂未看,以后再研究
  // 修改了jbpm4中的源码, 主要是用来计算任务的url的, 把其中的占位符替:{TASK_ID}换为该task的task id  
  TaskActivity.replaceTaskResourceFormTaskIdMarco(subtask);  
  
  HistoryEvent.fire(new TaskActivityStart(subtask), exec);  
  ht.addSubTask(dbsession.get(HistoryTaskImpl.class, subtask.getDbid()));  
}  
 

Signal的实现

1. signalName,作为了审核答复

2. 把task作为map中的一个参数,传给了Signal方法(在signal方法中,通过execution.getTask获取的task,是个null

3.

4. 将所有的会签结果,放在ProcessInstance的variable中,这样在整个流程中可见

 

通过传给signal方法的subtask,获取到父Task,通过这个父task,可以获取到其他所有的subtask,把这些task、execution停止;

List<Task> subTaskList = taskService.getSubTasks(task.getId());   // 这个task是父task
if (subTaskList != null && subTaskList.size() > 1) {   
 // 处理未完成的会签子任务  
  String assignee = theSubTask.getAssignee();  
  for (Task subTask : subTaskList) {  
    if (!assignee.equals(subTask.getAssignee())) {  
      TaskImpl subTaskImpl = (TaskImpl) subTask;  
      subTaskImpl.setSuperTask(null);  
      taskService.completeTask(subTaskImpl.getId(), COUNTER_SIGN_SUB_TASK_CANEL_STATE);  
      subTaskImpl.getExecution().end(COUNTER_SIGN_SUB_EXECUTION_END_STATE); // 结束execution  
    }  
  }  
}  
 

下面是处理转向的流程

// 定义一个转向
Transition transition = null;  
// 获得当前的activity
Activity activity = executionImpl.getActivity();  

// 找到这个转向
if ((outcome == null)  
    || outcome.length() == 0  
    || ((Task.STATE_COMPLETED.equals(outcome) || TaskConstants.NO_TASK_OUTCOME_SPECIFIED.equals(outcome))  
        && (activity.getOutgoingTransitions() != null) && (activity.getOutgoingTransitions().size() == 1))) {  
  transition = activity.getOutgoingTransitions().get(0);  
} else {  
  transition = activity.findOutgoingTransition(outcome);  
}  

String transitionName = transition == null ? null : transition.getName();  
variables.put(transtionName, transitionName);

// 完成父任务,进行转向 
taskService.completeTask(task.getId(), transitionName, variables);  
if (transition != null) {  
  executionImpl.take(transition);  
}  
 

 

 

 

 

 

你可能感兴趣的:(Blog)