写一个简单的工作流(二)

    hoho,今天完成了选择路由的实现,完成了配置文件的读写和解析,流程定义文件还是决定采用xml文件,不过与其他工作流引擎采用的xml完全不同,因为是基于petri网的,因此引入了place的概念,比如下面这个4个节点的顺序路由的流程:
< workflow  maxCases ="100" >
    
< node  type ="start"  name ="start"  id ="0" >
        
< inputs >
            
< place  id ="1"   />
        
</ inputs >
        
< outputs >
            
< place  id ="2"   />
        
</ outputs >
    
</ node >
    
< node  name ="hello"  id ="1"  resource ="user" >
        
< conditions  type ="and" >
            
< condition
                
class ="net.rubyeye.insect.workflow.impl.NullHandler"  value ="false"
                variable-name
="name"   />
        
</ conditions >
        
< handler
            
class ="net.rubyeye.insect.workflow.test.HelloWorldHandler"   />
        
< inputs >
            
< place  id ="2"   />
        
</ inputs >
        
< outputs >
            
< place  id ="3"   />
        
</ outputs >
    
</ node >
    
< node  name ="calc"  id ="2"  resource ="user" >
        
< conditions  type ="and" >
            
< condition  variable-name ="num" >
                
< exp >
                    
<![CDATA[ num<=1000 ]]>
                
</ exp >
            
</ condition >
            
< conditions  type ="or" >
                
< condition  variable-name ="num" >
                    
< exp >
                        
<![CDATA[ num>=10 ]]>
                    
</ exp >
                
</ condition >
                
< condition
                    
class ="net.rubyeye.insect.workflow.impl.NullHandler"  value ="false"
                    variable-name
="name"   />
            
</ conditions >
        
</ conditions >
        
< handler
            
class ="net.rubyeye.insect.workflow.test.CalculateHandler"   />
        
< inputs >
            
< place  id ="3"   />
        
</ inputs >
        
< outputs >
            
< place  id ="4"   />
        
</ outputs >
    
</ node >
    
< node  type ="end"  name ="hello"  id ="3" >
        
< inputs >
            
< place  id ="4"   />
        
</ inputs >
        
< outputs >
            
< place  id ="5"   />
        
</ outputs >
    
</ node >
</ workflow >
   
并行路由和选择路由引入了and-split,and-join,or-split,or-join四种transition,比如and-split,它就有多个输出place:

< node  name ="split"  type ="and-split"  id ="1"  resource ="user" >
        
< inputs >
            
< place  id ="2"   />
        
</ inputs >
        
< outputs >
            
< place  id ="3"   />
            
< place  id ="4"   />
        
</ outputs >
    
</ node >

   Place和Transition都有条件,用于决定操作是否执行,Transition额外指定了驱动的资源以及回调的handler,这一点非常重要,资源可能是用户、用户组、某个时间点定时事件、特定消息等等。
   今天额外发现的一个好处就是,引入Place之后,我可以轻易地将不同的流程连接起来组织成一个更复杂的流程,仅仅是需要修改各个流程的开始和结束的节点的输入输出库所,从而实现了层次化的Petri网,,类似代码:
WorkFlow sequence  =  wm.getWorkFlow( " sequence " );
        WorkFlow concurrency 
=  wm.getWorkFlow( " concurrency " );
        WorkFlow choose 
=  wm.getWorkFlow( " choose " );

        
// 组合流程
        composite  =   new  WorkFlow();
        composite.setName(
" composite " );
        composite.setId(
100 );
        
        wm.saveWorkFlow(composite);

        
// 修改开始结束节点的输入输出库所
        sequence.getEnd().setType(TransitionType.NORMAL);
        sequence.getEnd().setOutputs(concurrency.getStart().getInputs());

        concurrency.getEnd().setType(TransitionType.NORMAL);
        concurrency.getEnd().setOutputs(choose.getStart().getInputs());
        
        composite.setStart(sequence.getStart());
        composite.setEnd(choose.getEnd());
        List
< Transition >  transitions  =   new  ArrayList < Transition > ();
        transitions.addAll(sequence.getTransitions());
        transitions.addAll(concurrency.getTransitions());
        transitions.addAll(choose.getTransitions());
        composite.setTransitions(transitions);




你可能感兴趣的:(写一个简单的工作流(二))