转载来自:http://cheen.iteye.com/blog/1591900
最近公司需要使用工作流引擎,选用了activiti。需求中提到的流程比较简单,也就3级审核,送审时需要选择下一节点的用户,所以必须在流程中需要获取当前节点的下一个节点。代码如下:
- /**
- * 根据实例编号查找下一个任务节点
- * @param String procInstId :实例编号
- * @return
- */
- public TaskDefinition nextTaskDefinition(String procInstId){
- //流程标示
- String processDefinitionId = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstId).singleResult().getProcessDefinitionId();
- ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(processDefinitionId);
- //执行实例
- ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
- //当前实例的执行到哪个节点
- String activitiId = execution.getActivityId();
- //获得当前任务的所有节点
- List<ActivityImpl> activitiList = def.getActivities();
- String id = null;
- for(ActivityImpl activityImpl:activitiList){
- id = activityImpl.getId();
- if(activitiId.equals(id)){
- System.out.println("当前任务:"+activityImpl.getProperty("name"));
- return nextTaskDefinition(activityImpl, activityImpl.getId(),"${iscorrect==1}");
- // System.out.println(taskDefinition.getCandidateGroupIdExpressions().toArray()[0]);
- // return taskDefinition;
- }
- }
- return null;
- }
- /**
- * 下一个任务节点
- * @param activityImpl
- * @param activityId
- * @param elString
- * @return
- */
- private TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString){
- if("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())){
- TaskDefinition taskDefinition = ((UserTaskActivityBehavior)activityImpl.getActivityBehavior()).getTaskDefinition();
- // taskDefinition.getCandidateGroupIdExpressions().toArray();
- return taskDefinition;
- }else{
- List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
- List<PvmTransition> outTransitionsTemp = null;
- for(PvmTransition tr:outTransitions){
- PvmActivity ac = tr.getDestination(); //获取线路的终点节点
- if("exclusiveGateway".equals(ac.getProperty("type"))){
- outTransitionsTemp = ac.getOutgoingTransitions();
- if(outTransitionsTemp.size() == 1){
- return nextTaskDefinition((ActivityImpl)outTransitionsTemp.get(0).getDestination(), activityId, elString);
- }else if(outTransitionsTemp.size() > 1){
- for(PvmTransition tr1 : outTransitionsTemp){
- Object s = tr1.getProperty("conditionText");
- if(elString.equals(StrUtils.trim(s.toString()))){
- return nextTaskDefinition((ActivityImpl)tr1.getDestination(), activityId, elString);
- }
- }
- }
- }else if("userTask".equals(ac.getProperty("type"))){
- return ((UserTaskActivityBehavior)((ActivityImpl)ac).getActivityBehavior()).getTaskDefinition();
- }else{
- logger.debug(ac.getProperty("type"));
- }
- }
- return null;
- }
- }
思路是通过实例ID获取当前节点,然后查找当前节点后后面所有的活动,主要查找的活动是exclusiveGateway和userTask,如果exclusiveGateway中的条件符合${iscorrect==1}就直接查找exclusiveGateway后的活动,直到找到userTask为止。如果当前节点后的活动是userTask,说明这个userTask就是你想要的。
代码中${iscorrect==1}表达式是流程中定义,表示审核通过。当时对于在java中解析表达式遇到困难,所以使用字符串来比较,代码
- if(elString.equals(StrUtils.trim(s.toString())))
- ExpressionFactory factory = new ExpressionFactoryImpl();
- SimpleContext context = new SimpleContext();
- context.setVariable("count", factory.createValueExpression(10000, String.class));
- ValueExpression e = factory.createValueExpression(context, "${count>=1000}", boolean.class);
- System.out.println(e.getValue(context));