JBPM中的任务分配 - Candidate-groups(候选组)

一、 jbpm 任务分配

  JBPM实现两种任务分派机制:

  1. Client based assignment
      基本思想就是用户自己很清楚整个流程由哪些人来执行。流程定义文件中只指定流程执行的节点步骤。而在用户接口的每一步执行前,让用户手工输入下一步节点的执行人。这个有点类似通达OA的自由流程。
  2. Process based assignment
      在流程定义中规定好某个节点由谁来执行。有很多不同的asignHandler,例如直接给出用户名,或者指定为上一个流程执行的用户名,或者使用某种表达式来给出用户。常见的有以下几种方式:
      (1) Swimlanes:详见链接: JBPM中的任务分配 - Swimlanes(泳道).
      (2) Candidate-groups
      (3) assignmentHandler:详见链接: JBPM中的任务分配 - assignmentHandler.
    今天我们介绍的是第二种分配方式中的Candidate-groups - 候选组。

二、Candidate-groups - 候选组

2.1 介绍

  当几个任务受理人有相同的任务节点时,可以划分为一个候选组(Candidate-groups)。该任务节点为多个人员,当其中之一完成后,流程就进入下一个节点。

注:
1、分配任务之前,可以通过findGroupTasks方式获取用户的组任务,findPersonalTasks用户的个人任务中没有该任务。
2、使用assign或take方式分配任务后,用户通过findPersonalTasks可以获取到个人任务,此时组任务中已经没有该任务。
3、 assign和take方式分配任务的区别:
taskService.assignTask(taskId,userId):直接把ID为taskId的任务分配给userId对应的用户处理,该任务处理结束后,接下来的任务流程回归到组任务,等待分配用户;
taskService.takeTask(taskId,userId):直接把ID为taskId的任务分配给userId对应的用户处理,拾取之后,该任务及接下来流程的所有任务都变成userId用户的个人任务了,只能由该用户处理,其他人就看不到了 。

2.2 示例

2.2.1 jdpl配置文件示例

jpdl文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<process name="testProcess" xmlns="http://jbpm.org/4.4/jpdl">
   <start g="-6,173,72,48" name="start1">
      <transition g="-22,-25" name="to task1" to="task1"/>
   </start>
   <task g="91,166,102,56" name="task1" candidate-groups="testCandicateGroup">
      <transition g="-22,-18" name="to task2" to="task2"/>
   </task>
   <task g="257,168,109,52" name="task2" candidate-groups="testCandicateGroup">
      <transition g="-18,-27" name="to task3" to="task3"/>
   </task>
   <end g="593,173,48,48" name="end1"/>
   <task g="440,168,92,52" name="task3" candidate-groups="testCandicateGroup">
      <transition g="-25,-20" name="to end1" to="end1"/>
   </task>
</process>

2.2.2 java实现

用户组的名称为“testCandicateGroup”,在java代码中,我们需要给这个组分配用户:

