`
man1900
  • 浏览: 428919 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

利用JBPM4.4的AssignmentHandler实现用户角色整合另一种构思

    博客分类:
  • JBPM
阅读更多

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>

 

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>

 以上的userIds的1,以及roleIds的1,2则代表我们系统中的用户id与角色的id,其值由后台用户在后面通过界面来设置。

 

其设置后,就生成以上的代码写至jbpm4_lob表中的blobvalue字段中去则可,这是持久化的处理。

 

也可以临时调用类似以下的代码动态实现以上效果:

 

/**
     * 为流程定义加上任务的指派人员接口
     * @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;

/**
 * 尚未开始使用
 * <B><P>Joffice -- http://www.jee-soft.cn</P></B>
 * <B><P>Copyright (C) 2008-2010 GuangZhou HongTian Software Company (广州宏天软件有限公司)</P></B> 
 * <B><P>description:</P></B>
 * <P></P>
 * <P>product:joffice</P>
 * <P></P> 
 * @see com.htsoft.core.jbpm.UserAssignHandler
 * <P></P>
 * @author 
 * @version V1
 * @create: 2010-11-23下午02:58:01
 */
public class UserAssignHandler implements AssignmentHandler{
	private Log logger=LogFactory.getLog(UserAssignHandler.class);
	//授予用户ID
	String userIds;
	//授权角色ID
	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;
		}
		
		//在表单中指定了执行的角色TODO
		
		//在表单中指定了会签人员
		String signUserIds=(String)execution.getVariable(Constants.FLOW_SIGN_USERIDS);
		
		if(signUserIds!=null){
			//TODO 取到该任务,进行会签设置
		}
		
		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);
			}
		}

	}

}

 

分享到:
评论
4 楼 jakey766 2011-10-31  
我现在正碰到这样个问题,想请教下楼主:

String assignId=(String)execution.getVariable(Constants.FLOW_ASSIGN_ID); 
logger.info("assignId:===========>" + assignId); 
//在表单提交中指定了固定的执行人员 
if(StringUtils.isNotEmpty(assignId)){ 
    assignable.setAssignee(assignId); 
    return; 
}
这样的话如果execution.getVariable(Constants.FLOW_ASSIGN_ID)获取到的值不为空,那该流程的后面每一步都能取到该值?
如果在流程的第一个表单选择指派一个人,然后之后的环节又不指派人,那不是后面的环节都只有这个指派的人有权限么?
3 楼 jakey766 2011-10-31  
<assignment-handler class="org.jbpm.examples.task.assignmenthandler.AssignTask"> 
   <field name="assignee"> 
      <string value="johndoe" /> 
   </field> 
</assignment-handler>
你好,请问如果我在定义中这样写,又想在代码中也可以动态给org.jbpm.examples.task.assignmenthandler.AssignTask传递参数,该怎样做?
(如果在表单选了指派人,则只分派给所选的人,否则默认分派给johndoe)
2 楼 xuanzd 2011-07-03  
aizhimin 写道
我采用了类似的方式,只不过我不去修改流程定义的xml,而是将每个人工任务的参与者分配保存到数据库的一张表中,然后UserAssignHandler 中读取实现。

UserAssignHandler 中读取具体是怎么实现的呢,能分享一下吗?
1 楼 aizhimin 2011-01-06  
我采用了类似的方式,只不过我不去修改流程定义的xml,而是将每个人工任务的参与者分配保存到数据库的一张表中,然后UserAssignHandler 中读取实现。

相关推荐

Global site tag (gtag.js) - Google Analytics