CSDN博客

img roshui

osworkflow 文摘

发表于2004/8/5 10:16:00  3899人阅读

分类: Workflow

OSWorkflow基本概念>>

http://www.blogdriver.com/showBlog.do?diaryID=113138

   

Step

大致相当于流程所在的位置。譬如企业年检,年检报告书在企业端算一个step,在工商局算第二个step,在复核窗口算第三个step。每个step可以有多种状态(status)和多个动作(action),用Workflow.getCurrentSteps()可以获得所有当前的step(如果有并列流程,则可能同时有多个step,例如一次年检可能同时位于初审”step广告经营资格审查”step)。

 

Status

流程在某个step中的状态。很容易理解,譬如待认领审核不通过之类的。OSWorkflow中的状态完全是由开发者自定义的,状态判别纯粹是字符串比对,灵活性相当强,而且可以把定义文件做得很好看。

 

Action

导致流程状态变迁的动作。一个action典型地由两部分组成:可以执行此动作的条件(conditions),以及执行此动作的结果(results)。条件可以用BeanShell脚本来判断,因此具有很大的灵活性,几乎任何与流程相关的东西都可以用来做判断。

 

Result

执行动作后的结果。这是个比较重要的概念。result分为两种,conditional-resultunconditional-result。执行一个动作之后,首先判断所有conditional-result的条件是否满足,满足则使用该结果;如果没有任何contidional-result满足条件,则使用unconditional-resultunconditional-result需要指定两部分信息:old-status,表示当前step的状态变成什么;后续状态,可能是用step+status指定一个新状态,也可能进入split或者join

 

conditional-result非常有用。还是以年检为例,同样是提交年检报告书,未提交被退回是不同的状态,在这两个状态基础上执行提交动作,结果分别是初次提交退回之后再次提交。这时可以考虑在提交动作上用conditional-result

 

Split/Join

流程的切分和融合。很简单的概念,split提供多个resultjoin则判断多个current step的状态,提供一个result

 

*     *     *

 

熟悉这些概念,在流程定义中尽量使用中文,可以给业务代码和表现层带来很多方便。

电子政务/ OA 如果要使用workflow engine的话, shark, jbpm之类的workflow engine有点杀鸡用牛刀的味道. shark jbpm都强迫你使用它的用户模型, 怎样把企业现有的用户模型(包括组织结构)映射过来是很繁琐的事情, 比如常见的OA应用中, 申请者对应的部门负责人为下一个流程的人工参与者, 使用shark 或者 jbpm都得绕一圈, 通过现有的人力资源系统, 获得用户, 再对应过来. 这还仅仅是一个简单的需求, 更不用说国内企业千奇百怪的组织结构, 以及各种特殊流程, wfmc 或者其他所谓的workflow通用标准去做不怎么标准的事情, 吃力不讨好.osworkflow这种基于状态机的workflow engine反而会轻松很多, 而且它也没有强迫你使用它的用户模型. 另外纠正一点: osworkflow不仅仅支持简单的BeanShell, 还支持java class, bsf, ejb. 如果做电子政务/ OA的话, 觉得目前osworkflow是最适用的opensource workflow engine.

 

OSWorkflowBeanShell的运行环境>>

http://www.blogdriver.com/showBlog.do?diaryID=109107

   

以前问Potian脚本可以做什么,现在明白了。脚本语言具有无穷大的威力,只要你给它无穷大的运行环境(context)。设计可以嵌入脚本的框架时,就要考虑给脚本怎样的context。一些最可能用到的东西,应该放在脚本伸手可及的地方;如果所有东西都可以通过一个全局Service Locator导航获得,那么脚本就什么都可以做。

 

com.opensymphony.workflow.util.beanshell这个包里的几个类就是OSWorkflow配置文件中BeanShell脚本的运行环境,每个类对应一种BeanShell定义。譬如对于type="beanshell" name="bsh.condition"BeanShell脚本,它得到的运行环境是这样设置的(BeanShellCondition.passesCondition方法):

 

        Interpreter i = new Interpreter();  // BeanShell解释器
        Map transientVars;

        PropertySet ps;

        WorkflowContext context;
        WorkflowEntry entry;

        ClassLoader loader;

            i.set("entry", entry);
            i.set("context", context);
            i.set("transientVars", transientVars);
            i.set("propertySet", ps);
            i.set("jn", transientVars.get("jn"));


 

通过entry变量(WorkflowEntry)可以得到工作流ID、名称、状态(激活、挂起、结束等等);通过context变量(WorkflowContext)可以得到调用者(caller,我打算用这个值来作为每个工作流实例的唯一标识,不知道是否合理);transientVars是一个Map,传递临时性的参数;propertySet是持久化的属性设置。

 

