1、节点含义
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example001"> <start-state name="start"> <transition name="" to="state1"></transition> </start-state> <state name="state1"> <transition name="" to="node1"></transition> </state> <node name="node1"> <transition name="" to="state2"></transition> </node> <state name="state2"> <transition name="" to="task1"></transition> </state> <task-node name="task1"> <transition name="tobf" to="end1"></transition> </task-node> <end-state name="end1"></end-state> </process-definition>
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName()); token.signal(); logger.info("NodeName:"+token.getNode().getName()); token.signal(); logger.info("NodeName:"+token.getNode().getName());
NodeName:state1
NodeName:state2
NodeName:end1
总结:
node、state、task节点分别为node、等待节点、任务节点。
进过node、task-node不需要singal就往下走,所以没有显示他们的名称,state节点必须singal才往下走。
二、ActionHandler、设置工作参与者以及获取工作路由
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example002"> <start-state name="start"> <transition name="" to="state1"></transition> </start-state> <state name="state1"> <transition name="" to="node1"></transition> </state> <node name="node1"> <action class="jbpm.java.handler.example.TestAction"></action> <transition name="" to="state2"></transition> </node> <state name="state2"> <transition name="" to="task1"></transition> </state> <task-node name="task1"> <task> <assignment actor-id="#{user}"></assignment> </task> <transition name="tobf" to="end1"></transition> </task-node> <end-state name="end1"></end-state> </process-definition>
TestAction.java
public class TestAction implements ActionHandler { private static final long serialVersionUID = 1196655833977006482L; @Override public void execute(ExecutionContext executionContext) throws Exception { System.out.println("通过Action类来解决问题!!!"); } }
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); processInstance.getContextInstance().setVariable("user", "用户"); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName()); token.signal(); logger.info("NodeName:"+token.getNode().getName()); token.signal(); logger.info("NodeName:"+token.getNode().getName()); token.signal(); logger.info("NodeName:"+token.getNode().getName()); TaskInstance ti = (TaskInstance)processInstance.getTaskMgmtInstance().getTaskInstances().iterator().next(); System.out.println("现在工作的参与者是"+ti.getActorId()); //获取该工作的路由 List<Transition> tns = ti.getTask().getTaskNode().getLeavingTransitions(); for(Transition tn : tns) { System.out.println("该工作的所有路由"+tn.getName()); }
NodeName:state1
通过Action类来解决问题!!!
NodeName:node1
NodeName:state2
NodeName:task1
现在工作的参与者是用户
该工作的所有路由tobf
三、beanShell脚本、Assignment应用
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example003"> <start-state name="start"> <transition name="" to="task1"></transition> </start-state> <task-node name="task1"> <task> <assignment class="jbpm.java.handler.example.TestAssignment"></assignment> <assignment actor-id="用户001"/> </task> <event type="node-enter"> <script> print("当前节点对象的ID:"+token.getId()); contextInstance = executionContext.getContextInstance(); print("流程变量param的值:"+contextInstance.getVariable("param")); print("直接获取变量值:"+param); </script> </event> <transition name="" to="end1"></transition> </task-node> <end-state name="end1"></end-state> </process-definition>
TestAssignment.java
public class TestAssignment implements AssignmentHandler{ private static final long serialVersionUID = 1443420479356838909L; @Override public void assign(Assignable assignable, ExecutionContext executionContext) throws Exception { assignable.setActorId("用户001"); } }
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); ContextInstance contextInstance = processInstance.getContextInstance(); contextInstance.setVariable("param", "参数param值"); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName()); token.signal(); logger.info("NodeName:"+token.getNode().getName());
当前节点对象的ID:23
流程变量param的值:param的值
直接获取变量值:param的值
NodeName:task1
NodeName:end1
现在工作的参与者是用户001
四、fork join 节点
discriminator = true 经过一个节点,则结束。 一般开发不使用。
默认情况下join会等到所有从fork上生成的子token都到达join节点时,才会继续向下。
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example004"> <start-state name="start"> <transition name="" to="fork1"></transition> </start-state> <fork name="fork1"> <script> <variable name="transNames" access="write"></variable> <expression> transNames = new ArrayList(); if(param>100){ transNames.add("tr1"); transNames.add("tr2"); }else{ transNames.add("tr3"); transNames.add("tr4"); } </expression> </script> <transition name="tr1" to="node1"></transition> <transition name="tr2" to="node2"></transition> <transition name="tr3" to="node3"></transition> <transition name="tr4" to="node4"></transition> </fork> <node name="node1"> <event type="node-enter"> <script> print("进入第一个节点"); </script> </event> <transition name="" to="join1"></transition> </node> <node name="node2"> <event type="node-enter"> <script> print("进入第二个节点"); </script> </event> <transition name="" to="join1"></transition> </node> <node name="node3"> <event type="node-enter"> <script> print("进入第三个节点"); </script> </event> <transition name="" to="join1"></transition> </node> <node name="node4"> <event type="node-enter"> <script> print("进入第四个节点"); </script> </event> <transition name="" to="join1"></transition> </node> <join name="join1"> <transition name="" to="end1"></transition> </join> <end-state name="end1"> <event type="node-enter"> <script> print("结束操作"); </script> </event> </end-state> </process-definition>
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); processInstance.getContextInstance().setVariable("param", new Integer(11)); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName());
进入第三个节点
进入第四个节点
结束操作
NodeName:end1
四、Decision节点
定义流程走向节点,在本节点上添加多个Transtion,和Fork相反,只能在多个Transition内选择一个。
A:未指定decision线路。
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example005"> <start-state name="start"> <transition name="" to="decision1"></transition> </start-state> <decision name="decision1"> <transition name="tr1" to="node1"></transition> <transition name="tr2" to="node2"></transition> <transition name="tr3" to="node3"></transition> </decision> <node name="node1"> <event type="node-enter"> <script> print("进入第一个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <node name="node2"> <event type="node-enter"> <script> print("进入第二个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <node name="node3"> <event type="node-enter"> <script> print("进入第三个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <end-state name="end1"> <event type="node-enter"> <script> print("结束操作"); </script> </event> </end-state> </process-definition>
String processName = (String)Persistence.getVariable("processName"); logger.info("processName:"+processName); JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName());
只要经过一个节点,就可以继续向下流转。没指定默认进入第一个。
结果如下:end
B:通过表达式变量程序内指定方式指定decision线路
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example005"> <start-state name="start"> <transition name="" to="decision1"></transition> </start-state> <decision name="decision1" expression="#{tname}"> <transition name="tr1" to="node1"></transition> <transition name="tr2" to="node2"></transition> <transition name="tr3" to="node3"></transition> </decision> <node name="node1"> <event type="node-enter"> <script> print("进入第一个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <node name="node2"> <event type="node-enter"> <script> print("进入第二个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <node name="node3"> <event type="node-enter"> <script> print("进入第三个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <end-state name="end1"> <event type="node-enter"> <script> print("结束操作"); </script> </event> </end-state> </process-definition>
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); processInstance.getContextInstance().setVariable("tname", "tr2"); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName());
进入第二个节点
结束操作
NodeName:end1
end
C:通过DecisionHandler方式指定decision线路
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example005"> <start-state name="start"> <transition name="" to="decision1"></transition> </start-state> <decision name="decision1"> <handler class="jbpm.java.handler.example.TestDecision"/> <transition name="tr1" to="node1"></transition> <transition name="tr2" to="node2"></transition> <transition name="tr3" to="node3"></transition> </decision> <node name="node1"> <event type="node-enter"> <script> print("进入第一个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <node name="node2"> <event type="node-enter"> <script> print("进入第二个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <node name="node3"> <event type="node-enter"> <script> print("进入第三个节点"); </script> </event> <transition name="" to="end1"></transition> </node> <end-state name="end1"> <event type="node-enter"> <script> print("结束操作"); </script> </event> </end-state> </process-definition>
public class TestDecision implements DecisionHandler { private static final long serialVersionUID = -9083605280987838663L; @Override public String decide(ExecutionContext executionContext) throws Exception { return "tr3"; } }
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName());
进入第三个节点
结束操作
NodeName:end1
end
五、根据参与者actor-id取到对应任务、根据任务ID取得实例
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example008"> <start-state name="start"> <transition name="" to="task1"></transition> </start-state> <task-node name="task1"> <event type="task-create"> <script> print("触发了task-create事件"); </script> </event> <event type="task-start"> <script> print("触发了task-start事件"); </script> </event> <event type="task-assign"> <script> print("触发了task-assign事件"); </script> </event> <event type="task-end"> <script> print("触发了task-end事件"); </script> </event> <task> <assignment actor-id="admin001"></assignment> </task> <transition name="" to="end1"></transition> </task-node> <end-state name="end1"></end-state> </process-definition>
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName()); //根据参与者actor-id取到对应任务 List<TaskInstance> taskInstance = jbpmContext.getTaskMgmtSession().findTaskInstances("admin001"); for(TaskInstance ti : taskInstance){ logger.info("actor-id:"+ti.getName()); }输出结果:
触发了task-create事件
触发了task-assign事件
NodeName:task1
actor-id:task1
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName()); //根据任务ID取得实例 TaskInstance taskInstance = jbpmContext.loadTaskInstance(taskInstanceId); logger.info("actor-id:"+taskInstance.getName());/
触发了task-create事件
触发了task-assign事件
NodeName:task1
actor-id:task1
六、Swimlane方式
用于处理一个流程中多个任务节点由同一个人或者角色来完成。
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example009"> <swimlane name="user"> <assignment actor-id="#{userId}"></assignment> </swimlane> <start-state name="start"> <transition name="" to="task1"></transition> </start-state> <task-node name="task1"> <event type="task-create"> <script> print("触发了task-create事件"); </script> </event> <event type="task-start"> <script> print("触发了task-start事件"); </script> </event> <event type="task-assign"> <script> print("触发了task-assign事件"); </script> </event> <event type="task-end"> <script> print("触发了task-end事件"); </script> </event> <task swimlane="user"/> <transition name="" to="end1"></transition> </task-node> <end-state name="end1"></end-state> </process-definition>
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); processInstance.getContextInstance().setVariable("userId", "admin002"); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName()); List<TaskInstance> taskInstance = jbpmContext.getTaskMgmtSession().findTaskInstances("admin002"); for(TaskInstance ti : taskInstance){ logger.info("actor-id:"+ti.getName()); }
触发了task-create事件
触发了task-assign事件
NodeName:task1
actor-id:task1
七、pooled-actors方式
一个任务直接分配给多个参与者,多个参与者用逗号隔开。
例如:提交给一个部门,该部门的人都能看到,其中一个人处理就可以了。
这种方式只能静态分配,不能动态分配。所以适用范围有限。
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="example010"> <start-state name="start"> <transition name="" to="task1"></transition> </start-state> <task-node name="task1"> <event type="task-create"> <script> print("触发了task-create事件"); </script> </event> <event type="task-start"> <script> print("触发了task-start事件"); </script> </event> <event type="task-assign"> <script> print("触发了task-assign事件"); </script> </event> <event type="task-end"> <script> print("触发了task-end事件"); </script> </event> <task> <assignment pooled-actors="admin001,admin002,admin003"></assignment> </task> <transition name="" to="end1"></transition> </task-node> <end-state name="end1"></end-state> </process-definition>
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName()); List<TaskInstance> taskInstance = jbpmContext.getTaskMgmtSession().findPooledTaskInstances("admin001"); for(TaskInstance ti : taskInstance){ logger.info("pooled-actors:"+ti.getName()); }
触发了task-create事件
NodeName:task1
pooled-actors:task1
七、发送mail提醒
A、建立邮件服务。
下载james-2.3.2,解压。进入dos命令行模式,进入C:\james-2.3.2\bin,执行run.bat
例图所示邮件服务器启动完毕,请不要关闭dos窗口。
pop3,smtp,等信息显示如上。
再打开新的dos窗口。
输入telnet localhost 4555
提示输入用户名密码:都是root
之后输入help,可以看到命令帮助。
输入 adduser adminsender 123456
新增一个用户以及密码。新增完毕之后即可关闭此窗口,或者输入quit退出。
B、程序配置。
把jbpm-jpdl-3.2.3中的两个jar文件activation.jar、mail.jar放置工程中。
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="" name="example011"> <start-state name="start-state1"> <transition to="task-node1"></transition> </start-state> <task-node name="task-node1"> <task name="notifyTask" notify="true"> <assignment actor-id="adminsender"></assignment> </task> <transition to="end-state1"></transition> </task-node> <end-state name="end-state1"></end-state> </process-definition>
或者使用下面流程文件:
<?xml version="1.0" encoding="UTF-8"?> <process-definition xmlns="" name="example012"> <start-state name="start-state1"> <transition to="task-node1"></transition> </start-state> <task-node name="task-node1"> <task name="notifyTask"> <assignment actor-id="adminsender"/> <event type="task-assign"> <mail template="task-assign"/> </event> </task> <transition to="end-state1"></transition> </task-node> <end-state name="end-state1"></end-state> </process-definition>
原因暂时不清数,不过去掉,即可正常部署。
建立MailResolver.java文件
package jbpm.java.mail; import org.jbpm.mail.AddressResolver; public class MailResolver implements AddressResolver{ private static final long serialVersionUID = 3634448991562190346L; @Override public Object resolveAddress(String actorId) { if(actorId.equals("adminsender")){ return "adminsender@localhost"; }else{ return "adminsender@localhost"; } } }
<string name="resource.mail.templates" value="jbpm.mail.templates.xml"/> <string name="jbpm.mail.smtp.host" value="localhost"/> <string name="jbpm.mail.smtp.port" value="25"/> <bean name="jbpm.mail.address.resolver" class="jbpm.java.mail.MailResolver" singleton="true"/> <string name="jbpm.mail.from.address" value="adminsender@localhost"/> <string name="jbpm.mail.smtp.auth" value="true"/>
JbpmContext jbpmContext = getJbpmContext(); GraphSession graphSession=jbpmContext.getGraphSession(); ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition(processName); ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); token.signal(); logger.info("NodeName:"+token.getNode().getName());
java.lang.NoClassDefFoundError: com/sun/mail/util/LineInputStream错误。
主要原因是javax.mail和javax.activation这两个包已经在javaEE5当中属于基础包了,但是里面的方法与现在jbpm提供的的mail.jar和activation.jar有一些出入
X:/Program Files/MyEclipse 6.5/myeclipse/eclipse/plugins/com.genuitec.eclipse.j2eedt.core_6.5.0.zmyeclipse650200806/data/libraryset/EE_5
这个路径里,可以看到javaee.jar,用rar把这个文件打开,然后进到javax文件夹里,删除mail.jar和activation.jar。注意备份。
之后执行,则通过。
八、任务调度