package com.norteksoft.wf.engine.service;
import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import com.norteksoft.acs.entity.authorization.BusinessSystem;
import com.norteksoft.acs.entity.organization.User;
import com.norteksoft.acs.service.AcsUtils;
import com.norteksoft.acs.service.authorization.BusinessSystemManager;
import com.norteksoft.acs.service.organization.UserManager;
import com.norteksoft.mms.form.dao.GeneralDao;
import com.norteksoft.mms.form.entity.FormView;
import com.norteksoft.mms.form.entity.ListColumn;
import com.norteksoft.mms.form.enumeration.DataType;
import com.norteksoft.mms.form.jdbc.JdbcSupport;
import com.norteksoft.mms.form.service.FormViewManager;
import com.norteksoft.product.enumeration.DataState;
import com.norteksoft.product.orm.Page;
import com.norteksoft.product.util.ContextUtils;
import com.norteksoft.product.util.MemCachedUtils;
import com.norteksoft.product.util.ParameterUtils;
import com.norteksoft.product.util.PropUtils;
import com.norteksoft.product.util.ThreadParameters;
import com.norteksoft.wf.base.enumeration.ProcessProperties;
import com.norteksoft.wf.base.enumeration.ProcessState;
import com.norteksoft.wf.base.enumeration.ProcessType;
import com.norteksoft.wf.base.utils.DocumentParameterUtils;
import com.norteksoft.wf.base.utils.DocumentThreadParameters;
import com.norteksoft.wf.base.utils.Dom4jUtils;
import com.norteksoft.wf.engine.core.DefinitionXmlParse;
import com.norteksoft.wf.engine.dao.WorkflowDefinitionDao;
import com.norteksoft.wf.engine.dao.WorkflowDefinitionFileDao;
import com.norteksoft.wf.engine.dao.WorkflowDefinitionTemplateDao;
import com.norteksoft.wf.engine.dao.WorkflowDefinitionTemplateFileDao;
import com.norteksoft.wf.engine.dao.WorkflowInstanceDao;
import com.norteksoft.wf.engine.entity.WorkflowDefinition;
import com.norteksoft.wf.engine.entity.WorkflowDefinitionFile;
import com.norteksoft.wf.engine.entity.WorkflowDefinitionTemplate;
import com.norteksoft.wf.engine.entity.WorkflowDefinitionTemplateFile;
import com.norteksoft.wf.engine.entity.WorkflowType;
@Service
@Transactional
public class WorkflowDefinitionManager {
private Log log = LogFactory.getLog(WorkflowDefinitionManager.class);
private static final String TIME_FORMAT_STRING = "yyyy-MM-dd HH:mm:ss";
private static final String JBPM_DEFINITION_FILE_EXTENSION = ".jpdl.xml";
private static final String KEY_OF_PROCESS_NAME_IN_XML = "wf_name";
private static final String ENCODING_UTF_8 = "UTF-8";
private static final String EMPTY_STRING = "";
private static final Integer TIME_STRING_LENGTH = 19;
private static final String DELTA_START_REGEXP = "\\[";
private static final String DELTA_END = "]";
private static final String WF_MANAGER_ROLE_CODE="workflowManager";//工作流管理员角色编码
private static final String DEF_MANAGER_ROLE_CODE="defManager";//流程定义管理员编码
private ProcessEngine processEngine;
private WorkflowDefinitionDao workflowDefinitionDao;
private WorkflowDefinitionFileDao workflowDefinitionFileDao;
private WorkflowDefinitionTemplateDao workflowDefinitionTemplateDao;
private GeneralDao generalDao;
private FormViewManager formViewManager;
private UserManager userManager;
private WorkflowInstanceDao workflowInstanceDao;
private WorkflowTypeManager workflowTypeManager;
private BusinessSystemManager businessSystemManager;
@Autowired
private WorkflowDefinitionTemplateFileDao workflowDefinitionTemplateFileDao;
@Autowired
private AcsUtils acsUtils;
@Autowired
public void setWorkflowInstanceDao(WorkflowInstanceDao workflowInstanceDao) {
this.workflowInstanceDao = workflowInstanceDao;
}
@Autowired
public void setUserManager(UserManager userManager) {
this.userManager = userManager;
}
@Autowired
public void setFormViewManager(FormViewManager formManager) {
this.formViewManager = formManager;
}
@Autowired
public void setGeneralDao(GeneralDao generalDao) {
this.generalDao = generalDao;
}
@Autowired
public void setAcsUtils(AcsUtils acsUtils) {
this.acsUtils = acsUtils;
}
@Autowired
public void setWorkflowTypeManager(WorkflowTypeManager workflowTypeManager) {
this.workflowTypeManager = workflowTypeManager;
}
@Autowired
public void setBusinessSystemManager(
BusinessSystemManager businessSystemManager) {
this.businessSystemManager = businessSystemManager;
}
public WorkflowDefinitionFile getWorkflowDefinitionFile(Long wfdId){
return workflowDefinitionFileDao.getWfDefinitionFileByWfdId(wfdId);
}
public Long getSystemId(){
return ContextUtils.getSystemId();
}
public Long getCompanyId(){
return ContextUtils.getCompanyId();
}
public String getLoginName(){
return ContextUtils.getLoginName();
}
/**
* 查询模版列表
* @param typeId
* @param companyId
* @return
*/
public List<WorkflowDefinitionTemplate> getWorkflowDefinitionTemplates(Long typeId) {
return workflowDefinitionTemplateDao.getWorkflowDefinitionTemplates(typeId,this.getCompanyId());
}
/**
* 根据类型Id得到流程
* @param typeId
* @param companyId
* @return
*/
public List<WorkflowDefinition> getWorkflowDefinitionByTypeId(Long typeId,Long companyId) {
return workflowDefinitionDao.getWorkflowDefinition(typeId,this.getCompanyId());
}
/**
* 查询模版的xml(flex 用)
* @param templateId
* @return
*/
public String getTemplateXml(Long templateId){
WorkflowDefinitionTemplateFile file=workflowDefinitionTemplateFileDao.getWorkflowDefinitionTemplateFileByTemplateId(templateId);
if(file!=null) return file.getXml();
return null;
}
/**
* 分页查询流程定义
* @param page
*/
public void getWfDefinitions(Page<WorkflowDefinition> page){
workflowDefinitionDao.getWfDefinitions(page, getCompanyId());
}
/**
* 是否是流程定义管理员
* @return true表示是流程定义管理员,否则则是工作流管理员。工作流管理员可以看见所有的流程
*/
public boolean isSuperWf(){
Set<User> wfManager=acsUtils.getUsersByRole(ContextUtils.getSystemId(), ContextUtils.getCompanyId(), WF_MANAGER_ROLE_CODE);//工作流管理员列表
boolean isSuperWf=false;
for(User user:wfManager){
if(user.getLoginName().equals(ContextUtils.getLoginName())){//如果当前用户既是流程管理员,又是流程定义管理员,则取工作流管理员权限
return false;
}
}
Set<User> defManagers=acsUtils.getUsersByRole(ContextUtils.getSystemId(), ContextUtils.getCompanyId(), DEF_MANAGER_ROLE_CODE);//流程定义管理员
for(User user:defManagers){
if(user.getLoginName().equals(ContextUtils.getLoginName())){
isSuperWf=true;
break;
}
}
return isSuperWf;
}
public void getWfDefinitions(Page<WorkflowDefinition> page,String vertionType,String adminCode){
boolean isSuperWf=isSuperWf();
workflowDefinitionDao.getWfDefinitions(page, getCompanyId(),vertionType,adminCode,isSuperWf);
}
public void getWfDefinitions(Page<WorkflowDefinition> page, Long type) {
workflowDefinitionDao.getWfDefinitions(page, getCompanyId(),type);
}
public void getWfDefinitions(Page<WorkflowDefinition> page, Long type,String vertionType,String adminCode) {
boolean isSuperWf=isSuperWf();
workflowDefinitionDao.getWfDefinitions(page, getCompanyId(),type,vertionType,adminCode,isSuperWf);
}
public void getWfDefinitionsBySystemId(Page<WorkflowDefinition> page, Long systemId) {
workflowDefinitionDao.getWfDefinitionsBySystemId(page, getCompanyId(),systemId);
}
public void getWfDefinitionsBySystemId(Page<WorkflowDefinition> page, Long systemId,String vertionType,String adminCode) {
boolean isSuperWf=isSuperWf();
workflowDefinitionDao.getWfDefinitionsBySystemId(page, getCompanyId(),systemId,vertionType,adminCode,isSuperWf);
}
public void getEnableWfDefinitions(Page<WorkflowDefinition> page){
workflowDefinitionDao.getEnableWfDefinitions(page, getCompanyId());
}
public void getEnableWfDefinitions(Page<WorkflowDefinition> page, Long type){
workflowDefinitionDao.getEnableWfDefinitions(page, getCompanyId(), type);
}
@Transactional(readOnly=false)
public void saveWorkflowDefinition(WorkflowDefinition workflowDefinition){
workflowDefinitionDao.save(workflowDefinition);
}
@Transactional(readOnly=false)
public void saveWorkflowDefinitionFile(WorkflowDefinitionFile workflowDefinitionFile){
workflowDefinitionFileDao.save(workflowDefinitionFile);
}
/**
* 根据流程定义ID查询流程定义(不包含流程定义文件)
* @param id
* @return
*/
public WorkflowDefinition getWfDefinition(Long id){
Assert.notNull(id, "流程定义id不能为null");
return workflowDefinitionDao.get(id);
}
/**
* 通过流程定义ID查询所有的环节名称
* @param jbpmDefinitionId
* @return 环节名封装的集合
*/
public List<String> getTachesByprocessId(String processId){
return DefinitionXmlParse.getTaskNames(processId);
}
/**
* 通过流程定义ID查询所有的环节名称
* @param workflowDefinitionId 定义id
* @return 环节名称封装成的集合
*/
public List<String> getTachesByProcessDefinition(Long workflowDefinitionId){
WorkflowDefinition wfd = getWfDefinition(workflowDefinitionId);
return getTachesByprocessId(wfd.getProcessId());
}
/**
* 查询类型为type所有活动的流程
* @param page
*/
public void getActiveDefinition(Page<WorkflowDefinition> page,Long type){
workflowDefinitionDao.getActiveDefinition(page,
getCompanyId(), DataState.ENABLE,type, getSystemId());
}
/**
* 查询所有活动的流程
* @param page
*/
public void getActiveDefinition(Page<WorkflowDefinition> page){
workflowDefinitionDao.getActiveDefinition(page,
getCompanyId(), DataState.ENABLE, getSystemId());
}
/**
* 根据系统查询所有活动的流程(返回List)
*/
public List<WorkflowDefinition> getActiveDefinition(){
return workflowDefinitionDao.getActiveDefinition(
getCompanyId(), DataState.ENABLE);
}
/**
* 查询所有活动的流程(返回List)
*/
public List<WorkflowDefinition> getAllActiveDefinition(){
return workflowDefinitionDao.getActiveDefinition(
getCompanyId(), DataState.ENABLE);
}
/**
* 查询所有活动的流程(返回List)(flex用)
* 公司Id
*/
public List<WorkflowDefinition> getActiveDefinition(Long companyId,String systemCode){
BusinessSystem system=businessSystemManager.getSystemBySystemCode(systemCode);
if(system!=null) return workflowDefinitionDao.getActiveDefinition(companyId, DataState.ENABLE, system.getId());
return new ArrayList<WorkflowDefinition>();
}
/**
* 查询所有活动的流程(返回List)
*/
public List<WorkflowDefinition> getActiveDefinitionsByForm(String formName){
return workflowDefinitionDao.getActiveDefinitionsByFrom(
getCompanyId(), DataState.ENABLE, formName, getSystemId());
}
public List<WorkflowDefinition> getAllDefinitionsByName(String name,Long companyId){
return workflowDefinitionDao.getAllDefinitionsByName(name,companyId, getSystemId());
}
/**
* 根据流程定义ID查询流程定义(包含流程定义文件)
* @param wfdId
* @return
*/
public WorkflowDefinition getWfdAndXmlFile(Long wfdId){
WorkflowDefinition wfd = workflowDefinitionDao.get(wfdId);
wfd.setWorkflowDefinitionFile(
workflowDefinitionFileDao.getWfDefinitionFileByWfdId(wfdId));
return wfd;
}
/**
* 删除流程定义.启用过的流程定义不会被删除。
* @param wdfIds
* @return 删除的记录数
*/
@Transactional(readOnly=false)
public int deleteWfDefinitions(List<Long> wdfIds){
int deleteNum = 0;
WorkflowDefinition definition = null;
Integer wfInstanceNum = 0;
for(int i=0;i<wdfIds.size();i++){
definition = this.getWfDefinition(wdfIds.get(i));
wfInstanceNum=workflowInstanceDao.getInstancesNumByDefId(wdfIds.get(i), getCompanyId(), definition.getSystemId());
if(definition.getEnable()==DataState.DRAFT
||(definition.getEnable()==DataState.DISABLE&&wfInstanceNum==0)){
workflowDefinitionDao.delete(definition);
workflowDefinitionFileDao.deleteDefinitionFileByWfdId(definition.getId());
deleteNum++;
}
}
return deleteNum;
}
/**
* 根据流程定义ID查询流程定义文件(flex用)
*/
public String getXmlByDefinitionId(Long wfdId, Long companyId){
return workflowDefinitionFileDao.getWfDefinitionFileByWfdId(wfdId, companyId).getDocument();
}
/**
* 创建流程定义(flex用)
*/
@Transactional(readOnly=false)
public Long createWfDefinition(Long companyId, String xmlFile,String typeCode,String systemCode){
ThreadParameters params=new ThreadParameters(companyId);
ParameterUtils.setParameters(params);
WorkflowType type=workflowTypeManager.getWorkflowType(typeCode);
BusinessSystem system=businessSystemManager.getSystemBySystemCode(systemCode);
if(type==null) throw new RuntimeException("创建流程定义时,流程类型不能为null");
if(system==null) throw new RuntimeException("创建流程定义时,系统不能为null");
return saveWorkflowDefinition(null, companyId, xmlFile,type.getId(),system.getId());
}
/**
* 修改流程定义(flex用)
* @param id
* @param xmlFile
*/
@Transactional(readOnly=false)
public Long updateWfDefinition(Long id, Long companyId, String xmlFile,String typeCode,String systemCode){
ThreadParameters params=new ThreadParameters(companyId);
ParameterUtils.setParameters(params);
WorkflowType type=workflowTypeManager.getWorkflowType(typeCode);
BusinessSystem system=businessSystemManager.getSystemBySystemCode(systemCode);
if(type==null) throw new RuntimeException("更新流程定义时,流程类型不能为null");
if(system==null) throw new RuntimeException("更新流程定义时,系统不能为null");
return saveWorkflowDefinition(id, companyId, xmlFile,type.getId(),system.getId());
}
/**
* 修改流程定义,且及时生效
* @param id
* @param xmlFile
*/
@Transactional(readOnly=false)
public Long updateWfDefVersion(Long id, Long companyId, String xmlFile,Long type,Long systemId){
ThreadParameters params=new ThreadParameters(companyId);
ParameterUtils.setParameters(params);
log.debug("*** updatewfDefVersion 方法开始");
Map<String, String> props = DefinitionXmlParse.getProcessBaseInfo(xmlFile);
WorkflowDefinition wfd = workflowDefinitionDao.get(id);
Integer version=wfd.getVersion();
DataState enable=wfd.getEnable();
setWfDefinitionBaseInfo(wfd, props);
//还原版本和状态
wfd.setVersion(version);
wfd.setEnable(enable);
workflowDefinitionDao.save(wfd);
WorkflowDefinitionFile file = workflowDefinitionFileDao.getWfDefinitionFileByWfdId(id,companyId);
file.setDocument(xmlFile);
workflowDefinitionFileDao.save(file);
if(wfd.getEnable()!=DataState.DRAFT){
MemCachedUtils.add(wfd.getProcessId(),file.getDocument());
DocumentThreadParameters parameters = new DocumentThreadParameters();
DocumentParameterUtils.setParameters(parameters);
long a = System.currentTimeMillis();
DefinitionXmlParse.getDefinitionParseInfo(wfd.getProcessId());
DocumentParameterUtils.clearParameter();
long b = System.currentTimeMillis();
System.out.println((b-a)+"---------------updateWfDefVersion");
}
log.debug("*** updatewfDefVersion 方法结束");
return wfd.getId();
}
/**
* 修改流程定义
* @param id
* @param xmlFile
*/
@Transactional(readOnly=false)
public Long updateWfDefinition(Long id, Long companyId, String xmlFile){
return saveWorkflowDefinition(id, companyId, xmlFile,null,getSystemId());
}
/**
* 保存流程定义
* @param id
* @param xmlFile
*/
@Transactional(readOnly=false)
public Long saveWorkflowDefinition(Long id, Long companyId, String xmlFile,Long type,Long systemId){
log.debug("*** saveWorkflowDefinition 方法开始");
log.debug(new StringBuilder("*** Received parameter:[")
.append("id:").append(id)
.append(", companyId:").append(companyId)
.append(", type:").append(type)
.append(", systemId:").append(systemId)
.append("]").toString());
if(id == null){
id = createWorkflowDefinition(companyId, xmlFile, type, systemId);
}else{
id = updateWorkflowDefinition(id, companyId, xmlFile, type, systemId);
}
log.debug("*** saveWorkflowDefinition 方法结束");
return id;
}
/*
* 创建一个新的流程定义
*/
@Transactional(readOnly=false)
private Long createWorkflowDefinition(Long companyId, String xmlFile,Long type,Long systemId){
log.debug("*** createWorkflowDefinition 方法开始");
Map<String, String> props = DefinitionXmlParse.getProcessBaseInfo(xmlFile);
//保存流程定义信息
WorkflowDefinition wfd = createWorkflowDefinition(companyId, props, type, systemId);
workflowDefinitionDao.save(wfd);
//保存流程定义文件
createWorkflowDefinitionFile(xmlFile, wfd.getId(), companyId);
log.debug("*** createWorkflowDefinition 方法结束");
return wfd.getId();
}
@Transactional(readOnly=false)
private WorkflowDefinition createWorkflowDefinition(Long companyId, Map<String, String> props,Long type,Long systemId){
WorkflowDefinition wfd = new WorkflowDefinition();
setWfDefinitionBaseInfo(wfd, props);
wfd.setCompanyId(companyId);
wfd.setTypeId(type);
if(StringUtils.isNotEmpty(props.get(DefinitionXmlParse.SYSTEM_CODE))){
String systemCode=props.get(DefinitionXmlParse.SYSTEM_CODE);
BusinessSystem system=businessSystemManager.getSystemBySystemCode(systemCode);
if(system!=null)wfd.setSystemId(system.getId());
}
wfd.setCustomType(props.get(DefinitionXmlParse.CUSTOME_TYPE));
wfd.setProcessType(ProcessType.PREDEFINED_PROCESS);
wfd.setVersion(workflowDefinitionDao.generateWorkflowDefinitionVersion(
props.get(ProcessProperties.WF_CODE.toString()),companyId, systemId));
return wfd;
}
/*
* 修改流程定义
* 如果流程已经启用过,则为流程增加新版本
*/
@Transactional(readOnly=false)
private Long updateWorkflowDefinition(Long id, Long companyId, String xmlFile,Long type,Long systemId){
log.debug("*** updateWorkflowDefinition 方法开始");
Map<String, String> props = DefinitionXmlParse.getProcessBaseInfo(xmlFile);
WorkflowDefinition wfd = workflowDefinitionDao.get(id);
//2. ID不为空,流程为草稿状态,直接保存
if(wfd.getEnable()==DataState.DRAFT){
log.debug("*** 保存为草稿");
if(StringUtils.isNotEmpty(props.get(DefinitionXmlParse.SYSTEM_CODE))){
String systemCode=props.get(DefinitionXmlParse.SYSTEM_CODE);
BusinessSystem system=businessSystemManager.getSystemBySystemCode(systemCode);
if(system!=null)wfd.setSystemId(system.getId());
}
wfd.setCustomType(props.get(DefinitionXmlParse.CUSTOME_TYPE));
log.debug("*** setWfDefinitionBaseInfo开始**");
log.debug("*** wfd="+wfd+"**props="+props);
setWfDefinitionBaseInfo(wfd, props);
log.debug("*** setWfDefinitionBaseInfo结束**");
log.debug("*** workflowDefinitionDao.save开始**");
workflowDefinitionDao.save(wfd);
log.debug("*** workflowDefinitionDao.save结束**");
log.debug("*** workflowDefinitionFileDao.getWfDefinitionFileByWfdId***wfdId="+id);
WorkflowDefinitionFile file = workflowDefinitionFileDao.getWfDefinitionFileByWfdId(id,companyId);
log.debug("*** file***companyId="+file.getCompanyId());
log.debug("*** file.setDocument开始");
file.setDocument(xmlFile);
log.debug("*** file.setDocument结束");
log.debug("*** workflowDefinitionFileDao.save开始***file="+file);
workflowDefinitionFileDao.save(file);
log.debug("*** workflowDefinitionFileDao.save结束***file="+file);
}else {
//2. ID不为空,流程已经启用过,复制保存
log.debug("*** 流程已经启用过, 增加新版本");
wfd = createWorkflowDefinition(companyId, props, type, systemId);
workflowDefinitionDao.save(wfd);
createWorkflowDefinitionFile(xmlFile, wfd.getId(), companyId);
}
log.debug("*** updateWorkflowDefinition 方法结束");
return wfd.getId();
}
/*
* 创建流程定义文件
*/
@Transactional(readOnly=false)
private void createWorkflowDefinitionFile(String xmlFile, Long workflowDefinitionId, Long companyId){
log.debug("*** createWorkflowDefinitionFile 方法开始");
WorkflowDefinitionFile file = new WorkflowDefinitionFile();
log.debug("*** setXmlFile开始***");
file.setDocument(xmlFile);
log.debug("*** setXmlFile结束***");
log.debug("*** setWfDefinitionId开始***");
file.setWfDefinitionId(workflowDefinitionId);
log.debug("*** setWfDefinitionId结束***workflowDefinitionId="+workflowDefinitionId);
log.debug("*** setCompanyId开始***");
file.setCompanyId(companyId);
log.debug("*** setCompanyId结束***companyId="+companyId);
log.debug("*** save开始***");
workflowDefinitionFileDao.save(file);
log.debug("*** save结束***");
log.debug("*** createWorkflowDefinitionFile 方法结束");
}
/*
* 设置流程定义的基本属性
*/
@Transactional(readOnly=false)
private void setWfDefinitionBaseInfo(WorkflowDefinition wfd, Map<String, String> props){
if(StringUtils.isNotEmpty(props.get(ProcessProperties.WF_TYPE.toString()))){
wfd.setTypeId(Long.valueOf(props.get(ProcessProperties.WF_TYPE.toString())));
}
if(StringUtils.isNotEmpty(props.get(ProcessProperties.WF_TYPE_CODE.toString()))){
String typeCode=props.get(ProcessProperties.WF_TYPE_CODE.toString());
WorkflowType type=workflowTypeManager.getWorkflowType(typeCode);
if(type!=null)wfd.setTypeId(type.getId());
}
wfd.setName(props.get(KEY_OF_PROCESS_NAME_IN_XML));
wfd.setCode(props.get(ProcessProperties.WF_CODE.toString()));
wfd.setCreator(props.get(ProcessProperties.WF_CREATOR.toString()));
if(userManager.getUserByLoginName(wfd.getCreator())!=null){
wfd.setCreatorName(userManager.getUserByLoginName(wfd.getCreator()).getName());
}
wfd.setFormName(props.get(ProcessProperties.WF_FORM.toString()));
wfd.setFormCode(props.get(ProcessProperties.WF_FORM_CODE.toString()));
String formVersion = props.get(ProcessProperties.WF_FORM_VERSION.toString());
wfd.setFromVersion(StringUtils.isNotEmpty(formVersion)
? Integer.parseInt(formVersion) : null);
String admin = props.get(ProcessProperties.WF_ADMIN.toString());
if(admin != null){
String[] names = admin.split(DELTA_START_REGEXP);
wfd.setAdminName(names[0]);
wfd.setAdminLoginName(names[1].replace(DELTA_END, EMPTY_STRING));
}
wfd.setEnable(DataState.DRAFT);
String createdTime = props.get(ProcessProperties.WF_CREATED_TIME.toString());
if(createdTime != null && createdTime.length() == TIME_STRING_LENGTH){
wfd.setCreatedTime(stringToDate(createdTime));
}
if(StringUtils.isNotEmpty(props.get(DefinitionXmlParse.SYSTEM_CODE))){
String systemCode=props.get(DefinitionXmlParse.SYSTEM_CODE);
BusinessSystem system=businessSystemManager.getSystemBySystemCode(systemCode);
if(system!=null)wfd.setSystemId(system.getId());
}
wfd.setCustomType(props.get(DefinitionXmlParse.CUSTOME_TYPE));
}
/**
* 流程启用与禁用
* @param standardXml
* @param extendXml
* @return
* @throws UnsupportedEncodingException
*/
@Transactional(readOnly=false)
public String deployProcess(Long wfdId) throws UnsupportedEncodingException{
log.debug("*** deployProcess 方法开始");
log.debug(new StringBuilder("*** Received parameter:[")
.append("wfdId:").append(wfdId)
.append("]").toString());
String message = "";
WorkflowDefinition wfd = workflowDefinitionDao.get(wfdId);
//如果流程为启用状态,设置为禁用 ,如果是禁用状态,设置为启用
if(wfd.getEnable()==DataState.ENABLE){
log.debug("*** 启用 -> 禁用");
wfd.setEnable(DataState.DISABLE);
message = "启用 -> 禁用";
}else if(wfd.getEnable()==DataState.DISABLE){
log.debug("*** 禁用 -> 启用");
//disableOtherProcess(wfd);
wfd.setEnable(DataState.ENABLE);
message = "禁用 -> 启用";
}else{
if(ProcessType.PREDEFINED_PROCESS.equals(wfd.getProcessType())){
log.debug("*** 草稿 -> 启用");
//如果是草稿状态,部署流程并设置为启用
WorkflowDefinitionFile file = workflowDefinitionFileDao.getWfDefinitionFileByWfdId(wfdId);
log.debug("file:"+file);
try {
String processKey = processEngine.getRepositoryService().createDeployment()
.addResourceFromInputStream(wfd.getName() + JBPM_DEFINITION_FILE_EXTENSION,
new ByteArrayInputStream(DefinitionXmlParse.getStandardXml4Jbpm(file.getDocument(),wfd.getId()).getBytes(ENCODING_UTF_8)))
.deploy();
ProcessDefinition pd = processEngine.getRepositoryService()
.createProcessDefinitionQuery().deploymentId(processKey).uniqueResult();
//将流程定义文件放入cache
MemCachedUtils.add(pd.getId(), file.getDocument());
wfd.setProcessId(pd.getId());
DocumentThreadParameters parameters = new DocumentThreadParameters();
DocumentParameterUtils.setParameters(parameters);
// MemCachedUtils.add("document="+wfd.getProcessId(), Dom4jUtils.getDocument(file.getDocument()));
DefinitionXmlParse.getDefinitionParseInfo(wfd.getProcessId());
DocumentParameterUtils.clearParameter();
} catch (Exception e) {
log.debug(e);
log.debug("jbpm部署异常",e);
}
}else{
wfd.setProcessId("workflow_"+wfd.getId()+"_1");
}
//disableOtherProcess(wfd);
wfd.setEnable(DataState.ENABLE);
saveWorkflowDefinition(wfd);
message = "草稿 -> 启用";
}
log.debug("*** deployProcess 方法结束");
return message;
}
/**
* 获得最新版本的流程定义
* @param name
* @param companyId
* @return
*/
public WorkflowDefinition getLatestVersion(String name, Long companyId){
return workflowDefinitionDao.getLatestVersion(name, companyId, getSystemId());
}
/**
* 获得最新版本的流程定义
* @param name
* @param companyId
* @return
*/
public WorkflowDefinition getEnabledHighestVersionWorkflowDefinition(String code){
if(StringUtils.isEmpty(code)) throw new RuntimeException("没有给定查询最新版本流程定义的查询条件: 流程定义编号. ");
Assert.notNull(getSystemId(), "systemId不能为null");
Assert.notNull(getCompanyId(), "companyId不能为null");
return workflowDefinitionDao.getEnabledHighestVersionWorkflowDefinition(code, getCompanyId(), getSystemId());
}
/**
* 获得最新版本的流程定义
* @param name
* @param companyId
* @return
*/
public WorkflowDefinition getEnabledHighestVersionWorkflowDefinitionBySystem(String code,Long systemId){
if(StringUtils.isEmpty(code)) throw new RuntimeException("没有给定查询最新版本流程定义的查询条件: 流程定义编号. ");
Assert.notNull(systemId, "systemId不能为null");
Assert.notNull(getCompanyId(), "companyId不能为null");
return workflowDefinitionDao.getEnabledHighestVersionWorkflowDefinition(code, getCompanyId(), systemId);
}
/**
* 获得最新版本的流程定义
* @param name
* @param companyId
* @return
*/
public WorkflowDefinition getEnabledHighestVersionWorkflowDefinition(String code,Long companyId){
return workflowDefinitionDao.getEnabledHighestVersionWorkflowDefinition(code, companyId, getSystemId());
}
/**
* 初始化系统中的所有流程定义,仅供Listener调用
*/
@Transactional(readOnly=false)
public void initWorkflowDefinition(){
List<Object[]> wfdAndFile = workflowDefinitionDao.getAllDefinitionAndFile(getSystemId());
for(Object[] objs : wfdAndFile){
WorkflowDefinition wfd = (WorkflowDefinition) objs[0];
WorkflowDefinitionFile wfdf = (WorkflowDefinitionFile) objs[1];
MemCachedUtils.add(wfd.getProcessId(), wfdf.getDocument());
}
}
/**
* 初始化所有的流程定义,仅供Listener调用
*/
@Transactional(readOnly=false)
public void initAllWorkflowDefinition(){
DocumentThreadParameters parameters = new DocumentThreadParameters();
DocumentParameterUtils.setParameters(parameters);
List<Object[]> wfdAndFile = workflowDefinitionDao.getAllDefinitionAndFile();
if(PropUtils.getProp("project.model")==null||PropUtils.getProp("project.model").equals("product.model")){//默认是产品模式,或配置的是产品模式时
int i=0;
for(Object[] objs : wfdAndFile){
WorkflowDefinition wfd = (WorkflowDefinition) objs[0];
WorkflowDefinitionFile wfdf = (WorkflowDefinitionFile) objs[1];
MemCachedUtils.add(wfd.getProcessId(), wfdf.getDocument());
if(wfd.getEnable()==DataState.ENABLE){
System.out.println(i+"=正在加载流程【"+wfd.getName()+"】......");
DefinitionXmlParse.getDefinitionParseInfo(wfd.getProcessId());
DocumentParameterUtils.clearParameter();
i++;
}
}
}else{//开发模式时
for(Object[] objs : wfdAndFile){
WorkflowDefinition wfd = (WorkflowDefinition) objs[0];
WorkflowDefinitionFile wfdf = (WorkflowDefinitionFile) objs[1];
MemCachedUtils.add(wfd.getProcessId(), wfdf.getDocument());
}
}
}
/**
* 通过流程定义的Key和version查询WorkflowDefinition
* @param key
* @param version
* @return
*/
public WorkflowDefinition getWorkflowDefinitionByProcessId(String processId){
return workflowDefinitionDao.findUniqueNoCompanyCondition("from WorkflowDefinition def where def.processId=? ", processId);
}
@Autowired
public void setProcessEngine(ProcessEngine processEngine) {
this.processEngine = processEngine;
}
@Autowired
public void setWorkflowDefinitionDao(WorkflowDefinitionDao workflowDefinitionDao) {
this.workflowDefinitionDao = workflowDefinitionDao;
}
@Autowired
public void setWorkflowDefinitionFileDao(
WorkflowDefinitionFileDao workflowDefinitionFileDao) {
this.workflowDefinitionFileDao = workflowDefinitionFileDao;
}
@Autowired
public void setWorkflowDefinitionTemplateDao(
WorkflowDefinitionTemplateDao workflowDefinitionTemplateDao) {
this.workflowDefinitionTemplateDao = workflowDefinitionTemplateDao;
}
/**
* 将字符装换成日期类型
* @param source "yyyy-MM-dd HH:mm:ss"
* @return
*/
public static Date stringToDate(String source){
SimpleDateFormat dateFormat = new SimpleDateFormat(TIME_FORMAT_STRING);
try {
return dateFormat.parse(source);
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
public List<String> getTaskNames(String processDefinitionId) {
if(StringUtils.isEmpty(processDefinitionId)||"0".equals(processDefinitionId))return new ArrayList<String>();
return DefinitionXmlParse.getTaskNames(processDefinitionId);
}
public List<Long> getList(String ids){
String[] dids=ids.split(",");
List<Long> id=new ArrayList<Long>();
for(int i=0;i<dids.length;i++){
id.add(Long.parseLong(dids[i]));
}
return id;
}
public WorkflowDefinitionTemplate getWorkflowDefinitionTemplate(
Long templateId) {
return workflowDefinitionTemplateDao.get(templateId);
}
public Integer generateWorkflowDefinitionVersion(String name) {
return workflowDefinitionDao.generateWorkflowDefinitionVersion(name, getCompanyId(), getSystemId());
}
/**
* 流程监控
*/
public void monitor(Page<Object> page,WorkflowDefinition definition) {
searchMonitor(page,definition,null);
}
/**
* 流程监控
*/
public void monitorDefinition(Page<Object> page,Long typeId,String defCode) {
searchManagerMonitor(page,typeId,defCode,null);
}
public void searchManagerMonitor(Page<Object> page,Long typeId,String defCode,List<ListColumn> fields){
monitorWorkflowDefinition(page,typeId,defCode,fields);
}
/**
* 流程监控(查询)
*/
public void searchMonitor(Page<Object> page,
WorkflowDefinition definition,
List<ListColumn> fields){
FormView form = formViewManager.getCurrentFormViewByCodeAndVersion(definition.getFormCode(), definition.getFromVersion());
// if(form.isStandardForm()){
// monitorStandardWorkflowDefinition(page,definition,form,fields);
// }else{
monitorDefaultWorkflowDefinition(page,definition,form,fields);
// }
}
private void monitorDefaultWorkflowDefinition(Page<Object> page,
WorkflowDefinition definition, FormView form, List<ListColumn> searchField) {
StringBuilder sql = new StringBuilder(
);
List<Object> objs = new ArrayList<Object>();
sql.append(" from ").append(" WorkflowInstance wi ")
.append(" where wi.processState<>? and wi.workflowDefinitionId=?");
sql.append(" order by wi.submitTime desc ");
objs.add(ProcessState.UNSUBMIT);
objs.add(definition.getId());
generalDao.searchPageByHql(page, sql.toString(),objs.toArray());
}
@SuppressWarnings("deprecation")
public void monitorWorkflowDefinition(Page<Object> page,
Long typeId, String defCode,List<ListColumn> searchField) {
StringBuilder hql = new StringBuilder("select wi ");
List<Object> objs = new ArrayList<Object>();
objs.add(ProcessState.UNSUBMIT);
boolean isSuperWf=isSuperWf();
if(isSuperWf){//是否是流程定义管理员
hql.append(" from ").append(" WorkflowInstance wi , WorkflowDefinition wfd ").append("where wi.processState<>? and wi.workflowDefinitionId=wfd.id and wfd.adminLoginName=? ");
objs.add(getLoginName());
}else{
hql.append(" from ").append(" WorkflowInstance wi , WorkflowDefinition wfd ").append("where wi.processState<>? and wi.workflowDefinitionId=wfd.id ");
}
if(typeId!=null && typeId.intValue() != 0){
hql.append("and wi.typeId = ? ");
objs.add(typeId);
}
if(StringUtils.isNotEmpty(defCode)){
hql.append("and wi.processCode=? ");
objs.add(defCode);
}
hql.append("and wi.companyId = ? ");
objs.add(getCompanyId());
if(searchField!=null && !searchField.isEmpty()){
String temp2 = " and wi.";
for(ListColumn field:searchField){
hql.append(temp2).append(field.getTableColumn().getName()).append(" ").append(field.getTableColumn().getOperate()).append(" ?");
try {
if(DataType.DATE.toString().equalsIgnoreCase(field.getTableColumn().getDataType().getEnumName())){
objs.add(JdbcSupport.SIMPLEDATEFORMAT1.parse(field.getTableColumn().getSearchValue()));
}else if(DataType.TIME.toString().equalsIgnoreCase(field.getTableColumn().getDataType().getEnumName())){
objs.add(JdbcSupport.SIMPLEDATEFORMAT2.parse(field.getTableColumn().getSearchValue()));
}else if(DataType.AMOUNT.toString().equalsIgnoreCase(field.getTableColumn().getDataType().getEnumName())){
objs.add(Double.valueOf(field.getTableColumn().getSearchValue()));
}else if(DataType.NUMBER.toString().equalsIgnoreCase(field.getTableColumn().getDataType().getEnumName())){
objs.add(Integer.valueOf(field.getTableColumn().getSearchValue()));
}else{
if(field.getTableColumn().getOperate().equals("like")||field.getTableColumn().getOperate().equals("not like")){
objs.add("%"+field.getTableColumn().getSearchValue()+"%");
}else{
if(field.getTableColumn().getName().equals("processState")){
objs.add(ProcessState.valueOf((short)Integer.parseInt(field.getTableColumn().getSearchValue())));
}else{
objs.add(field.getTableColumn().getSearchValue());
}
}
}
} catch (NumberFormatException e) {
log.debug("字段:'"+field.getTableColumn().getAlias()+"'的searchValue不是数字格式。");
throw new RuntimeException(e);
} catch (ParseException e) {
log.debug("字段:'"+field.getTableColumn().getAlias()+"'的searchValue不是日期格式。");
throw new RuntimeException(e);
}
}
}
hql.append(" order by wi.submitTime desc ");
generalDao.searchPageByHql(page, hql.toString(),objs.toArray());
}
public List<Long> getAllDefinitionIdNotDraft(WorkflowDefinition definition) {
return workflowDefinitionDao.getAllDefinitionIdNotDraft(definition);
}
public List<WorkflowDefinition> getAllEnableDefinitionsByformCodeAndVersion(String code, Integer version) {
return workflowDefinitionDao.getAllEnableDefinitonsByFormCodeAndVersion(code, version);
}
public List<WorkflowDefinition> getCommonEnableDefinitionsByformCodeAndVersion(String code, Integer version) {
return workflowDefinitionDao.getCommonEnableDefinitonsByFormCodeAndVersion(code, version);
}
public WorkflowDefinition getEnabledWorkflowDefinitionByCodeAndVersion(String definitionCode,
Integer definitionVersion,Long companyId){
return workflowDefinitionDao.getEnabledWorkflowDefinitionByCodeAndVersion(definitionCode,definitionVersion,companyId);
}
public WorkflowDefinition getWorkflowDefinitionByCodeAndVersion(String definitionCode,
Integer definitionVersion,Long companyId,Long systemId){
if(StringUtils.isEmpty(definitionCode)) throw new RuntimeException("没有给定查询流程定义的查询条件:流程定义编号");
if(definitionVersion == null) throw new RuntimeException("没有给定查询流程定义的查询条件:流程定义版本号");
if(companyId == null) throw new RuntimeException("没有给定查询流程定义的查询条件:公司ID");
if(systemId == null) throw new RuntimeException("没有给定查询流程定义的查询条件:系统ID");
return workflowDefinitionDao.getWorkflowDefinitionByCodeAndVersion(definitionCode,definitionVersion,companyId,systemId);
}
public WorkflowDefinition getWorkflowDefinitionByCodeAndVersion(String definitionCode,
Integer definitionVersion,Long companyId,boolean isSuperWf){
return workflowDefinitionDao.getWorkflowDefinitionByCodeAndVersion(definitionCode,definitionVersion,companyId,isSuperWf);
}
public List<WorkflowDefinition> getWfDefinitionsByType(Long companyId,Long typeId){
return workflowDefinitionDao.getWfDefinitionsByType(companyId,typeId);
}
public List<String> getWfDefinitionCodesByType(Long companyId,Long typeId){
return workflowDefinitionDao.getWfDefinitionCodesByType(companyId,typeId);
}
public List<WorkflowDefinition> getWfDefinitionsByCode(String code){
if(StringUtils.isEmpty(code)) throw new RuntimeException("没有给定查询流程定义的查询条件:流程编号");
return workflowDefinitionDao.getWfDefinitionsByCode(getCompanyId(), code);
}
public WorkflowDefinitionFile getWfDefinitionFileByWfdId(Long wfdId, Long companyId){
return workflowDefinitionFileDao.getWfDefinitionFileByWfdId(wfdId, companyId);
}
public List<WorkflowDefinition> getWfDefinitions(Long companyId,String systemIds){
return workflowDefinitionDao.getWfDefinitions(companyId, systemIds);
}
public void saveWfBasic(WorkflowDefinition definition){
workflowDefinitionDao.save(definition);
try{
WorkflowDefinitionFile defFile=workflowDefinitionFileDao.getWfDefinitionFileByWfdId(definition.getId());
if(defFile!=null){
Document document=Dom4jUtils.getDocument(defFile.getDocument());
Element root = document.getRootElement();
Element basePropElement = Dom4jUtils.getElementByPath(root, "extend:basic-properties");
Element propElement = null;
List<Element> tableList = document.selectNodes("process");
Iterator it = tableList.iterator();
while(it.hasNext()){//只会循环一次
Element element = (Element)it.next();
Attribute attr=element.attribute("name");
attr.setValue(definition.getName());
}
propElement = Dom4jUtils.getSubElementByName(basePropElement, "admin");
propElement.setText(definition.getAdminName()+"["+definition.getAdminLoginName()+"]");
propElement = Dom4jUtils.getSubElementByName(basePropElement, "process-type-code");
WorkflowType type=workflowTypeManager.getWorkflowType(definition.getTypeId());
if(type!=null)propElement.setText(type.getCode());
propElement = Dom4jUtils.getSubElementByName(basePropElement, "process-type-name");
if(type!=null)propElement.setText(type.getName());
propElement = Dom4jUtils.getSubElementByName(basePropElement, "system-name");
BusinessSystem system=businessSystemManager.getBusiness(definition.getSystemId());
if(system!=null)propElement.setText(system.getName());
propElement = Dom4jUtils.getSubElementByName(basePropElement, "system-code");
if(system!=null)propElement.setText(system.getCode());
propElement = Dom4jUtils.getSubElementByName(basePropElement, "custom-type");
propElement.setText(definition.getCustomType());
defFile.setDocument(document.asXML());
workflowDefinitionFileDao.save(defFile);
}
}catch (Exception e) {
log.debug(PropUtils.getExceptionInfo(e));
}
}
/**
* 根据流程名称模糊查询某类别下的流程
* @param companyId
* @param typeId
* @return
*/
public List<WorkflowDefinition> getWfDefinitionsByName(Long companyId, Long typeId,String name){
return workflowDefinitionDao.getWfDefinitionsByName(companyId, typeId, name);
}
}