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

Jbpm4提供的IdentitySession接口并不是一种很好的处理方式,鉴于我们每个业务系统都有一套自己的用户及权限认证管理机制,需要与jbpm4.4集成的话,就比较周折了,我们经常需要查询的就是用户自己的任务。jbpm4的任务里有一个比较好的任务人员指派定义方式,就是使用AssignmentHandler接口,其定义如下所示:

Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2.   
  3. <process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">   
  4.   
  5.   <start g="20,20,48,48">   
  6.     <transition to="review" />   
  7.   </start>   
  8.   
  9.   <task name="review" g="96,16,127,52">   
  10.     <assignment-handler class="org.jbpm.examples.task.assignmenthandler.AssignTask">   
  11.       <field name="assignee">   
  12.         <string value="johndoe" />   
  13.       </field>   
  14.     </assignment-handler>   
  15.     <transition to="wait" />   
  16.   </task>   
  17.   
  18.   <state name="wait" g="255,16,88,52" />   
  19.   
  20. </process>  
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">  
  4.   
  5.   <start g="20,20,48,48">  
  6.     <transition to="review" />  
  7.   </start>  
  8.   
  9.   <task name="review" g="96,16,127,52">  
  10.     <assignment-handler class="org.jbpm.examples.task.assignmenthandler.AssignTask">  
  11.       <field name="assignee">  
  12.         <string value="johndoe" />  
  13.       </field>  
  14.     </assignment-handler>  
  15.     <transition to="wait" />  
  16.   </task>  
  17.   
  18.   <state name="wait" g="255,16,88,52" />  
  19.   
  20. </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>

 

Java代码 复制代码
  1. package org.jbpm.examples.task.assignmenthandler;   
  2.   
  3. import org.jbpm.api.model.OpenExecution;   
  4. import org.jbpm.api.task.Assignable;   
  5. import org.jbpm.api.task.AssignmentHandler;   
  6.   
  7.   
  8. /**  
  9.  * @author Tom Baeyens  
  10.  */  
  11. public class AssignTask implements AssignmentHandler {   
  12.      
  13.   private static final long serialVersionUID = 1L;   
  14.   
  15.   String assignee;   
  16.   
  17.   public void assign(Assignable assignable, OpenExecution execution) {   
  18.     assignable.setAssignee(assignee);   
  19.   }   
  20. }  
  1. package org.jbpm.examples.task.assignmenthandler;  
  2.   
  3. import org.jbpm.api.model.OpenExecution;  
  4. import org.jbpm.api.task.Assignable;  
  5. import org.jbpm.api.task.AssignmentHandler;  
  6.   
  7.   
  8. /** 
  9.  * @author Tom Baeyens 
  10.  */  
  11. public class AssignTask implements AssignmentHandler {  
  12.     
  13.   private static final long serialVersionUID = 1L;  
  14.   
  15.   String assignee;  
  16.   
  17.   public void assign(Assignable assignable, OpenExecution execution) {  
  18.     assignable.setAssignee(assignee);  
  19.   }  
  20. }  
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之后的版本,启动流程及运行流程时,都会去读取流程定义,因此,我们可以动态修改以上配置文件,让其生成类似如下的配置格式即可以满足我们的要求:

 

Java代码 复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2.   
  3. <process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">   
  4.   
  5.   <start g="20,20,48,48">   
  6.     <transition to="review" />   
  7.   </start>   
  8.   
  9.   <task name="review" g="96,16,127,52">   
  10.     <assignment-handler class="com.htsoft.core.jbpm.AssignmentHandler">   
  11.       <field name="userIds">   
  12.         <string value="1" />   
  13.       </field>   
  14.      <field name="roleIds">   
  15.         <string value="1,2" />   
  16.       </field>   
  17.     </assignment-handler>   
  18.     <transition to="wait" />   
  19.   </task>   
  20.   
  21.   <state name="wait" g="255,16,88,52" />   
  22.   
  23. </process>  
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2.   
  3. <process name="TaskAssignmentHandler" xmlns="http://jbpm.org/4.4/jpdl">  
  4.   
  5.   <start g="20,20,48,48">  
  6.     <transition to="review" />  
  7.   </start>  
  8.   
  9.   <task name="review" g="96,16,127,52">  
  10.     <assignment-handler class="com.htsoft.core.jbpm.AssignmentHandler">  
  11.       <field name="userIds">  
  12.         <string value="1" />  
  13.       </field>  
  14.      <field name="roleIds">  
  15.         <string value="1,2" />  
  16.       </field>  
  17.     </assignment-handler>  
  18.     <transition to="wait" />  
  19.   </task>  
  20.   
  21.   <state name="wait" g="255,16,88,52" />  
  22.   
  23. </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字段中去则可,这是持久化的处理。

 

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

 