jn变量是用在join节点中的——当两个流程需要合并时,就会进入一个join节点。譬如说,年检流程和广告审查流程、注册流程和并联审批流程,它们的合并就要在一个join节点中判断两条流程是否都达到合适的位置。调用jn.getStep()方法可以获得任意一个step,然后调用getStatus()方法就可以判断任意step的当前状态。

/

OSWorkflow真灵活>>

http://www.blogdriver.com/showBlog.do?diaryID=108339

   

比如年检流程,未提交年检报告书的状态其实有好几种情况:首次填写未提交、报告书被退回未提交、初审不通过未提交。把这几个状态分别定义为UnCommit1UnCommit2UnCommit3。在提交的动作那里判断条件时,用BeanShell写一个脚本:

 

String status = getStatus();

status.indexOf("UnCommit") >= 0;

 

也就是说,只要当前状态字中含有UnCommit字样,就可以执行提交的动作。嘿嘿,灵活地。现在要把BeanShell的中文问题解决一下,再试试分支流程。

 

OSWorkflow奋斗一天>>

http://www.blogdriver.com/showBlog.do?diaryID=107566

   

解决了两个问题:

 

不能根据Hibernate映射文件生成数据库——SchemaExport生成数据库的时候,DOM4J报错org.xml.sax.driver系统属性没有设置。查看了一下,在以往的任何一个项目中,这个系统属性都没有设置,但都可以生成数据库,不知道为什么在这里就不行了。自己动手给SchemaExport做了个包装,先设置org.xml.sax.driver系统属性值为org.apache.xerces.parsers.SAXParser,再调用SchemaExport

 

执行速度巨慢——是因为没有开启工作流工厂的缓存。在osworkflow.xml定义文件中加上<property key="cache" value="true" />,速度明显提高。第一次加载工作流定义时,XML解析和验证(validation)费时较多,改用JDOM解析(CrimsonDOMAdapter),有所加快。

 

Hibernate持久化时,OSWorkflow要求client提供SessionFactory,然后自主控制sessiontransaction。我计划将它纳入G-Roller框架,直接向HibernateWorkflowStore提供SessionAdapter,仍然用G-Roller统一管理sessiontransaction。首先要把核心部分的单元测试补起来,hani这个家伙从来不爱写测试,偶尔写几个也是sample一样的,估计是OpenSymphony公司给他下的任务——就像我的文档任务一样。

 

 

 

OSWorkFlow又爱又恨