2.2.2.1 调用类
import java.util.List;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.task.Task;
import com.math.jbpm.util.JbpmUtil;
public class TestCandicate {
	public static void main(String[] args) {
		//清除上一次的流程
		JbpmUtil.clearProcessDeployments();
		//创建用户
		JbpmUtil.identityService.createUser("u1", "tom1", "uu1");
		JbpmUtil.identityService.createUser("u2", "tom2", "uu2");
		//创建group用户组
		String group= JbpmUtil.identityService.createGroup("testCandicateGroup");
		//为用户组添加永固
		JbpmUtil.identityService.createMembership("u1",group);
		JbpmUtil.identityService.createMembership("u2",group);
		//发布任务
		JbpmUtil.createDeployment("candidate/testProcess.jpdl.xml");
		ProcessInstance processInstance = JbpmUtil.startProcessInstanceByKey("testProcess", null, "");
		Task task = JbpmUtil.findActiveTask(processInstance.getId());
		System.out.println("当前的任务:"+task.getName());//task1
		//通过findGroupTasks可以拿到组任务。可以显示在每个收到此任务的人的代办任务列表中。
		List<Task> tsU1 = JbpmUtil.taskService.findGroupTasks("u1");
		System.out.print("用户u1的组任务: ");
		for(Task t:tsU1){
			System.out.print(t.getName());// task1
		}
		System.out.println();
		List<Task> tsU2 = JbpmUtil.taskService.findGroupTasks("u2");
		System.out.print("用户u2的组任务: ");//task1
		for(Task t:tsU2){
			System.out.print(t.getName());
		}
		System.out.println();
		//查看每个用户的个人任务 -   
		List<Task> tsU11 = JbpmUtil.taskService.findPersonalTasks("u1");
		System.out.print("用户u1的个人任务: ");
		for(Task t:tsU11){
			System.out.print(t.getName());//空
		}
		System.out.println();
		List<Task> tsU22 = JbpmUtil.taskService.findPersonalTasks("u2");
		System.out.print("用户u2的个人任务: ");
		for(Task t:tsU22){
			System.out.print(t.getName());//空
		}
		System.out.println();
		//分配任务给u1
		JbpmUtil.taskService.assignTask(task.getId(), "u1");
		//通过findGroupTasks可以拿到组任务。可以显示在每个收到此任务的人的代办任务列表中。
		tsU1 = JbpmUtil.taskService.findGroupTasks("u1");
		System.out.print("用户u1的组任务: ");
		for(Task t:tsU1){
			System.out.print(t.getName());//空
		}
		System.out.println();
		tsU2 = JbpmUtil.taskService.findGroupTasks("u2");
		System.out.print("用户u2的组任务: ");
		for(Task t:tsU2){
			System.out.print(t.getName());//空
		}
		System.out.println();
		//查看每个用户的个人任务 -   
		tsU11 = JbpmUtil.taskService.findPersonalTasks("u1");
		System.out.print("用户u1的个人任务: ");
		for(Task t:tsU11){
			System.out.print(t.getName());//task1
		}
		System.out.println();
		tsU22 = JbpmUtil.taskService.findPersonalTasks("u2");
		System.out.print("用户u2的个人任务: ");
		for(Task t:tsU22){
			System.out.print(t.getName());//空
		}
		System.out.println();
		
		//用户u1完成任务
		try {
			JbpmUtil.completeTask(task.getId(), null);
		} catch (Exception e) {
			e.printStackTrace();
		}
		//查看当前任务
		task = JbpmUtil.findActiveTask(processInstance.getId());
		System.out.println("当前的任务:"+task.getName());//task2
		
		//通过findGroupTasks可以拿到组任务。可以显示在每个收到此任务的人的代办任务列表中。
		tsU1 = JbpmUtil.taskService.findGroupTasks("u1");
		System.out.print("用户u1的组任务: ");
		for(Task t:tsU1){
			System.out.print(t.getName());//task2
		}
		System.out.println();
		tsU2 = JbpmUtil.taskService.findGroupTasks("u2");
		System.out.print("用户u2的组任务: ");
		for(Task t:tsU2){
			System.out.print(t.getName());//task2
		}
		System.out.println();
		//查看每个用户的个人任务 -   
		tsU11 = JbpmUtil.taskService.findPersonalTasks("u1");
		System.out.print("用户u1的个人任务: ");
		for(Task t:tsU11){
			System.out.print(t.getName());//空
		}
		System.out.println();
		tsU22 = JbpmUtil.taskService.findPersonalTasks("u2");
		System.out.print("用户u2的个人任务: ");
		for(Task t:tsU22){
			System.out.print(t.getName());//空
		}
		System.out.println();
	}
}

u1和u2都是testCandicateGroup组中的用户,当一个用户完成任务之后,流程就进入下一个节点。

2.2.2.2 工具类 - JbpmUtil
package com.math.jbpm.util;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.log4j.Logger;
import org.jbpm.api.Configuration;
import org.jbpm.api.Deployment;
import org.jbpm.api.ExecutionService;
import org.jbpm.api.HistoryService;
import org.jbpm.api.IdentityService;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.RepositoryService;
import org.jbpm.api.TaskService;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.model.ExecutionImpl;
import com.math.jbpm.model.ProcessInstanceInfo;
/**
 * 工作流工具类
 * 
 * @author mling
 */
public class JbpmUtil {
	public static Logger logger = Logger.getLogger(JbpmUtil.class);
	/** processid的连接符号: - */
	public static String connSymbol = ".";
	/** 流程引擎 */
	public static ProcessEngine processEngine;
	/** 流程管理:流程模板的部署、查询、删除 */
	public static RepositoryService repositoryService;
	/** 流程执行:设置流程实例的发起、执行 */
	public static ExecutionService executionService;
	/** 任务服务 */
	public static TaskService taskService;
	/** 历史服务 */
	public static HistoryService historyService;
	/** (可配置的)身份组件的接口。 */
	public static IdentityService identityService;

