Jbpm4提供的IdentitySession接口并不是一种很好的处理方式,鉴于我们每个业务系统都有一套自己的用户及权限认证管理机制,需要与jbpm4.4集成的话,就比较周折了,我们经常需要查询的就是用户自己的任务。jbpm4的任务里有一个比较好的任务人员指派定义方式,就是使用AssignmentHandler接口,其定义如下所示:
- <?xml version="1.0" encoding="UTF-8"?>
-
- <process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">
-
- <start g="20,20,48,48">
- <transition to="review" />
- </start>
-
- <task name="review" g="96,16,127,52">
- <assignment-handler class="org.jbpm.examples.task.assignmenthandler.AssignTask">
- <field name="assignee">
- <string value="johndoe" />
- </field>
- </assignment-handler>
- <transition to="wait" />
- </task>
-
- <state name="wait" g="255,16,88,52" />
-
- </process>
<?xml version="1.0" encoding="UTF-8"?>
<process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">
<start g="20,20,48,48">
<transition to="review" />
</start>
<task name="review" g="96,16,127,52">
<assignment-handler class="org.jbpm.examples.task.assignmenthandler.AssignTask">
<field name="assignee">
<string value="johndoe" />
</field>
</assignment-handler>
<transition to="wait" />
</task>
<state name="wait" g="255,16,88,52" />
</process>
- package org.jbpm.examples.task.assignmenthandler;
-
- import org.jbpm.api.model.OpenExecution;
- import org.jbpm.api.task.Assignable;
- import org.jbpm.api.task.AssignmentHandler;
-
-
-
-
-
- public class AssignTask implements AssignmentHandler {
-
- private static final long serialVersionUID = 1L;
-
- String assignee;
-
- public void assign(Assignable assignable, OpenExecution execution) {
- assignable.setAssignee(assignee);
- }
- }
package org.jbpm.examples.task.assignmenthandler;
import org.jbpm.api.model.OpenExecution;
import org.jbpm.api.task.Assignable;
import org.jbpm.api.task.AssignmentHandler;
/**
* @author Tom Baeyens
*/
public class AssignTask implements AssignmentHandler {
private static final long serialVersionUID = 1L;
String assignee;
public void assign(Assignable assignable, OpenExecution execution) {
assignable.setAssignee(assignee);
}
}
这要求我们在设计流程定义后,任务的处理人已经必须定下来了,但若我们在流程发布后,还需要手工改这里的任务执行人员(并且人员是我们系统的用户),甚至人员可能在流程运行过程中,由用户在任务表单或计算过程中动态指定,以上的方式并不能满足我们的要求。
基于这种想法,应该设计另一种允许用户修改流程定义中的人员,并且跟我们的系统用户角色结合起来。
jbpm4之后的版本,启动流程及运行流程时,都会去读取流程定义,因此,我们可以动态修改以上配置文件,让其生成类似如下的配置格式即可以满足我们的要求:
- <?xml version="1.0" encoding="UTF-8"?>
-
- <process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">
-
- <start g="20,20,48,48">
- <transition to="review" />
- </start>
-
- <task name="review" g="96,16,127,52">
- <assignment-handler class="com.htsoft.core.jbpm.AssignmentHandler">
- <field name="userIds">
- <string value="1" />
- </field>
- <field name="roleIds">
- <string value="1,2" />
- </field>
- </assignment-handler>
- <transition to="wait" />
- </task>
-
- <state name="wait" g="255,16,88,52" />
-
- </process>
<?xml version="1.0" encoding="UTF-8"?>
<process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">
<start g="20,20,48,48">
<transition to="review" />
</start>
<task name="review" g="96,16,127,52">
<assignment-handler class="com.htsoft.core.jbpm.AssignmentHandler">
<field name="userIds">
<string value="1" />
</field>
<field name="roleIds">
<string value="1,2" />
</field>
</assignment-handler>
<transition to="wait" />
</task>
<state name="wait" g="255,16,88,52" />
</process>
以上的userIds的1,以及roleIds的1,2则代表我们系统中的用户id与角色的id,其值由后台用户在后面通过界面来设置。
其设置后,就生成以上的代码写至jbpm4_lob表中的blobvalue字段中去则可,这是持久化的处理。
也可以临时调用类似以下的代码动态实现以上效果:
-
-
-
-
- public void addAssignHandler(ProUserAssign proUserAssign){
- ProcessDefinitionImpl pd=(ProcessDefinitionImpl)repositoryService.createProcessDefinitionQuery().deploymentId(proUserAssign.getDeployId()).uniqueResult();
- EnvironmentFactory environmentFactory = (EnvironmentFactory) processEngine;
- EnvironmentImpl env=null;
- try {
- env = environmentFactory.openEnvironment();
-
- TaskDefinitionImpl taskDef=pd.getTaskDefinition(proUserAssign.getActivityName());
- UserCodeReference userCodeReference = new UserCodeReference();
- ObjectDescriptor descriptor = new ObjectDescriptor();
-
- descriptor.setClassName("com.htsoft.core.jbpm.UserAssignHandler");
-
- FieldOperation userIdsFo = new FieldOperation();
- userIdsFo.setFieldName("userIds");
- userIdsFo.setDescriptor(new StringDescriptor(proUserAssign.getUserId()));
-
- FieldOperation groupIdsFo=new FieldOperation();
- groupIdsFo.setFieldName("groupIds");
- groupIdsFo.setDescriptor(new StringDescriptor(proUserAssign.getRoleId()));
-
- List<Operation> listOp=new ArrayList<Operation>();
- listOp.add(userIdsFo);
- listOp.add(groupIdsFo);
- descriptor.setOperations(listOp);
-
- userCodeReference.setCached(false);
- userCodeReference.setDescriptor(descriptor);
- taskDef.setAssignmentHandlerReference(userCodeReference);
-
- }catch(Exception ex){
- logger.error("ADD AssignHandler Error:" + ex.getMessage());
- }finally{
- if(env!=null){
- env.close();
- }
- }
- }
/**
* 为流程定义加上任务的指派人员接口
* @param deployId
*/
public void addAssignHandler(ProUserAssign proUserAssign){
ProcessDefinitionImpl pd=(ProcessDefinitionImpl)repositoryService.createProcessDefinitionQuery().deploymentId(proUserAssign.getDeployId()).uniqueResult();
EnvironmentFactory environmentFactory = (EnvironmentFactory) processEngine;
EnvironmentImpl env=null;
try {
env = environmentFactory.openEnvironment();
//找到任务的定义
TaskDefinitionImpl taskDef=pd.getTaskDefinition(proUserAssign.getActivityName());
UserCodeReference userCodeReference = new UserCodeReference();
ObjectDescriptor descriptor = new ObjectDescriptor();
//加上任务的人员动态指派
descriptor.setClassName("com.htsoft.core.jbpm.UserAssignHandler");
//动态加参数
FieldOperation userIdsFo = new FieldOperation();
userIdsFo.setFieldName("userIds");
userIdsFo.setDescriptor(new StringDescriptor(proUserAssign.getUserId()));
FieldOperation groupIdsFo=new FieldOperation();
groupIdsFo.setFieldName("groupIds");
groupIdsFo.setDescriptor(new StringDescriptor(proUserAssign.getRoleId()));
List<Operation> listOp=new ArrayList<Operation>();
listOp.add(userIdsFo);
listOp.add(groupIdsFo);
descriptor.setOperations(listOp);
userCodeReference.setCached(false);
userCodeReference.setDescriptor(descriptor);
taskDef.setAssignmentHandlerReference(userCodeReference);
}catch(Exception ex){
logger.error("ADD AssignHandler Error:" + ex.getMessage());
}finally{
if(env!=null){
env.close();
}
}
}
不过该方式没有持久久,重启系统后,保存的用户及角色设置并不会生效。
UserAssignHandler类代码如下:
- package com.htsoft.core.jbpm;
-
- import org.apache.commons.lang.StringUtils;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.jbpm.api.model.OpenExecution;
- import org.jbpm.api.task.Assignable;
- import org.jbpm.api.task.AssignmentHandler;
-
- import com.htsoft.core.Constants;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- public class UserAssignHandler implements AssignmentHandler{
- private Log logger=LogFactory.getLog(UserAssignHandler.class);
-
- String userIds;
-
- String groupIds;
-
- @Override
- public void assign(Assignable assignable, OpenExecution execution) throws Exception {
-
- String assignId=(String)execution.getVariable(Constants.FLOW_ASSIGN_ID);
-
- logger.info("assignId:===========>" + assignId);
-
-
- if(StringUtils.isNotEmpty(assignId)){
- assignable.setAssignee(assignId);
- return;
- }
-
-
-
-
- String signUserIds=(String)execution.getVariable(Constants.FLOW_SIGN_USERIDS);
-
- if(signUserIds!=null){
-
- }
-
- logger.debug("Enter UserAssignHandler assign method~~~~");
-
- if(userIds!=null){
- String[]uIds=userIds.split("[,]");
- if(uIds!=null && uIds.length>1){
- for(String uId:uIds){
- assignable.addCandidateUser(uId);
- }
- }else{
- assignable.setAssignee(userIds);
- }
- }
-
- if(groupIds!=null){
- String[]gIds=userIds.split("[,]");
- if(gIds!=null&& gIds.length>1){
- for(String gId:gIds){
- assignable.addCandidateGroup(gId);
- }
- }else{
- assignable.addCandidateGroup(groupIds);
- }
- }
-
- }
-
- }