http://www.blogdriver.com/showBlog.do?diaryID=182514

   OSWorkFlow我研究已有一段时间了,并已在一些项目中开始使用了。OSWorkFlow流程定义灵活清晰,工作流引擎支持多种持久方式(MemoryStore ,SerializableStore, JDBCStore, OfbizStore, and EJBStore,HibernateStore等),具有极强的可扩展性。OSWorkFlow强大的脚本支持(BeanShellBSF等),多样化的function,function可以直接使用普通java类函数、XworkActionJMSEJB、脚本等。使用propertyset动态存取类型化的数据,使用成熟的Quartz实现工作流任务定时调度。最新版本OSWorkFlow2.7也添加了Spring框架的支持,设计器也有了很好的改善。

     可是,OSWorkFlow的学习资料太少,只有opensymphony的一些概论介绍和简单的例子,连一个完善的实际项目使用都没有。代码的注释也是非常少,更不能接受的是只有部分的单元测试,若想在其基础上改进也困难,哎!设计器的代码更烂,好在OSWorkFlow2.7的设计器(Designer2.7)的改进,总算是能在实际中使用。

  期待OSworkflow更好的完善、改进、发展(http://www.opensymphony.com/osworkflow/)...............

 

 

 

OSWorkFlow概论:function(函数)

http://www.blogdriver.com/showBlog.do?diaryID=158730

function(函数),在OSWorkFlow中是用来定义(引用)并执行外部的商业逻辑和服务,实现OSWorkFlow与外部具体的应用之间交互。

function有二种类型:
pre function(
预处理函数)post function(后处理函数)
pre function
在工作流的一个转变操作执行之前调用,例如:在执行Action的一个结果之前,设置这个结果将导致状态改变的Owner
 <action id="0" name="
启动工作流">
      <results>
        <unconditional-result id="2" old-status="Finished" status="Queued" step="1" owner="${caller}">
          <pre-functions>
            <function name="set.caller" type="class">
              <arg name="class.name">com.opensymphony.workflow.util.Caller</arg>
            </function>
          </pre-functions>
        </unconditional-result>
      </results>
    </action>

post function在工作流的一个转变操作执行完之后调用:例如在设备申请工作流中,部门经理审核步骤完成之后可以给申请的员工发email通知

等。


function
将被应用在stepActionResult
具体见workflow_2_7.dtd
..
<!ELEMENT step (meta*, pre-functions?, external-permissions?, actions?, post-functions?)>
<!ELEMENT action (meta*, restrict-to? , validators?, pre-functions?, results, post-functions?)>
<!ELEMENT result (conditions, validators?, pre-functions?, post-functions?)>
..

 

functionaction级别的应用:在执行某一步骤的Action时,它会首先执行当前Action级别的pre-function,再去寻找Action里的result

result执行完成之后再调用Action级别的post-function,于是Action的执行结束。

如下图:


function
result级别的应用:类似action级别
function
step级别的应用:上一个步骤执行结束,运转到当前步骤,执行当前步骤的pre-function。当前步骤执行完成,在未运转到下一步

之前,执行post-function

如下图:

 

 

 

注意:OSWorkFlow里的Action和我们具体业务操作中的Action(比如:xwork中的Action)的区别:

          OSWorkFlowAction是个更粗粒度的操作,它是指OSWorkFlow某一步骤可以执行的操作。在我们经常用的action(比如:xwork中的Action),是业务相关的一个操作,在OSWorkFlow相当于一个具体的function

 

 

http://www.blogdriver.com/showBlog.do?diaryID=142676

opensymphony的开源项目>>

   

很多好用的openSource.webwork就来源于这个组织!

opensymphony 也是一個 opensource 案的組織, 推出了個膾炙人口的
http://wiki.opensymphony.com/space/OpenSymphonyComponents

 

 OSCore: 一些開發 j2ee 基礎的核心程式
OSUser: 人員管理的程式, 主要處理 authetication
OSAccess: 存取控管的程式, 主要處理 authorization
WebWork: 方便簡 MVC Framework
WebWork2: 顧名思義, WebWork 第二版
XWork: Model2x MVC Framework.
SiteMesh: View 端的網頁處理器 ( 許多籍推薦 )
PropertySet: 管理 properties 的好工具
OSWorkflow: WorkFlow engine 工作流引擎
OSCache: J2EE Caching 機制

 

 

BeanShell的中文问题>>

http://www.blogdriver.com/showBlog.do?diaryID=108228

   

XML文件中写这么一段BeanShell

 

String status = getStatus();       // 通过某种途径得到状态

System.out.println(status);       // 这里输出未提交

System.out.println(status.indexOf("未提交"));

 

最后一句就得到了-1

 

System.out.println("未提交");

 

这句直接就得到了乱码。这到底是XML解析器的问题呢还是BeanShell的问题呢?搞不拎清……再试一下去。

 

试过了,在Java里面写:

 

  Interpreter i = new Interpreter();
  i.setClassLoader(getClass().getClassLoader());
  i.eval("System.out.println(/"
中文/");");

 

输出乱码。果然是BeanShell的问题。

原来是BeanShell版本的问题,1.2就不支持中文,换成2.0就搞定了。现在我的工作流配置是这个样子:

      <actions>
        <action id="1201" name="
认领年检报告书">
          <restrict-to>
            <conditions type="AND">
              <condition type="beanshell" name="bsh.condition">
                <arg name="script">
                 com.opensymphony.workflow.util.beanshell.WorkflowStatus.isStatus(transientVars, "
未认领");
                </arg>        
              </condition>
            </conditions>
          </restrict-to>
          <results>
            <unconditional-result old-status="Finished" status="
认领未初审" step="12" owner="${ycheckId}" />
          </results>
        </action>

好漂亮哦!

 

 

OsWorkFlow配合Hibernate攻略>>

http://www.blogdriver.com/showBlog.do?diaryID=178570

1. 下载最新的OsWorkflow2.7.0,地址是https://osworkflow.dev.java.net/files/documents/635/4647/osworkflow-2.7.0.zip

2. 解压后,osworkflow-2.7.0-example.war解压到一个目录,我一般起web,方便对里面进行修改

3. 部署到Tomcat5

4. 试验一下,这个时候,默认的MemoryWorkflowStore应该已经工作正常了

5. 开始向HibernateWorkflowStore转移,先修改WEB-INF/classes/目录下的osworkflow.xml,改为

     <persistence class="com.opensymphony.workflow.spi.hibernate.HibernateWorkflowStore">
     </persistence>

6. 把一个Hibernate.cfg.xml加到WEB-INF/classes/下面,我用的数据库是mysql.

 <property name="hibernate.hbm2ddl.auto">update</property>这句是为了帮你创建数据库表的,跑起来后最好去掉,不去也没关系.


 <?xml version='1.0' encoding='utf-8'?>
 <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
 <hibernate-configuration>
 <session-factory>
  <!-- properties -->
  <property name="connection.driver_class">org.gjt.mm.mysql.Driver</property>
  <property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf-8</property>
  <property name="connection.username">root</property>
  <property name="connection.password">123456</property>

  <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
  <property name="show_sql">true</property>
  <property name="use_outer_join">true</property>

  <property name="connection.pool_size">10</property>
  <property name="statement_cache.size">25</property>

  <property name="hibernate.hbm2ddl.auto">update</property>

  <mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateCurrentStep.hbm.xml"></mapping>
  <mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateHistoryStep.hbm.xml"></mapping>
  <mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateWorkflowEntry.hbm.xml"></mapping>
  <mapping resource="com/opensymphony/module/propertyset/hibernate/PropertySetItemImpl.hbm.xml"></mapping>

 </session-factory>
 </hibernate-configuration>

7. hibernatejarhibernate所有要到的jar,统统加到WEB-INF/lib/

8. 最后一步,修改源程序.
  OsWorkFlow
主要作者Hani,认为生成SessionFactory的责任并不是OsWorkFlow的事情,坚持应该是用户,或者是服务器生成后,传给HibernateWorkflowStore.他可能是Spring的思想太深了吧.我也赶紧开始学习了.但是如果这样的话,最好加个说明,说这个产品的Hibernate特性还必须配合Spring才行,那么我再装一个.既然他没有说明,我又暂时还打算用spring,而我又不想改web层任何代码,那么我就只好修改他的源程序,HibernateWorkflowStore里面生成一个独一无二的SessionFactory.

  
  
修改一是添加下面在开头:

  private static SessionFactory sessionFactory;

  //~ Constructors ///////////////////////////////////////////////////////////
  static{
   try {
     sessionFactory = new Configuration().configure().buildSessionFactory();
   } catch (HibernateException ex) {
      throw new RuntimeException("Configuration problem: " + ex.getMessage(), ex);
    }
 
  }

  二是在init

  sessionFactory = (SessionFactory) props.get("sessionFactory");注释

  编译,生成class,放到osworkflow-2.7.0.jar,取代原来的HibernateWorkflowStore.class,重启服务器,OK

 

 

Shark第一印象>>- >> from GIGIX

  

试了一下Enhydra Shark工作流引擎,暂时还不知道如何编程使用,只有一些肤浅的印象。

 

庞大——OSWorkflowWerkflow都大了许多,概念非常完整,一时间还很难完全理解这些概念。对于OSWorkflowWerkflow这种轻量级工作流来说,要管理的唯一目标就是流程实例(process instance),操纵流程实例的状态变迁,至于如何使用流程实例、状态如何发展,都在工作流引擎之外。Shark管理的目标要宽泛得多,比如有UserUserGroup的概念,用户必须有此角色(即group)才能涉足此流程。不知道这会不会和统一用户管理平台冲突。

 

标准——完全符合WfMC参考模型,并且没有任何额外扩展,采用XPDL作为工作流定义语言。标准是好事,但是对于一些比较特殊的流程,我担心它的扩展能力。比如电子政务中经常会出现一种无序流程(只要领导插手,就可以随便到任何位置),WfMC是否能支持呢?另外,Enhydra提供JaWE编辑器,可能是最好的XPDL可视化编辑器。

 

支持多语言插件——对于需要自动执行的流程,Shark允许插入多种语言的运行单元,包括JavaJavaScriptBeanShellPython等等,相信提供对Groovy的支持也会很简单。我们自己的工作流不支持自动执行,OSWorkflow只支持简单的BeanShell(语句直接写在配置文件中)。

 

持久化——默认的持久化方式是DODS,这是Enhydra自己做的一个O/R mapping。原来用的数据库是HSQL,我今天尝试迁移到MySQL还没有成功,因此也不知道这个持久化机制究竟如何。另外还提供LDAP的持久化,持久化方式的移植也不知道是否困难。我相信O/R mapping基础上移植不会太难。

 

服务接口——可以作为应用程序的一部分在代码级集成,也可以作为外部服务通过RPC集成。Shark很重视CORBA接口,对于异构环境的集成应该是很有帮助的。这里也有一点性能上的顾虑:应用内集成时,工作流引擎和工作流实例会不会带来太大的性能开销?毕竟它给我一种重量级的感觉。

 

明天如果有空就继续尝试,先把应用内集成搞明白,那么RPC集成也就简单了

 

阅读全文
0 0

相关文章推荐

img
取 消
img