SSH與工作流Activiti的集成開發

Activiti 數據庫表結構說明:

數據庫表結構說明:

·             ACT_GE_PROPERTY:屬性數據表。存儲整個流程引擎級別的數據。

1. NAME_:屬性名稱

2. VALUE_:屬性值

3. REV_INT:版本號?

·             ACT_GE_BYTEARRAY:用來保存部署文件的大文本數據的。

1. ID_:資源文件編號,自增長

2. REV_INT:版本號?

3. NAME_:資源文件名稱

4. DEPLOYMENT_ID_:來自於父表ACT_RE_DEPLOYMENT中的主鍵

5. BYTES_:大文本類型,存儲文本字節流

·             ACT_RE_DEPLOYMENT:用來存儲部署時需要被持久化保存下來的信息。

1. ID_:部署編號,自增長

2. NAME_:部署的包名稱

3. DEPLOY_TIME_:部署時間

·             ACT_RE_PROCDEF:業務流程定義數據表。

1. ID_:流程ID,由“流程編號:流程版本號:自增長ID ” 組成

2. CATEGORY_:流程命令空間(該編號就是流程文件targetNamespace的屬性值)

3. NAME_:流程名稱(該編號就是流程文件process元素的name屬性值)

4. KEY_:流程編號(該編號就是流程文件process元素的id屬性值)

5. VERSION_:流程版本號(由程序控制,新增即爲1,修改後依次加1來完成的)

6. DEPLOYMENT_ID_:部署編號

7. RESOURCE_NAME_:資源文件名稱

8. DGRM_RESOURCE_NAME_:圖片資源文件名稱

9. HAS_START_FORM_KEY_:是否有Start Form Key。

注意:此表與ACT_RE_DEPLOYMENT是多對一的關係,即,一個部署的bar包裏可能包含多個流程定義文件,每個流程定義文件都會有一條記錄在ACT_RE_PROCDEF表內,每條流程定義的數據,都會對應ACT_GE_BYTEARRAY表內的一個資源文件和PNG圖片文件。與ACT_GE_BYTEARRAY的關聯是通過程序用ACT_GE_BYTEARRAY.NAME_ACT_RE_PROCDEF.RESOURCE_NAME_完成的,在數據庫表結構內沒有體現。

·             ACT_ID_GROUP:用來保存用戶組信息。

1. ID_:用戶組名

2. REV_INT:版本號?

3. NAME_:用戶組描述信息

4. TYPE_:用戶組類型

·             ACT_ID_MEMBERSHIP:用來保存用戶分組信息。

1. USER_ID_:用戶名

2. GROUP_ID_:用戶組名

·             ACT_ID_USER:用來保存用戶信息。

1. ID_:用戶名

2. REV_INT:版本號?

3. FIRST_:用戶名稱

4. LAST_:用戶姓氏

5. EMAIL_:郵箱

6. PWD_:登錄密碼

·             ACT_RU_EXECUTION:

1. ID_:

2. REV_:版本號?

3. PROC_INST_ID_:流程實例編號

4. BUSINESS_KEY_:業務編號

5. PARENT_ID_:

6. PROC_DEF_ID_:流程ID

7. SUPER_EXEC_:

8. ACT_ID_:

9. IS_ACTIVE_:

10.            IS_CONCURRENT_:

11.            IS_SCOPE_:

·             ACT_RU_JOB:運行時定時任務數據表。

1. ID_:

2. REV_:

3. TYPE_:

4. LOCK_EXP_TIME_:

5. LOCK_OWNER_:

6. EXCLUSIVE_:

7. EXECUTION_ID_:

8. PROCESS_INSTANCE_ID_:

9. RETRIES_:

10.            EXCEPTION_STACK_ID_:

11.            EXCEPTION_MSG_:

12.            DUEDATE_:

13.            REPEAT_:

14.            HANDLER_TYPE_:

15.            HANDLER_CFG_:

