公开我个人写的一个Activiti的工具栏

package com.thinkgem.jeesite.modules.act.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
import org.activiti.engine.impl.bpmn.helper.ClassDelegate;
import org.activiti.engine.impl.javax.el.ExpressionFactory;
import org.activiti.engine.impl.javax.el.ValueExpression;
import org.activiti.engine.impl.juel.ExpressionFactoryImpl;
import org.activiti.engine.impl.juel.SimpleContext;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.task.TaskDefinition;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.act.entity.Condition;
import com.thinkgem.jeesite.modules.act.utils.ActUtils;

/**
 * ActComponent2 
 * @author yuguo
 *
 */
@Component
public class ActComponent2 {

	/**
	 * 日志对象
	 */
	protected Logger logger = LoggerFactory.getLogger(getClass());
	
	@Autowired
	private RepositoryService repositoryService;
	@Autowired
	private TaskService taskService;
	
	public Task getCurrentTask(String taskId) {
		return taskService.createTaskQuery().taskId(taskId).singleResult();
	}
	
	/**
	 * <p>获取ProcessDefinitionEntity<p>
	 * @param procDefId
	 * @return
	 */
	public ProcessDefinitionEntity getProcDefEntByprocDefId (String procDefId) {
		return (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)  
                .getDeployedProcessDefinition(procDefId);
	}
	
	/**
	 * 
	 * <p>获取ProcessDefinitionEntity<p>
	 * @param definitionId
	 * @return
	 */
	public ProcessDefinitionEntity getProcDefEntBy (String definitionId) {
		return (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)  
                .getDeployedProcessDefinition(definitionId); 
	}
	
	/**
	 * <p>获取流程上的所有节点 包括 task gateway start end</p>
	 * @param processDefinitionEntity
	 * @return
	 */
	public List<ActivityImpl> getAllActivityImpl(ProcessDefinitionEntity processDefinitionEntity){
		return processDefinitionEntity.getActivities();
	}
	
	/**
	 * 根据Id获取指定Activity
	 * @param activityList
	 * @param activityId
	 * @return
	 */
	public ActivityImpl findActivityImpl (List<ActivityImpl> activityList, String activityId) {
		for (ActivityImpl ac : activityList) {
			if (activityId.equals(ac.getId())) {
				return ac;
			}
		}
		return null;
	}
	
	/**
	 * 获取目标最近的flow_line
	 * @param activityImpl
	 * @return
	 */
	public List<PvmTransition> getNearFlow (ActivityImpl activityImpl) {
		//因为下面使用了递归,这里使用引用当作参数传递
		List<PvmTransition> pvmTransitionList = new ArrayList<PvmTransition>();
		//递归查找临近节点
		recursionPvmTransition(pvmTransitionList, activityImpl);
		//返回查找到的所有节点
		return pvmTransitionList;
	}
	
	/**
	 * 递归获取到目标task最近的flow_line
	 * @param pvmTransitionList
	 * @param activityImpl
	 */
	public void recursionPvmTransition (List<PvmTransition> pvmTransitionList, ActivityImpl activityImpl) {
		List<PvmTransition> tmpPvmTransition = activityImpl.getOutgoingTransitions();
		
		for (PvmTransition tr : tmpPvmTransition) {
			PvmActivity ac = tr.getDestination();
			//flow_line 连接的目标类型
			String desType = (String)ac.getProperty("type");
			//判断类型是不是用户审批节点
			if ("userTask".equals(desType)) {
				//如果是用户审批节点 添加节点
				pvmTransitionList.add(tr);
			}else {
				//如果不是的话 继续递归
				recursionPvmTransition(pvmTransitionList, (ActivityImpl) ac);
			}
		}
		
		return ;
	}
	
	/**
	 * 根据表达式获取目标ActivityImpl
	 * @param pvmTransitionList
	 * @param flagValue
	 * @return
	 */
	public ActivityImpl getActivityImplByCondition (List<PvmTransition> pvmTransitionList, String flagValue) {
		//String condition = (String)tr1.getProperty("conditionText");
		if (pvmTransitionList.size()>1) {
			for (PvmTransition tmpPvm : pvmTransitionList) {
				//获取表达式
				String condition = (String)tmpPvm.getProperty("conditionText");
				//判断表达式是不是成立
				boolean judge = isCondition("flag", condition, flagValue);
				if (judge) {
					return (ActivityImpl)tmpPvm.getDestination();
				}
			}
		}else {
			return (ActivityImpl)pvmTransitionList.get(0).getDestination();
		}
		
		return null;
	}
	
    /** 
     * 根据key和value判断el表达式是否通过信息  
     * @param String key    el表达式key信息  如 $(flag==0) 这里的flag就是key  
     * @param String el     el表达式  
     * @param String value  el表达式传入值信息  
     * @return 
     */  
    public boolean isCondition(String key, String el, String value) {  
        ExpressionFactory factory = new ExpressionFactoryImpl();    
        SimpleContext context = new SimpleContext();    
        context.setVariable(key, factory.createValueExpression(value, String.class));    
        ValueExpression e = factory.createValueExpression(context, el, boolean.class);    
        return (Boolean) e.getValue(context);  
    }  
	
