package com.mossle.bpm.support;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
import com.mossle.api.form.FormDTO;
import com.mossle.bpm.cmd.CompleteTaskWithCommentCmd;
import com.mossle.bpm.cmd.DeleteTaskWithCommentCmd;
import com.mossle.bpm.cmd.FindTaskDefinitionsCmd;
import com.mossle.bpm.cmd.RollbackTaskCmd;
import com.mossle.bpm.cmd.SignalStartEventCmd;
import com.mossle.bpm.cmd.WithdrawTaskCmd;
import com.mossle.bpm.persistence.domain.BpmConfForm;
import com.mossle.bpm.persistence.domain.BpmConfOperation;
import com.mossle.bpm.persistence.domain.BpmConfUser;
import com.mossle.bpm.persistence.domain.BpmTaskConf;
import com.mossle.bpm.persistence.manager.BpmConfFormManager;
import com.mossle.bpm.persistence.manager.BpmConfOperationManager;
import com.mossle.bpm.persistence.manager.BpmConfUserManager;
import com.mossle.bpm.persistence.manager.BpmTaskConfManager;
import com.mossle.spi.process.InternalProcessConnector;
import com.mossle.spi.process.ProcessTaskDefinition;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.TaskService;
import org.activiti.engine.impl.cmd.GetDeploymentProcessDefinitionCmd;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.el.ExpressionManager;
import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.persistence.entity.TaskEntity;
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.jdbc.core.JdbcTemplate;
/**
* 这是一个spi接口,因为HumanTask的配置还没有完全从bpm里抽象出去,所以还有不少配置需要从bpm里读取.
*/
public class ActivitiInternalProcessConnector implements
InternalProcessConnector {
/** logger. */
private static Logger logger = LoggerFactory
.getLogger(ActivitiInternalProcessConnector.class);
private ProcessEngine processEngine;
private BpmConfOperationManager bpmConfOperationManager;
private BpmConfFormManager bpmConfFormManager;
private BpmTaskConfManager bpmTaskConfManager;
private BpmConfUserManager bpmConfUserManager;
private JdbcTemplate jdbcTemplate;
/**
* 获得任务表单,不包含表单内容.
*/
public FormDTO findTaskForm(String taskId) {
if (taskId == null) {
logger.error("taskId cannot be null");
return null;
}
Task task = processEngine.getTaskService().createTaskQuery()
.taskId(taskId).singleResult();
if (task == null) {
logger.error("cannot find task for {}", taskId);
return null;
}
String processDefinitionId = task.getProcessDefinitionId();
String activityId = task.getTaskDefinitionKey();
FormDTO formDto = new FormDTO();
formDto.setTaskId(taskId);
List<BpmConfOperation> bpmConfOperations = bpmConfOperationManager
.find("from BpmConfOperation where bpmConfNode.bpmConfBase.processDefinitionId=? and bpmConfNode.code=?",
processDefinitionId, activityId);
for (BpmConfOperation bpmConfOperation : bpmConfOperations) {
formDto.getButtons().add(bpmConfOperation.getValue());
}
formDto.setProcessDefinitionId(processDefinitionId);
formDto.setActivityId(activityId);
List<BpmConfForm> bpmConfForms = bpmConfFormManager
.find("from BpmConfForm where bpmConfNode.bpmConfBase.processDefinitionId=? and bpmConfNode.code=?",
processDefinitionId, activityId);
if (!bpmConfForms.isEmpty()) {
BpmConfForm bpmConfForm = bpmConfForms.get(0);
if (!Integer.valueOf(2).equals(bpmConfForm.getStatus())) {
// 外部表单
if (Integer.valueOf(1).equals(bpmConfForm.getType())) {
formDto.setRedirect(true);
formDto.setUrl(bpmConfForm.getValue());
} else {
formDto.setCode(bpmConfForm.getValue());
}
}
}
return formDto;
}
/**
* 获得任务定义.
*/
public List<ProcessTaskDefinition> findTaskDefinitions(
String processDefinitionId) {
List<ProcessTaskDefinition> processTaskDefinitions = new ArrayList<ProcessTaskDefinition>();
FindTaskDefinitionsCmd cmd = new FindTaskDefinitionsCmd(
processDefinitionId);
List<TaskDefinition> taskDefinitions = processEngine
.getManagementService().executeCommand(cmd);
for (TaskDefinition taskDefinition : taskDefinitions) {
ProcessTaskDefinition processTaskDefinition = new ProcessTaskDefinition();
processTaskDefinition.setKey(taskDefinition.getKey());
if (taskDefinition.getNameExpression() != null) {
processTaskDefinition.setName(taskDefinition
.getNameExpression().getExpressionText());
}
if (taskDefinition.getAssigneeExpression() != null) {
processTaskDefinition.setAssignee(taskDefinition
.getAssigneeExpression().getExpressionText());
}
processTaskDefinitions.add(processTaskDefinition);
}
return processTaskDefinitions;
}
/**
* 完成任务.
*/
public void completeTask(String taskId, String userId,
Map<String, Object> variables) {
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
if (task == null) {
throw new IllegalStateException("任务不存在");
}
// 先设置登录用户
IdentityService identityService = processEngine.getIdentityService();
identityService.setAuthenticatedUserId(userId);
// 处理子任务
if ("subtask".equals(task.getCategory())) {
processEngine.getManagementService().executeCommand(
new DeleteTaskWithCommentCmd(taskId, "完成"));
int count = jdbcTemplate.queryForObject(
"select count(*) from ACT_RU_TASK where PARENT_TASK_ID_=?",
Integer.class, task.getParentTaskId());
if (count > 1) {
return;
}
taskId = task.getParentTaskId();
}
processEngine.getManagementService().executeCommand(
new CompleteTaskWithCommentCmd(taskId, variables, "完成"));
}
/**
* 转发任务.
*/
public void transfer(String taskId, String assignee, String owner) {
processEngine.getTaskService().setAssignee(taskId, assignee);
processEngine.getTaskService().setOwner(taskId, owner);
}
/**
* 撤销任务.
*/
public void withdrawTask(String taskId) {
Command<Integer> cmd = new WithdrawTaskCmd(taskId);
processEngine.getManagementService().executeCommand(cmd);
}
/**
* 回退指定节点,指定负责人. 如果activityId为null,就自动查询上一个节点.
*/
public void rollback(String taskId, String activityId, String userId) {
Command<Object> cmd = new RollbackTaskCmd(taskId, activityId, userId);
processEngine.getManagementService().executeCommand(cmd);
}
/**
* 回退自定节点,使用最后的负责人. 如果activityId为null,就自动查询上一个节点.
*/
public void rollbackAuto(String taskId, String activityId) {
Command<Object> cmd = new RollbackTaskCmd(taskId, activityId);
processEngine.getManagementService().executeCommand(cmd);
}
/**
* 协办任务.
*/
public void delegateTask(String taskId, String userId) {
processEngine.getTaskService().delegateTask(taskId, userId);
}
/**
* 完成协办.
*/
public void resolveTask(String taskId) {
processEngine.getTaskService().resolveTask(taskId);
}
/**
* 根据activityId找到任务定义.
*
* TODO: 支持ExpressionManager,支持Expr
*/
public ProcessTaskDefinition findTaskDefinition(String processDefinitionId,
String taskDefinitionKey, String businessKey) {
// 先从流程定义里读取设计配置的负责人
List<BpmConfUser> bpmConfUsers = bpmConfUserManager
.find("from BpmConfUser where bpmConfNode.bpmConfBase.processDefinitionId=? and bpmConfNode.code=?",
processDefinitionId, taskDefinitionKey);
logger.debug("{}", bpmConfUsers);
ProcessTaskDefinition processTaskDefinition = new ProcessTaskDefinition();
try {
for (BpmConfUser bpmConfUser : bpmConfUsers) {
logger.debug("status : {}, type: {}", bpmConfUser.getStatus(),
bpmConfUser.getType());
logger.debug("value : {}", bpmConfUser.getValue());
String value = bpmConfUser.getValue();
if (bpmConfUser.getStatus() == 1) {
if (bpmConfUser.getType() == 0) {
logger.debug("add assignee : {}", value);
processTaskDefinition.setAssignee(value);
} else if (bpmConfUser.getType() == 1) {
logger.debug("add candidate user : {}", value);
processTaskDefinition.addParticipantDefinition("user",
value, "add");
} else if (bpmConfUser.getType() == 2) {
logger.debug("add candidate group : {}", value);
processTaskDefinition.addParticipantDefinition("group",
value, "add");
}
} else if (bpmConfUser.getStatus() == 2) {
if (bpmConfUser.getType() == 0) {
logger.debug("delete assignee : {}", value);
processTaskDefinition.setAssignee(null);
} else if (bpmConfUser.getType() == 1) {
logger.debug("delete candidate user : {}", value);
processTaskDefinition.addParticipantDefinition("user",
value, "delete");
} else if (bpmConfUser.getType() == 2) {
logger.debug("delete candidate group : {}", value);
processTaskDefinition.addParticipantDefinition("group",
value, "delete");
}
}
}
} catch (Exception ex) {
logger.info(ex.getMessage(), ex);
}
try {
String hql = "from BpmTaskConf where businessKey=? and taskDefinitionKey=?";
BpmTaskConf bpmTaskConf = bpmTaskConfManager.findUnique(hql,
businessKey, taskDefinitionKey);
if (bpmTaskConf != null) {
String assignee = bpmTaskConf.getAssignee();
if ((assignee != null) && (!"".equals(assignee))) {
logger.debug("add assignee : {}", assignee);
processTaskDefinition.setAssignee(assignee);
}
} else {
logger.info("cannot find BpmTaskConf {} {}", businessKey,
taskDefinitionKey);
}
} catch (Exception ex) {
logger.info(ex.getMessage(), ex);
}
return processTaskDefinition;
}
/**
* 获得流程发起人.
*/
public String findInitiator(String processInstanceId) {
String initiator = null;
if (Context.getCommandContext() == null) {
initiator = processEngine.getHistoryService()
.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult()
.getStartUserId();
} else {
initiator = Context.getCommandContext()
.getHistoricProcessInstanceEntityManager()
.findHistoricProcessInstance(processInstanceId)
.getStartUserId();
}
return initiator;
}
/**
* 获得某个节点的历史负责人.
*/
public String findAssigneeByActivityId(String processInstanceId,
String activityId) {
return null;
}
/**
* 解析表达式.
*/
public Object executeExpression(String taskId, String expressionText) {
TaskEntity taskEntity = Context.getCommandContext()
.getTaskEntityManager().findTaskById(taskId);
ExpressionManager expressionManager = Context
.getProcessEngineConfiguration().getExpressionManager();
return expressionManager.createExpression(expressionText).getValue(
taskEntity);
}
/**
* 获得开始事件id.
*/
public String findInitialActivityId(String processDefinitionId) {
GetDeploymentProcessDefinitionCmd getDeploymentProcessDefinitionCmd = new GetDeploymentProcessDefinitionCmd(
processDefinitionId);
ProcessDefinitionEntity processDefinition = processEngine
.getManagementService().executeCommand(
getDeploymentProcessDefinitionCmd);
return processDefinition.getInitial().getId();
}
/**
* 获得提交节点
*/
public String findFirstUserTaskActivityId(String processDefinitionId,
String initiator) {
GetDeploymentProcessDefinitionCmd getDeploymentProcessDefinitionCmd = new GetDeploymentProcessDefinitionCmd(
processDefinitionId);
ProcessDefinitionEntity processDefinitionEntity = processEngine
.getManagementService().executeCommand(
getDeploymentProcessDefinitionCmd);
ActivityImpl startActivity = processDefinitionEntity.getInitial();
if (startActivity.getOutgoingTransitions().size() != 1) {
throw new IllegalStateException(
"start activity outgoing transitions cannot more than 1, now is : "
+ startActivity.getOutgoingTransitions().size());
}
PvmTransition pvmTransition = startActivity.getOutgoingTransitions()
.get(0);
PvmActivity targetActivity = pvmTransition.getDestination();
if (!"userTask".equals(targetActivity.getProperty("type"))) {
logger.info("first activity is not userTask, just skip");
return null;
}
return targetActivity.getId();
}
/**
* 触发execution继续执行.
*/
public void signalExecution(String executionId) {
// processEngine.getRuntimeService().signal(executionId);
processEngine.getManagementService().executeCommand(
new SignalStartEventCmd(executionId));
}
// ~ ==================================================
@Resource
public void setProcessEngine(ProcessEngine processEngine) {
this.processEngine = processEngine;
}
@Resource
public void setBpmConfOperationManager(
BpmConfOperationManager bpmConfOperationManager) {
this.bpmConfOperationManager = bpmConfOperationManager;
}
@Resource
public void setBpmConfFormManager(BpmConfFormManager bpmConfFormManager) {
this.bpmConfFormManager = bpmConfFormManager;
}
@Resource
public void setBpmTaskConfManager(BpmTaskConfManager bpmTaskConfManager) {
this.bpmTaskConfManager = bpmTaskConfManager;
}
@Resource
public void setBpmConfUserManager(BpmConfUserManager bpmConfUserManager) {
this.bpmConfUserManager = bpmConfUserManager;
}
@Resource
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
}