·             ACT_RU_TASK:運行時任務數據表。

1. ID_:

2. REV_:

3. EXECUTION_ID_:

4. PROC_INST_ID_:

5. PROC_DEF_ID_:

6. NAME_:

7. DESCRIPTION_:

8. TASK_DEF_KEY_:

9. ASSIGNEE_:

10.            PRIORITY_:

11.            CREATE_TIME_:

·             ACT_RU_IDENTITYLINK:任務參與者數據表。主要存儲當前節點參與者的信息。

1. ID_:

2. REV_:

3. GROUP_ID_:

4. TYPE_:

5. USER_ID_:

6. TASK_ID_:

·             ACT_RU_VARIABLE:運行時流程變量數據表。

1. ID_:

2. REV_:

3. TYPE_:

4. NAME_:

5. EXECUTION_ID_:

6. PROC_INST_ID_:

7. TASK_ID_:

8. BYTEARRAY_ID_:

9. DOUBLE_:

10.            LONG_:

11.            TEXT_:

12.            TEXT2_:

·             ACT_HI_PROCINST:

·             ACT_HI_ACTINST:

·             ACT_HI_TASKINST:

·             ACT_HI_DETAIL:

3、結論及改造建議

  •  
    • 流程文件部署主要涉及到3個表,分別是:ACT_GE_BYTEARRAY、ACT_RE_DEPLOYMENT、ACT_RE_PROCDEF。主要完成“部署包”-->“流程定義文件”-->“所有包內文件”的解析部署關係。從表結構中可以看出,流程定義的元素需要每次從數據庫加載並解析,因爲流程定義的元素沒有轉化成數據庫表來完成,當然流程元素解析後是放在緩存中的,具體的還需要後面詳細研究。
    • 流程定義中的java類文件不保存在數據庫裏 。
    • 組織機構的管理相對較弱,如果要納入單點登錄體系內還需要改造完成,具體改造方法有待研究。
    • 運行時對象的執行與數據庫記錄之間的關係需要繼續研究
    • 歷史數據的保存及作用需要繼續研究。 

       
  • 集成到SSH中所需jar包:

mybatis最新jar包+

 

配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="
 http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
 http://www.springframework.org/schema/tx
 http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
 ">

 <!-- Activiti Configcation -->
 <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration"> 
        <property name="dataSource" ref="dataSource" /> 
        <property name="transactionManager" ref="transactionManager" /> 
        <property name="databaseSchemaUpdate" value="true" /> 
        <property name="databaseType" value="mysql" /> 
        <property name="jobExecutorActivate" value="false" /> 
        <property name="history" value="full" /> 
      
       <property name="beans"> 
            <map> 
                <entry key="ITResReqsProcess_CurrentDepartmentApproval" value="DevDepartment"/> 
                <entry key="ITResReqsProcess_ITDepartmentApprova" value="ITDepartment"/> 
                <entry key="ITResReqsProcess_OperationMaintenanceDepartmentApproval" value="OperationMaintenanceDepartment"/> 
            </map> 
        </property> 
    </bean> 
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean" > 
        <property name="processEngineConfiguration" ref="processEngineConfiguration" /> 
    </bean> 
    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" /> 
    <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" /> 
    <bean id="formService" factory-bean="processEngine" factory-method="getFormService" /> 
    <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" /> 
    <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" /> 
    <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" /> 
    <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" /> 
 <!--<bean id="userBean" class="org.activiti.spring.test.UserBean">   
  <property name="runtimeService" ref="runtimeService" /> 
 </bean> 
 <bean id="printer" class="org.activiti.spring.test.Printer" />-->
 
</beans>

 

 

工作流查詢代碼(僅選取可關鍵部分的代碼),如需全部源碼,請發送郵件到我的郵箱索取([email protected]):