	static {
		// 流程定义引擎的初始化:new Configuration().setResource("jbpm.cfg.xml").buildProcessEngine();
		processEngine = Configuration.getProcessEngine();
		try {createSchema();} catch (Exception e) {}
		identityService = processEngine.getIdentityService();
		// 管理流程定义
		repositoryService = processEngine.getRepositoryService();
		// executionService 用于执行流程定义实例
		executionService = processEngine.getExecutionService();
		// 任务服务
		taskService = processEngine.getTaskService();
		// 历史服务
		historyService = processEngine.getHistoryService();
	}
	/**
	 * jbpm启动 自动建表 :如果表不存在就创建; 表存在就不创建 hbm2ddl.auto=update
	 * 
	 * @throws Exception
	 */
	public static void createSchema() throws Exception {
		new org.hibernate.cfg.Configuration()
				.configure("jbpm.hibernate.cfg3.xml").buildSessionFactory();
	}
	/**
	 * 获取工作流任务进程链表
	 * @return
	 * @throws Exception
	 */
	public static List<ProcessInstance> getProcessInstanceList(){
		try {
			return executionService.createProcessInstanceQuery().list();
		} catch (Exception e) {
			logger.warn("getProcessInstanceList - 获取工作流任务信息异常:",e);
		}
		return null;
	}
	/**
	 * 发布一个流程,返回流程deploymentId
	 * 
	 * @param url
	 * @return
	 * @throws Exception
	 */
	public static String createDeployment(String url) {
		try {
			return repositoryService.createDeployment().addResourceFromClasspath(url).deploy();
		} catch (Exception e) {
			logger.warn("createDeployment - 发布工作流 "+url+" 流程异常:",e);
		}
		return null;
	}

