天天看點

activiti構造屬于自己的流程定義

說起actviti,很多人都會說它支援bpmn标準,它的流轉都是基于bpmn檔案來運作!

但我們在設計流程時,流程定義真的隻能是bpmn定義嗎?  

其實不然,activti可以支援任意流程定義,隻要你釋出流程時,将你的流程定義轉成bpmn檔案即可!   

分析如下:

  1. 表act_re_model是activiti用于存儲流程模闆的表,其中字段EDITOR_SOURCE_VALUE_ID_,EDITOR_SOURCE_EXTRA_VALUE_ID_是用于提供給使用者存儲自己的私有定義.

    EDITOR_SOURCE_VALUE_ID一般存自己的定義,EDITOR_SOURCE_EXTRA_VALUE_ID_存流程定義的圖檔,如activti-explorer就是這麼存儲,真正使用可以隻用其中一個

  2. 表act_ge_bytearray是activti用于存儲流程定義,其中name值為source就是對應act_re_model表中EDITOR_SOURCE_VALUE_ID定義存儲,值為source-extra為自己的EDITOR_SOURCE_EXTRA_VALUE_ID_定義存儲

    現在代碼如下

  3. 儲存自己的私有流程定義
public class CdpProcessDefintionCreateCommand implements Command<String> {
    private static Logger logger = LoggerFactory.getLogger(CdpProcessDefintionCreateCommand.class);

    private String modelId;
    private String modelName;
    private String flowContent;
 
    @Override
    public String execute(CommandContext commandContext) {
        
        try {
     
        Model model = commandContext.getModelEntityManager().findModelById(modelId);
        String processName = modelName;
        
        if (model == null) {
            model = commandContext.getModelEntityManager().createNewModel();
            ((ModelEntity) model).setId(modelId);
            ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
            modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processName);
            modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
            model.setMetaInfo(modelObjectNode.toString());
            model.setName(processName);
            commandContext.getModelEntityManager().insertModel(model);
            commandContext.getDbSqlSession().flush();
        }   
        //儲存流程定義
        commandContext.getModelEntityManager().insertEditorSourceForModel(modelId, flowContent.getBytes("utf-8"));
        //
        return modelId;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            throw new ActivitiException(e.getMessage());
        }
    }
    public CdpProcessDefintionCreateCommand(String modelId, String modelName,String flowContent ) {
        super();
        this.modelId = modelId;
        this.modelName=modelName;
        this.flowContent = flowContent;
         
    }
           

2.擷取自己的私有流程定義

/**
     * 增加自定義流程定義
     * 
     * @param modelId
     * @return
     */
    public String getProcessDefiniton(String modelId) throws Exception {
        byte[] flowContent= ((RuntimeServiceImpl) runtimeService).getCommandExecutor().execute(new GetModelEditorSourceCmd(modelId));
        return new String(flowContent);
    }
           
  1. 儲存并部署自己的流程定義
public class CdpProcessDefintionDeployCommand implements Command<String> {
    private static Logger logger = LoggerFactory.getLogger(CdpProcessDefintionDeployCommand.class);

    private String modelId;
    private String modelKey;
    private String flowContent;

    private RepositoryService repositoryService;

    @Override
    public String execute(CommandContext commandContext) {
        try {

            BpmnModel bpmnModel = new MxBpmnXMLConverter().convertToBpmnModel(flowContent);
            Model model = commandContext.getModelEntityManager().findModelById(modelId);
            //一定要設定ID,否則釋出時這個東西會有問題
            bpmnModel.getMainProcess().setId(modelKey);
            bpmnModel.getProcesses().get(0).setId(modelKey);
            String processName = null;
            if (StringUtils.isNotEmpty(bpmnModel.getMainProcess().getName())) {
                processName = bpmnModel.getMainProcess().getName();
            } else {
                processName = model.getName();
            }
            if (model == null) {
                model = commandContext.getModelEntityManager().createNewModel();
                ((ModelEntity) model).setId(modelId);
                ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
                modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processName);
                modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
                model.setMetaInfo(modelObjectNode.toString());
                model.setName(processName);
                commandContext.getModelEntityManager().insertModel(model);
            } else {
                commandContext.getModelEntityManager().updateModel((ModelEntity) model);
            }
            commandContext.getDbSqlSession().flush();

            commandContext.getModelEntityManager().insertEditorSourceForModel(modelId, flowContent.getBytes("utf-8"));
            commandContext.getDbSqlSession().flush();
            //名稱一定要是bpmn20.xml,否則釋出不會成功
            String bpmnName = modelKey + ".bpmn20.xml";
            Deployment deployment = repositoryService.createDeployment().name(bpmnName)
                    .addBpmnModel(bpmnName, bpmnModel).deploy();
            //釋出完成後,更新表act_re_model的DEPLOYMENT_ID_字段,activti好像不會自動更新該字段,不知道是不是bug
            model.setDeploymentId(deployment.getId());
            commandContext.getModelEntityManager().updateModel((ModelEntity) model);
            return deployment.getId();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            logger.error("部署流程失敗", e);
            throw new ActivitiException(e.getMessage());
        }
    }

    public CdpProcessDefintionDeployCommand(String modelId, String flowContent, String modelKey,
            final RepositoryService repositoryService) {
        super();
        this.modelId = modelId;
        this.flowContent = flowContent;
        this.repositoryService = repositoryService;
        this.modelKey = modelKey;
    }

}

           

上述代碼中,new MxBpmnXMLConverter().convertToBpmnModel(flowContent);需要自己構造轉換bpmn對象的方法.

至此,activti構造屬于自己流程定義已成功!