说起actviti,很多人都会说它支持bpmn标准,它的流转都是基于bpmn文件来运行!
但我们在设计流程时,流程定义真的只能是bpmn定义吗?
其实不然,activti可以支持任意流程定义,只要你发布流程时,将你的流程定义转成bpmn文件即可!
分析如下:
- 表act_re_model是activiti用于存储流程模板的表,其中字段EDITOR_SOURCE_VALUE_ID_,EDITOR_SOURCE_EXTRA_VALUE_ID_是用于提供给用户存储自己的私有定义.
EDITOR_SOURCE_VALUE_ID一般存自己的定义,EDITOR_SOURCE_EXTRA_VALUE_ID_存流程定义的图片,如activti-explorer就是这么存储,真正使用可以只用其中一个 - 表act_ge_bytearray是activti用于存储流程定义,其中name值为source就是对应act_re_model表中EDITOR_SOURCE_VALUE_ID定义存储,值为source-extra为自己的EDITOR_SOURCE_EXTRA_VALUE_ID_定义存储
现在代码如下 - 保存自己的私有流程定义
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);
}
- 保存并部署自己的流程定义
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构造属于自己流程定义已成功!