Java代码 复制代码
  1. /**  
  2.      * 为流程定义加上任务的指派人员接口  
  3.      * @param deployId  
  4.      */  
  5.     public void addAssignHandler(ProUserAssign proUserAssign){   
  6.         ProcessDefinitionImpl pd=(ProcessDefinitionImpl)repositoryService.createProcessDefinitionQuery().deploymentId(proUserAssign.getDeployId()).uniqueResult();   
  7.          EnvironmentFactory environmentFactory = (EnvironmentFactory) processEngine;   
  8.          EnvironmentImpl env=null;   
  9.          try {   
  10.              env = environmentFactory.openEnvironment();   
  11.              //找到任务的定义   
  12.              TaskDefinitionImpl taskDef=pd.getTaskDefinition(proUserAssign.getActivityName());   
  13.              UserCodeReference userCodeReference = new UserCodeReference();   
  14.              ObjectDescriptor descriptor = new ObjectDescriptor();   
  15.              //加上任务的人员动态指派   
  16.              descriptor.setClassName("com.htsoft.core.jbpm.UserAssignHandler");   
  17.              //动态加参数   
  18.              FieldOperation userIdsFo = new FieldOperation();   
  19.              userIdsFo.setFieldName("userIds");    
  20.              userIdsFo.setDescriptor(new StringDescriptor(proUserAssign.getUserId()));   
  21.                 
  22.              FieldOperation groupIdsFo=new FieldOperation();   
  23.              groupIdsFo.setFieldName("groupIds");   
  24.              groupIdsFo.setDescriptor(new StringDescriptor(proUserAssign.getRoleId()));   
  25.                 
  26.              List<Operation> listOp=new ArrayList<Operation>();   
  27.              listOp.add(userIdsFo);   
  28.              listOp.add(groupIdsFo);   
  29.              descriptor.setOperations(listOp);   
  30.                 
  31.              userCodeReference.setCached(false);   
  32.              userCodeReference.setDescriptor(descriptor);   
  33.              taskDef.setAssignmentHandlerReference(userCodeReference);   
  34.                 
  35.          }catch(Exception ex){   
  36.              logger.error("ADD AssignHandler Error:" + ex.getMessage());   
  37.          }finally{   
  38.              if(env!=null){   
  39.                  env.close();   
  40.              }   
  41.          }   
  42.     }  
  1. /** 
  2.      * 为流程定义加上任务的指派人员接口 
  3.      * @param deployId 
  4.      */  
  5.     public void addAssignHandler(ProUserAssign proUserAssign){  
  6.         ProcessDefinitionImpl pd=(ProcessDefinitionImpl)repositoryService.createProcessDefinitionQuery().deploymentId(proUserAssign.getDeployId()).uniqueResult();  
  7.          EnvironmentFactory environmentFactory = (EnvironmentFactory) processEngine;  
  8.          EnvironmentImpl env=null;  
  9.          try {  
  10.              env = environmentFactory.openEnvironment();  
  11.              //找到任务的定义   
  12.              TaskDefinitionImpl taskDef=pd.getTaskDefinition(proUserAssign.getActivityName());  
  13.              UserCodeReference userCodeReference = new UserCodeReference();  
  14.              ObjectDescriptor descriptor = new ObjectDescriptor();  
  15.              //加上任务的人员动态指派   
  16.              descriptor.setClassName("com.htsoft.core.jbpm.UserAssignHandler");  
  17.              //动态加参数   
  18.              FieldOperation userIdsFo = new FieldOperation();  
  19.              userIdsFo.setFieldName("userIds");   
  20.              userIdsFo.setDescriptor(new StringDescriptor(proUserAssign.getUserId()));  
  21.                
  22.              FieldOperation groupIdsFo=new FieldOperation();  
  23.              groupIdsFo.setFieldName("groupIds");  
  24.              groupIdsFo.setDescriptor(new StringDescriptor(proUserAssign.getRoleId()));  
  25.                
  26.              List<Operation> listOp=new ArrayList<Operation>();  
  27.              listOp.add(userIdsFo);  
  28.              listOp.add(groupIdsFo);  
  29.              descriptor.setOperations(listOp);  
  30.                
  31.              userCodeReference.setCached(false);  
  32.              userCodeReference.setDescriptor(descriptor);  
  33.              taskDef.setAssignmentHandlerReference(userCodeReference);  
  34.                
  35.          }catch(Exception ex){  
  36.              logger.error("ADD AssignHandler Error:" + ex.getMessage());  
  37.          }finally{  
  38.              if(env!=null){  
  39.                  env.close();  
  40.              }  
  41.          }  
  42.     }  
