在发表文章之前,先写一下博客声明,由于JE限制了本人的发贴功能,所以大家回复的内容本人现在没有办法在线回复各位,望见谅。需要技术交流的请加我Q:1165655130。
最近JBPM比较火,很多同行也跟我探讨如何使用这个东西完成企业应用中的流程问题,本人也谈谈对Jbpm4的理解,JBPM在实现流程上应该没有什么问题,但是由于其客户端的可视化相对薄弱,如设计器不够人性化,流程表单也不方便,所以客户要设计企业内的业务流程就会遇到问题,毕竟大部分的客户都不是开发人员。
尽管JBPM的客户化相对薄弱,但是它比较轻巧,相对其他商业的工作流引擎,部署及开发都是相当方便,这使得连IBM有些系统都采用JBPM来开发。JOffice中也在努力提升的JBPM的易用性,提供一些可视化的在线流程设计器及表单设计器。
大家都知道Jbpm有一个eclipse的plugin可以完成流程的设计开发,但是那个东西却没有提供在线的设计器,而JBPM也提供一个在线的设计器(Signavio),其是基于SVG来进行画图的,可惜ie目前的版本却不支持SVG。Flex应该是个不错的流程设计器的做法,不过目前的版本对图形的支持相对差一些,Flex3也有一个不错的流程框架如degrafa,可惜文档及例子不多,使用起来也相当困难。Flex4还在期待。而JavaFx初看却不错,但是感觉不如直接用JAVA写,用JAVA写要在浏览器中使用,就离不开Applet了。
而画流程图最好还是有一个框架,记得在C++下完成一个简单的画板功能,完全自己写,也是费很多功夫。用现成的框架,却可以省很多功夫。开源的JAVA画图框架可以省去我们的功夫呢,如:JUNG,JHotDraw,他们的画图及编辑图形的功能已经很强,不需要再写大量的代码去实现,并且提供在线的Applet演示,同时文档也比较丰富。
用了类似的图形画图框架后,可以让他们生成对应自己程序的XML文件后,就可以与JBPM的XML文件作一个相互转换则可。最终的目的就是转换成JBPM所认识的流程定义,同时可以比较容易恢复流程的定义图形的显示。
(在线演示地址:http://joffice.jee-soft.cn user:csx,pwd:111)
如在JOffice 1.3中,在线定义一个公文撰稿的流程,如下所示:
以上画图会有不同的画图属性,因而会生成一个画图对应的文件存储内容,如字体大小、颜色等,其最终生成以下文件:
<drawing id="0">
<figures>
<start id="1" x="151" y="8" w="48" h="48" name="开始">
<a>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</start>
<end id="2" x="492" y="423" w="48" h="48" name="结束1">
<a>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</end>
<task id="3" name="公文拟稿" x="123" y="107"
w="101" h="39">
<a>
<text>
<string>公文拟稿</string>
</text>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</task>
<transition id="4" g="-24,-16" name="准备">
<points>
<p colinear="true" x="174.6095238095238" y="56.6" c1x="0" c1y="0"
c2x="0" c2y="0" />
<p colinear="true" x="173.81904761904764" y="106.4" c1x="0" c1y="0"
c2x="0" c2y="0" />
</points>
<startConnector>
<rConnector id="5">
<Owner>
<start ref="1" />
</Owner>
</rConnector>
</startConnector>
<endConnector>
<rConnector id="6">
<Owner>
<task ref="3" />
</Owner>
</rConnector>
</endConnector>
<a>
<endDecoration>
<arrowTip id="7" angle="0.35" innerRadius="11.3"
outerRadius="12" isFilled="true" isStroked="false" isSolid="true" />
</endDecoration>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</transition>
<fork id="8" x="150" y="204" w="48" h="48"
name="同步任务">
<a>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</fork>
<transition id="9" g="-24,-16" name="同步">
<points>
<p colinear="true" x="173.5990147783251" y="146.60000000000002"
c1x="0" c1y="0" c2x="0" c2y="0" />
<p colinear="true" x="173.87881773399016" y="203.4" c1x="0" c1y="0"
c2x="0" c2y="0" />
</points>
<startConnector>
<rConnector id="a">
<Owner>
<task ref="3" />
</Owner>
</rConnector>
</startConnector>
<endConnector>
<rConnector id="b">
<Owner>
<fork ref="8" />
</Owner>
</rConnector>
</endConnector>
<a>
<endDecoration>
<arrowTip ref="7" />
</endDecoration>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</transition>
<task id="c" name="审核" x="301" y="166" w="108" h="41">
<a>
<text>
<string>审核</string>
</text>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</task>
<task id="d" name="印章准备" x="305" y="282"
w="111" h="42">
<a>
<text>
<string>印章准备</string>
</text>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</task>
<transition id="e" g="-24,-16" name="任务">
<points>
<p colinear="true" x="198.60000000000002" y="222.3596685082873"
c1x="0" c1y="0" c2x="0" c2y="0" />
<p colinear="true" x="300.4" y="199.01878453038674" c1x="0" c1y="0"
c2x="0" c2y="0" />
</points>
<startConnector>
<rConnector id="f">
<Owner>
<fork ref="8" />
</Owner>
</rConnector>
</startConnector>
<endConnector>
<rConnector id="10">
<Owner>
<task ref="c" />
</Owner>
</rConnector>
</endConnector>
<a>
<endDecoration>
<arrowTip ref="7" />
</endDecoration>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</transition>
<transition id="11" g="-24,-16" name="准备">
<points>
<p colinear="true" x="198.60000000000002" y="237.89276139410188"
c1x="0" c1y="0" c2x="0" c2y="0" />
<p colinear="true" x="306.78799999999995" y="281.4" c1x="0" c1y="0"
c2x="0" c2y="0" />
</points>
<startConnector>
<rConnector id="12">
<Owner>
<fork ref="8" />
</Owner>
</rConnector>
</startConnector>
<endConnector>
<rConnector id="13">
<Owner>
<task ref="d" />
</Owner>
</rConnector>
</endConnector>
<a>
<endDecoration>
<arrowTip ref="7" />
</endDecoration>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</transition>
<join id="14" x="488" y="209" w="48" h="48"
name="汇集任务">
<a>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</join>
<transition id="15" g="-24,-16" name="提交">
<points>
<p colinear="true" x="409.59999999999997" y="202.67133757961784"
c1x="0" c1y="0" c2x="0" c2y="0" />
<p colinear="true" x="487.4" y="225.7140127388535" c1x="0" c1y="0"
c2x="0" c2y="0" />
</points>
<startConnector>
<rConnector id="16">
<Owner>
<task ref="c" />
</Owner>
</rConnector>
</startConnector>
<endConnector>
<rConnector id="17">
<Owner>
<join ref="14" />
</Owner>
</rConnector>
</endConnector>
<a>
<endDecoration>
<arrowTip ref="7" />
</endDecoration>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</transition>
<transition id="18" g="-24,-16" name="提交">
<points>
<p colinear="true" x="407.2485714285714" y="281.4" c1x="0" c1y="0"
c2x="0" c2y="0" />
<p colinear="true" x="487.4" y="244.36633663366337" c1x="0" c1y="0"
c2x="0" c2y="0" />
</points>
<startConnector>
<rConnector id="19">
<Owner>
<task ref="d" />
</Owner>
</rConnector>
</startConnector>
<endConnector>
<rConnector id="1a">
<Owner>
<join ref="14" />
</Owner>
</rConnector>
</endConnector>
<a>
<endDecoration>
<arrowTip ref="7" />
</endDecoration>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</transition>
<task id="1b" name="定稿" x="456" y="327" w="119" h="45">
<a>
<text>
<string>定稿</string>
</text>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</task>
<transition id="1c" g="-24,-16" name="提交">
<points>
<p colinear="true" x="512.7390557939914" y="257.6" c1x="0" c1y="0"
c2x="0" c2y="0" />
<p colinear="true" x="514.806008583691" y="326.4" c1x="0" c1y="0"
c2x="0" c2y="0" />
</points>
<startConnector>
<rConnector id="1d">
<Owner>
<join ref="14" />
</Owner>
</rConnector>
</startConnector>
<endConnector>
<rConnector id="1e">
<Owner>
<task ref="1b" />
</Owner>
</rConnector>
</endConnector>
<a>
<endDecoration>
<arrowTip ref="7" />
</endDecoration>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</transition>
<transition id="1f" g="-24,-16" name="1">
<points>
<p colinear="true" x="515.6184615384616" y="372.59999999999997"
c1x="0" c1y="0" c2x="0" c2y="0" />
<p colinear="true" x="515.8738461538461" y="422.4" c1x="0" c1y="0"
c2x="0" c2y="0" />
</points>
<startConnector>
<rConnector id="20">
<Owner>
<task ref="1b" />
</Owner>
</rConnector>
</startConnector>
<endConnector>
<rConnector id="21">
<Owner>
<end ref="2" />
</Owner>
</rConnector>
</endConnector>
<a>
<endDecoration>
<arrowTip ref="7" />
</endDecoration>
<strokeColor>
<color rgba="#ff000000" />
</strokeColor>
</a>
</transition>
</figures>
</drawing>
转为jbpm的定义为:
<?xml version="1.0" encoding="GBK"?>
<process xmlns="http://jbpm.org/4.0/jpdl" name="pd7250331474571141836">
<start name="开始" g="151,8,58,58">
<transition name="准备" to="公文拟稿" g="-24,-16" />
</start>
<end name="结束1" g="492,423,58,58" />
<task name="公文拟稿" g="123,107,111,49">
<transition name="同步" to="同步任务" g="-24,-16" />
</task>
<fork name="同步任务" g="150,204,58,58">
<transition name="准备" to="印章准备" g="-24,-16" />
<transition name="任务" to="审核" g="-24,-16" />
</fork>
<task name="审核" g="301,166,118,51">
<transition name="提交" to="汇集任务" g="-24,-16" />
</task>
<task name="印章准备" g="305,282,121,52">
<transition name="提交" to="汇集任务" g="-24,-16" />
</task>
<join name="汇集任务" g="488,209,58,58">
<transition name="提交" to="定稿" g="-24,-16" />
</join>
<task name="定稿" g="456,327,129,55">
<transition name="1" to="结束1" g="-24,-16" />
</task>
</process>
相对来说,画图需要存储的内容比较多, jbpm却只是关心流程,在界面恢复图形,仅需要使用流程画图的xml,而流程发布则仅需要使用生成的Jbpm流程定义。
而流程在线表单功能目前已经提供了模板及可视化的设计,不过可视化的设计还是相对弱一些,强大的流程表单设计功能将会在后续的版本提供。如将提供表单的自定义功能,并且可以动态生成表单对应的表,提供方便的查询及权限控制显示等功能。