package com.workflow.service.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import org.activiti.engine.ActivitiException;
import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.runtime.ProcessInstanceQuery;
import org.activiti.spring.ProcessEngineFactoryBean;
import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.jeecg.pageModel.DataGrid;
import com.jeecg.service.impl.BaseServiceImpl;
import com.workflow.pageModel.Activiti;
import com.workflow.pageModel.ActivitiInstance;
import com.workflow.service.ActivitiServiceI;

/**
 * Activiti Service 工作流
 * <p>
 * ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
 * RuntimeService runtimeService = processEngine.getRuntimeService();
 * RepositoryService repositoryService = processEngine.getRepositoryService();
 * TaskService taskService = processEngine.getTaskService(); ManagementService
 * managementService = processEngine.getManagementService(); IdentityService
 * identityService = processEngine.getIdentityService(); HistoryService
 * historyService = processEngine.getHistoryService(); FormService formService =
 * processEngine.getFormService();
 * 這些服務的名稱是相當一目瞭然的。更多關於服務和引擎 API
 * </p>
 *
 * @author HurryJiang
 *
 */
@Service("activitiService")
public class ActivitiServiceImpl extends BaseServiceImpl implements
  ActivitiServiceI {
 private static final Logger logger = Logger.getLogger(ActivitiServiceImpl.class);
 private static final String SORTBY_ID = "id";
 private static final String SORTBY_INSTANCEID = "processInstanceId";
 private static final String SORTBY_DEPLOYEMENTID = "deploymentId";
 private static final String SORTBY_NAME = "name";
 private static final String SORTBY_VERSION = "version";
 private static final String SORTBY_KEY = "key";
 private static final String SORTBY_CATEGORY = "category";
 
 private static final String ORDERBY_ASC = "asc";
 private static final String ORDERBY_DESC = "desc";
 
 private ProcessEngineFactoryBean processEngine;
 private RepositoryService repositoryService;
 private RuntimeService runtimeService;
 private FormService formService;
 private IdentityService identityService;
 private TaskService taskService;
 private WorkflowTraceService traceService;
 private HistoryService historyService;
 private ManagementService managementService;
 
 public ActivitiServiceImpl(){

 }
 /**
  * Get ActivitiEngine
  *
  * @return
  */
 public ProcessEngineFactoryBean getProcessEngine() {
  return processEngine;
 }

 @Autowired
 public void setProcessEngine(ProcessEngineFactoryBean processEngine) {
  this.processEngine = processEngine;
 }

 public RuntimeService getRuntimeService() {
  return runtimeService;
 }

 @Autowired
 public void setRuntimeService(RuntimeService runtimeService) {
  this.runtimeService = runtimeService;
 }

 public FormService getFormService() {
  return formService;
 }

 @Autowired
 public void setFormService(FormService formService) {
  this.formService = formService;
 }

 public IdentityService getIdentityService() {
  return identityService;
 }

 @Autowired
 public void setIdentityService(IdentityService identityService) {
  this.identityService = identityService;
 }

 public TaskService getTaskService() {
  return taskService;
 }

 @Autowired
 public void setTaskService(TaskService taskService) {
  this.taskService = taskService;
 }

 public HistoryService getHistoryService() {
  return historyService;
 }

 @Autowired
 public void setHistoryService(HistoryService historyService) {
  this.historyService = historyService;
 }

 public ManagementService getManagementService() {
  return managementService;
 }

 @Autowired
 public void setManagementService(ManagementService managementService) {
  this.managementService = managementService;
 }

 public RepositoryService getRepositoryService() {
  return repositoryService;
 }
 @Autowired
 public void setRepositoryService(RepositoryService repositoryService) {
  this.repositoryService = repositoryService;
 }

 @Transactional(propagation = Propagation.SUPPORTS)
 public DataGrid datagrid(Activiti entity) {
  DataGrid j = new DataGrid();
  /*
      * 查詢兩個對象,一個是ProcessDefinition(流程定義),一個是Deployment(流程部署)
      */
  ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
  //查詢總數
  long total = query.count();
  //查詢分頁記錄(根據條件)
  if(entity.getSort()!=null){
   if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_ID)){
    query = query.orderByProcessDefinitionId();
   }else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_NAME)){
    query = query.orderByProcessDefinitionName();
   }else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_CATEGORY)){
    query = query.orderByProcessDefinitionCategory();
   }else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_KEY)){
    query = query.orderByProcessDefinitionKey();
   }else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_VERSION)){
    query = query.orderByProcessDefinitionVersion();
   }else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_DEPLOYEMENTID)){
    query = query.orderByDeploymentId();
   }
  }
  if(entity.getOrder()!=null){
   if( entity.equals(ActivitiServiceImpl.ORDERBY_DESC)){
    query = query.desc();
   }else{
    query = query.asc();
   }
  }
  if(entity.getRows()>0 && entity.getPage()>=0){//分頁查詢
   query.listPage((entity.getPage() - 1) * entity.getRows(), entity.getRows() );//listPage(int firstResult, int maxResults);
  }
     List<ProcessDefinition> processDefinitionList = query.list();
    
  j.setRows(getActivitisFromProcessDefinitions(processDefinitionList));
  j.setTotal(total);
  return j;
 }

 private List<Activiti> getActivitisFromProcessDefinitions(List<ProcessDefinition> defs) {
  List<Activiti> acts = new ArrayList<Activiti>();
  if (defs != null && defs.size() > 0) {
   for (ProcessDefinition tb : defs) {
    Activiti b = new Activiti();
    BeanUtils.copyProperties(tb, b);
    String deploymentId = tb.getDeploymentId();
       Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
    if(deployment!=null){
     b.setDeploymentTime(deployment.getDeploymentTime());
     b.setCategory(deployment.getCategory());
    }
       acts.add(b);
   }
  }
  return acts;
 }

 private String addWhere(Activiti entity, String hql, List<Object> values) {
  return hql;
 }

 public void add(Activiti entity) {
  logger.debug("add...");
 }

 public void update(Activiti entity) {
  logger.debug("update...");
 }

 /**
  * 可選擇級聯刪除
  * @param ids
  */
 public void deleteByCascade(String ids,boolean cascade) {
  if (ids != null) {
   for (String id : ids.split(",")) {
    ProcessDefinition def = repositoryService.getProcessDefinition(id);
    if (def != null) {
     repositoryService.deleteDeployment(id,cascade);
     logger.debug("delete..."+id);
    }
   }
  }
 }
 /**
  * 強制級聯刪除已部署的流程(非流程定義)
  * @param ids
  */
 public void deleteDeployment(String ids) {
  if (ids != null) {
   for (String id : ids.split(",")) {
    DeploymentQuery depQuery = repositoryService.createDeploymentQuery().deploymentId(id);
    if (depQuery != null && depQuery.list()!=null) {
     repositoryService.deleteDeployment(id,true);
     logger.debug("delete..."+id);
    }
   }
  }
 }
 /**
  * 強制級聯刪除已上傳的流程定義(ProcessDefinition)
  * @param ids
  */
 public void deleteProcdef(String ids) {
  if (ids != null) {
   for (String id : ids.split(",")) {
    ProcessDefinition def = repositoryService.getProcessDefinition(id);
    if (def != null) {
     repositoryService.deleteDeployment(id,true);
     logger.debug("delete..."+id);
    }
   }
  }
 }

 @Override
 public ProcessDefinition get(Activiti entity) {
  if(entity!=null){
   ProcessDefinition def = repositoryService.getProcessDefinition(entity.getId());
   return def;
  }
  return null;
 }
 @Override
 public void deploy(InputStream fileInputStream,String fileName) {
   try {
        String extension = FilenameUtils.getExtension(fileName);
        logger.info("File extension:"+extension);
        if (extension.equals("zip") || extension.equals("bar")) {
          ZipInputStream zip = new ZipInputStream(fileInputStream);
          repositoryService.createDeployment().addZipInputStream(zip).deploy();
        } else if (extension.equals("png")) {
          repositoryService.createDeployment().addInputStream(fileName, fileInputStream).deploy();
        } else if (fileName.indexOf("bpmn20.xml") != -1) {
          repositoryService.createDeployment().addInputStream(fileName, fileInputStream).deploy();
        } else if (extension.equals("bpmn")) {
          /*
           * bpmn擴展名特殊處理,轉換爲bpmn20.xml
           */
          String baseName = FilenameUtils.getBaseName(fileName);
          repositoryService.createDeployment().addInputStream(baseName + ".bpmn20.xml", fileInputStream).deploy();
        } else if (extension.equals("tmp")) {
         ZipInputStream zip = new ZipInputStream(fileInputStream);
         repositoryService.createDeployment().addZipInputStream(zip).deploy();
        }else {
          throw new ActivitiException("no support file type of " + extension);
        }
      } catch (Exception e) {
       logger.error("error on deploy process, because of file input stream", e);
      }
 }
 
 @Override
 public InputStream getResourceAsStreamByDeployment(String deploymentId,
   String resourceName) {
  return repositoryService.getResourceAsStream(deploymentId, resourceName);
 }
 
 @Override
 public InputStream getResourceAsStreamByProcessInstance(
   String processInstanceId, String resourceType) {
  InputStream resourceAsStream = null;
     ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
     ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId())
             .singleResult();

     String resourceName = "";
     if (resourceType.equals("image")) {
       resourceName = processDefinition.getDiagramResourceName();
     } else if (resourceType.equals("xml")) {
       resourceName = processDefinition.getResourceName();
     }
     resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
     return resourceAsStream;
 }
 
 @Override
 public List<Map<String, Object>> traceProcess(String processInstanceId) throws Exception {
  return traceService.traceProcess(processInstanceId);
 }
 public WorkflowTraceService getTraceService() {
  return traceService;
 }
 public void setTraceService(WorkflowTraceService traceService) {
  this.traceService = traceService;
 }
 @Override
 public DataGrid datagridForInstance(ActivitiInstance entity) {
  DataGrid j = new DataGrid();
  ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery();
  //查詢總數
  long total = query.count();
  //查詢分頁記錄(根據條件)
  if(entity.getSort()!=null){
   if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_ID)){
    query = query.orderByProcessDefinitionId();
   }else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_INSTANCEID)){
    query = query.orderByProcessInstanceId();
   }else if(entity.getSort().equals(ActivitiServiceImpl.SORTBY_KEY)){
    query = query.orderByProcessDefinitionKey();
   }
  }
  if(entity.getOrder()!=null){
   if( entity.equals(ActivitiServiceImpl.ORDERBY_DESC)){
    query = query.desc();
   }else{
    query = query.asc();
   }
  }
  if(entity.getRows()>0 && entity.getPage()>=0){//分頁查詢
   query.listPage((entity.getPage() - 1) * entity.getRows(), entity.getRows() );//listPage(int firstResult, int maxResults);
  }
  List<ProcessInstance> processInstanceList = query.list();
    
  j.setRows(getActivitisFromProcessInstances(processInstanceList));
  j.setTotal(total);
  return j;
 }
 private List<ActivitiInstance> getActivitisFromProcessInstances(List<ProcessInstance> ins) {
  List<ActivitiInstance> acts = new ArrayList<ActivitiInstance>();
  if (ins != null && ins.size() > 0) {
   for (ProcessInstance tb : ins) {
    ActivitiInstance b = new ActivitiInstance();
    BeanUtils.copyProperties(tb, b);
    String deploymentId = tb.getProcessDefinitionId();
       Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(deploymentId).singleResult();
    if(deployment!=null){
     b.setName(deployment.getName());
     b.setDeploymentTime(deployment.getDeploymentTime());
     b.setCategory(deployment.getCategory());
    }
       acts.add(b);
   }
  }
  return acts;
 }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章