	/**
	 * 使用指定key的最新版本的流程定义启动流程实例,并设置流程变量
	 * 
	 * @return
	 * @throws Exception
	 */
	public static ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables,
			String processInstanceKey){
		try {
			if (variables != null && variables.size() > 0) {
				return executionService.startProcessInstanceByKey(processDefinitionKey, variables, processInstanceKey);
			} else {
				return executionService.startProcessInstanceByKey(processDefinitionKey, processInstanceKey);
			}
		} catch (Exception e) {
			logger.warn("startProcessInstanceByKey - 启动流程实例异常:",e);
		}
		return null;
	}
	/**
	 * 指定任务执行用户对象:
	 * 	 张三拾取组任务,拾取之后就变成张三的个人任务了,只能由张三处理,其他人就看不到了 
	 * @param taskId
	 * @param userId
	 * @throws Exception
	 */
	public static void takeTask(String taskId, String userId) throws Exception{
		try {
			JbpmUtil.taskService.takeTask(taskId,userId);
		} catch (Exception e) {
			throw new Exception(e);
		}
	}
	/**
	 * 分配任务执行用户对象
	 *  直接把ID为taskId的任务分配给张三处理
	 * @param taskId
	 * @param userId
	 * @throws Exception
	 */
	public static void assignTask(String taskId, String userId) throws Exception {
		try {
			JbpmUtil.taskService.assignTask(taskId,userId);
		} catch (Exception e) {
			throw new Exception(e);
		}
	}
	/**
	 * 任务完成
	 * 
	 * @param taskId
	 * @param outboundTransName
	 * @throws Exception
	 */
	public static void completeTask(String taskId, String outboundTransName) throws Exception{
		try {
			if (outboundTransName != null) {
				taskService.completeTask(taskId, outboundTransName);
			} else {
				taskService.completeTask(taskId);
			}
		} catch (Exception e) {
			throw new Exception(e);
		}
	}
	/**
	 * 创建用户
	 */
	public static void createIdentities(String groupName) {
		 String groupId = identityService.createGroup(groupName);
		//
		// identityService.createUser("1111", "飞","路");
		// identityService.createMembership("1111", groupId, "developer");
		//
		// identityService.createUser("2222", "一","王");
		// identityService.createMembership("2222", groupId, "developer");
	}
	/**
	 * 获取指定用户流程的当前待处理任务
	 * 
	 * @param user 用户
	 * @param isGroupOrPerson true:group任务 false :个人personal任务
	 * @throws Exception
	 */
	public static Task findActiveTask(String processID, String userId, boolean isGroupOrPerson){
		try {
			if(userId != null && !"".equals(userId)){
				List<Task> taskList = findActiveTask(userId,isGroupOrPerson);
				if(taskList != null && taskList.size() > 0) {
					for (Task task : taskList) {
						if (processID.equals(task.getExecutionId())) {
							return task;
						}
					}
				}
			}else{
				return findActiveTask(processID);
			}
		} catch (Exception e) {
			logger.warn("findActiveTask - 获取流程"+processID+"的当前待处理任务异常:",e);
		}
		return null;
	}
	/**
	 * 获取指定用户的当前待处理任务
	 * 
	 * @param user 用户
	 * @param isGroupOrPerson true:group任务 false :个人personal任务
	 * @throws Exception
	 */
	public static List<Task> findActiveTask(String userId, boolean isGroupOrPerson){
		List<Task> taskList = null;
		try {
			if (isGroupOrPerson) {
				taskList = taskService.findGroupTasks(userId);
			} else {
				taskList = taskService.findPersonalTasks(userId);
			}
			
		} catch (Exception e) {
			logger.warn("findActiveTask - 获取指定用户"+userId+"的当前待处理任务异常:",e);
		}
		return taskList;
	}
	/**
	 * 获取工作流中当前正在进行的任务
	 * 
	 * @return
	 * @throws Exception
	 */
	public static Task findActiveTask(String processID){
		try {
			return taskService.createTaskQuery().processInstanceId(processID).uniqueResult();
		} catch (Exception e) {
			logger.warn("findActiveTask - 获取当前流程 "+processID+" 当前正在进行的任务异常:",e);
		}
		return null;
	}
	/**
	 * 获取一个任务的所有外向转移名称
	 * 
	 * @param taskId
	 */
	public static Set<String> getTaskOutcomes(String taskId){
		try {
			return taskService.getOutcomes(taskId);
		} catch (Exception e) {
			logger.warn("getTaskOutcomes - 获取指定任务 "+taskId+" 的所有外向转移名称异常:",e);
		}
		return null;
	}

	/**
	 * 获取当前流程的所有外向转移名称
	 * 
	 * @param processID
	 * @return
	 */
	public static Set<String> findActiveActivityNames(String processID){
		try {
			return executionService.createProcessInstanceQuery().processInstanceId(processID).uniqueResult()
					.findActiveActivityNames();
		} catch (Exception e) {
			logger.warn("findActiveActivityNames - 获取当前流程 "+processID+" 的所有外向转移名称异常:",e);
		}
		return null;
	}

	/**
	 * 根据Execution设置多个流程变量(需要先把流程变量放到一个Map中)
	 * 
	 * @throws Exception
	 */
	public static void setExecutionParams(String processID, Map<String, Object> varis){
		try {
			executionService.setVariables(processID, varis);
		} catch (Exception e) {
			logger.warn("setExecutionParams - 设置流程 "+processID+" 变量异常:",e);
		}
	}

	/**
	 * 根据Execution设置一个流程变量: 如果key已存在,则value覆盖原始值
	 * 
	 * @throws Exception
	 */
	public static void setExecutionParam(String processID, String key, Object value){
		try {
			executionService.setVariable(processID, key, value);
		} catch (Exception e) {
			logger.warn("setExecutionParam - 设置流程 "+processID+" 变量异常:",e);
		}
	}

	/**
	 * 根据Task设置多个任务变量(需要先把任务变量放到一个Map中):
	 * 设置的变量与当前任务绑定,只有使用当前任务的id才能查询,当这个任务完成时下一个任务不能获取到当前任务设置的变量。
	 * 
	 * @throws Exception
	 */
	public static void setTaskParams(String taskId, Map<String, Object> varis){
		try {
			taskService.setVariables(taskId, varis);
		} catch (Exception e) {
			logger.warn("setTaskParams - 设置任务 "+taskId+" 变量异常:",e);
		}
	}
	/**
	 * 根据Task设置一个任务变量:
	 * 设置的变量与当前任务绑定,只有使用当前任务的id才能查询,当这个任务完成时下一个任务不能获取到当前任务设置的变量。
	 * 
	 * @throws Exception
	 */
	public static void setTaskParams(String taskId, String key, Object value){
		try {
			Map<String, Object> map = getTaskVariables(taskId);
			if(map == null){
				map = new HashMap<String, Object>();
			}
			map.put(key, value);
			setTaskParams(taskId,map);
		} catch (Exception e) {
			logger.warn("setTaskParams - 设置任务 "+taskId+" 变量异常:",e);
		}
	}
	/**
	 * 获取流程实例所有变量变量
	 * @throws Exception
	 */
	public static Map<String, Object> getExecutionVariables(String processID){
		try {
			// 根据实例ID,查询所有实例变量的名字
			Set<String> variableSet = executionService.getVariableNames(processID);
			if (variableSet != null && variableSet.size() > 0) {
				// 根据实例ID和实例变量名字,查询所属实例变量的值
				return executionService.getVariables(processID, variableSet);
			}
		} catch (Exception e) {
			logger.warn("getExecutionVariables - 获取流程实例 "+processID+" 变量异常:",e);
		}
		return null;
	}

	/**
	 * 获取流程实例指定变量key的值
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static Object getExecutionVariableByKey(String processID, String key){
		try {
			return executionService.getVariable(processID, key);
		} catch (Exception e) {
			logger.warn("getExecutionVariableByKey - 获取流程实例 "+processID+" 变量异常:",e);
		}
		return null;
	}

	/**
	 * 获取任务指定变量key的值
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static Object getTaskVariableByKey(String taskID, String key){
		try {
			return taskService.getVariable(taskID, key);
		} catch (Exception e) {
			logger.warn("getTaskVariableByKey - 获取任务 "+taskID+" 变量异常:",e);
		}
		return null;
	}

	/**
	 * 获取任务所有变量
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static Map<String, Object> getTaskVariables(String taskID){
		try {
			Set<String> variableSet = taskService.getVariableNames(taskID);
			if (variableSet != null && variableSet.size() > 0) {
				// 根据实例ID和实例变量名字,查询所属实例变量的值
				return taskService.getVariables(taskID, variableSet);
			}
		} catch (Exception e) {
			logger.warn("getTaskVariables - 获取任务 "+taskID+" 变量异常:",e);
		}
		return null;
	}

	/**
	 * 状态结束
	 * 
	 * @param activityName
	 * @return
	 * @throws Exception
	 */
	public static void executeActiveActivityByName(String processID, String activityName){
		try {
			executionService.signalExecutionById(executionService.createProcessInstanceQuery()
					.processInstanceId(processID).uniqueResult().findActiveExecutionIn(activityName).getId());
			logger.info(" -- 流程 "+processID+" 的状态-"+activityName+"结束");
		} catch (Exception e) {
			logger.warn("executeActiveActivityByName - 结束流程 "+processID+" 的状态-"+activityName+"异常:",e);
		}
	}

	/**
	 * 关闭并清除一条工作流
	 * 
	 * @throws Exception
	 */
	public static void closedOneProcessDeployment(String deploymentId) throws Exception{
		try {
			repositoryService.deleteDeploymentCascade(deploymentId);
		} catch (Exception e) {
			throw new Exception(e);
		}
	}

	/**
	 * 清除所有工作流
	 * @param db_id_list
	 * @return
	 */
	public static void clearProcessDeployments() {
		List<Deployment> deployments = repositoryService.createDeploymentQuery().list();
		if (deployments != null && deployments.size() > 0) {
			for (Deployment del : deployments) {
				try {
					closedOneProcessDeployment(del.getId());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	public static List<ProcessInstanceInfo> getProcessInsanceInfoList(){
		try {
			List<ProcessInstanceInfo> processInfoList = new ArrayList<ProcessInstanceInfo>();
			List<ProcessInstance> processInstances = getProcessInstanceList();
			if(processInstances != null && processInstances.size() > 0){
				for(ProcessInstance process:processInstances){
					ExecutionImpl execution = (ExecutionImpl) process;
					Map<String,Object> variables = null;
					//1.判断是否有参数
					if(execution.hasVariables()){
						variables = JbpmUtil.getExecutionVariables(execution.getId());
					}
					processInfoList.add(new ProcessInstanceInfo(execution.getId(),
							Long.parseLong(execution.getKey()),
							execution.getActivityName(), 
							variables));
				}
			}
			return processInfoList;
		} catch (Exception e) {
			logger.warn("JbpmResume-获取数据库中待处理工作流信息异常:",e);
		}
		return null;
	}
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值