	/**
	 * 判断是不是多实例
	 * @param procDefId
	 * @param taskId	task定义Id 开始节点Id请设置为start
	 * @param flagValue 前台传递过来的值用于判断分支走向 如果没有多分支设置为null即可
	 * @return
	 */
	public Boolean isMultiInstance (String procDefId, String activityId, String flagValue) {
		ProcessDefinitionEntity procEntity = this.getProcDefEntByprocDefId(procDefId);
		ActivityImpl ac = this.findActivityImpl(this.getAllActivityImpl(procEntity), activityId);
		List<PvmTransition> nearFlowLine = this.getNearFlow(ac);
		ActivityImpl targetAc = this.getActivityImplByCondition(nearFlowLine, flagValue);
		Object mutil = targetAc.getProperty("multiInstance");
		if (mutil != null) {
			return true;
		}
		return false;
	}
	/**
	 * 获取单实例task定义信息
	 * @param ac
	 * @return
	 */
	public TaskDefinition getTaskDefinition (PvmActivity ac) {
    	return ((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior()).getTaskDefinition();
    }
	
	/**
	 * <p>封装ConditionList 用于前台选择分支</p>
	 * @param procDefId
	 * @param activityId
	 * @return
	 */
	public List<Condition> getConditions (String procDefId, String activityId){
		List<Condition> conditions = new ArrayList<Condition>();
		
		ProcessDefinitionEntity procEntity = this.getProcDefEntByprocDefId(procDefId);
		ActivityImpl ac = this.findActivityImpl(this.getAllActivityImpl(procEntity), activityId);
		List<PvmTransition> nearFlowLine = this.getNearFlow(ac);
		
		for (PvmTransition tmpPvm : nearFlowLine) {
			String condition = (String)tmpPvm.getProperty("conditionText");
			ActivityImpl targetAc = (ActivityImpl)tmpPvm.getDestination();
			Object multi = targetAc.getProperty("multiInstance");
			String name = (String)tmpPvm.getProperty("name");
			Boolean isAssignee = false;
			
			if (multi != null) {
				Map<String, List<ExecutionListener>> executionListeners = ((ActivityImpl) targetAc).getExecutionListeners();
				isAssignee = isSetAssignee(executionListeners);
			}else {
				TaskDefinition taskDefinition = this.getTaskDefinition((ActivityImpl)targetAc);
				isAssignee = this.isSetAssignee(taskDefinition);
			}
			
			conditions.add(this.setCondition(condition, name, isAssignee));
		}
		
		return conditions;
	}
	
	/**
	 * 
	 * @param condition 条件表达式
	 * @param name flow_line的名称
	 * @param isSetAssignee 有没有设置办理人
	 * @return
	 */
	public Condition setCondition (String condition, String name, Boolean isSetAssignee){
		Pattern p = null;
		Integer valueNumber = null;
		if (condition.indexOf("\"")>=0 || condition.indexOf("'")>=0) {
			p = Pattern.compile(ActUtils.conditionRegex);
			valueNumber = 5;
		}else {
			p = Pattern.compile(ActUtils.conditionRegexNumber);
			valueNumber = 4;
		}
		Matcher m = p.matcher(condition);
		if (m.find() && m.groupCount()==ActUtils.groupCount) {
			Condition conditionEntity = new Condition();
			conditionEntity.setKey(m.group(2));
			conditionEntity.setOperation(m.group(3));
			conditionEntity.setValue(m.group(valueNumber));
			conditionEntity.setName(name);
			conditionEntity.setIsSetAssignee(isSetAssignee);
			return conditionEntity;
		}else {
			throw new RuntimeException(this.getClass().getName()+".matcherCondition :条件表达式错误");
		}
	}
	
	/**
	 * 多实例情况下判断有没有设置办理人 注意这里使用的是执行监听 不要设置成task监听
	 * @param executionListeners 多实例的监听
	 * @return
	 */
    public Boolean isSetAssignee (Map<String, List<ExecutionListener>> executionListeners) {
    	Set<Entry<String, List<ExecutionListener>>> entrySet = executionListeners.entrySet();
		for (Entry<String, List<ExecutionListener>> tmpEntry : entrySet) {
			List<ExecutionListener> executionListenerList = tmpEntry.getValue();
			for (ExecutionListener tmpExecution : executionListenerList) {
				if (tmpExecution instanceof ClassDelegate) {
					try {
						Class tmpClass = Class.forName(((ClassDelegate)tmpExecution).getClassName());
						Class supClass = tmpClass.getSuperclass();
						if ("com.thinkgem.jeesite.activity.taskListener.abs.SetMultiplayerAbs".equals(supClass.getName())) {
							return true;
						}
					} catch (ClassNotFoundException e) {
						logger.error(getClass().getName()+":isuMutilInstanceSetAssignee ClassNotFoundException");
					}
				}
				
			}
		}
    	return false;
    }
    
    /**
     * <p>单实例的情况下判断是不是需要前台选择人员</p>
     * @param taskDefinition
     * @return
     */
    public Boolean isSetAssignee (TaskDefinition taskDefinition) {
    	Expression expression = taskDefinition.getAssigneeExpression();
    	String assigee = null;
    	if (expression != null) {
    		assigee = expression.getExpressionText();
    	}
    	//候选人
    	Integer cduId = taskDefinition.getCandidateUserIdExpressions().size();
    	//候选组
    	Integer cdgId = taskDefinition.getCandidateGroupIdExpressions().size();
    	
    	//如果匹配不上要不要写日志提示一下呢 考虑一下觉得这个流程图配置不正确属实没办法
    	if (StringUtils.isNotEmpty(assigee)) {
    		if (!Pattern.matches(ActUtils.matchesAssigneeConditiob, assigee) || cduId>0 || cdgId>0) {
        		return true;
        	}
    	}
    	
    	return false;
    }
}
  1. 这个工具类提供了获取之后的临近节点

  2. 根据activiti条件表达式获取节点

  3. 判断是不是多人会签

猜你喜欢

转载自blog.csdn.net/aa80303857/article/details/86487971