/**
     * 为流程定义加上任务的指派人员接口
     * @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类代码如下:

 

 

Java代码 复制代码
  1. package com.htsoft.core.jbpm;   
  2.   
  3. import org.apache.commons.lang.StringUtils;   
  4. import org.apache.commons.logging.Log;   
  5. import org.apache.commons.logging.LogFactory;   
  6. import org.jbpm.api.model.OpenExecution;   
  7. import org.jbpm.api.task.Assignable;   
  8. import org.jbpm.api.task.AssignmentHandler;   
  9.   
  10. import com.htsoft.core.Constants;   
  11.   
  12. /**  
  13.  * 尚未开始使用  
  14.  * <B><P>Joffice -- http://www.jee-soft.cn</P></B> 
  15.  * <B><P>Copyright (C) 2008-2010 GuangZhou HongTian Software Company (广州宏天软件有限公司)</P></B>  
  16.  * <B><P>description:</P></B> 
  17.  * <P></P>  
  18.  * <P>product:joffice</P>  
  19.  * <P></P>   
  20.  * @see com.htsoft.core.jbpm.UserAssignHandler 
  21.  * <P></P>  
  22.  * @author   
  23.  * @version V1  
  24.  * @create: 2010-11-23下午02:58:01 
  25.  */  
  26. public class UserAssignHandler implements AssignmentHandler{   
  27.     private Log logger=LogFactory.getLog(UserAssignHandler.class);   
  28.     //授予用户ID   
  29.     String userIds;   
  30.     //授权角色ID   
  31.     String groupIds;   
  32.        
  33.     @Override  
  34.     public void assign(Assignable assignable, OpenExecution execution) throws Exception {   
  35.            
  36.         String assignId=(String)execution.getVariable(Constants.FLOW_ASSIGN_ID);   
  37.            
  38.         logger.info("assignId:===========>" + assignId);   
  39.            
  40.         //在表单提交中指定了固定的执行人员   
  41.         if(StringUtils.isNotEmpty(assignId)){   
  42.             assignable.setAssignee(assignId);   
  43.             return;   
  44.         }   
  45.            
  46.         //在表单中指定了执行的角色TODO   
  47.            
  48.         //在表单中指定了会签人员   
  49.         String signUserIds=(String)execution.getVariable(Constants.FLOW_SIGN_USERIDS);   
  50.            
  51.         if(signUserIds!=null){   
  52.             //TODO 取到该任务,进行会签设置  
  53.         }   
  54.            
  55.         logger.debug("Enter UserAssignHandler assign method~~~~");   
  56.            
  57.         if(userIds!=null){//若用户不为空  
  58.             String[]uIds=userIds.split("[,]");   
  59.             if(uIds!=null && uIds.length>1){//多于一个人的  
  60.                 for(String uId:uIds){   
  61.                     assignable.addCandidateUser(uId);   
  62.                 }   
  63.             }else{   
  64.                 assignable.setAssignee(userIds);   
  65.             }   
  66.         }   
  67.            
  68.         if(groupIds!=null){//若角色组不为空  
  69.             String[]gIds=userIds.split("[,]");   
  70.             if(gIds!=null&& gIds.length>1){//多于一个角色的  
  71.                 for(String gId:gIds){   
  72.                     assignable.addCandidateGroup(gId);   
  73.                 }   
  74.             }else{   
  75.                 assignable.addCandidateGroup(groupIds);   
  76.             }   
  77.         }   
  78.   
  79.     }   
  80.   
展开阅读全文

Git 实用技巧

11-24
这几年越来越多的开发团队使用了Git,掌握Git的使用已经越来越重要,已经是一个开发者必备的一项技能;但很多人在刚开始学习Git的时候会遇到很多疑问,比如之前使用过SVN的开发者想不通Git提交代码为什么需要先commit然后再去push,而不是一条命令一次性搞定; 更多的开发者对Git已经入门,不过在遇到一些代码冲突、需要恢复Git代码时候就不知所措,这个时候哪些对 Git掌握得比较好的少数人,就像团队中的神一样,在队友遇到 Git 相关的问题的时候用各种流利的操作来帮助队友于水火。 我去年刚加入新团队,发现一些同事对Git的常规操作没太大问题,但对Git的理解还是比较生疏,比如说分支和分支之间的关联关系、合并代码时候的冲突解决、提交代码前未拉取新代码导致冲突问题的处理等,我在协助处理这些问题的时候也记录各种问题的解决办法,希望整理后通过教程帮助到更多对Git操作进阶的开发者。 本期教程学习方法分为“掌握基础——稳步进阶——熟悉协作”三个层次。从掌握基础的 Git的推送和拉取开始,以案例进行演示,分析每一个步骤的操作方式和原理,从理解Git 工具的操作到学会代码存储结构、演示不同场景下Git遇到问题的不同处理方案。循序渐进让同学们掌握Git工具在团队协作中的整体协作流程。 在教程中会通过大量案例进行分析,案例会模拟在工作中遇到的问题,从最基础的代码提交和拉取、代码冲突解决、代码仓库的数据维护、Git服务端搭建等。为了让同学们容易理解,对Git简单易懂,文章中详细记录了详细的操作步骤,提供大量演示截图和解析。在教程的最后部分,会从提升团队整体效率的角度对Git工具进行讲解,包括规范操作、Gitlab的搭建、钩子事件的应用等。 为了让同学们可以利用碎片化时间来灵活学习,在教程文章中大程度降低了上下文的依赖,让大家可以在工作之余进行学习与实战,并同时掌握里面涉及的Git不常见操作的相关知识,理解Git工具在工作遇到的问题解决思路和方法,相信一定会对大家的前端技能进阶大有帮助。

实用主义学Python(小白也容易上手的Python实用案例)

12-24
原价169,限时立减100元! 系统掌握Python核心语法16点,轻松应对工作中80%以上的Python使用场景! 69元=72讲+源码+社群答疑+讲师社群分享会  【哪些人适合学习这门课程?】 1)大学生,平时只学习了Python理论,并未接触Python实战问题; 2)对Python实用技能掌握薄弱的人,自动化、爬虫、数据分析能让你快速提高工作效率; 3)想学习新技术,如:人工智能、机器学习、深度学习等,这门课程是你的必修课程; 4)想修炼更好的编程内功,优秀的工程师肯定不能只会一门语言,Python语言功能强大、使用高效、简单易学。 【超实用技能】 从零开始 自动生成工作周报 职场升级 豆瓣电影数据爬取 实用案例 奥运冠军数据分析 自动化办公:通过Python自动化分析Excel数据并自动操作Word文档,最终获得一份基于Excel表格的数据分析报告。 豆瓣电影爬虫:通过Python自动爬取豆瓣电影信息并将电影图片保存到本地。 奥运会数据分析实战 简介:通过Python分析120年间奥运会的数据,从不同角度入手分析,从而得出一些有趣的结论。 【超人气老师】 二两 中国人工智能协会高级会员 生成对抗神经网络研究者 《深入浅出生成对抗网络:原理剖析与TensorFlow实现》一书作者 阿里云大学云学院导师 前大型游戏公司后端工程师 【超丰富实用案例】 0)图片背景去除案例 1)自动生成工作周报案例 2)豆瓣电影数据爬取案例 3)奥运会数据分析案例 4)自动处理邮件案例 5)github信息爬取/更新提醒案例 6)B站百大UP信息爬取与分析案例 7)构建自己的论文网站案例
©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值