天天看点

camunda 流程执行追踪_camunda对BPMN流程定义解析、执行、展现的JS库

1 写在前面

本文介绍了camunda 对BPMN流程定义文件的解析实现。

该类库的JS框架采用的dojo

(了解下dojo与jquery的区别:http://blog.csdn.net/dojotoolkit/article/details/7682978)

这个类库有四个文件

Bpmn.js提供相应功能的接口。

三个组件:Executor.js——轻量级流程引擎

Renderer.js——通过dojo展现渲染流程图的组件

Transformer.js——解析流程图的组件

最坑爹的是camunda首页的流程模拟是用jquery框架和Raphael图形处理库,因此确定,除了Renderer组件,其他组件都能复用。

camunda首页还采用了bootstrap框架,并且自己拓展了相关组件,值得借鉴。

2 结构

src

-bpmn

-Bpmn.js

-Executor.js

-Renderer.js

-Transforme.js

test

-bpmn

-engine

-lib

-renderer

-resources

-transformer

-util

-runner.html

3 各类接口

3.1 bpmn.js

renderUrl(url, options)通过url解析流程图

render(bpmnXml, options)通过字符串解析流程图

zoom(factor)放大缩小

annotate(id, innerHTML, classesArray)注释

clear()清除

例子:

new Bpmn().renderUrl("test/resources/task_loop.bpmn", {

diagramElement : "diagram",

overlayHtml : '

}).then(function (bpmn){

bpmn.zoom(0.8);

bpmn.annotate("reviewInvoice", 'New Text', ["highlight"]);

//bpmn.clear();

});

3.2 Executor.js

CAM轻量级流程引擎核心

在这里定义了监听事件和公共方法,并注册了各种类型元素的执行行为。

接口

ActivityExecution活动执行类

ActivityExecution(activityDef,parentExecution) 构造函数activityDef:流程定义

parentExecution:父执行

bindVariableScope(scope) 绑定变量scope:绑定变量到父执行

executeActivities(activities) 执行多活动activities:活动的数组

executeActivity(activity, sequenceFlow) 执行活动activity:当前活动

sequenceFlow:活动相关的顺序流

invokeListeners (type, sequenceFlow) 调用监听type:监听类型

sequenceFlow :监听类型绑定到顺序流

getActivityInstance() 获得流程实例

以下是控制流程执行

start 开始流程活动记录开始时间,注册开始监听

continue 执行活动

end 结束流程活动记录结束时间,注册结束监听

takeAll 执行所有sequenceFlows连接的活动

take 执行sequenceFlow连接的活动注册TAKE监听

signal 标记活动如果活动定义了标记方法就执行,否则结束活动

ActivityInstance活动实例类(是私有类,有以下属性)

activityId 活动id

isEnded 是否结束

startDate 开始时间

endDate 结束时间

activities 未结束的活动们

异步调用

异步活动通过调用signal来控制执行

BPMN2.0中规定的活动元素应有的执行,通过注册活动类型来实现

抛出异常

3.3 Renderer.js

渲染器中内置了各个BPMN元素的render方法集放在Map中,并根据元素类型调用它们各自的render方法,用dojo的dom-construct生成dom节点。

3.4 Transformer.js

解析流程图的xml文件,返回含有元素集合的数组。

例子:

var processDefinition = new Transformer().transform(bpmn.bpmnXml)[0];

下面是processDefinition对象的样子:

其中的一个baseElement

4 实例

4.1 流程执行

var docXml = '<?xml version……'';

var processDefinition = new Transformer().transform(docXml)[0];

var execution = new CAM.ActivityExecution(processDefinition);

execution.variables.input = 10;

execution.start();

//活动没结束

expect(execution.isEnded).toBe(false);

var processInstance = execution.getActivityInstance();

//expect(XXX).toBe(XXX2);是判断XXX是否等于XXX2的意思

//以下说明执行完的活动数量

expect(processInstance.activities.length).toBe(2);

expect(processInstance.activities[0].activityId).toBe("theStart");

expect(processInstance.activities[1].activityId).toBe("userTask");

// 为userTask发送一个信号

execution.activityExecutions[1].signal();

execution.activityExecutions[2].signal();

// 现在流程结束了

expect(execution.isEnded).toBe(true);

//以下说明流程实例的执行情况

processInstance = execution.getActivityInstance();

expect(processInstance.activities.length).toBe(4);

expect(processInstance.activities[0].activityId).toBe("theStart");

expect(processInstance.activities[1].activityId).toBe("userTask");

expect(processInstance.activities[3].activityId).toBe("theEnd");

解释:

execution定义了一个流程的执行。即为引擎中的ActivityExecution类。

execution.getActivityInstance()获取到了该执行的一个流程实例类activityInstance。

用户任务通过execution.activityExecutions[1].signal();方法来完成

该引擎支持多执行,多实例。

4.2 任务传参

当流程执行到某步时,我们想传递参数,可以通过对执行实例加监听来实现

var processDefinition = new Transformer().transform(docXml)[0];

//为流程定义增加监听

for (var i = 0; i < processDefinition.baseElements.length; i++) {

var activity = processDefinition.baseElements[i];

var listeners = activity.listeners;

if(!!activity.listeners) {

listeners.push({

"start" : function(activityExecution) {

var actId = activityExecution.activityDefinition.id;

console.log("start "+actId);

if(activityExecution.activityDefinition.type=="userTask"){

var lala = prompt("input lala","");

activityExecution.variables.lala = lala;

activityExecution.signal();

}

},

"end" : function(activityExecution){

var actId = activityExecution.activityDefinition.id;

console.log("end "+actId)

},

"signal" : function(activityExecution){

var actId = activityExecution.activityDefinition.id;

console.log("signal "+actId)

}

});

}

}

4.3 延迟加载

5 启发

5.1 可用性

流程定义对象的解析(Transformer)

流程预演功能(Executor)