??xml version="1.0" encoding="utf-8" standalone="yes"?>成人av一区二区三区,亚洲性视频网站,久久电影在线http://www.aygfsteel.com/pdw2009/category/12604.htmlJ2EE相关应用技术日?/description>zh-cnFri, 23 May 2008 09:21:02 GMTFri, 23 May 2008 09:21:02 GMT60jbpm最单的例子(?http://www.aygfsteel.com/pdw2009/archive/2007/04/11/110027.html有猫怼的日?/dc:creator>有猫怼的日?/author>Wed, 11 Apr 2007 15:48:00 GMThttp://www.aygfsteel.com/pdw2009/archive/2007/04/11/110027.htmlhttp://www.aygfsteel.com/pdw2009/comments/110027.htmlhttp://www.aygfsteel.com/pdw2009/archive/2007/04/11/110027.html#Feedback0http://www.aygfsteel.com/pdw2009/comments/commentRss/110027.htmlhttp://www.aygfsteel.com/pdw2009/services/trackbacks/110027.html<?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="urn:jbpm.org:jpdl-3.1"  name="example_5">
    
<start-state name="开?>
      
<event type="node-leave">
         
<action name="action1"></action>
      
</event>
      
<transition name="tr1" to="工作?></transition>
      
<transition name="tr2" to="求学?></transition>
    
</start-state>
    
<state name="工作?>
      
<event type="node-enter">
         
<action name="工作" class="com.wide.example5.WorkAction"></action>
      
</event>
      
<transition name="" to="l成正果"></transition>
   
</state>
   
<state name="求学?>
      
<event type="node-enter">
         
<action name="学习" class="com.wide.example5.StudyAction"></action>
      
</event>
      
<transition name="" to="l成正果"></transition>
   
</state>
   
<end-state name="l成正果">
      
<event type="node-enter">
         
<action name="圆满" class="com.wide.example5.EndAction"></action>
      
</event>
   
</end-state>
   
</process-definition>

q是一个比较简单的jbpm程模板Q通过q几天的学习Q基本上是看别h的事子)发现jbpm原来q么的复杂的Q好多东西想C来,特别是一个同行ȝ出的例子Q非常简z的描述了各个小功能炏V以下也是一个很单的jpdl模板Q清楚的描述了note与state的区别。jbpm提供了好几种不同的节炏V?br>
<?xml version="1.0" encoding="UTF-8"?>
<process-definition xmlns="urn:jbpm.org:jpdl-3.1"  name="example_7">
   
<start-state name="start">
      
<transition name="tr1" to="state"></transition>
      
<transition name="tr2" to="node"></transition>
   
</start-state>
   
<state name="state"> <!-- 只有{收signal才执?nbsp;-->
      
<transition name="" to="end"></transition>
   
</state>
   
<node name="node"> <!-- 直接执行Q当{到这节点Ӟ马上执行transition -->
      
<transition name="" to="end"></transition>
   
</node>
   
<end-state name="end"></end-state>
</process-definition>
试代码也很单,
package com.jbpm;

import org.jbpm.JbpmConfiguration;
import org.jbpm.JbpmContext;
import org.jbpm.db.GraphSession;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
import org.jbpm.graph.exe.Token;

import java.io.*;

public class Execute {
    
static JbpmConfiguration cfg=JbpmConfiguration.getInstance();
    
/**
     * 把流E部|到数据?br>     * 
@param file
     
*/
    
public void deploy(String file){
        JbpmContext jc
=null;
        
try{
            FileInputStream fis 
= new FileInputStream("src/proc2.xml");
            ProcessDefinition pd
=ProcessDefinition.parseXmlInputStream(fis);
            jc
=cfg.createJbpmContext();
            jc.deployProcessDefinition(pd);
        }
catch(Exception e){
            e.printStackTrace();
        }
finally{
            jc.close();
        }
    }

    
public static void main(String args[])throws Exception {
        Execute e
=new Execute();
        
//e.deploy("src/proc2");
        JbpmContext jc=cfg.createJbpmContext();
        GraphSession gs
=jc.getGraphSession();
        ProcessDefinition pd
=gs.findLatestProcessDefinition("example_5");
        ProcessInstance pi
=new ProcessInstance(pd);
        Token token
=pi.getRootToken();
        System.out.println(
"token-->"+token.getNode().getName());
        token.signal(
"tr1");
        System.out.println(
"tr1-->"+token.getNode().getName());
        token.signal();
        System.out.println(
"kk->"+token.getNode().getName());
        System.out.println(
"是否已结?>"+pi.hasEnded());
        jc.save(pi);
        
    }
    
    
    
}
以上q个cd应第一个工作流模板Q至于该模板里定义的接口Q?br> <action name="工作" class="com.wide.example5.WorkAction"></action>
该class只需要实现ActionHandler接口p了,具体有啥用我C没搞懂:Q我一直努力着?

]]>
jbpm程部v和执?/title><link>http://www.aygfsteel.com/pdw2009/archive/2007/04/09/109512.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Mon, 09 Apr 2007 15:27:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2007/04/09/109512.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/109512.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2007/04/09/109512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/109512.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/109512.html</trackback:ping><description><![CDATA[   看了q么久jbpmq没有一个头l,需要l分析。jbpm把流E部|到数据库有好几U方法,今晚l于调试通过了java直接部v 的子Q仅于此Q不做分析?br> static JbpmConfiguration cfg=JbpmConfiguration.getInstance(); //jbpm一切一切的基础<br> <br> public void setUp(){<br>  //cfg.createSchema();  //重徏jbpm存储?.<br> }<br>以下是一个部|的Ҏ<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> testDeployProcessDefinition()</span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> Exception{<br>        assertNotNull(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">JbpmConfiguration is null</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,cfg);<br>        FileInputStream fis </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> FileInputStream(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">src/proc1.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>        ProcessDefinition pd</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">ProcessDefinition.parseXmlInputStream(fis);<br>        assertNotNull(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">definition should not be null</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,pd);<br>        JbpmContext jc</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">cfg.createJbpmContext();<br>        </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">{<br>            jc.deployProcessDefinition(pd);<br>        }</span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000">{<br>            jc.close();<br>        }<br>    }</span></div> 实例化ƈ生成程实例的方?br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> testLoadProcessAndInstance() </span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> Exception {<br>        JbpmContext jbpmContext </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> cfg.createJbpmContext() ;            <br>        </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> {<br>              GraphSession graphSession </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> jbpmContext.getGraphSession();                  <br>              ProcessDefinition processDefinition </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <br>              graphSession.findLatestProcessDefinition(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pro1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">); <br>              <br>              ProcessInstance processInstance </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> <br>                  </span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000"> ProcessInstance(processDefinition);<br>              Token token </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> processInstance.getRootToken(); <br>              <br>              assertEquals(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">start</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, token.getNode().getName());<br>              </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Let's start the process execution</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">             token.signal();<br>              assertEquals(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">state1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, token.getNode().getName());<br>              jbpmContext.save(processInstance);<br>            } </span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000"> {<br>              </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> Tear down the pojo persistence context.</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">              jbpmContext.close();<br>            }<br>    }</span></div> 再执行上面生成的程Ҏ<br> <div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">    </span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> testLoadInstanceAndDoActionAndEnd() </span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000"> Exception {<br><br>        JbpmContext jbpmContext </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> cfg.createJbpmContext() ;            <br>          </span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000"> {<br>              GraphSession graphSession </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> jbpmContext.getGraphSession();<br>              ProcessDefinition processDefinition </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> graphSession.findLatestProcessDefinition(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pro1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>              List processInstances </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> graphSession.findProcessInstances(processDefinition.getId());                   <br>              ProcessInstance processInstance </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">  (ProcessInstance) processInstances.get(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);                  <br>             </span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"> this.assertEquals("message",(String)(processInstance.getContextInstance().getVariable("message")));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">              processInstance.signal();<br>              assertTrue(processInstance.hasEnded());<br>              jbpmContext.save(processInstance);<br>            } </span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000"> {<br>              jbpmContext.close();<br>            }<br><br>    }</span></div> <br>实际上,上面的几D代码中写来写去p几句话吧。加载流E,生成实例Q然后签收执行?br>明天l箋...... <img src ="http://www.aygfsteel.com/pdw2009/aggbug/109512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2007-04-09 23:27 <a href="http://www.aygfsteel.com/pdw2009/archive/2007/04/09/109512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jbpm表结构部|到oraclehttp://www.aygfsteel.com/pdw2009/archive/2007/04/09/109487.html有猫怼的日?/dc:creator>有猫怼的日?/author>Mon, 09 Apr 2007 12:01:00 GMThttp://www.aygfsteel.com/pdw2009/archive/2007/04/09/109487.htmlhttp://www.aygfsteel.com/pdw2009/comments/109487.htmlhttp://www.aygfsteel.com/pdw2009/archive/2007/04/09/109487.html#Feedback0http://www.aygfsteel.com/pdw2009/comments/commentRss/109487.htmlhttp://www.aygfsteel.com/pdw2009/services/trackbacks/109487.html看了|上挺多例子l于?span>jbpm的数据库l构部v好,之前部v到mysql ,今晚部vCoracle。步骤如下:
1、在lib目录下徏立oracle目录Q把oracle 9.1的jdbc驱动class12.jar拯q来?br>2、在src/resources目录下徏立oracle目录Q把hsqldb目录入的两个文g拯q来?br>3、修改create.db.hibernate.properties

 

hibernate.dialect=org.hibernate.dialect.Oracle9Dialect
# for Oracle 
8 compatibility use
#hibernate.dialect
=org.hibernate.dialect.OracleDialect
hibernate.connection.driver_class
=oracle.jdbc.driver.OracleDriver
hibernate.connection.url
=jdbc:oracle:thin:@192.168.0.20:1521:JBPM
hibernate.connection.username
= JBPM
hibernate.connection.password
= JBPM
hibernate.show_sql
=true
hibernate.c3p0.min_size
=1
hibernate.c3p0.max_size
=3

 

4、在src目录入copy build.deploy.xml文g到src目录Qƈ改名为build.deploy.oracle.xmlQ然后修Ҏ件的create.db    target。内容如?/span>

 



<target name="create.db" depends="declare.jbpm.tasks" description="creates a oracle database with the jbpm tables and loads the processes in there">

 
<jbpmschema actions="create" properties="${basedir}/src/resources/oracle/create.db.hibernate.properties" cfg="${basedir}/src/config.files/hibernate.cfg.xml"/> 

 
<loadidentities file="${basedir}/src/resources/oracle/identity.db.xml" properties="${basedir}/src/oracle/hsqldb/create.db.hibernate.properties"/> 

 
<ant antfile="build.xml" target="build.processes" inheritall="false" /> 

 
<deploypar properties="${basedir}/src/resources/oracle/create.db.hibernate.properties">

    
<fileset dir="build" includes="*.par" />

 
</deploypar>

</target>

至于开发环境就把jbpm本n自带例子中相关jar文gUL到自己新建的celipse Web目中了?

jbpm表名所对应的中文名U?
JBPM_ACTION action记录?nbsp;
JBPM_DECISIONCONDITIONS l果条g?nbsp;
JBPM_DELEGATION 委托?nbsp;
JBPM_EVENT 事g?nbsp;处理q入或者离开事g 
JBPM_EXCEPTIONHANDLER 异常处理?nbsp;
JBPM_ID_GROUP 用户l表 
JBPM_ID_MEMBERSHIP 用户成员?nbsp;表现用户和组之间的多对多关系 
JBPM_ID_PERMISSIONS 用户权限?nbsp;
JBPM_ID_USER 用户?nbsp;
JBPM_MODULEDEFINITION 模块定义?nbsp;
JBPM_MODULEINSTANCE 模块实例?nbsp;
JBPM_NODE 程节点?nbsp;
JBPM_POOLEDACTOR 汇集参与着?nbsp;
JBPM_PROCESSDEFINITION 程定义?nbsp;
JBPM_PROCESSFILE 程文g?nbsp;
JBPM_PROCESSFILEBLOCK 程文g块表 
JBPM_PROCESSINSTANCE 程实例?nbsp;
JBPM_RUNTIMEACTION q行中行 
JBPM_SCRIPTVARIABLES 脚本变量?nbsp;
JBPM_SWIMLANE 泳道?nbsp;
JBPM_SWIMLANEINSTANCE 泳道实例?nbsp;
JBPM_TASK d?nbsp;
JBPM_TASKACTORPOOL 用户行ؓ汇?nbsp;
JBPM_TASKINSTANCE d实例 
JBPM_TIMER 计时?nbsp;
JBPM_TOKEN 令牌?nbsp;
JBPM_TOKENVARIABLEMAP 令牌变量影射?nbsp;
JBPM_TRANSITION 转换?nbsp;
JBPM_VARIABLEINSTANCE 变量实例?nbsp;
JBPM_VARIABLEINSTANCEBLOCK 变量实例块表 
JBPM_VARIABLEMAPPING 变量影射?nbsp;

 

 



]]>
一个值得参考的osworkflow工作模?/title><link>http://www.aygfsteel.com/pdw2009/archive/2007/01/15/94002.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Mon, 15 Jan 2007 09:31:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2007/01/15/94002.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/94002.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2007/01/15/94002.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/94002.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/94002.html</trackback:ping><description><![CDATA[     摘要: <? xml version="1.0" encoding="UTF-8" ?> <! DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.7//EN" "http://www.opensymphony.com/oswork...  <a href='http://www.aygfsteel.com/pdw2009/archive/2007/01/15/94002.html'>阅读全文</a><img src ="http://www.aygfsteel.com/pdw2009/aggbug/94002.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2007-01-15 17:31 <a href="http://www.aygfsteel.com/pdw2009/archive/2007/01/15/94002.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工作管理系l需?/title><link>http://www.aygfsteel.com/pdw2009/archive/2006/10/17/75677.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Tue, 17 Oct 2006 08:26:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2006/10/17/75677.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/75677.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2006/10/17/75677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/75677.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/75677.html</trackback:ping><description><![CDATA[ <div> <font size="3">整理的工作流理pȝ的需求列表,惌做一个好东西真的很难?/font> <p> <br /> <font size="3">工作定义?/font> </p> <p> <font size="3">  1.1 工作定义语法检?br />  1.2 工作定义有效性检查?br />  1.3 程可视化徏模?br />  1.4 l织机构数据的引用?br />  1.5 支持ȝq程定义 <br />  1.6 工作数据定义 ?br />  1.7 囑Ş打印工作过E定义图?br />  1.8 以xml格式保存q程定义文g<br />  1.9 直接Ҏ板库讉K操作 <br />  1.10 xmlq程定义文g打开~辑 </font> </p> <p> <font size="3">工作模板库 </font> </p> <p> <font size="3">  2.1 工作模板的导入和导出?br />  2.2 工作模板版本控制?br />  2.3 工作模板复制?br />  2.4 工作模板所有者定?br />  2.5 工作模板状态(草稿、发布、过Ӟ<br />  2.6 工作模板有效时?/font> </p> <p> <font size="3">实例初始化?/font> </p> <p> <font size="3">  3.1 通过Email启动 <br />  3.2 通过文本文gQText FilesQ启?br />  3.3 通过XML消息启动  <br />  3.4 旉事g启动  <br />  3.5 手工启动 <br />  3.6 q程调用启动 <br /> <br />工作模式?/font> </p> <p> <font size="3">  4.1 序QSequenceQ?br />  4.2 q行分支QAND-splitQ?br />  4.3 q行汇聚QAND-joinQ?br />  4.4 条g分支QConditional routingQ、互斥选择QExclusive Choice、XOR<br />  4.5 单汇聚(XOR-joinQ?br />  4.6 多重选择QOR-split、Conditional routingQ?br />  4.7 多重汇聚Q?Q?<br />  4.8 部分汇聚QPartial joinQMI<br />  4.9 取消zd  <br />  4.10 取消实例  <br />  4.11 同步/异步子过E?br /> <br />工作Q务分配?/font> </p> <p> <font size="3">  5.1 d分配的两U模式(拉和推)<br />  5.2 d队列Q拉模式Q?br />  5.3 按工作量分配dQ推模式Q?br />  5.4 分配dl所有h员(部门、角艌Ӏ工作组Q?br />  5.5 按h员优先数分配dQ适合Z角色d分配Q?br />  5.6 先来先做QFCFAQ,Q务队列中最早创建的d分配l最先提出执行Q务请求的人员<br />  5.7 分配dl指定h?br />  5.8 推模式下的Q务分配异常处理(d分配异常Ӟ通知模板所有者或工作管理员Q?br />  5.9 d重分配(Q务分配给其他用户、指定角色中的用戗角Ԍ<br />  5.10 d替代者,׃h员指定(交办、代办)</font> </p> <p> <font size="3">工作动作?/font> </p> <p> <font size="3">  5.11 接收dQ状态{换)accept<br />  5.12 退Ӟ回退C一节点Q)decline<br />  5.13 执行d<br />  5.14 完成dQ状态{换)<br />  5.15 反向回传/抽单/召回QProcess RollbackQ?br />  5.16 分配dl指定角?br />  5.17 分配dl指定h?br />  5.18 使用路由表分配Q务?br />  5.19 取消d分配<br />  5.20 创徏子过E(Q务节点用子过E代替?Q?br />  5.21 讄d优先U(动态修改工作流zd优先U)<br />  5.22 讄d说明<br />  5.23 讄d期限Q设|之时v旉Dc指定时间点Q?br />  5.24 取消d<br />  5.25 挂vQ暂停)d<br />  5.26 l止d<br />  5.27 启动工作实?br />  5.28 挂vQ暂停)工作实?br />  5.29 取消工作实?br />  5.30 l止工作实?br />  5.31 讄工作实例说?br />  5.32 讄工作实例变量(工作实例变量赋|Q可以作为工作流异常处理的一U方?/font> </p> <p> <font size="3">工作活动\由?/font> </p> <p> <font size="3">  6.1 Z角色路由QQ务分配给角色Q职务发生变化,程设计不需变化Q?br />  6.2 Z关系路由Q根据相对职务关p\由)<br />  6.3 讑֮型(Ad hocQ\由(由办理h员指定下一节点办理人)Ҏ程处理内容Q由办理Z指定人员中选择合适的下一步执行h?/font> </p> <p> <font size="3">工作组l机构?/font> </p> <p> <font size="3">  7.1 支持LDAP目录服务<br />  7.2 支持l(GroupQ?br />  7.3 循环l?br />  7.4 权重l?br />  7.5 工作职务l(相同职务的hl成一个组Q?br />  7.6 支持动态定义组Q流E执行过E中定义的组Q?br />  7.7 多重角色理Q一人数职)<br />  7.8 相对职务关系<br />  7.9 l织图拥有hQ组l结构的分l护Q?/font> </p> <p> <font size="3">工作时间管理?/font> </p> <p> <font size="3">  8.1 非工作日讑֮<br />  8.2 旉事情启动工作实例(指定旉炏V时间间隔、周期时_<br />  8.3 d挂v恢复Q指定时间点、时间间隔)<br />  8.4 q程实例挂v恢复Q指定时间点、时间间隔)<br />  8.5 d时通知<br />  8.6 工作超旉知<br />  8.7 pȝ旉</font> </p> <p> <font size="3">工作系l通知 </font> </p> <p> <font size="3">  9.1 以邮件方式通知工作时<br />  9.2 可自订通知邮gQ新d通知Q?br />  9.3 d式邮仉知Q相对Web-based被动方式Q?br />  9.4 工作异帔R知<br />  9.4 d取消通知<br />  9.5 工作取消通知</font> </p> <p> <font size="3">工作异常处理?/font> </p> <p> <font size="3">  10.1 异常的分c?br />  10.2 不同的异常处理方?br />  10.3 异常的报告、通知机制<br />  10.4 异常恢复E序的预定义</font> </p> <p> <font size="3">工作接口需求?/font> </p> <p> <font size="3">  11.1 与Email服务器接口(JMSQ?br />  11.2 与文件系l接口(如NTFS、unix-FSQ?br />  11.3 与ERP、CRM、HR、SCM{系l接?br />  11.4 与文档管理系l系l接?br />  11.5 与其它工作流pȝ接口<br />  11.6 与其它应用系l接?/font> </p> <p> <font size="3">工作系l需求?/font> </p> <p> <font size="3">  12.1 支持多个操作pȝQ包括windows、AIX、Solaris、HP-Unix、Linux{?br />  12.2 支持多种数据库,包括MS SQL server、Oracle、DB2、MySQL{?br />  12.3 支持多种应用服务器,包括weblogic、websphere、Jboss、Apusic、Tomcat{?br />  12.4 完备的系l日?br />  12.5 可处理大量流E?br />  12.6 从失败(或错误)中恢复系l(自动、手动)、系l(应用Q数据备?br />  12.7 支持q发处理</font> </p> <p> <font size="3">工作系l管理?/font> </p> <p> <font size="3">  13.1 囑Ş化流E监?br />  13.2 程实例动态修改(修改未执行的q程步骤Q?br />  13.3 工作负荷量显C?br />  13.4 工作统计(程模板、流E实例、Q务统计)<br />  13.5 自定义统计报?br />  13.6 l计数据囑Ş化显C?br />  13.7 临时更改收g?br />  13.8 工作重?br />  13.9 程实例挂v/恢复<br />  13.10 zd实例挂v/恢复<br />  13.11 代理未来工作<br />  13.12 可指定代理期?br />  13.13 工作实例超时统?br />  13.14 单一步骤时l计<br />  13.15 可传回子程l计数据<br />  13.16 服务器定时清?/font> </p> <p> <font size="3">工作客L </font> </p> <p> <font size="3">  14.1 B/Sl构客户端界?br />  14.2 览器端的数字认证功?br />  14.3 单点d<br />  14.4 按重要程度排列Q务清?br />  14.5 用户查看程执行状?br />  14.6 我的d和共享Q务队列(按角色分c)<br />  14.7 从共享Q务队列中选取d<br />  14.8 用户指定/取消代理?br />  14.9 昄已被代理的工?/font> </p> <p> <font size="3">工作数据?/font> </p> <p> <font size="3">  15.1 基本数据cdQ整型、符点型、字W型、日期型、布型Q?br />  15.2 复合数据cdQ数l)<br />  15.3 XML数据定义<br />  15.4 旉数据Q三U类型:旉炏V时间间隔、周期时_<br />  15.5 附gQword、excel{)文g夹的概念QFolderQ?br />  15.6 附g的检?出?<br />  15.7 变量作用域(全局变量、过E变量)<br />  15.8 数据的访问控Ӟd、读、不可见Q?br />  15.9 数据集合QData SetQ(由多个不同类型数据或数据子集合所构成Q?br />  15.10 数据的表玎ͼ表单Q?br />  15.11 子表单(sub-formQ?br /></font> </p> <p> <font size="3">x看,自己实现的太了Q!Q只做到了皮毛而已!需l箋努力</font> </p> </div> <img src ="http://www.aygfsteel.com/pdw2009/aggbug/75677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2006-10-17 16:26 <a href="http://www.aygfsteel.com/pdw2009/archive/2006/10/17/75677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工作系l功能特性描q?/title><link>http://www.aygfsteel.com/pdw2009/archive/2006/09/12/69127.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Tue, 12 Sep 2006 04:31:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2006/09/12/69127.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/69127.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2006/09/12/69127.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/69127.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/69127.html</trackback:ping><description><![CDATA[ <div id="wmqeeuq" class="postText"> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"> <span style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: Arial; mso-hansi-font-family: Arial; mso-bidi-font-weight: bold">工作系l功能特性描q?/span> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; FONT-FAMILY: Arial; mso-bidi-font-weight: bold; mso-bidi-font-family: 'Times New Roman'"> <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /?> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"> <span style="LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">~写Q?/span> <span lang="EN-US" style="LINE-HEIGHT: 125%; FONT-FAMILY: Arial; mso-bidi-font-weight: bold; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt"> <span style="mso-field-code: ' USERNAME '"> <span style="mso-no-proof: yes">jerry</span> </span> </span> <b> <span lang="EN-US" style="LINE-HEIGHT: 125%; FONT-FAMILY: 华文新魏; mso-bidi-font-size: 10.5pt; mso-fareast-font-family: 宋体"> </span> </b> <span style="LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">创徏日期Q?/span> <span lang="EN-US" style="LINE-HEIGHT: 125%; FONT-FAMILY: Arial; mso-bidi-font-weight: bold; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt"> <span style="mso-no-proof: yes">2005-05-18</span> </span> <span lang="EN-US" style="LINE-HEIGHT: 125%; mso-bidi-font-size: 10.5pt"> </span> <span style="LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">最后更斎ͼ</span> <span lang="EN-US" style="LINE-HEIGHT: 125%; FONT-FAMILY: Arial; mso-bidi-font-weight: bold; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt"> <span style="mso-no-proof: yes">2005-05-20</span> </span> <span lang="EN-US" style="LINE-HEIGHT: 125%; mso-bidi-font-size: 10.5pt"> </span> <span style="LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">版次Q?/span> <span lang="EN-US" style="LINE-HEIGHT: 125%; FONT-FAMILY: Arial; mso-bidi-font-weight: bold; mso-bidi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">1.0</span> <span lang="EN-US" style="LINE-HEIGHT: 125%; mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align="center"> <span lang="EN-US" style="LINE-HEIGHT: 125%; mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt"> <span lang="EN-US" style="LINE-HEIGHT: 125%; mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21.25pt; TEXT-INDENT: -21.25pt; tab-stops: list 21.25pt; mso-outline-level: 1; mso-list: l0 level1 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.<span style="FONT: 7pt 'Times New Roman'">      </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程操作</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21.25pt; LINE-HEIGHT: 150%"> <span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">程在流转过E中需要确定的Z一环节以及该环节的相应的参与?/span> <span lang="EN-US" style="LINE-HEIGHT: 150%; mso-bidi-font-size: 10.5pt">(</span> <span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">人或应用E序</span> <span lang="EN-US" style="LINE-HEIGHT: 150%; mso-bidi-font-size: 10.5pt">)</span> <span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">Q所有的程操作均是围绕q两斚wq行?/span> <span lang="EN-US" style="LINE-HEIGHT: 150%; mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.1.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">{收</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">对事进行签收表明该程步骤q行生效阶段Q说明当前h员已事从待办状态切换ؓ了在办状态?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.2.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">直?/span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%">(</span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">直流</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%">) <o:p></o:p></span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">直流为流E操作中最为简单的一U操作,直流为当前环节往下仅有一个环节,不存在分支的{Q在直流q程中可定的是程下一环节Q不可确定的是执行此环节的h?/span> <span lang="EN-US">(</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">需要系l根据流E设计时配置的环节参与角色获取具有相x限的人员Q根据配|的是否需要选择人员来决定是否显C选h界面</span> <span lang="EN-US">)</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span lang="EN-US"> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.3.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">分?/span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%">(</span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">分流</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%">)<o:p></o:p></span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">分流在流E操作中也很常见Q分ؓ当前环节往下具有一个以上的环节可供选择Q即存在分支的流转,在此U情况下往往需要提供选择环节的页面以供用L定需要发往哪个环节?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span lang="EN-US"> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.4.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">q流</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt">q流为当前环节往下具有一个以上的环节可供选择Q即存在分支的流转,但ƈ不需要用户选择往哪个环节的一U流转操作,在ƈ的情况下系l将自动往所有的分支环节{Qƈ{待所有分支环节办理完毕后汇总至他们共同的下一环节?/span> <span lang="EN-US" style="LINE-HEIGHT: 150%; mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="LINE-HEIGHT: 150%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'; mso-bidi-font-size: 10.5pt"> </span> <span lang="EN-US" style="LINE-HEIGHT: 150%; mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span lang="EN-US" style="LINE-HEIGHT: 150%; mso-bidi-font-size: 10.5pt"> <o:p> </o:p> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.5.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">条g{</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">条g{为根据流E设计时所~写的脚本由pȝ计算出结果ƈ军_程的下一环节或下一环节的参与者。D例来_当前甌事项金额大于</span> <span lang="EN-US">10</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">万的时候至l理审批Q而大?/span> <span lang="EN-US">50</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">万的时候则需递交臛_ȝ理审扏V?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'"> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span lang="EN-US"> </span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.6.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">退?/span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">审批人员收到甌事项后发现申h件不W或资料不齐{时需要退回当前申请事至甌人或上一环节受理人,q种程操作通常UCؓ退回?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.7.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">取回</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">当审批h员发现申请事发送给了一个不合适的办理人员Ӟ如该办理人员未{收该事,则审批h员可此甌事项取回Q避免不必要的麻烦?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.8.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">挂v</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">׃甌事项的资料不W或其他原因需要将当前甌事项q行暂停办理Q挂起当前流E,当需要恢复的时候则恢复该流El执行?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.9.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">l止</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%">(</span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">撤销甌</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%">)<o:p></o:p></span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">׃甌事项的不合理或申请h员需要撤销该事的甌Ӟ可对该流E进行终止或撤销甌操作?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.10.<span style="FONT: 7pt 'Times New Roman'">        </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">会签</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">甌事项需要几个h员按序的进行审批,事项按序依次发送给相应的h员进行事的审批。D例来_事项需要进行会{,选择人员分别为张三、李四、王五,那么张三首先接收到该事项Q张三填写意见后q行发送,pȝ自动发送至李四q行处理Q李四处理完毕后pȝ自动发送至王五Q王五处理完毕后q入实现的下一处理环节处理?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.11.<span style="FONT: 7pt 'Times New Roman'">        </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">催办</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">事项审批q程中的审批人员如觉得该事项在某一个审批h员处停留旉太长的话可对其进行催促,以提醒其q速办理该事项Q在程操作上称为催办?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.12.<span style="FONT: 7pt 'Times New Roman'">        </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">竞争办理</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">竞争办理的概念ؓ当两个用户都收到某事ҎQ谁先签收了该事则对该事项q行办理Q同时该事项也将从另一用户的待办列表中U除?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.13.<span style="FONT: 7pt 'Times New Roman'">        </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">联审</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">联审为流E操作中较复杂的一U,事项发送后发送至当前环节的下面所有环节,q时的环节通常׃个子程构成Q在各自的子程执行完毕后统一回至LE的下一环节中,此种{q程UCؓ联审?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span lang="EN-US"> </span> </p> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.14.<span style="FONT: 7pt 'Times New Roman'">        </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">跌{</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> <p> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">审批人员在进行事审ҎQ觉得该事项不需要经q流E图上所C意的其下的环节而可直接跌{C面的其他L一个环节进行流转?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如审批h员觉得不需要提交至U长审批以及处长审批Q则可直接通过跌{操作事直接送至办公室环节进行办理?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.15.<span style="FONT: 7pt 'Times New Roman'">        </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">传阅</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">审批人员在进行事审ҎQ觉得需要将该事传送给相关人员q行查看Q此{q程UCؓ传阅Q相关h员在接收到此事项后只可查看不可进行审扏V?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.16.<span style="FONT: 7pt 'Times New Roman'">        </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">传阅办理</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">传阅办理与传阅的不同之处在于接收到此事项的h员可选择Ҏ事项q行办理或不办理Q而事的{q不{待此传阅办理过E的l束?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">1.17.<span style="FONT: 7pt 'Times New Roman'">        </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">意见补签</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">事项的审批h员在事项已经发送至后箋环节办理的过E中均可q行意见的补{,此操作称为意见补{?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21.25pt; TEXT-INDENT: -21.25pt; tab-stops: list 21.25pt; mso-outline-level: 1; mso-list: l0 level1 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">2.<span style="FONT: 7pt 'Times New Roman'">      </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程理</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">2.1.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">调度</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在流E执行的q程中根据流E的执行状态等{可对该程事项q行调度Q将事项调度至相应的环节中?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">2.2.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">监控</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">ҎE事进行监控,包括查看程的执行过E?/span> <span lang="EN-US">(</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">最好是可视化的囑Ş表示</span> <span lang="EN-US">)</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">、流E执行过E中的相关信?/span> <span lang="EN-US">(</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">如签收h、签收时间、办理时间等</span> <span lang="EN-US">)</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">2.3.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">查询</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ程事项的关键字ҎE事进行简单或l合的查询?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">2.4.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">l计分析</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Ҏ询所得的程事项q行l计分析Q主要ؓ分析某类事项的办l率、效率、在办g、已办结件、已归档件等{?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21.25pt; TEXT-INDENT: -21.25pt; tab-stops: list 21.25pt; mso-outline-level: 1; mso-list: l0 level1 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">3.<span style="FONT: 7pt 'Times New Roman'">      </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">程列表</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">3.1.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">待办列表</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在待办列表中列出发送至当前用户的所有事,包括事项的一些基本信?/span> <span lang="EN-US">(</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">标题Q时间等{?/span> <span lang="EN-US">)</span> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">Q用户通过此处q行事项的签收工作?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">3.2.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">已办列表</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在已办列表中列出l过当前用户办理但目前尚未办l归档的所有事,用户可通过此对q些事项的办理状况进行监控,同时也可对事进行催办操作?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">3.3.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">已办l列?/span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在已办结列表中列出经q当前用户办理ƈ已办l归档的所有事,用户可通过此查看事的整个办理q程以及办理l果?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 21.25pt; TEXT-INDENT: -21.25pt; tab-stops: list 21.25pt; mso-outline-level: 1; mso-list: l0 level1 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">4.<span style="FONT: 7pt 'Times New Roman'">      </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">与应用的接口</span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 16pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">4.1.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">l织机构的接?/span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在事Ҏ转过E中需要确定下一环节的参与者,此时如配|了此环节需q行选h操作Q此旉要调用应用的l织机构接口以提供选h界面供用户选择下一环节的参与者,接口中需提供按角色获取h员以及根据h员组装出其相应的l织机构树?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">4.2.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">角色的接?/span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">在流E设计时需配置相应环节的参与角Ԍ此时需调用应用提供的角色接口,接口中需提供获取该流E事类型的角色、创程事项cd的角色的功能Q或者也可以采用在设计阶D不调用应用接口Q当程部v臛_用时同时创徏所需的角艌Ӏ?/span> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; TEXT-INDENT: -1cm; tab-stops: list 1.0cm; mso-outline-level: 2; mso-list: l0 level2 lfo1"> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; mso-fareast-font-family: 'Times New Roman'"> <span style="mso-list: Ignore">4.3.<span style="FONT: 7pt 'Times New Roman'">    </span></span> </span> </b> <b style="mso-bidi-font-weight: normal"> <span style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表单的接?/span> </b> <b style="mso-bidi-font-weight: normal"> <span lang="EN-US" style="FONT-SIZE: 14pt; LINE-HEIGHT: 125%"> <o:p> </o:p> </span> </b> </p> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt 1cm; LINE-HEIGHT: 150%"> <span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">表单使得程pȝ有了实际的应用意义,表单作ؓ{q程中的载体Q与程pȝ的接口至关重要,涉及到表单的存储方式Q表单数据的获取方式Q流E环节中表单的挂接,程信息与表单信息构成的相关数据表?/span> </p> </div> <img src ="http://www.aygfsteel.com/pdw2009/aggbug/69127.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2006-09-12 12:31 <a href="http://www.aygfsteel.com/pdw2009/archive/2006/09/12/69127.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>osworkflow不错的文?/title><link>http://www.aygfsteel.com/pdw2009/archive/2006/06/09/51671.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Fri, 09 Jun 2006 05:26:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2006/06/09/51671.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/51671.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2006/06/09/51671.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/51671.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/51671.html</trackback:ping><description><![CDATA[ <script language="javascript"> <!-- function getObject(objectId) { if(document.getElementById) { return document.getElementById(objectId) } else if(document.all&&document.all(objectId)) { return document.all(objectId) } else { return false } } function hideObject(objectId) { var obj=getObject(objectId); if(obj&&obj.style) { obj.style.display="none"; return true } return false } function showObject(objectId) { var obj=getObject(objectId); if(obj&&obj.style) { obj.style.display=""; return true } return false } function hideComment(){ hideObject("commentForm"); hideObject("commentform"); return; } function showComment(){ return; } //--> </script>  OSWorkflow在用L理方面所提供的功能,主要包括用户的创建、群l的定义、用户验证、以及对step执行人的跟踪记录和执行权限的判断{等? <form id="Form1" name="Form1" onsubmit="javascript:return WebForm_OnSubmit();" action="447742.aspx" method="post"><div id="wmqeeuq" class="pagelayout"><div id="wmqeeuq" class="centercolumn"><div id="wmqeeuq" class="post"><div id="wmqeeuq" class="postText"><div id="wmqeeuq" class="post"><div id="wmqeeuq" class="storycontent"><p>用户/组的管理是由UserManager来完成的Q它包含于一个单独的jar包内。我们可以这样用UserManagerQ?/p><p class="prettycode">UserManager um = UserManager.getInstance();<br />User test = um.createUser("test");<br />test.setPassword("test");<br />Group foos = um.createGroup("foos");<br />test.addToGroup(foos); </p><p>利用UserManager也可以实现用户验证功能:</p><p class="prettycode">UserManager um = UserManager.getInstance();<br />boolean authenticated = false;<br />authenticated = um.getUser(username).authenticate(password);<br />if (authenticated) {<br /> session.setAttribute("username");<br /> …?br />} else {<br /> …?br />} </p><p>关于step执行人的跟踪Q首先我们可以在创徏程的时候传入调用者(callerQ名Uͼ比如Q?/p><p class="prettycode">Workflow wf = new BasicWorkflow((String) session.getAttribute("username")); </p><p>BasicWorkflow会负责创Z个实CWorkflowContext接口的实例,其中记录了caller的信息。利用com.opensymphony.workflow.util.CallerQ可以将WorkflowContext中的caller随时植入transientVars中,以供后箋的条件判断。ؓ此,我们需要在程定义文g中的适当位置加入如下定义Q比如initial-actions中的pre-functions节点处)Q?/p><p class="prettycode"><pre-functions><br /> <function type="class"><br />  <arg name="class.name">com.opensymphony.workflow.util.Caller</arg><br /> </function><br /></pre-functions> </p><p>Caller是一个FunctionProviderQ其excuteҎ中包含了如下代码Q?/p><p class="prettycode">WorkflowContext context = (WorkflowContext) transientVars.get("context");<br />transientVars.put("caller", context.getCaller()); </p><p>同时Q我们还可以指定程中某个step的执行hQownerQ,只需要在action的results节点处ؓ其指定owner属性:</p><p class="prettycode"><step id="2?name="Edit Doc"><br /> <actions><br />  <action id="2?name="Sign Up For Editing"><br />   …?br />   <results><br />    <unconditional-result old-status="Finished?status="Underway?step="2?owner="${caller}"/><br />   </results> </p><p>利用caller和owner信息Q我们可以在程定义文g的condition节点中以多种形式指定限定条gQ比如,利用脚本限定只允许caller为test的用戯发某l果Q?/p><p class="prettycode"><result old-status="Finished"><br /> <condition type="beanshell"><br />  <arg name="script"><br />   propertySet.getString("caller").equals("test")<br />  </arg><br /> </condition><br /> …?br /></result> </p><p>又比如,利用util包中的OSUserGroupCondition限定仅当caller为foos组中的用户Ӟ才触发actionQ?/p><p class="prettycode"><action id="1?name="Start Workflow"><br /> …?br /> <condition type="class"><br />  <arg name="class.name">com.opensymphony.workflow.util.OSUserGroupCondition</arg><br />  <arg name="group">foos</arg><br /> </condition> </p><p>再比如:利用util包中的AllowOwnerOnlyCondition限定仅当caller{于ownerӞ才触发actionQ?/p><p class="prettycode"><action id="1?name="Start Workflow"><br /> …?br /> <condition type="class"><br />  <arg name="class.name">com.opensymphony.workflow.util.AllowOwnerOnlyCondition</arg><br /> </condition> </p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=79" dc:identifier="http://morningspace.51.net/weblog/index.php?p=79" dc:title="OSWorkflow解读之九" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/79" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/29/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-78"><a title="Permanent Link: OSWorkflow解读之八" rel="bookmark">OSWorkflow解读之八</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 10:21 am </div><div id="wmqeeuq" class="storycontent"><p>WorkflowQuery及其有关查询c?gt;></p><p>我们知道Q通常ZL希望了解程当前的运行状况,因此需要工作流引擎在提供流E流转的基本功能的同Ӟq需要提供查询功能。在osworkflow中,查询功能是由WorkflowQuery及其相关cL供的?/p><p>WorkflowQuery提供了两U类型的构造函敎ͼ</p><p class="prettycode">public WorkflowQuery(int field, int type, int operator, Object value)<br />public WorkflowQuery(WorkflowQuery left, int operator, WorkflowQuery right) </p><p>我们可以利用W一个构造函数创建基本的WorkflowQuery实例Q然后利用第二个构造函数组l装配。以查询执行者是“test”且状态是“Underway”的step实例ZQ?/p><p class="prettycode">WorkflowQuery queryLeft = new WorkflowQuery(<br />  WorkflowQuery.OWNER, WorkflowQuery.CURRENT, WorkflowQuery.EQUALS, “test");<br />WorkflowQuery queryRight = new WorkflowQuery(<br />  WorkflowQuery.STATUS, WorkflowQuery.CURRENT, WorkflowQuery.EQUALS, “Underway");<br />WorkflowQuery query = new WorkflowQuery(<br />  queryLeft, WorkflowQuery.AND, queryRight);<br />List workflows = wf.query(query);<br />for (Iterator iterator = workflows.iterator(); iterator.hasNext();)<br />  Long wfId = (Long) iterator.next();<br />} </p><p>装配好的查询条gQ将会传入AbstractoWorkflow的queryҎ中,然后再由WorkflowStore的queryҎ执行具体查询操作。不同的WorkflowStore实例其查询方式不相同,以MemoryWorkflowStoreZQ它遍历所有位于cache中的程Q然后将满条g的流EID攑օ一个ArrayList中返回,查询的核心代码采用了递归调用的Ş式:</p><p class="prettycode">if (query.getLeft() == null) {<br /> return queryBasic(entryId, query);<br />} else {<br /> int operator = query.getOperator();<br /> WorkflowQuery left = query.getLeft();<br /> WorkflowQuery right = query.getRight();<br /> switch (operator) {<br />  case WorkflowQuery.AND:<br />   return query(entryId, left) && query(entryId, right);<br />  case WorkflowQuery.OR:<br />   return query(entryId, left) || query(entryId, right);<br />  case WorkflowQuery.XOR:<br />   return query(entryId, left) ^ query(entryId, right);<br /> }<br />} </p><p>q里的queryBasic再次使用了递归调用的方式,详细情况可以查看osworkflow的源代码。通过q样的方式,可以满L复杂的流E查询条件指定?</p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=78" dc:identifier="http://morningspace.51.net/weblog/index.php?p=78" dc:title="OSWorkflow解读之八" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/78" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/28/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-74"><a title="Permanent Link: OSWorkflow解读之七" rel="bookmark">OSWorkflow解读之七</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 4:32 pm </div><div id="wmqeeuq" class="storycontent"><p>Descriptors>></p><p>在osworkflow的很多地斚w会看到Descriptor的用,最重要的一个是前面提到的WorkflowDescriptor。除此以外还有,ActionDescriptor、ConditionsDescriptor、ConditionDescriptor、FunctionDescriptor、PermissionDescriptor{等。这些类均位于com.opensymphony.workflow.loader包中。它们的作用Q除了提供getterҎ外(cMmodel的角ԌQ还负责xml文g的读取与写入。WorkflowDescriptor在执行xml文g的读写时Q如果涉及具体的程定义元素Q将会交由对应的DescriptorcL完成。比如,在WorkflowDescriptor的writeXMLҎ中,对initial action的序列化是这么实现的Q?/p><p class="prettycode">XMLUtil.printIndent(out, indent++);<br />out.println("<initial-actions>");<br />for (int i = 0; i < initialActions.size(); i++) {<br /> ActionDescriptor action = (ActionDescriptor) initialActions.get(i);<br /> action.writeXML(out, indent);<br />}<br />XMLUtil.printIndent(out, –indent);<br />out.println("</initial-actions>"); </p><p>实际上,q是典型的Interpreter Pattern的运用,下面是类图ȝ?br /><a title="点击查看大图" ><img height="177" alt="" src="http://morningspace.51.net/weblog/wp-content/osworkflow-desc.jpg" width="580" border="0" /></a></p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=74" dc:identifier="http://morningspace.51.net/weblog/index.php?p=74" dc:title="OSWorkflow解读之七" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/74" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/27/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-71"><a title="Permanent Link: OSWorkflow解读之六" rel="bookmark">OSWorkflow解读之六</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 10:53 am </div><div id="wmqeeuq" class="storycontent"><p>pre function和post function>></p><p>pre function和post function是osworkflow提供的又一特色Q它为某Ҏ行逻辑提供了前驱和后处理Q运用十分灵zRƈ且,osworkflow多元件的执行逻辑都配备了pre function和post function的调用时机。这一点也可以从AbstractWorkflow.doAction的执行逻辑中看到。可以用和pre function和post function的元件包括:actionQresult/unconditional resultQstepQsplitQjoin?/p><p>ScriptVariableParser>></p><p>作ؓosworkflow的一个util classQScriptVariableParser的主要功能是给定字串中?{var}替换成相应的value。这意味着我们可以在许多地方用类gAnt中引用property的语法,来进一步提高灵zL。比如:<br /><results><br /> <unconditional -result old-status="Finished?status="Underway?step="1?owner="${caller}"/><br /></results><br />在这里,unconditional result的owner属性将被caller的实际值所替代?/p><p>TransientVars和PropertySet>></p><p>在osworkflow的流E流转过E中Q时怼用到Transient Vars和Property Set。这两个工具用来暂存一些时信息或者在step间传递一些共享信息,比如Qcontext信息Qworkflow entry信息Q以及上面提到的${var}的valueQ等{?/p><p>Transient Vars实际上就是一个普通的MapQ至于Property SetQ则是opensymphony的另一个独立模块,需要单独下载jar包。与Transient Vars信息暂存与内存不同QProperty Setq支持数据库存储QJDBCPropertySetQ?/p><p>Register>></p><p>Z更进一步提高灵zL,osworkflowq提供了Register功能。我们可以定义自qRegisterQ以执行ҎdQƈ在流E定义文件中注明Q该Register便会被动态注册到Transient Vars中,以备随时取用。以下便是一个典型的使用场景Q?/p><div id="wmqeeuq" class="prettycode "><registers><br /> <register type="class?variable-name="log"><br />  <arg name="class.name">com.opensymphony.workflow.util.LogRegister</arg><br />  <arg name="addInstanceId">true</arg><br /> </register><br /></registers> </div><div id="wmqeeuq" class="prettycode "><function type="beanshell?name="bsh.function"><br /> <arg name="script">transientVars.get("log").info("function called");</arg><br /></function> </div><p>此外Qؓ了方便用,osworkflow的util包中q预定义了大量的Condition和FunctionProviderQ以及其他的一些辅助类Q比如:StatusCondition、AllowOwnerOnlyCondition、BeanShellCondition、Caller、EJBInvoker、ScheduleJob?/p><p>借助q些设施Qosworkflow的扩展性、灵zL、易用性,得到了极大的体现?</p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=71" dc:identifier="http://morningspace.51.net/weblog/index.php?p=71" dc:title="OSWorkflow解读之六" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/71" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/26/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-75"><a title="Permanent Link: OSWorkflow解读之五" rel="bookmark">OSWorkflow解读之五</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 12:00 am </div><div id="wmqeeuq" class="storycontent"><p>Schedule>></p><p>在osworkflow中提供了定时执行某项d的功能,q主要得益于opensymphony的另一个项目——QuatzQ该目为工作的定期执行提供了底层设施支持。ؓ此,我们需要引用quatrz.jar包,好在osworkflow的下载包中已l包含了该文件?/p><p>Z实现d定时Q我们需要在程定义文g中做cM如下的配|:</p><div id="wmqeeuq" class="prettycode"><function type="class"><br /> <arg name="class.name">com.opensymphony.workflow.util.ScheduleJob</arg><br /> <arg name="triggerId">1</arg><br /> <arg name="jobName">testJob</arg><br /> <arg name="triggerName">testTrigger</arg><br /> <arg name="groupName">test</arg><br /> <arg name="repeat">10</arg><br /> <arg name="repeatDelay">2000</arg><br /> <arg name="cronExpression">0,5,10,15,20,25,30,35,40,45,50,55 * * * * ?</arg><br /> <arg name="username">test</arg><br /> <arg name="password">test</arg><br /> <arg name="local">true</arg><br /> <arg name="schedulerStart">true</arg><br /></function> </div><p>ScheduleJob是一个FunctionProiverQ因此具有executeҎ。在该方法执行期_ScheduleJob会dq些配置参数Q创建好job实例Q实际上是一个JobDetail实例Q和trigger实例Q然后启动schedule。大致流E如下:<br />- Ҏ传入的shedulerName参数Q利用org.quartz.impl.StdSchedulerFactory的getSchedulerҎ创徏sheduler实例Q该实例实现了org.quartz.Scheduler接口Q?br />- Ҏ传入的jobClass参数Q决定创ZUJob实例Qosworkflow自n提供了两U选择QWorkflowJob和LocalWorkflowJob。前者支持SOAP协议Q后者则是本地调用,它们都实Corg.quartz.Job接口?br />- 创徏一个描qJob信息的JobDetail实例Qƈ做好初始讄Q?br />- 若传入参C未指定cronExpressionQ则创徏SimpleTriggerQƈ讄好startDate、endDate、repeatQ否则创建CronTrigger<br />- 在jobDetail和trigger准备完毕后,可以启动schedule了:</p><p class="prettycode">s.addJob(jobDetail, true);<br />s.scheduleJob(trigger);<br />s.start(); </p><p>scheduler中应该可以同时维护多个job和triggerQ当trigger的触发条件满_Q将会激zȝ正的job实例。由于,scheduler中只保存了jobDetail的实例,因此我猜惻Ijob实例的真正创建是由jobDetail完成的。job实例QWorkflowJob、LocalWorkflowJob或者是其他自定义扩展类Q激zdQ其excuteҎ会被执行。其内部的执行逻辑大体是获得指定的Workflow实例Q然后执行该实例的executeTriggerFunctionҎ。trigger function的执行与先前在流E定义文件中所出现q的普通function大同异。当Ӟ我们q需要在程定义文g中加入对trigger function的描qͼ大致格式如下Q?/p><p class="prettycode"><trigger-functions><br /> <trigger-function id="1?><br /> <function><br />  ?br /> </function><br /></trigger-functions> </p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=75" dc:identifier="http://morningspace.51.net/weblog/index.php?p=75" dc:title="OSWorkflow解读之五" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/75" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/25/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-73"><a title="Permanent Link: osworkflow解读之四" rel="bookmark">osworkflow解读之四</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 9:38 am </div><div id="wmqeeuq" class="storycontent"><p>程启动>></p><p>前面分析程{的执行逻辑Ӟq没有讲到流E的启动。实际上Q有了前面的基础Q再加上ҎE定义文件加载的q程有清晰认识之后,程启动逻辑是很Ҏ理解的。大致情况如下:<br />- 调用DefaultConfiguration的getWorkflowQ传入流E名Uͼ然后q回一个WorkflowDescriptor实例Q流E定义文件的加蝲是在这个时候完成的Q?br />- 然后做一些准备工作,比如Q获取WorkflowStore实例、准备好transientVars和propertySet{等Q?br />- 调用WorkflowDescriptor的getInitialActionҎQ获取initial actionQ如果有的话Q,注意此前的第一步中Q流E定义文件已l成功加载;<br />- 调用transitionWorkflowQ执行流E的{Q就是前面提到doAction执行逻辑时调用的那个重要的方法)Q?/p><p>在transitionWorkflowҎ中,与流E启动后step间的{E有不同的是Q当发现action为initial actionӞ会把流E设|ؓactivated状态,表示程启动。就是下面这D代码:</p><p class="prettycode">if ((wf.getInitialAction(action.getId()) != null) && (entry.getState() != WorkflowEntry.ACTIVATED)) {<br /> changeEntryState(entry.getId(), WorkflowEntry.ACTIVATED);<br />} </p><p>WorkflowStore和WorkflowEntry>></p><p>前面提到q,在AbstractWorkflow中,包含程{关键逻辑的transitionWorkflowҎQ会创徏新的step。而这一创徏工作是通过调用另一个member method实现的,也就是createNewCurrentStep。其执行逻辑大致如下Q?/p><p class="prettycode">int nextStep = theResult.getStep();<br />if (nextStep == -1) {<br /> if (currentStep != null) {<br />  nextStep = currentStep.getStepId();<br /> }<br />}<br />?br />if (currentStep != null) {<br /> store.markFinished(currentStep, actionId, new Date(), oldStatus, context.getCaller());<br /> store.moveToHistory(currentStep);<br />}<br />?br />Step newStep = store.createCurrentStep(entry.getId(), nextStep, owner, startDate, dueDate, status, previousIds); </p><p>从这D代码中Q我们首先可以看刎ͼosworkflow可以支持step节点自n再次被“激zZ的行ؓQ也是重复执行某个step。而另一斚wQ随后的创徏工作则是调用了store.createCurrentStep?/p><p>q个store变量是一个实CWorkflowStore接口的实例变量,~省是MemoryWorkflowStore。WorkflowStore除了创徏step之外Q还提供了一pdfind和queryҎ。在其内部分别保存着step的历史记录(history stepsQ以及当前处于“激zZ状态的stepQcurrent stepsQ,以MemoryWorkflowStoreZQ分别对应了两个HashMapQ而JDBCWorkflowStore则利用数据库表来记录q些信息?/p><p>实际上,WorkflowStore可以同时保存多个程的记录,q样可以满_时存在多个流E的情况。ؓ此,osworkflow提供了一个WorkflowEntry接口用来描述程信息Q其中包含了程名称、流EID、当前状态等{。WorkflowEntry中定义了如下几个程状态常量:</p><p class="prettycode">public static final int CREATED = 0; //创徏<br />public static final int ACTIVATED = 1; // Ȁz?br />public static final int SUSPENDED = 2; // 挂v<br />public static final int KILLED = 3; // 异常l止<br />public static final int COMPLETED = 4; // 正常l束<br />public static final int UNKNOWN = -1; </p><p>在WorkflowStore提供的接口方法中有如下几个方法供l护WorkflowEntry使用Q?/p><p class="prettycode">public WorkflowEntry createEntry(String workflowName) throws StoreException;<br />public WorkflowEntry findEntry(long entryId) throws StoreException;<br />public void setEntryState(long entryId, int state) throws StoreException; </p><p>具体的方法实玎ͼ各个LcL所不同。比如。在MemoryWorkflowStore中,是通过l护一个存储SimpleWorkflowEntry实例Q实CWorkflowEntry接口Q的HashMap辑ֈ目的的?</p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=73" dc:identifier="http://morningspace.51.net/weblog/index.php?p=73" dc:title="osworkflow解读之四" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/73" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/24/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-72"><a title="Permanent Link: OSWorkflow解读之三" rel="bookmark">OSWorkflow解读之三</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 9:48 am </div><div id="wmqeeuq" class="storycontent"><p>初始配置加蝲及工作流定义文g加蝲>></p><p>AbstractWorkflow首先会取得一个Configuration实例Q缺省时为DefaultConfigurationQ实CConfiguration接口Q,该实例负责系l配|的加蝲。AbstractWorkflow会调用其loadҎQ该Ҏ内部会查找一个名为osworkflow.xml的配|文Ӟq对其解析。osworkflow.xml文g中一般会指定persistence class和factory classQ比如:</p><p class="prettycode"><osworkflow><br /> <persistence class="com.opensymphony.workflow.spi.memory.MemoryWorkflowStore"/><br /> <factory class="com.opensymphony.workflow.loader.XMLWorkflowFactory"><br />  <property key="resource?value="workflows.xml?/><br /> </factory><br /></osworkflow> </p><p>loadҎ会动态加载这些classQ还可以指定一些参敎ͼ在它们初始化的时候传入。在q里Q我们指定了XMLWorkflowFactoryQ实际上q有其他U类的WorkflowFactoryQ比如JDBCWorkflowFactory、URLWorkflowFactoryQ它们均z自AbstractWorkflowFactoryQ其共同职责是通过某种媒介加蝲程定义?/p><p>以XMLWorkflowFactoryZQ其相应实例在loadҎ内部完成初始化的q程中,会查找一个名为workflows.xml的文Ӟ可以在该文g中定义多个流E,每个程指明其对应的xml定义文g。比如:</p><p class="prettycode"><workflows><br /> <workflow name="example?type="resource?location="example.xml"/><br /></workflows> </p><p>在XMLWorkflowFactory内部l护了一个MapQ保存着程名称与其对应的文件\径(实际上是一个WorkflowConfig实例Q不q这只是l节Q。然后,DefaultConfiguration调用XMLWorkflowFactory.getWorkflowҎQƈ传入程名称?/p><p>getWorkflowҎ内部又会流E加载的具体执行逻辑转交l一个名为WorkflowLoader的类Q调用WorkflowLoader.loadҎQ,由WorkflowLoader实现程定义文gd。不q,真正的xml文g解析是由WorkflowDescriptorcd成的。它^面的xml{化ؓosworkflow内部所使用的具有真正意义的对象。此cL很多getҎQ在osworkflow的许多地斚w会用到q个cȝgetҎQ以获取具体的对象,比如QgetActionQgetJoinQgetStep{等?/p><p>最l,代表example.xml程定义文g的WorkflowDescriptor实例会被逐层q回Q直至AbstractWorkflow。至此,程定义文g加蝲完毕Q整个初始化q程也就基本完成了?</p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=72" dc:identifier="http://morningspace.51.net/weblog/index.php?p=72" dc:title="OSWorkflow解读之三" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/72" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/23/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-70"><a title="Permanent Link: OSWorkflow解读之二" rel="bookmark">OSWorkflow解读之二</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 9:09 am </div><div id="wmqeeuq" class="storycontent"><p>多种方式定制逻辑>></p><p>osworkflow的几个基本元仉h很好的扩展性,它们分别是:conditionQfunctionQregisterQvalidator。以conditionZQ我们可以ؓ触发action的condition定义L复杂的逻辑Q而这U逻辑可以包含在一个java class中,也可以采用bsfQ或者bean shellQ还有local ejb和remote ejb。只要流E定义文件做相应配置卛_Q以java class和bean shellZQ?/p><p class="prettycode"><action id="1?name="Start Workflow"><br /> <restrict-to><br />  <conditions type="AND"><br />   <condition type="beanshell"><br />    <arg name="script">true</arg><br />   </condition><br />   <condition type="class"><br />    <arg name="class.name">com.opensymphony.workflow.util.OSUserGroupCondition</arg><br />    <arg name="group">foos</arg><br />   </condition><br />  </conditions><br /> </restrict-to><br /> ?br /></action> </p><p>在osworkflow的许多地斚w可以见到cM如下的代码(此处以functionZQ:</p><pre class="prettycode">if ("remote-ejb".equals(type)) { clazz = RemoteEJBFunctionProvider.class.getName(); } else if ("local-ejb".equals(type)) { clazz = LocalEJBFunctionProvider.class.getName(); } else if ("jndi".equals(type)) { clazz = JNDIFunctionProvider.class.getName(); } else if ("bsf".equals(type)) { clazz = BSFFunctionProvider.class.getName(); } else if ("beanshell".equals(type)) { clazz = BeanShellFunctionProvider.class.getName(); } else { clazz = (String) args.get(CLASS_NAME); } FunctionProvider provider = (FunctionProvider) loadObject(clazz); provider.execute(transientVars, args, ps); </pre><p>loadObject会动态加载相应的L处理c(比如BSFFunctionProviderQ,q{换ؓ基类cdQ比如FunctionProviderQ,然后调用相应的执行逻辑Q比如provider.executeQ。这一模式屡试不爽?</p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=70" dc:identifier="http://morningspace.51.net/weblog/index.php?p=70" dc:title="OSWorkflow解读之二" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/70" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/22/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-68"><a title="Permanent Link: OSWorkflow解读之一" rel="bookmark">OSWorkflow解读之一</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 9:35 am </div><div id="wmqeeuq" class="storycontent"><p>AbstractWorkflow>></p><p>osworkflow中有兛_作流{的所有核心代码都在AbstractWorkflow中,BasicWorkflow是z自它Q不q这个BasicWorkflow基本上没做什么事情。也许我们还可以从AbstractWorkflowz自己的WorkflowcM加入扩展功能Q大概这也算是osworkflow所体现的一U灵zL了Q即Q允许对工作流转的执行逻辑q行修改。AbstractWorkflow实现了Workflow接口Q该接口包含了有兛_作流的核心方法,最重要的是doActionҎQAbstractWorkflow实现了该ҎQ后面会提及Q其他还有一些getter和query method?/p><p>程{的执行逻辑>></p><p>当流E执行到的某个stepӞ可能有一个或多个action可供用户选择执行。一旦确定执行某个action后,我们需要调用AbstractWorkflow.doActionQƈ传入程id和action的id。以下是对doAction的执行逻辑的一个不太严紧的法描述Q?/p><p>*  *  *</p><p>-  Ҏ程idQ获得所有当前的stepQ这U情况往往发生在有split的时候,此时会有多个step{待执行Q?br />-  Ҏ传入的action的idQ检查是否是global actionQ?br />-  若不是global actionQ则遍历所有当前的stepQ对每个step的每个action调用isActionAvailableҎQ检查该action是否可用Q记住step和action是一对多的关p)Q?br />-  所谓可用是指,通过执行passesConditionsQ逐个查action的conditionQ若是OR的关p,则有一个condition为真即ؓ可用QAND关系则类推;<br />-  若action可用Q则调用transitionWorkflowQ这是流E流转处理的关键部分Q?br /> 执行transitionWorkflowӞ<br /> -  首先获取当前stepQ存在有多个当前step的情况,比如splitQ此时获取首个isAvailableAction为真的stepQ?br /> -  调用verifyInputs验证输入Q如果action有validator的话Q;<br /> -  执行当前step的post functionQ因step卛_l束Q;<br /> -  执行action的pre functionQ?br /> -  判断当前step所属的result中的所有condition是否满要求Q判断方法类似action的conditionQ?br /> -  一旦满I则获取result的pre function和post functionQ?br /> -  否则xunconditional resultQ获取相应的pre function和post functionQ?br /> -  在没有split和join的情况下<br />  -  会根据在result中指定的下一个step的idQ创Z个新的stepQ作为当前的stepQ?br />  -  从current steps中移除原来的当前stepQƈd到history steps中;<br />  -  如果新的step有pre functionQ则会马上执行;<br /> -  执行result的post functionQ?br /> -  执行action的post functionQ?br /> -  若action是intial actionQ则流E设|ؓactivated状态;<br /> -  若action是finish actionQ则流E设|ؓcompleted状态,q回trueQ?br /> -  Lauto actionQ若有的话,则执行之Q执行方法是调用doAction本nQ?br /> -  q回falseQ?br />-  ҎtransitionWorkflow的返回值判断流E是否结束;<br />-  若返回falseQ则调用checkImplicitFinish查是否存在implicit finishQ即Q当前没有一个step的action可用Ӟp为流E应该结束;</p><p>*  *  *</p><p>- 若存在splitQ则会创建多个新的stepQƈ且在创徏之前先执行split的pre functionQ在创徏之后执行split的post functionQ?br />- 创徏step的过E和上面描述的普通状늛同:l护好current steps和history stepsQƈ执行新的step的pre functionQ?/p><p>*  *  *</p><p>- 若存在joinQ先l束当前stepQƈ该stepd至history steps和join stepsQ?br />- 查找history stepsQ对每个已完成的stepQ查看是否在其result或unconditional result中有join一,若有则加入join steps中;<br />- 查join是否已经满Q可以用Bean ShellQ在xml定义文g的join节点中,通过引用一个名为“jn”的Ҏ变量来指定join的满xӞjn记录了有关join的关键信息;<br />- 若条件满I则执行join的pre functionQ维护好history stepsQƈ创徏下一个stepQ然后执行join的post functionQ?/p><p>*  *  *</p><p>- 对于条g循环的情况,可以通过result的某个action的下一个step指定w来加以实现Q这只是在xml定义文g中做文章Q流E执行逻辑无需做特D处理; </p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (1)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=68" dc:identifier="http://morningspace.51.net/weblog/index.php?p=68" dc:title="OSWorkflow解读之一" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/68" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/20/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-67"><a title="Permanent Link: time granulrity,issue tracking,tools vs. human" rel="bookmark">time granulrity,issue tracking,tools vs. human</a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Software Engineering" ><font size="2">Software Engineering</font></a></li></ul>?site admin @ 10:12 pm </div><div id="wmqeeuq" class="storycontent"><p>time granulrityQ?/p><p>作ؓ旉的一U度量单位,或小时记Q或天记Q都是灵zȝ和因异的。比如你完全可以?个小时理解ؓ1天。但是,_度的确定ƈ非没有原则:ZQ务分配时间是一U预伎ͼq样的估计如果易变而不准确Q那么多半也失M意义。一般而言Q只有在Ҏ做的工作十分了解的前提下Q才能够准确估计。对于一个易变的的环境,陌生的环境,时常被打断的环境Q或者时常冒Z“障”的环境Q比如某个艰qbug fixQ,旉的粒度就不亦q细Q至在q代的初期是如此。随着旉的推Udl验的积累,估计的粒度也׃相应改进?/p><p>issue tracking</p><p>issue tracking臛_重要Q否则事态就可能滑入不可控的危险Qteam member׃失去寚w目状늚全景认识Q这也是我的切n体会。实际上Q不单是bugQfeatureQdefactQ……,很多东西都是需要有tracking的。比如某此会议中的一个ideaQ如果没有某UŞ式的trackingQ很Ҏ׃消失在大家的记忆中,直到哪次再被大家带着一U似曄识的感情从被遗忘的角落里重新提v?/p><p>tools vs. human</p><p>我始l觉得,在一个开发团队中Q对于工L使用QL二等考量Q更为重要的是h的因素。因为,即有趁手的工具Q也依然有可能存在缺乏交的team memberQ以及由q些team member参加的冗长的~Z主题的会议?</p></div><div id="wmqeeuq" class="feedback"><a ><font color="#667755">Comments (0)</font></a></div><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://morningspace.51.net/weblog/index.php?p=67" dc:identifier="http://morningspace.51.net/weblog/index.php?p=67" dc:title="time granulrity,issue tracking,tools vs. human" trackback:ping="http://morningspace.51.net/weblog/wp-trackback.php/67" /> </rdf:RDF> --></div><div id="wmqeeuq" class="date">11/17/2004</div><div id="wmqeeuq" class="post"><h3 class="xstorytitle" id="post-66"><a title="Permanent Link: OSWorkflow开? rel="bookmark">OSWorkflow开?/a></h3><div id="wmqeeuq" class="meta">Filed under: <ul class="post-categories"><li><a title="View all posts in Workflow" ><font size="2">Workflow</font></a></li></ul>?site admin @ 11:04 pm </div><div id="wmqeeuq" class="storycontent"><p>刚刚下蝲了OSWorkflowQ这里摘录的是联机文档中的开部分,也就是OSWorkflow的核心概念了Q?/p><p>OSWorkflow is based heavily on the concept of the <b>finite state machine</b>. Each state is represented by the combination of a <b>step ID</b> and a <b>status</b>. A <b>transition</b> from one state to another cannot happen without an <b>action</b> occuring first. There are always at least one or more active states during the lifetime </p></div></div><br /><br /><p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=447742</p></div><div id="wmqeeuq" class="postFoot"><script src="http://writeblog.csdn.net/PromoteIcon.aspx?Id=447742"></script> [<a href="javascript:StorePage()">点击此处收藏本文</a>]   发表?2005q?8?7?16:29:00 </div></div><link rel="pingback" /><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://blog.csdn.net/yun15291li/articles/447742.aspx" dc:identifier="http://blog.csdn.net/yun15291li/articles/447742.aspx" dc:title="解读osworkflow1~9" trackback:ping="http://tb.blog.csdn.net/TrackBack.aspx?PostId=447742" /> </rdf:RDF> --><script><![CDATA[unction hide(){showComment();}]]></script><script type="text/javascript"><![CDATA[ocument.write("<img src=http://counter.csdn.net/pv.aspx?id=24 border=0 width=0 height=0>");]]></script><img height="0" src="http://counter.csdn.net/pv.aspx?id=24" width="0" border="0" /><br /><div class="wmqeeuq" id="comments"><h3><p>h3 定义条g和函?/p><p>你也许已l注意到Q到目前为止Q我们定义的条g和函数类型都?class""""""""""""""""""""class.name"""""""""""FunctionProvider或Condition接口的完整类名?/p><p>在osworkflow里面也有一些其他内|的cdQ包括beanshellQ无状态的session beanQJNDI树上的函数等。我们在下面的例子里使用beanshellcd?/p><p>h3 Property sets</p><p>我们可能需要在工作的L步骤持久化一些少量数据。在osworkflow里,q是通过OpenSymphony的PropertySet library来实现。一个PropertySet基本上是一个可以持久化的类型安全mapQ你可以dL的数据到propertysetQ一个工作流实例对应一个propertysetQ,q在以后的流E中再读取这些数据。除非你特别指定操作Q否则propertyset中的数据不会被清I或者被删除。Q意的函数和条仉可以和propertyset交互Q以beanshell script来说Q可以在脚本上下文中?propertyset"""""""""""""""""""""""""""""""""""Start First Draft""""pre-functions里面Q?/p><div id="wmqeeuq" class="code"><div id="wmqeeuq" class="codeContent"><pre class="code-xml"><span id="wmqeeuq" class="code-tag"><function type=<span id="wmqeeuq" class="code-quote">"beanshell"</span>></span><span id="wmqeeuq" class="code-tag"><arg name=<span id="wmqeeuq" class="code-quote">"script"</span>></span>propertySet.setString(<span id="wmqeeuq" class="code-quote">"foo"</span>, <span id="wmqeeuq" class="code-quote">"bar"</span>)<span id="wmqeeuq" class="code-tag"></arg></span><span id="wmqeeuq" class="code-tag"></function></span></pre></div></div><p>q样我们添加了一个持久化的属?foo"""""""bar""""""""""""""""""""""""</p><p>h3 Transient Map 临时变量</p><p>另外一个和propertyset变量相对的概忉|临时变量Q?transientVars""""""""""""mapQ只是在当前的工作流调用的上下文内有效。它包括当前的工作流实例Q工作流定义{对应值的引用。你可以通过FunctionProvider的javadoc来查看这个map有那些可用的key?/p><p>q记得我们在教程的第2部分传入的那个null吗?如果我们不传入null的话Q那么这些输入数据将会被dC时变量的map里?/p><p>h3 inputs 输入</p><p>每次调用workflow的动作时可以输入一个可选的mapQ可以在q个map里面包含供函数和条g使用的Q何数据,它不会被持久化,只是一个简单的数据传递?/p><p>h3 Validators 校验?/p><p>Z让工作流能够校验输入的数据,引入了校验器的概c一个校验器和函敎ͼ条g的实现方式非常类|比如Q它可以是一个classQ脚本,或者EJBQ。在q个教程里面Q我们将会定义一个校验器Q在"finish first draft""""""""""""""""working.title"""""30个字W。这个校验器看v来是q样的:</p><div id="wmqeeuq" class="code"><div id="wmqeeuq" class="codeContent"><pre class="code-java"><span id="wmqeeuq" class="code-keyword">package</span> com.mycompany.validators; <span id="wmqeeuq" class="code-keyword">public</span> class TitleValidator <span id="wmqeeuq" class="code-keyword">implements</span> Validator { <span id="wmqeeuq" class="code-keyword">public</span> void validate(Map transientVars, Map args, PropertySet ps) <span id="wmqeeuq" class="code-keyword">throws</span> InvalidInputException, WorkflowException { <span id="wmqeeuq" class="code-object">String</span> title = (<span id="wmqeeuq" class="code-object">String</span>)transientVars.get(<span id="wmqeeuq" class="code-quote">"working.title"</span>); <span id="wmqeeuq" class="code-keyword">if</span>(title == <span id="wmqeeuq" class="code-keyword">null</span>) <span id="wmqeeuq" class="code-keyword">throw</span><span id="wmqeeuq" class="code-keyword">new</span> InvalidInputException(<span id="wmqeeuq" class="code-quote">"Missing working.title"</span>); <span id="wmqeeuq" class="code-keyword">if</span>(title.length() > 30) <span id="wmqeeuq" class="code-keyword">throw</span><span id="wmqeeuq" class="code-keyword">new</span> InvalidInputException(<span id="wmqeeuq" class="code-quote">"Working title too <span id="wmqeeuq" class="code-object">long</span>"</span>); } }</pre></div></div><p>然后通过在流E定义文件添加validators元素Q就可以登记q个校验器了Q?/p><div id="wmqeeuq" class="code"><div id="wmqeeuq" class="codeContent"><pre class="code-xml"><span id="wmqeeuq" class="code-tag"><validators></span><span id="wmqeeuq" class="code-tag"><validator type=<span id="wmqeeuq" class="code-quote">"class"</span>></span><span id="wmqeeuq" class="code-tag"><arg name=<span id="wmqeeuq" class="code-quote">"class.name"</span>></span> com.mycompany.validators.TitleValidator <span id="wmqeeuq" class="code-tag"></arg></span><span id="wmqeeuq" class="code-tag"></validator></span><span id="wmqeeuq" class="code-tag"></validators></span></pre></div></div><p>q样Q当我们执行动作2的时候,q个校验器将会被调用Qƈ且检验我们的输入。这样在试代码里面Q如果加上:</p><div id="wmqeeuq" class="code"><div id="wmqeeuq" class="codeContent"><pre class="code-java">Map inputs = <span id="wmqeeuq" class="code-keyword">new</span> HashMap(); inputs.put(<span id="wmqeeuq" class="code-quote">"working.title"</span>, <span id="wmqeeuq" class="code-quote">"the quick brown fox jumped over the lazy dog,"</span> + <span id="wmqeeuq" class="code-quote">" thus making <span id="wmqeeuq" class="code-keyword">this</span> a very <span id="wmqeeuq" class="code-object">long</span> title"</span>); workflow.doAction(workflowId, 2, inputs);</pre></div></div><p>我们会得到一个InvalidInputExceptionQ这个动作将不会被执行。减输入的title字符Q将会让q个动作成功执行?/p><p>我们已经介绍了输入和校验Q下面来看看寄存器?/p><p>h3 Registers 寄存?/p><p>寄存器是一个工作流的全局变量。和propertysetcMQ它可以在工作流实例的Q意地方被获取。和propertyset不同的是Q它不是一个持久化的数据,而是每次调用旉需要重新计的数据?/p><p>它可以被用在什么地方呢Q在我们的文档管理系l里面,如果定义了一?document""""""""""""""""""""""""""""""""""""""""""""</p><p>寄存器地g被放在时变量(transientVars mapQ里Q这栯够在L地方获得它?/p><p>定义一个寄存器和函数、条件的一个重要区别是Q它q不是依靠特定的调用Q不用关心当前的步骤Q或者是输入数据Q它只是单地暴露一些数据而已Q,所以它不用临时变量里的倹{?/p><p>寄存器必d现Register接口Qƈ且被定义在流E定义文件的头部Q在初始化动作之前?/p><p>举例来说Q我们将会用一个osworkflow内置的寄存器:LogRegister。这个寄存器单的d一?log""""""""""Jakarta的commons-logging输出日志信息。它的好处是会在每条信息前添加工作流实例的ID?/p><div id="wmqeeuq" class="code"><div id="wmqeeuq" class="codeContent"><pre class="code-xml"><span id="wmqeeuq" class="code-tag"><registers></span><span id="wmqeeuq" class="code-tag"><register type=<span id="wmqeeuq" class="code-quote">"class"</span> variable-name=<span id="wmqeeuq" class="code-quote">"log"</span>></span><span id="wmqeeuq" class="code-tag"><arg name=<span id="wmqeeuq" class="code-quote">"class.name"</span>></span> com.opensymphony.workflow.util.LogRegister <span id="wmqeeuq" class="code-tag"></arg></span><span id="wmqeeuq" class="code-tag"><arg name=<span id="wmqeeuq" class="code-quote">"addInstanceId"</span>></span>true<span id="wmqeeuq" class="code-tag"></arg></span><span id="wmqeeuq" class="code-tag"><arg name=<span id="wmqeeuq" class="code-quote">"Category"</span>></span>workflow<span id="wmqeeuq" class="code-tag"></arg></span><span id="wmqeeuq" class="code-tag"></register></span><span id="wmqeeuq" class="code-tag"></registers></span></pre></div></div><p>q样我们定义了一个可用的"log"""""""""""preQfunction的脚本里面用它Q?/p><div id="wmqeeuq" class="code"><div id="wmqeeuq" class="codeContent"><pre class="code-xml"><span id="wmqeeuq" class="code-tag"><function type=<span id="wmqeeuq" class="code-quote">"beanshell"</span>></span><span id="wmqeeuq" class="code-tag"><arg name=<span id="wmqeeuq" class="code-quote">"script"</span>></span>transientVars.get(<span id="wmqeeuq" class="code-quote">"log"</span>).info(<span id="wmqeeuq" class="code-quote">"executing action 2"</span>)<span id="wmqeeuq" class="code-tag"></arg></span><span id="wmqeeuq" class="code-tag"></function></span></pre></div></div><p>日志输出会在前面添加工作流实例的ID</p><p>h3 l论</p><p>q个教程的目的是希望可以阐明一些主要的osworkflow概念。你q可以通过API和流E定义格式去获取更多的信息。有一些更高的特性没有在此提刎ͼ比如splits 分支、joins q接, nested conditions 复合条g、auto stpes 自动步骤{等。你可以通过阅读手册来获得更q一步的理解?/p><p>如果你遇CQ何的困难Q可以在osworkflow的email list上询问?/p><!-- <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"> <rdf:Description rdf:about="http://wiki.opensymphony.com/display/WF/3.+Further+descriptor+concepts+-+Chinese" dc:identifier="http://wiki.opensymphony.com/display/WF/3.+Further+descriptor+concepts+-+Chinese" dc:title="3. Further descriptor concepts - Chinese" trackback:ping="http://wiki.opensymphony.com/rpc/trackback/3016"/> </rdf:RDF> --><!-- Root decorator: all decisions about how a page is to be decorated via the inline decoration begins here. --><!-- Switch based upon the context. However, for now, just delegate to a decorator identified directly by the context. --></h3></div></div><div id="wmqeeuq" class="footer"><p></p></div><script type="text/javascript"><!-- var Page_Validators = new Array(document.getElementById("PostComment.ascx_RequiredFieldValidator2"), document.getElementById("PostComment.ascx_RequiredFieldValidator3")); // --></script><script type="text/javascript"><!-- var PostComment.ascx_RequiredFieldValidator2 = document.all ? document.all["PostComment.ascx_RequiredFieldValidator2"] : document.getElementById("PostComment.ascx_RequiredFieldValidator2"); PostComment.ascx_RequiredFieldValidator2.controltovalidate = "PostComment.ascx_tbName"; PostComment.ascx_RequiredFieldValidator2.errormessage = "误入名?; PostComment.ascx_RequiredFieldValidator2.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid"; PostComment.ascx_RequiredFieldValidator2.initialvalue = ""; var PostComment.ascx_RequiredFieldValidator3 = document.all ? document.all["PostComment.ascx_RequiredFieldValidator3"] : document.getElementById("PostComment.ascx_RequiredFieldValidator3"); PostComment.ascx_RequiredFieldValidator3.controltovalidate = "PostComment.ascx_tbComment"; PostComment.ascx_RequiredFieldValidator3.errormessage = "误入评?; PostComment.ascx_RequiredFieldValidator3.evaluationfunction = "RequiredFieldValidatorEvaluateIsValid"; PostComment.ascx_RequiredFieldValidator3.initialvalue = ""; // --></script><div> </div><script type="text/javascript"><!-- var Page_ValidationActive = false; if (typeof(ValidatorOnLoad) == "function") { ValidatorOnLoad(); } function ValidatorOnSubmit() { if (Page_ValidationActive) { return ValidatorCommonOnSubmit(); } else { return true; } } // --></script></div></form><script language="javascript"><!-- try{ hide(); } catch(e){ } //--></script><img src ="http://www.aygfsteel.com/pdw2009/aggbug/51671.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2006-06-09 13:26 <a href="http://www.aygfsteel.com/pdw2009/archive/2006/06/09/51671.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>osworkflow限制的相兌明?/title><link>http://www.aygfsteel.com/pdw2009/archive/2006/04/22/42509.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Sat, 22 Apr 2006 10:16:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2006/04/22/42509.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/42509.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2006/04/22/42509.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/42509.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/42509.html</trackback:ping><description><![CDATA[ <p>限制是指的是当前作动的执行h!<br /><br /><br /><br /><!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.8//EN" "<a ></p> <p><workflow><br />   <initial-actions><br />      <action id="0" name="开?><br />        <pre-functions><br />           <functions type="class"><br />            <arg name="class.name">com.opensymphony.workflow.util.Caller</arg><br />           </functions><br />        </pre-functions><br />         <results><br />          <unconditional-result old-status="Finished" status="Queued" step="1" owner="${caller}" /><br />         </results><br />      </action><br />      <br />   </initial-actions><br />   <steps><br />     <step id="1" name="送假?><br />        <actions><br />          <action id="1" name="送出"><br />              <restrict-to><br />                   <conditions><br />                     <condition type="class"><br />                              <arg name="class.name"><br />                                com.opensymphony.workflow.util.AllowOwnerOnlyCondition<br />                              </arg><br />                           </condition><br />                  </conditions><br />              </restrict-to><br />           <pre-functions><br />            <function type="class"><br />          <arg name="class.name">com.opensymphony.workflow.util.Caller</arg><br />         </function><br />           </pre-functions><br />           <results><br />            <unconditional-result old-status="Finished" status="Queued" step="2" owner="${caller}"/><br />           </results><br />          <br />          </action><br />        </actions><br />     </step> <br />     <step id="2" name="送假?><br />      <actions><br />       <action id="2" name="批准"><br />        <pre-functions><br />         <function type="class"><br />          <arg name="class.name">com.opensymphony.workflow.util.Caller</arg><br />         </function><br />        </pre-functions><br />        <results><br />         <unconditional-result old-status="finished" status="Queued" step="3" owner="${caller}"/><br />        </results><br />       </action><br />       <action id="3" name="驛_"><br />        <pre-functions><br />         <function type="class"><br />          <arg name="class.name">com.opensymphony.workflow.util.Caller</arg><br />         </function><br />        </pre-functions><br />        <results><br />         <unconditional-result old-status="finished" status="Queued" step="1" owner="${caller}"/><br />        </results><br />       </action><br />      </actions><br />     </step><br />     <step id="3" name="停止"  /><br />   </steps><br /></workflow><br />q是请假单的W二个演变,d?<br />  <restrict-to><br />                   <conditions><br />                     <condition type="class"><br />                              <arg name="class.name"><br />                                com.opensymphony.workflow.util.AllowOwnerOnlyCondition<br />                              </arg><br />                           </condition><br />                  </conditions><br />              </restrict-to><br />q个配置。这D配|就是用来限定下一步的执行人必Lq一步的发v人?br /><br />osworkflow限制的用法有Q?br />事實上OSWorkflow 2.7版提供了以下四種限制條g?br /></p> <ul> <li> <b>OSUserGroupCondition</b>Q限制由隸屬某指定Group的h埯?br /></li> <li> <b>StatusCondition</b>Q限制step的status為某個值時才能埯?br /></li> <li> <b>AllowOwnerOnlyCondition</b>Q只允許Owner埯?br /></li> <li> <b>DenyOwnerCondition</b>Q只有Owner不能埯?br /></li> </ul> <img src ="http://www.aygfsteel.com/pdw2009/aggbug/42509.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2006-04-22 18:16 <a href="http://www.aygfsteel.com/pdw2009/archive/2006/04/22/42509.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习Q史帝芬Qosworkflow入门教程后的一些体?/title><link>http://www.aygfsteel.com/pdw2009/archive/2006/04/18/41658.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Tue, 18 Apr 2006 07:43:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2006/04/18/41658.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/41658.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2006/04/18/41658.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/41658.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/41658.html</trackback:ping><description><![CDATA[ <p>可以q么说史帝芬?a >http://my.so-net.net.tw/idealist/OSWorkflow/osworkflow</a>资料是目前华文osworkflow资料中最好的一份入门教E。去面的时候在mssql中中实践q这份入门资料,感觉非常利。但感觉按作者的序把教E中的例子跑完了Q还不完全清楚的明白osworkflow的架构。前些在mysql5.0中重做一ơ,遇到了挺多问题,我通过一步一步的跟踪原代码调试终于把q些问题搞定。下图是把osworkflow所提供的mysql下的数据表的ER?<br /><br /><img style="WIDTH: 176px; HEIGHT: 159px" height="115" alt="t_osworkflow.jpg" src="http://www.aygfsteel.com/images/blogjava_net/pdw2009/8326/t_osworkflow.jpg" width="120" border="0" /><br /><br />如果你的osworkflow持久化到mysql中你的osworkflow.xml文g内如必需按如下格式来?<br /><br /><osworkflow><br /><persistence class="com.opensymphony.workflow.spi.jdbc.MySQLWorkflowStore"><br /> <property key="datasource" value="jdbc/DefaultDS"/><br /> <br />    <property key="step.sequence.increment"  value="INSERT INTO OS_STEPIDS (ID) values (null)"/><br />    <property key="step.sequence.retrieve"   value="SELECT count(ID) FROM OS_STEPIDS"/><br />    <property key="entry.sequence.increment" value="INSERT INTO OS_ENTRYIDS (ID) values (null)"/><br />    <property key="entry.sequence.retrieve"  value="SELECT count(ID) FROM OS_ENTRYIDS"/><br />    <br /> <property key="entry.table" value="OS_WFENTRY"/><br /> <property key="entry.id" value="ID"/><br /> <property key="entry.name" value="NAME"/><br /> <property key="entry.state" value="STATE"/><br /> </p> <p> <br /> <property key="history.table" value="OS_HISTORYSTEP"/><br /> <property key="current.table" value="OS_CURRENTSTEP"/><br /> <property key="historyPrev.table" value="OS_HISTORYSTEP_PREV"/><br /> <property key="currentPrev.table" value="OS_CURRENTSTEP_PREV"/><br /> <property key="step.id" value="ID"/><br /> <property key="step.entryId" value="ENTRY_ID"/><br /> <property key="step.stepId" value="STEP_ID"/><br /> <property key="step.actionId" value="ACTION_ID"/><br /> <property key="step.owner" value="OWNER"/><br /> <property key="step.caller" value="CALLER"/><br /> <property key="step.startDate" value="START_DATE"/><br /> <property key="step.finishDate" value="FINISH_DATE"/><br /> <property key="step.dueDate" value="DUE_DATE"/><br /> <property key="step.status" value="STATUS"/><br /> <property key="step.previousId" value="PREVIOUS_ID"/></p> <p>     <br /> </persistence><br /> <br /> <factory class="com.opensymphony.workflow.loader.XMLWorkflowFactory"><br />  <property key="resource" value="workflows.xml"/><br /> </factory><br /></osworkflow><br />propertyset.xml文g格式如下Q?br /><?xml version="1.0" encoding="UTF-8"?><br /><propertysets><br />    <propertyset name="jdbc" <br />      class="com.opensymphony.module.propertyset.database.JDBCPropertySet"><br />        <arg name="datasource" value="java:comp/env/jdbc/DefaultDS"/><br />        <arg name="table.name" value="OS_PROPERTYENTRY"/><br />        <arg name="col.globalKey" value="GLOBAL_KEY"/><br />        <arg name="col.itemKey" value="ITEM_KEY"/><br />        <arg name="col.itemType" value="ITEM_TYPE"/><br />        <arg name="col.string" value="STRING_VALUE"/><br />        <arg name="col.date" value="DATE_VALUE"/><br />        <arg name="col.data" value="DATA_VALUE"/><br />        <arg name="col.float" value="FLOAT_VALUE"/><br />        <arg name="col.number" value="NUMBER_VALUE"/><br />    </propertyset><br /></propertysets><br />workflows.xml文g格式如下Q?br /><br /><workflows><br />  <workflow name="leave" type="resource" location="leave.xml"/><br /></workflows><br /><br />osuser.xml文g格式如下Q?br /><?xml version="1.0" encoding="UTF-8"?><br /><opensymphony-user><br />         <provider class="com.opensymphony.user.provider.jdbc.JDBCAccessProvider"><br />         <property name="user.table">os_user</property><br />         <property name="group.table">os_group</property><br />         <property name="membership.table">os_membership</property><br />         <property name="user.name" >username</property><br />         <property name="user.password">passwordhash</property><br />         <property name="group.name">groupname</property><br />         <property name="membership.userName" >username</property><br />         <property name="membership.groupName">groupname</property><br />         <property name="datasource">java:comp/env/jdbc/DefaultDS</property><br />       </provider><br />       <provider class="com.opensymphony.user.provider.jdbc.JDBCCredentialsProvider"><br />         <property name="user.table">os_user</property><br />         <property name="group.table">os_group</property><br />         <property name="membership.table">os_membership</property><br />         <property name="user.name" >username</property><br />         <property name="user.password">passwordhash</property><br />         <property name="group.name">groupname</property><br />         <property name="membership.userName" >username</property><br />         <property name="membership.groupName">groupname</property><br />         <property name="datasource">java:comp/env/jdbc/DefaultDS</property><br />       </provider><br />       <provider class="com.opensymphony.user.provider.jdbc.JDBCProfileProvider"><br />         <property name="user.table">os_user</property><br />         <property name="group.table">os_group</property><br />         <property name="membership.table">os_membership</property><br />         <property name="user.name" >username</property><br />         <property name="user.password">passwordhash</property><br />         <property name="group.name">groupname</property><br />         <property name="membership.userName" >username</property><br />         <property name="membership.groupName">groupname</property><br />         <property name="datasource">java:comp/env/jdbc/DefaultDS</property><br />       </provider><br />       <authenticator class="com.opensymphony.user.authenticator.SmartAuthenticator" /><br />     </opensymphony-user></p> <p>请假列子的配|如下:<br /><br />package com.pdw.wfbo;</p> <p>import java.util.HashMap;<br />import java.util.Map;</p> <p>import com.opensymphony.workflow.*;<br />import com.opensymphony.workflow.basic.BasicWorkflow;<br />import com.opensymphony.workflow.config.DefaultConfiguration;</p> <p>public class LeaveWFBO {<br /> <br />   /**<br />    * 送出假单<br />    * @param employee<br />    * @return<br />    */<br /> public long send(String employee) {<br />  Workflow workflow=new BasicWorkflow("peidw");<br />  DefaultConfiguration config=new DefaultConfiguration();<br />  workflow.setConfiguration(config);<br />  long workflowId=-1;<br />  try {<br />   workflowId=workflow.initialize("leave",0,null);//leave是workflows.xml里配|的工作名U?br />   workflow.doAction(workflowId,1,null);<br />  }catch(Exception e) {<br />   e.printStackTrace();<br />  }<br />  return workflowId;<br /> }<br /> <br />    /**<br />     * 批假<br />     * @param workflowId 工作编?br />     * @param actionId  工作~号Q? 准许Q? 驛_<br />     */<br /> public void allow(long workflowId,int actionId) {<br />  Workflow workflow=new BasicWorkflow("peidw");<br />  DefaultConfiguration config=new DefaultConfiguration();<br />  workflow.setConfiguration(config);<br />  try {<br />   System.out.println("actionId->"+actionId);<br />   System.out.println("workflowId->"+workflowId);<br />   workflow.doAction(workflowId,actionId,null);<br />  }catch(Exception e) {<br />   e.printStackTrace();<br />  }<br /> }</p> <p>}<br /><br /></p> <table cellspacing="0" cellpadding="0" width="100%" border="0"> <tbody> <tr> <td id="wikititle"> <div id="wmqeeuq" class="pagetitle">q是上面的这个例子的一个说?/div> </td> </tr> <tr> <td> <font size="2">(史帝? 2005/6/6, <a href="mailto:hi.steven@gmail.com">hi.steven@gmail.com</a>)</font> </td> </tr> <tr> <td> <img onclick="openhome();" src="http://my.so-net.net.tw/idealist/images/Qoo1.gif" align="left" border="0" /> <div class="wmqeeuq" id="wikitext">看完<a >W一支程?/a>Q相信讀者會有許多疑問,這些先就程的設定做初步的介紏V首先,讀者應該注意到了,W一支程式的用到三個xmla定檔,沒錯Q這三個是a定程的設定檔?br /><ul><li><b><i>osworkflow.xml</i></b>Q這個檔案是a定程是否存在資料庫或存在a憶體,前面的內Ҏ存在MS SQL Server的寫法?br /></li><li><b><i>leave.xml</i></b>Q請假流E寫在這個檔案,這也是osworkflow的重點之一?br /></li><li><b><i>workflows.xml</i></b>Q指定系i啟動時要載入那些流E?br /></li></ul><br />這裡針對leave.xml做些說明?br /><ul><li><b>initial-actions</b>Q每個流E都臛_需定義一個initial-actionsQ這是程的v點?br /></li><li><b>action</b>Q導致流E變動的動作Q每個action都有個編號,且不能重複?br /></li><li><b>step</b>Q雖然它的名E是步驟Q似乎它會有動作? 其實它視為程位置可能比較恰當Qosworkflow真正的動作在action發生?br /></li><li><b>result</b>Q執行動作後的結果,result有兩Econditional-result和unconditional-resultQ每個result一定有unconditional-resultQ當conditional-result的條仉不滿xQ就埯unconditional-result?br /></li><li><b>status</b>Q流E在某個action時的狀態?br /></li><li><b>old-status</b>Q流E執行某個action後的狀態?br /></li><li><b>caller</b>Q這是OSWorkflow的保留字Q可取得呼叫此工作流的userQ即Workflow workflow = new BasicWorkflow(caller); 在資料n中會a錄於Table OS_HISTORYSTEP如下:<br /><img src="http://my.so-net.net.tw/idealist/OSWorkflow/caller.jpg" /><br />a得在pre-functions加上如下a定?br /><pre><pre-functions> <function type="class"> <arg name="class.name">com.opensymphony.workflow.util.Caller</arg> </function> </pre-functions></pre></li></ul></div> </td> </tr> </tbody> </table> <img src ="http://www.aygfsteel.com/pdw2009/aggbug/41658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2006-04-18 15:43 <a href="http://www.aygfsteel.com/pdw2009/archive/2006/04/18/41658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>osworkflow分析http://www.aygfsteel.com/pdw2009/archive/2006/04/12/40622.html有猫怼的日?/dc:creator>有猫怼的日?/author>Wed, 12 Apr 2006 05:27:00 GMThttp://www.aygfsteel.com/pdw2009/archive/2006/04/12/40622.htmlhttp://www.aygfsteel.com/pdw2009/comments/40622.htmlhttp://www.aygfsteel.com/pdw2009/archive/2006/04/12/40622.html#Feedback0http://www.aygfsteel.com/pdw2009/comments/commentRss/40622.htmlhttp://www.aygfsteel.com/pdw2009/services/trackbacks/40622.html1.    OSWorkFlow基本概念
    在商用和开源世界里QOSWorkflow 都不同于q些已有的工作流pȝ。最大不同在于 OSWorkflow 有着非常优秀的灵zL。在开始接触 OSWorkflow 时可能较难掌握(有h说不适合工作新手入门)Q比如,OSWorkflow 不要求图形化工具来开发工作流Q而推荐手工编写 xml 格式的工作流E描q符。它能ؓ应用E序开发者提供集成,也能与现有的代码和数据库q行集成。这一切似乎给正在L快速“即插即用”工作流解决Ҏ的h刉了ȝQ但研究发现Q那些“即插即用”方案也不能在一个成熟的应用E序中提供够的灉|性来实现所有需求?br />2.    OSWorkFlow主要优势
OSWorkflow l你l对的灵zL。OSWorkflow 被认为是一U“低U别”工作流实现。与其他工作系l能用图标表现“Loops(回\)”和“Conditions(条g)”相比,OSWorkflow 只是手工“编?Coded)”来实现的。但qƈ不能说实际的代码是需要完全手工编码的Q脚本语a能胜任这U情形。OSWorkflow 不希望一个非技术用户修改工作流E,虽然一些其他工作流pȝ提供了简单的 GUI 用于工作编辑,但像q样改变工作,通常会破坏这些应用。所以,q行工作调整的最佳h选是开发h员,他们知道该怎么改变。不q,在最新的版本中,OSWorkflow 也提供了 GUI 设计器来协助工作的~辑?br />
OSWorkflow Z有限状态机概念。每个 state 由 step ID 和 status 联合表现Q可单理解ؓ step 及其 status 表示有限状态机的 stateQ。一个 state 到另一 state 的 transition 依赖于 action 的发生,在工作流生命期内有至一个或多个zd的 state。这些简单概念展C OSWorkflow 引擎的核心思想Qƈ允许一个简单 XML 文g解释工作业务流E?br />3.    OSWorkFlow核心概念
3.1.    概念定义
 
步骤QStepQ?br />    一个 Step 描述的是工作所处的位置。可能从一个 Step TranstionQ流转)到另外一个 StepQ或者也可以在同一个 Step 内流转(因ؓ Step 可以通 Status 来细分,形成多个StateQ。一个流E里面可以多个Step?br />
状态(StatusQ?br />    工作 Status 是用来描q工作流E中具体StepQ步骤)状态的字符丌ӀOSWorkflow 的有 UnderwayQ进行中Q、QueuedQ等候处理中Q、FinishedQ完成)三种 Status。一个实际StateQ状态)真正是由两部分组成:State = (Step + Status) ?br />
{QTranstionQ?br />    一个State到另一个State的{UR?br />
动作QActionQ?br />    Action 触发了发生在 Step 内或 Step 间的{Q或者说是基于 State 的流转。一个 step 里面可以有多个Action。Action 和Step 之间的关pLQStep 说明“在哪里”,Action 说明“去哪里”。 一个 Action 典型地由两部分组成:可以执行此ActionQ动作)?br />ConditionQ条ӞQ以及执行此动作后的 ResultQ结果)。   ?br />
条gQConditionQ?br />cM于逻辑判断Q可包含“AND”和“OR”逻辑。比如一个请假流E中的“本部门审批阶段”,该阶D利用“AND”逻辑Q判断流E状态是否ؓ{候处理中Q以及审批者是否ؓ本部门主?br />
l果QResultQ?br />Result 代表执行ActionQ动作)后的l果Q指向新的 Step 及其 Step StatusQ也可能q入 Split 或者 Join。Result 分ؓ两种Q Contidional-Result Q有条gl果Q,只有条g为真时才使用该结果,和 Unconditional-ResultQ无条gl果Q,当条件不满或没有条件时使用该结果?br />
分离/q接QSplit/JoinQ?br />程的切分和融合。很单的概念QSplit 可以提供多个 ResultQ结果)QJoin 则判断多个 Current Step 的态提供一个 ResultQ结果)?br />3.2.    步骤、状态和动作(Step, Status, and Action)
工作要描述步骤(Step)、步骤的状?Status)、各个步骤之间的关系以及执行各个步骤的条件和权限Q每个步骤中可以含有一个或多个动作(Action)Q动作将会一个步骤的状态发生改变?br />
对于一个执行的工作来Ԍ步骤的切换是不可避免的。一个工作流在某一时刻会有一个或多个当前步骤Q每个当前步骤都有一个状态|当前步骤的状态值组成了工作实例的状态倹{一旦完成了一个步骤,那么q个步骤不再是当前步骤Q而是切换C个新的步骤)Q通常一个新的当前步骤将随之建立hQ以保证工作l执行。完成了的步骤的最l状态值是用Old-Status属性指定的Q这个状态值的讑֮发生在切换到其他步骤之前。Old-Status的值可以是L的,但在一般情况下Q我们设|ؓFinished?br />
切换本n是一个动作(ActionQ的执行l果。每个步骤可以含有多个动作,I竟要蝲入哪个动作是由最l用戗外部事件或者Tiggerd的自动调用决定的。随着动作的完成,一个特定的步骤切换也将发生。动作可以被限制在用戗用L或当前状态。每一个动作都必须包含一个Unconditional Result?个或多个Conditional Results?br />
所以,M来说Q一个工作流由多个步骤组成。每个步骤有一个当前状态(例如QQueued, Underway or FinishedQ,一个步骤包含多个动作。每个步骤含有多个可以执行的动作。每个动作都有执行的条gQ也有要执行的函数。动作包含有可以改变状态和当前工作步骤的results?br />3.3.    l果、分支和q接(Results, Joins, and Splits)
3.3.1.    无条件结?Unconditional Result)
对于每一个动作来Ԍ必须存在一个Unconditional Result。一个result是一pd指oQ这些指令将告诉OSWorkFlow下一个Q务要做什么。这包括使工作流从一个状态切换到另一个状态?br />3.3.2.    有条件结?Conditional Result)
Conditional Result是Unconditional Result的一个扩展。它需要一个或多个Condition子标{。第一个ؓtrue的ConditionalQ用AND或ORcdQ,会指明发生切换的步骤Q这个切换步骤的发生是由于某个用h行了某个动作的结果导致的?br />3.3.3.    三种不同的Results(conditional or unconditional)
一个新的、单一的步骤和状态的l合?br />一个分裂成两个或多个步骤和状态的l合?br />这个和其他的切换组合成一个新的单一的步骤和状态的l合?br />每种不同的result对应了不同的xml描述Q你可以阅读http://www.opensymphony.com/osworkflow/workflow_2_7.dtdQ获取更多的信息?br />注意Q通常Q一个split或一个join不会再导致一个split 或 join的发生?br />3.4.    自动步骤(Auto actions)
有的时候,我们需要一些动作可以基于一些条件自动地执行。ؓ了达到这个目的,你可以在action中加入auto="true"属性。流E将考察q个动作的条件和限制Q如果条件符合,那么执行这个动作。 Auto action是由当前的调用者执行的Q所以将对该动作的调用者执行权限检查?br />3.5.    整合抽象实例(Integrating with Abstract Entities)
在你的核心实体中Q例?Document" 或?Order"Q在内部创徏一个新的属性:workflowId。这P当新?Document" 或?Order"被创建的时候,它能够和一个workflow实例兌h。那么,你的代码可以通过OSWorkflow API查找到这个workflow实例q且得到q个workflow的信息和动作?br />3.6.    工作实例状?Workflow Instance State)
有的时候,为整个workflow实例指定一个状态是很有帮助的,它独立于程的执行步骤。OSWorkflow提供一些workflow实例中可以包含的"meta-states"。这?meta-states"可以是CREATED, ACTIVATED, SUSPENDED, KILLED 和 COMPLETED。当一个工作流实例被创建的时候,它将处于CREATED状态。然后,只要一个动作被执行Q它׃自动的变成ACTIVATED状态。如果调用者没有明地改变实例的状态,工作将一直保持这个状态直到工作流l束。当工作不可能再执行Q何其他的动作的时候,工作将自动的变成COMPLETED状态?br />
然而,当工作流处于ACTIVATED状态的时候,调用者可以终止或挂vq个工作(讄工作的状态ؓKILLED 或 SUSPENDEDQ。一个终止了的工作流不能再执行M动作Q而且永q保持着l止状态。一个被挂v了的工作会被冻l,他也不能执行M的动作,除非它的状态再变成ACTIVATED?br />4.    OSWorkFlow包用途分析及代码片断
4.1.    com.opensymphony.workflow
该包为整个OSWorkflow 引擎提供核心接口。例如 com.opensymphony.workflow.Workflow 接口Q可以说Q实际开发中的大部分工作都是围绕该接口展开的,该接口有 BasicWorkflow、EJBWorkflow、OfbizWorkflow 三个实现cR?br />4.2.    com.opensymphony.workflow.basic
该包有两个类QBasicWorkflow 与 BasicWorkflowContext。BasicWorkflow 不支持事务,管依赖持久实现Q事务也不能包裹它。BasicWorkflowContext 在实际开发中很少使用?br />
public void setWorkflow(int userId) {
    Workflow workflow = new BasicWorkflow(Integer.toString(userId));
}

4.3.    com.opensymphony.workflow.config
该包有一个接口和两个该接口的实现cR在 OSWorkflow 2.7 以前Q状态由多个地方的静态字D늻护,q种方式很方便,但是有很多缺陷和U束。最主要的缺Ҏ无法通过不同配置q行多个 OSWorkflow 实例。实现类 DefaultConfiguration 用于一般的配置文g载入。而 SpringConfiguration 则是让 Spring 容器理配置信息?br />
public void setWorkflow(int userId) {
    Workflow workflow = new BasicWorkflow(Integer.toString(userId));
}
4.4.    com.opensymphony.workflow.ejb
    该包有两个接口 WorkflowHome 和 WorkflowRemote。该包的若干cMQ最重要的是 EJBWorkflowQ该cd BasicWorkflow 的作用一P是 OSWorkflow 的核心,q利用 EJB 容器理事务Q也作ؓ工作 session bean 的包装器?br />4.5.    com.opensymphony.workflow.loader
该包有若q类Q用得最多的是 XxxxDescriptorQ如果在工作引擎运行时需要了解指定的动作、步骤的状态、名字,{信息时Q这些描q符会v到很大作用?br />
public String findNameByStepId(int stepId,String wfName) {
    WorkflowDescriptor wd = workflow.getWorkflowDescriptor(wfName);
    StepDescriptor stepDes = wd.getStep(stepId);
    return stepDes.getName();
}
4.6.    com.opensymphony.workflow.ofbiz
    OfbizWorkflow 和 BasicWorkflow 在很多方面非常相|除了需要调用 ofbiz 的 TransactionUtil 来包装事务?br />4.7.    com.opensymphony.workflow.query
该包主要为查询而设计,但不是所有的工作存储都支持查询。通常QHibernate 和 JDBC 都支持,而内存工作流存储不支持。值得注意的是 Hibernate 存储不支持؜合型查询Q例如,一个查询同时包含了 history step 上下文和 current step 上下文)。执行一个查询,需要创建 WorkflowExpressionQuery 实例Q接着调用 Workflow 对象的 query Ҏ来得到最l查询结果?br />
public List queryDepAdmin(int userId,int type) {
    int[] arr = getSubPerson(userId,type);
    
    //构造表辑ּ
    Expression[] expressions = new Expression[1 + arr.length];
    Expression expStatus = new FieldExpression(FieldExpression.STATUS,
    FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, "Queued");
    expressions[0] = expStatus;
    
    for (int i = 0; i < arr.length; i++) {
        Expression expOwner = new FieldExpression(FieldExpression.OWNER,
        FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS,
        Integer.toString(arr[i]));
        expressions[i + 1] = expOwner;
    }

    //查询未完成流~号
    List wfIdList = null;
    try {
        WorkflowExpressionQuery query = new WorkflowExpressionQuery(
        new NestedExpression(expressions, NestedExpression.AND));
        wfIdList = workflow.query(query);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
4.8.    com.opensymphony.workflow.soap
    OSWorkflow 通过 SOAP 来支持远端调用。这U调用借助 WebMethods 实现?br />4.9.    com.opensymphony.workflow.spi
该包可以说是 OSWorkflow 与持久层打交道的途径Q如当前工作的实体Q其中包括:EJB、Hibernate、JDBC、Memory、Ofbiz、OJB、Prevayler?br />
HibernateWorkflowEntry hwfe = (HibernateWorkflowEntry) getHibernateTemplate()
    .find("from HibernateWorkflowEntry where Id="
        + wfIdList.get(i)).get(0);
4.10.    com.opensymphony.workflow.util
该包是 OSWorkflow 的工具包Q包括了对 BeanShell、BSF、EJB Local、EJB Remote、JNDI 的支持?br />5.    OSWorkFlow表结构分?br />5.1.    OS_WFENTRY
工作主表,存放工作名U和状?br />
字段名    数据类型    说?br />ID    NUMBER    自动~号
NAME    VARCHAR2(20)    工作名U?br />STATE    NUMBER    工作状?br />
5.2.    OS_CURRENTSTEP
当前步骤表,存放当前正在q行步骤的数?br />
字段名    数据类型    说?br />ID    NUMBER    自动~号
ENTRY_ID    NUMBER    工作编?br />STEP_ID    NUMBER    步骤~号
ACTION_ID    NUMBER    动作~号
OWNER    VARCHAR2(20)    步骤的所有?br />START_DATE    DATE    开始时?br />FINISH_DATE    DATE    l束旉
DUE_DATE    DATE    授权旉
STATUS    VARCHAR2(20)    状?br />CALLER    VARCHAR2(20)    操作人员的帐号名U?br />
5.3.    OS_CURRENTSTEP_PREV
前步骤表Q存攑ֽ前步骤和上一个步骤的兌数据

字段名    数据类型    说?br />ID    NUMBER    当前步骤~号
PREVIOUS    NUMBER    前步骤编?br />
5.4.    OS_HISTORYSTEP
历史步骤表,存放当前正在q行步骤的数?br />
字段名    数据类型    说?br />ID    NUMBER    自动~号
ENTRY_ID    NUMBER    工作编?br />STEP_ID    NUMBER    步骤~号
ACTION_ID    NUMBER    动作~号
OWNER    VARCHAR2(20)    步骤的所有?br />START_DATE    DATE    开始时?br />FINISH_DATE    DATE    l束旉
DUE_DATE    DATE    授权旉
STATUS    VARCHAR2(20)    状?br />CALLER    VARCHAR2(20)    操作人员的帐号名U?br />
5.5.    OS_HISTORYSTEP_PREV
前历史步骤表Q存攑֎史步骤和上一个步骤的兌数据

字段名    数据类型    说?br />ID    NUMBER    当前历史步骤~号
PREVIOUS    NUMBER    前历史步骤编?br />
5.6.    OS_PROPERTYENTRY
属性表Q存放时变?br />
字段名    数据类型    说?br />GLOBAL_KEY    VARCHAR2(255)    全局关键?br />ITEM_KEY    VARCHAR2(255)    条目关键?br />ITEM_TYPE    NUMBER    条目cd
STRING_VALUE    VARCHAR2(255)    字符?br />DATE_VALUE    DATE    日期?br />DATA_VALUE    BLOB    数据?br />FLOAT_VALUE    FLOAT    点?br />NUMBER_VALUE    NUMBER    数字?br />


]]>
osworkflow分析http://www.aygfsteel.com/pdw2009/archive/2006/04/12/40621.html有猫怼的日?/dc:creator>有猫怼的日?/author>Wed, 12 Apr 2006 05:26:00 GMThttp://www.aygfsteel.com/pdw2009/archive/2006/04/12/40621.htmlhttp://www.aygfsteel.com/pdw2009/comments/40621.htmlhttp://www.aygfsteel.com/pdw2009/archive/2006/04/12/40621.html#Feedback0http://www.aygfsteel.com/pdw2009/comments/commentRss/40621.htmlhttp://www.aygfsteel.com/pdw2009/services/trackbacks/40621.html1.    OSWorkFlow基本概念
    在商用和开源世界里QOSWorkflow 都不同于q些已有的工作流pȝ。最大不同在于 OSWorkflow 有着非常优秀的灵zL。在开始接触 OSWorkflow 时可能较难掌握(有h说不适合工作新手入门)Q比如,OSWorkflow 不要求图形化工具来开发工作流Q而推荐手工编写 xml 格式的工作流E描q符。它能ؓ应用E序开发者提供集成,也能与现有的代码和数据库q行集成。这一切似乎给正在L快速“即插即用”工作流解决Ҏ的h刉了ȝQ但研究发现Q那些“即插即用”方案也不能在一个成熟的应用E序中提供够的灉|性来实现所有需求?br />2.    OSWorkFlow主要优势
OSWorkflow l你l对的灵zL。OSWorkflow 被认为是一U“低U别”工作流实现。与其他工作系l能用图标表现“Loops(回\)”和“Conditions(条g)”相比,OSWorkflow 只是手工“编?Coded)”来实现的。但qƈ不能说实际的代码是需要完全手工编码的Q脚本语a能胜任这U情形。OSWorkflow 不希望一个非技术用户修改工作流E,虽然一些其他工作流pȝ提供了简单的 GUI 用于工作编辑,但像q样改变工作,通常会破坏这些应用。所以,q行工作调整的最佳h选是开发h员,他们知道该怎么改变。不q,在最新的版本中,OSWorkflow 也提供了 GUI 设计器来协助工作的~辑?br />
OSWorkflow Z有限状态机概念。每个 state 由 step ID 和 status 联合表现Q可单理解ؓ step 及其 status 表示有限状态机的 stateQ。一个 state 到另一 state 的 transition 依赖于 action 的发生,在工作流生命期内有至一个或多个zd的 state。这些简单概念展C OSWorkflow 引擎的核心思想Qƈ允许一个简单 XML 文g解释工作业务流E?br />3.    OSWorkFlow核心概念
3.1.    概念定义
 
步骤QStepQ?br />    一个 Step 描述的是工作所处的位置。可能从一个 Step TranstionQ流转)到另外一个 StepQ或者也可以在同一个 Step 内流转(因ؓ Step 可以通 Status 来细分,形成多个StateQ。一个流E里面可以多个Step?br />
状态(StatusQ?br />    工作 Status 是用来描q工作流E中具体StepQ步骤)状态的字符丌ӀOSWorkflow 的有 UnderwayQ进行中Q、QueuedQ等候处理中Q、FinishedQ完成)三种 Status。一个实际StateQ状态)真正是由两部分组成:State = (Step + Status) ?br />
{QTranstionQ?br />    一个State到另一个State的{UR?br />
动作QActionQ?br />    Action 触发了发生在 Step 内或 Step 间的{Q或者说是基于 State 的流转。一个 step 里面可以有多个Action。Action 和Step 之间的关pLQStep 说明“在哪里”,Action 说明“去哪里”。 一个 Action 典型地由两部分组成:可以执行此ActionQ动作)?br />ConditionQ条ӞQ以及执行此动作后的 ResultQ结果)。   ?br />
条gQConditionQ?br />cM于逻辑判断Q可包含“AND”和“OR”逻辑。比如一个请假流E中的“本部门审批阶段”,该阶D利用“AND”逻辑Q判断流E状态是否ؓ{候处理中Q以及审批者是否ؓ本部门主?br />
l果QResultQ?br />Result 代表执行ActionQ动作)后的l果Q指向新的 Step 及其 Step StatusQ也可能q入 Split 或者 Join。Result 分ؓ两种Q Contidional-Result Q有条gl果Q,只有条g为真时才使用该结果,和 Unconditional-ResultQ无条gl果Q,当条件不满或没有条件时使用该结果?br />
分离/q接QSplit/JoinQ?br />程的切分和融合。很单的概念QSplit 可以提供多个 ResultQ结果)QJoin 则判断多个 Current Step 的态提供一个 ResultQ结果)?br />3.2.    步骤、状态和动作(Step, Status, and Action)
工作要描述步骤(Step)、步骤的状?Status)、各个步骤之间的关系以及执行各个步骤的条件和权限Q每个步骤中可以含有一个或多个动作(Action)Q动作将会一个步骤的状态发生改变?br />
对于一个执行的工作来Ԍ步骤的切换是不可避免的。一个工作流在某一时刻会有一个或多个当前步骤Q每个当前步骤都有一个状态|当前步骤的状态值组成了工作实例的状态倹{一旦完成了一个步骤,那么q个步骤不再是当前步骤Q而是切换C个新的步骤)Q通常一个新的当前步骤将随之建立hQ以保证工作l执行。完成了的步骤的最l状态值是用Old-Status属性指定的Q这个状态值的讑֮发生在切换到其他步骤之前。Old-Status的值可以是L的,但在一般情况下Q我们设|ؓFinished?br />
切换本n是一个动作(ActionQ的执行l果。每个步骤可以含有多个动作,I竟要蝲入哪个动作是由最l用戗外部事件或者Tiggerd的自动调用决定的。随着动作的完成,一个特定的步骤切换也将发生。动作可以被限制在用戗用L或当前状态。每一个动作都必须包含一个Unconditional Result?个或多个Conditional Results?br />
所以,M来说Q一个工作流由多个步骤组成。每个步骤有一个当前状态(例如QQueued, Underway or FinishedQ,一个步骤包含多个动作。每个步骤含有多个可以执行的动作。每个动作都有执行的条gQ也有要执行的函数。动作包含有可以改变状态和当前工作步骤的results?br />3.3.    l果、分支和q接(Results, Joins, and Splits)
3.3.1.    无条件结?Unconditional Result)
对于每一个动作来Ԍ必须存在一个Unconditional Result。一个result是一pd指oQ这些指令将告诉OSWorkFlow下一个Q务要做什么。这包括使工作流从一个状态切换到另一个状态?br />3.3.2.    有条件结?Conditional Result)
Conditional Result是Unconditional Result的一个扩展。它需要一个或多个Condition子标{。第一个ؓtrue的ConditionalQ用AND或ORcdQ,会指明发生切换的步骤Q这个切换步骤的发生是由于某个用h行了某个动作的结果导致的?br />3.3.3.    三种不同的Results(conditional or unconditional)
一个新的、单一的步骤和状态的l合?br />一个分裂成两个或多个步骤和状态的l合?br />这个和其他的切换组合成一个新的单一的步骤和状态的l合?br />每种不同的result对应了不同的xml描述Q你可以阅读http://www.opensymphony.com/osworkflow/workflow_2_7.dtdQ获取更多的信息?br />注意Q通常Q一个split或一个join不会再导致一个split 或 join的发生?br />3.4.    自动步骤(Auto actions)
有的时候,我们需要一些动作可以基于一些条件自动地执行。ؓ了达到这个目的,你可以在action中加入auto="true"属性。流E将考察q个动作的条件和限制Q如果条件符合,那么执行这个动作。 Auto action是由当前的调用者执行的Q所以将对该动作的调用者执行权限检查?br />3.5.    整合抽象实例(Integrating with Abstract Entities)
在你的核心实体中Q例?Document" 或?Order"Q在内部创徏一个新的属性:workflowId。这P当新?Document" 或?Order"被创建的时候,它能够和一个workflow实例兌h。那么,你的代码可以通过OSWorkflow API查找到这个workflow实例q且得到q个workflow的信息和动作?br />3.6.    工作实例状?Workflow Instance State)
有的时候,为整个workflow实例指定一个状态是很有帮助的,它独立于程的执行步骤。OSWorkflow提供一些workflow实例中可以包含的"meta-states"。这?meta-states"可以是CREATED, ACTIVATED, SUSPENDED, KILLED 和 COMPLETED。当一个工作流实例被创建的时候,它将处于CREATED状态。然后,只要一个动作被执行Q它׃自动的变成ACTIVATED状态。如果调用者没有明地改变实例的状态,工作将一直保持这个状态直到工作流l束。当工作不可能再执行Q何其他的动作的时候,工作将自动的变成COMPLETED状态?br />
然而,当工作流处于ACTIVATED状态的时候,调用者可以终止或挂vq个工作(讄工作的状态ؓKILLED 或 SUSPENDEDQ。一个终止了的工作流不能再执行M动作Q而且永q保持着l止状态。一个被挂v了的工作会被冻l,他也不能执行M的动作,除非它的状态再变成ACTIVATED?br />4.    OSWorkFlow包用途分析及代码片断
4.1.    com.opensymphony.workflow
该包为整个OSWorkflow 引擎提供核心接口。例如 com.opensymphony.workflow.Workflow 接口Q可以说Q实际开发中的大部分工作都是围绕该接口展开的,该接口有 BasicWorkflow、EJBWorkflow、OfbizWorkflow 三个实现cR?br />4.2.    com.opensymphony.workflow.basic
该包有两个类QBasicWorkflow 与 BasicWorkflowContext。BasicWorkflow 不支持事务,管依赖持久实现Q事务也不能包裹它。BasicWorkflowContext 在实际开发中很少使用?br />
public void setWorkflow(int userId) {
    Workflow workflow = new BasicWorkflow(Integer.toString(userId));
}

4.3.    com.opensymphony.workflow.config
该包有一个接口和两个该接口的实现cR在 OSWorkflow 2.7 以前Q状态由多个地方的静态字D늻护,q种方式很方便,但是有很多缺陷和U束。最主要的缺Ҏ无法通过不同配置q行多个 OSWorkflow 实例。实现类 DefaultConfiguration 用于一般的配置文g载入。而 SpringConfiguration 则是让 Spring 容器理配置信息?br />
public void setWorkflow(int userId) {
    Workflow workflow = new BasicWorkflow(Integer.toString(userId));
}
4.4.    com.opensymphony.workflow.ejb
    该包有两个接口 WorkflowHome 和 WorkflowRemote。该包的若干cMQ最重要的是 EJBWorkflowQ该cd BasicWorkflow 的作用一P是 OSWorkflow 的核心,q利用 EJB 容器理事务Q也作ؓ工作 session bean 的包装器?br />4.5.    com.opensymphony.workflow.loader
该包有若q类Q用得最多的是 XxxxDescriptorQ如果在工作引擎运行时需要了解指定的动作、步骤的状态、名字,{信息时Q这些描q符会v到很大作用?br />
public String findNameByStepId(int stepId,String wfName) {
    WorkflowDescriptor wd = workflow.getWorkflowDescriptor(wfName);
    StepDescriptor stepDes = wd.getStep(stepId);
    return stepDes.getName();
}
4.6.    com.opensymphony.workflow.ofbiz
    OfbizWorkflow 和 BasicWorkflow 在很多方面非常相|除了需要调用 ofbiz 的 TransactionUtil 来包装事务?br />4.7.    com.opensymphony.workflow.query
该包主要为查询而设计,但不是所有的工作存储都支持查询。通常QHibernate 和 JDBC 都支持,而内存工作流存储不支持。值得注意的是 Hibernate 存储不支持؜合型查询Q例如,一个查询同时包含了 history step 上下文和 current step 上下文)。执行一个查询,需要创建 WorkflowExpressionQuery 实例Q接着调用 Workflow 对象的 query Ҏ来得到最l查询结果?br />
public List queryDepAdmin(int userId,int type) {
    int[] arr = getSubPerson(userId,type);
    
    //构造表辑ּ
    Expression[] expressions = new Expression[1 + arr.length];
    Expression expStatus = new FieldExpression(FieldExpression.STATUS,
    FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, "Queued");
    expressions[0] = expStatus;
    
    for (int i = 0; i < arr.length; i++) {
        Expression expOwner = new FieldExpression(FieldExpression.OWNER,
        FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS,
        Integer.toString(arr[i]));
        expressions[i + 1] = expOwner;
    }

    //查询未完成流~号
    List wfIdList = null;
    try {
        WorkflowExpressionQuery query = new WorkflowExpressionQuery(
        new NestedExpression(expressions, NestedExpression.AND));
        wfIdList = workflow.query(query);
    } catch (Exception e) {
        e.printStackTrace();
    }
}
4.8.    com.opensymphony.workflow.soap
    OSWorkflow 通过 SOAP 来支持远端调用。这U调用借助 WebMethods 实现?br />4.9.    com.opensymphony.workflow.spi
该包可以说是 OSWorkflow 与持久层打交道的途径Q如当前工作的实体Q其中包括:EJB、Hibernate、JDBC、Memory、Ofbiz、OJB、Prevayler?br />
HibernateWorkflowEntry hwfe = (HibernateWorkflowEntry) getHibernateTemplate()
    .find("from HibernateWorkflowEntry where Id="
        + wfIdList.get(i)).get(0);
4.10.    com.opensymphony.workflow.util
该包是 OSWorkflow 的工具包Q包括了对 BeanShell、BSF、EJB Local、EJB Remote、JNDI 的支持?br />5.    OSWorkFlow表结构分?br />5.1.    OS_WFENTRY
工作主表,存放工作名U和状?br />
字段名    数据类型    说?br />ID    NUMBER    自动~号
NAME    VARCHAR2(20)    工作名U?br />STATE    NUMBER    工作状?br />
5.2.    OS_CURRENTSTEP
当前步骤表,存放当前正在q行步骤的数?br />
字段名    数据类型    说?br />ID    NUMBER    自动~号
ENTRY_ID    NUMBER    工作编?br />STEP_ID    NUMBER    步骤~号
ACTION_ID    NUMBER    动作~号
OWNER    VARCHAR2(20)    步骤的所有?br />START_DATE    DATE    开始时?br />FINISH_DATE    DATE    l束旉
DUE_DATE    DATE    授权旉
STATUS    VARCHAR2(20)    状?br />CALLER    VARCHAR2(20)    操作人员的帐号名U?br />
5.3.    OS_CURRENTSTEP_PREV
前步骤表Q存攑ֽ前步骤和上一个步骤的兌数据

字段名    数据类型    说?br />ID    NUMBER    当前步骤~号
PREVIOUS    NUMBER    前步骤编?br />
5.4.    OS_HISTORYSTEP
历史步骤表,存放当前正在q行步骤的数?br />
字段名    数据类型    说?br />ID    NUMBER    自动~号
ENTRY_ID    NUMBER    工作编?br />STEP_ID    NUMBER    步骤~号
ACTION_ID    NUMBER    动作~号
OWNER    VARCHAR2(20)    步骤的所有?br />START_DATE    DATE    开始时?br />FINISH_DATE    DATE    l束旉
DUE_DATE    DATE    授权旉
STATUS    VARCHAR2(20)    状?br />CALLER    VARCHAR2(20)    操作人员的帐号名U?br />
5.5.    OS_HISTORYSTEP_PREV
前历史步骤表Q存攑֎史步骤和上一个步骤的兌数据

字段名    数据类型    说?br />ID    NUMBER    当前历史步骤~号
PREVIOUS    NUMBER    前历史步骤编?br />
5.6.    OS_PROPERTYENTRY
属性表Q存放时变?br />
字段名    数据类型    说?br />GLOBAL_KEY    VARCHAR2(255)    全局关键?br />ITEM_KEY    VARCHAR2(255)    条目关键?br />ITEM_TYPE    NUMBER    条目cd
STRING_VALUE    VARCHAR2(255)    字符?br />DATE_VALUE    DATE    日期?br />DATA_VALUE    BLOB    数据?br />FLOAT_VALUE    FLOAT    点?br />NUMBER_VALUE    NUMBER    数字?br />


]]>
osworkflow代码分析http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40480.html有猫怼的日?/dc:creator>有猫怼的日?/author>Tue, 11 Apr 2006 08:03:00 GMThttp://www.aygfsteel.com/pdw2009/archive/2006/04/11/40480.htmlhttp://www.aygfsteel.com/pdw2009/comments/40480.htmlhttp://www.aygfsteel.com/pdw2009/archive/2006/04/11/40480.html#Feedback0http://www.aygfsteel.com/pdw2009/comments/commentRss/40480.htmlhttp://www.aygfsteel.com/pdw2009/services/trackbacks/40480.html1.com.opensymphony.workflow.Workflow 工作的用户接口?/p>

       主要定义了用户对工作的操作Ҏ和用戯得工作流信息的方法。如doAction(long id, int actionId, Map inputs)Ҏ可以执行工作的Actionq生transactionQ用戯用getAvailableActions(long id, Map inputs)可以获得知道工作实例中W合条g的可以执行的Action?/p>

2.com.opensymphony.workflow.WorkflowContext 工作的Context接口?/p>

      只有两个ҎQ其中getCaller()获得调用者,setRollbackOnly()可以回滚Action造成的transaction?/p>

      setRollbackOnly()Ҏ非常重要Q可以在此方法中实现工作数据与业务数据的事务处理。由于工作流引擎流E数据与业务数据分离开理Q所以工作流数据与业务数据之间的事务处理往往比较困难Q甚x很多商业的工作流引擎都没有解册个问题,造成软g上的漏洞。可惜在BasicWorkflowContext中ƈ没有实现回滚时的事务处理Q但实现h应该不会很困难,在以后会单独考虑?/p>

3.com.opensymphony.workflow.spi.WorkflowEntry 工作实例的接口?/p>

     定义了获得工作流实例信息的方法?/p>

4.com.opensymphony.workflow.config.Configuration 工作配|接口?/p>

      获得osworkflw的配|信息和程的定义信息, osworkflow中的例子是使用此接口的默认实现。如果想让osworkflw与自qpȝ更好的整合,q个接口需要自己实现?/p>

5.com.opensymphony.workflow.loader.AbstractWorkflowFactory 程定义的解析器?/p>

      osworkflow中提供了此抽象类?U实玎ͼ最常用的是XMLWorkflowFactoryQ可以对~写的工作流定义xml文gq行解析?/p>

6.com.opensymphony.workflow.spi.WorkflowStore 工作存储接口?/p>

      实现此接口可以实现用多种途径保存工作信息,jdbc,hibernate,ejb,memory.........

AbstractWorkflowcLworkflow接口的最基本的实现?/p>

1.public int[] getAvailableActions(long id, Map inputs)ҎQ?/p>

q回当前可以执行的Ation?/p>

  • 得到工作流E实例?
  • 得到工作实例的定义?
  • 得到工作实例的PropertySet?
  • 得到工作的当前Step?
  • 产生TransientVars?
  • 得到Global Actions?
  • 判断可以执行的Global Action增加到可执行Action列表中?
  • 获得当前Steps中的可执行Actionq添加到可执行Action列表中?
  • q回可执行Actions?

2. public void setConfiguration(Configuration configuration)ҎQ?/p>

讄工作配|方法?/p>

3.public Configuration getConfiguration()ҎQ?/p>

q回工作配|方法,如果没有获得配置信息Q初始化配置信息?/p>

4.public List getCurrentSteps(long id)Q?/p>

获得工作当前所在步骤?/p>

5.public int getEntryState(long id):

获得工作的状态?/p>

6.public List getHistorySteps(long id)

获得工作的历史步骤?/p>

7. public Properties getPersistenceProperties()

获得讄的持久化参数?/p>

8.public PropertySet getPropertySet(long id)

得到工作的PropertySetQ调用store中的Ҏ?/p>

9.public List getSecurityPermissions(long id)

得到工作当前Step的permissions?/p>

10.public WorkflowDescriptor getWorkflowDescriptor(String workflowName)

得到工作的定义?/p>

11.public String getWorkflowName(long id)

Ҏ工作实例返回工作流定义名?/p>

12. public String[] getWorkflowNames()

q回pȝ中配|的所有工作流的名字?/p>

13.public boolean canInitialize(String workflowName, int initialAction)Qpublic boolean canInitialize(String workflowName, int initialAction, Map inputs)Qprivate boolean canInitialize(String workflowName, int initialAction, Map transientVars, PropertySet ps) throws WorkflowException

判断指定的工作流初始化Action是不是可以执行?/p>

14.public boolean canModifyEntryState(long id, int newState)

判断工作是不是可以转换到指定状态?/p>

  • 不可以{换到CREATED状态?
  • CREATEDQSUSPENDED可以转换到ACTIVATED状态?
  • ACTIVATED可以转换到SUSPENDED状态?
  • CREATEDQACTIVATEDQSUSPENDED 可以转换到KILLED状态?

15.public void changeEntryState(long id, int newState) throws WorkflowException

转换工作状态?/p>

16.public void doAction(long id, int actionId, Map inputs) throws WorkflowException

执行Action?/p>

  • 获得工作storeQ和程实例entry?
  • 判断是不是活动的工作,不是p回?
  • 获得工作的定义?
  • 获得工作当前所再Steps?
  • 获得工作PropertySet?
  • 生成transientVars?
  • 从GlobalActions中和当前Steps的普通Actions中判断执行的Action是否试可执行的?
  • 完成Action的Transition?

17.public void executeTriggerFunction(long id, int triggerId) throws WorkflowException

调用工作的Trigger Function

18.public long initialize(String workflowName, int initialAction, Map inputs) throws InvalidRoleException, InvalidInputException, WorkflowException

初始化一个新的流E实例。返回流E实例id?/p>

19.public List query(WorkflowQuery query)Qpublic List query(WorkflowExpressionQuery query)

查询程实例?/p>

20.public boolean removeWorkflowDescriptor(String workflowName) throws FactoryException

删除已经配置的工作流定义?/p>

21.public boolean saveWorkflowDescriptor(String workflowName, WorkflowDescriptor descriptor, boolean replace) throws FactoryException

保存工作定义?/p>

22.protected List getAvailableActionsForStep(WorkflowDescriptor wf, Step step, Map transientVars, PropertySet ps) throws WorkflowException

获得指定步骤的可用Actions?/p>

23.protected int[] getAvailableAutoActions(long id, Map inputs)

q回可执行的AutoActions?/p>

24.protected List getAvailableAutoActionsForStep(WorkflowDescriptor wf, Step step, Map transientVars, PropertySet ps) throws WorkflowException

q回指定Step中可执行的AutoActions?/p>

25.protected WorkflowStore getPersistence() throws StoreException

q回配置的store?/p>

26.protected void checkImplicitFinish(long id) throws WorkflowException

判断工作是不是q有可执行的ActionQ如果没有,完成此工作流实例?/p>

27.protected void completeEntry(long id, Collection currentSteps) throws StoreException

l束工作实例,是把改变流E实例的状态ƈ把当前的Steps都放入到历史表中。?/p>

28.protected boolean passesCondition(ConditionDescriptor conditionDesc, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowException

29.protected boolean passesCondition(ConditionDescriptor conditionDesc, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowExceptionQprotected boolean passesConditions(String conditionType, List conditions, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowException

判断条g是不是符合?/p>

30.protected void populateTransientMap(WorkflowEntry entry, Map transientVars, List registers, Integer actionId, Collection currentSteps) throws WorkflowException

产生临时变量transientVarsQ包含contextQentryQstoreQdescriptorQactionIdQcurrentStepsQ以及定义的register和用L输入变量?/p>

31.protected void verifyInputs(WorkflowEntry entry, List validators, Map transientVars, PropertySet ps) throws WorkflowException

验证用户的输入?/p>

32.private boolean isActionAvailable(ActionDescriptor action, Map transientVars, PropertySet ps, int stepId) throws WorkflowException

判断Action是否可用?/p>

33.private Step getCurrentStep(WorkflowDescriptor wfDesc, int actionId, List currentSteps, Map transientVars, PropertySet ps) throws WorkflowException

获得Action所在Step?/p>

34.private boolean canInitialize(String workflowName, int initialAction, Map transientVars, PropertySet ps) throws WorkflowException

判断工作是不是可以实例化?/p>

35.private Step createNewCurrentStep(ResultDescriptor theResult, WorkflowEntry entry, WorkflowStore store, int actionId, Step currentStep, long[] previousIds, Map transientVars, PropertySet ps) throws WorkflowException

产生新的当前Step?/p>

  • 从resulte中获得nextStepQ如果ؓ-1QnextStep为当前Step?
  • 获得定义中的ownerQoldStatusQstatus?
  • 完成当前StepQƈ且将当前Step保存到历史库中?
  • 生成新的Step?

36.private void executeFunction(FunctionDescriptor function, Map transientVars, PropertySet ps) throws WorkflowException

执行Function?/p>

37.private boolean transitionWorkflow(WorkflowEntry entry, List currentSteps, WorkflowStore store, WorkflowDescriptor wf, ActionDescriptor action, Map transientVars, Map inputs, PropertySet ps) throws WorkflowException

完成工作的transation?br />

DefaultConfiguration是Configuration接口的默认实玎ͼ用于初始化系l的基本配置信息?/div>
1.public WorkflowDescriptor getWorkflow(String name) throws FactoryException
Ҏ工作的定义名获得工作流的定义?/div>
2.public WorkflowStore getWorkflowStore() throws StoreException
获得配置的持久化cStore?/div>
3.public void load(URL url) throws FactoryException
装蝲配置信息?/div>
  • 得到配置文g,q解析?
  • 获得持久化信息,包括持久化类的\径和持久化类初始化参数?
  • 获得工作信息解析类路径Qƈ初始化?

4. public WorkflowStore getWorkflowStore() throws StoreException

获得工作初始化cR?br />

XMLWorkflowFactory用于解析工作定义xml文gQ获得工作流信息?/div>
1.public WorkflowDescriptor getWorkflow(String name) throws FactoryException
Ҏ工作定义名获得工作定义?/div>
2.public String[] getWorkflowNames()
得到所有已l定义的工作名U?/div>
3.public void initDone() throws FactoryException
初始化workflows.xml文g中列出的工作定义文件信息?br />
转自于ch(耐心)


]]>osworkflow概念http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40478.html有猫怼的日?/dc:creator>有猫怼的日?/author>Tue, 11 Apr 2006 07:55:00 GMThttp://www.aygfsteel.com/pdw2009/archive/2006/04/11/40478.htmlhttp://www.aygfsteel.com/pdw2009/comments/40478.htmlhttp://www.aygfsteel.com/pdw2009/archive/2006/04/11/40478.html#Feedback0http://www.aygfsteel.com/pdw2009/comments/commentRss/40478.htmlhttp://www.aygfsteel.com/pdw2009/services/trackbacks/40478.html1. StepQ工作流所在的位置Q整个工作流的步骤,也可以是一pd工作中的某个工作Q比如某个审ҎE中的文件交到某个领导处审批Q此q程可能包括接收U书交来的文件、然后阅诅R提q意见、签字、叫l秘书l处理,q整个过E可以是一个Step。但q不是FSM中的Status?/p>

2. StatusQ某个Step的状态,每个Step可以有多个Status。比如上例中阅读Q等待提意见Q等待签字,{待交秘书处理,都是Step的状态。StepQStatus共同l成了工作流的状态,也就实现了FSM中的Status。Step的Status在OSWorkflow中就是一D|本,状态的判断其实是自定义的一D|本的比较Q非常灵zR?/p>

3. ActionQ造成工作状态{换的动作Q比如”阅L件“动作,造成了工作流状态从”领导审批+{待阅读"转换成“领导审批+{待提出意见”。由于工作流的状态是StepQStatusQ所以Action可以造成Stats的变化,也可以造成Step的变化?/p>

4. ResultQ工作流状态的转换Q也是Action造成的结果。也是FSM中的Transition。每个Action中至包含一个unconditional result和包?或多个conditional resultQResult的优先序?W一个符合条件的conditional result > 其他W合条g的conditional result  > unconditional result?/p>

5.Split/Join:字面意思就可以解释。Split可以产生多个unconditional resultQ而Join可以判断多个Step的状态,如果都满x件的时候,Join产生一个unconditional result。可以用来实现其他工作流产品定义中的同步区的作用Q比如一个投标文件的评标q程Q分别要在技术方面和商务斚wҎ书进行评分,q样可以用Split工作流分开q入商务评标l和技术评标组分别q行评标Q当两个评标q程都完成后使用Join两个流E合qӞq对两个评标做的评分q行汇怅R?/p>

6.External FunctionsQ执行的功能和动作。Q何的工作引擎都要与实际的业务操作相l合QExternal Functions是OSWorkflow中执行业务操作的部分Q比如审ҎE中Q领导填写意见后领导的意见更新C务数据库中的q程。Functions有两U类型,pre step function和post step functionQ分别发生{Ud和发生{Ud执行。Functions可以被定义到Step中和Action中?/p>

7.Trigger FunctionsQ一U不是定义在Action中的FunctionQ依靠计划自动执行?/p>

8.ValidatorsQ用来检验用戯入是否符合条Ӟ只有W合条gQAction对应的{UL能执行,如果不符合条Ӟq回InvalidInputException异常?br />
转于:ch(耐心)



]]>
在myeclipse下配|osworkflow的环?/title><link>http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40475.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Tue, 11 Apr 2006 07:40:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40475.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/40475.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/40475.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/40475.html</trackback:ping><description><![CDATA[1 新徏一个名为oswf的Web Projcet 目,q添加项目的  struts capabilities,q把osworkflow所需要jar文g拯到lib目录?<br /><br />2 在tomcat的servers.xml文g中配|一个项目连接到我们所在的myeclipse工作Z所建立的oswf目下的WebRoot目录?在servers.xml中添加如下代?<br /><br /><Context path="/oswf" docBase="D:\peidw\workplace\osworkflow\WebRoot" debug="5" reloadable="true" crossContext="true"><br />        <Resource name="jdbc/oswf" auth="Container" type="javax.sql.DataSource"/><br />          <ResourceParams name="jdbc/oswf"><br />          <parameter><br />            <name>factory</name><br />            <value>org.apache.commons.dbcp.BasicDataSourceFactory</value><br />          </parameter><br />          <parameter><br />            <name>driverClassName</name><br />            <value>com.mysql.jdbc.Driver</value><br />          </parameter><br />          <parameter><br />            <name>url</name><br />            <value>jdbc:mysql://localhost:3306/osworkflow</value><br />          </parameter><br />          <parameter><br />            <name>username</name><br />            <value>root</value><br />          </parameter><br />          <parameter><br />            <name>password</name><br />            <value></value><br />          </parameter><br />          <parameter><br />            <name>maxActive</name><br />            <value>20</value><br />          </parameter><br />          <parameter><br />            <name>maxIdle</name><br />            <value>2</value><br />          </parameter><br />          <parameter><br />            <name>maxWait</name><br />            <value>-1</value><br />          </parameter><br />          <parameter><br />            <name>removeAbandoned</name><br />            <value>true</value><br />          </parameter><br />          <parameter><br />            <name>removeAbandonedTimeout</name><br />            <value>300</value><br />          </parameter><br />        </ResourceParams><br />        </Context><br /><br />3  在src目录需要徏立三个文件来配置OSWorkflow的相关配|?首先是osworkflow.xml文g,至于文g的作用一看就明白,内容如下:<br />       <?xml version="1.0" encoding="UTF-8"?><br /><osworkflow><br /> <persistence class="com.opensymphony.workflow.spi.jdbc.JDBCWorkflowStore"><br />     <property key="datasource" value="jdbc/oswf"/><br />     <br />     <property key="entry.sequence" value="select max(id)+1 from os_wfentry"/><br />     <property key="entry.id" value="id"/><br />     <property key="entry.name" value="name" /><br />     <property key="entry.state" value="state"/><br />     <br />     <property key="step.sequence" value="select max(id)+1 from os_stepids"/><br />     <property key="step.sequence.increment" value="insert into os_stepids(id) values(null) "/><br />     <property key="step.sequence.retrieve" value="select max(id) from os_stepids"/><br />     <br />     <property key="history.table" value="os_historystep"/><br />     <property key="current.table" value="os_currentstep"/><br />     <property key="histroyPrev.table" value="os_historystep_prev"/><br />     <property key="currentPrev.table" value="os_currentstep_prev"/><br />     <br />     <property key="step.id" value="ID"/><br />        <property key="step.entryId" value="ENTRY_ID"/><br />        <property key="step.stepId" value="STEP_ID"/><br />        <property key="step.actionId" value="ACTION_ID"/><br />        <property key="step.owner" value="OWNER"/><br />        <property key="step.caller" value="CALLER"/><br />        <property key="step.startDate" value="START_DATE"/><br />        <property key="step.finishDate" value="FINISH_DATE"/><br />        <property key="step.dueDate" value="DUE_DATE"/><br />        <property key="step.status" value="STATUS"/><br />        <property key="step.previousId" value="PREVIOUS_ID"/><br />     <br /> </persistence><br /> <br /> <factory class="com.opensymphony.workflow.loader.JDBCWorkflowFactory"><br />  <property key="resource" value="workflows.xml"/><br /> </factory><br /></osworkflow><br />在src目录下新Z个propertyset.xml来存储相应的字段配置信息:<br /><br />  <?xml version="1.0" encoding="UTF-8"?><br /><propertysets><br />    <propertyset name="jdbc" <br />      class="com.opensymphony.module.propertyset.database.JDBCPropertySet"><br />        <arg name="datasource" value="jdbc/oswf"/><br />        <arg name="table.name" value="OS_PROPERTYENTRY"/><br />        <arg name="col.globalKey" value="GLOBAL_KEY"/><br />        <arg name="col.itemKey" value="ITEM_KEY"/><br />        <arg name="col.itemType" value="ITEM_TYPE"/><br />        <arg name="col.string" value="STRING_VALUE"/><br />        <arg name="col.date" value="DATE_VALUE"/><br />        <arg name="col.data" value="DATA_VALUE"/><br />        <arg name="col.float" value="FLOAT_VALUE"/><br />        <arg name="col.number" value="NUMBER_VALUE"/><br />    </propertyset><br /></propertysets><br />q要新徏一个流E的配置文g,该文件的命名与osworkflow.xml的factory节点里的值有??<br /><br /><?xml version="1.0" encoding="UTF-8"?><br /><workflows><br />  <workflow name="leave" type="resource" location="leave.xml"/><br /></workflows><br /><br />那么leave.xml是一个工作流的真正配|文件。其内容如下Q?br /><br /><pre><?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.7//EN" "http://www.opensymphony.com/osworkflow/workflow_2_7.dtd"> <workflow> <initial-actions> <action id="0" name="開始"> <results> <unconditional-result old-status="Finished" status="Queued" step="1" /> </results> </action> </initial-actions> <steps> <step id="1" name="填假?> <actions> <action id="1" name="送出"> <pre-functions> <function type="class"> <arg name="class.name">com.opensymphony.workflow.util.Caller</arg> </function> </pre-functions> <results> <unconditional-result old-status="Finished" status="Queued" step="2" owner="User100" /> </results> </action> </actions> </step> <step id="2" name="批假?> <actions> <action id="2" name="准許"> <pre-functions> <function type="class"> <arg name="class.name">com.opensymphony.workflow.util.Caller</arg> </function> </pre-functions> <results> <unconditional-result old-status="Finished" status="Queued" step="3" owner="${caller}"/> </results> </action> <action id="3" name="駁回"> <pre-functions> <function type="class"> <arg name="class.name">com.opensymphony.workflow.util.Caller</arg> </function> </pre-functions> <results> <unconditional-result old-status="Finished" status="Queued" step="1" owner="${caller}"/> </results> </action> </actions> </step> <step id="3" name="停止" /> </steps> </workflow></pre><br /><br />q样可以配|OSworkflow持久化进mysql?<img src ="http://www.aygfsteel.com/pdw2009/aggbug/40475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2006-04-11 15:40 <a href="http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40475.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>osworkflow工作实例状?/title><link>http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40474.html</link><dc:creator>有猫怼的日?/dc:creator><author>有猫怼的日?/author><pubDate>Tue, 11 Apr 2006 07:28:00 GMT</pubDate><guid>http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40474.html</guid><wfw:comment>http://www.aygfsteel.com/pdw2009/comments/40474.html</wfw:comment><comments>http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40474.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/pdw2009/comments/commentRss/40474.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/pdw2009/services/trackbacks/40474.html</trackback:ping><description><![CDATA[ <table class="fixedTable blogpost" cellspacing="0" width="100%" border="0"> <tbody> <tr> <td class="ellipse"> <span id="wmqeeuq" class="bvTitle" id="subjcns!41C07CC57E95C410!141"> <strong>工作实例状?/strong> </span> </td> </tr> <tr> <td class="bvh8"> <strong> </strong> </td> </tr> <tr> <td id="msgcns!41C07CC57E95C410!141"> <ul> <li>创徏的:0 </li> <li>zd的:1 </li> <li>挂v的:2 </li> <li>中止的:3 </li> <li>完成的:4 </li> <li>未知的:Q?</li> </ul> </td> </tr> </tbody> </table> <img src ="http://www.aygfsteel.com/pdw2009/aggbug/40474.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/pdw2009/" target="_blank">有猫怼的日?/a> 2006-04-11 15:28 <a href="http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40474.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OSWorkflow概况http://www.aygfsteel.com/pdw2009/archive/2006/04/11/40473.html有猫怼的日?/dc:creator>有猫怼的日?/author>Tue, 11 Apr 2006 07:26:00 GMThttp://www.aygfsteel.com/pdw2009/archive/2006/04/11/40473.htmlhttp://www.aygfsteel.com/pdw2009/comments/40473.htmlhttp://www.aygfsteel.com/pdw2009/archive/2006/04/11/40473.html#Feedback0http://www.aygfsteel.com/pdw2009/comments/commentRss/40473.htmlhttp://www.aygfsteel.com/pdw2009/services/trackbacks/40473.html OSWorkflow

OSWorkflow概况

OSWorkflow是一个灵zȝ工作引擎,可嵌入到企业应用E序中。它提供了许多的持久化API支持包括Q?a class="wikipage" >EJB,Hibernate,JDBC和其它。OSWorkflowq可以与Spring集成?

在商用和开源世界里QOSWorkflow 都不同于q些已有的工作流pȝ。最大不同在?OSWorkflow 有着非常优秀的灵zL?

OSWorkflow的优?/h2>OSWorkflow l你l对的灵zL。OSWorkflow 被认为是一U“低U别?a class="wikipage" >工作?/a>实现。与其他工作系l能用图标表现“Loops(回\)”和“Conditions(条g)”相比,OSWorkflow 只是手工“编?Coded)”来实现的。但qƈ不能说实际的代码是需要完全手工编码的Q脚本语a能胜任这U情形。OSWorkflow 不希望一个非技术用户修改工作流E,虽然一些其他工作流pȝ提供了简单的 GUI 用于工作编辑,但像q样改变工作?/a>Q通常会破坏这些应用。所以,q行工作?/a>调整的最佳h选是开发h员,他们知道该怎么改变。不q,在最新的版本中,OSWorkflow 也提供了 GUI 设计器来协助工作的~辑?

OSWorkflow Z有限状态机概念。每?state ?step ID ?status 联合表现Q可单理解ؓ step 及其 status 表示有限状态机?stateQ。一?state 到另一 state ?transition 依赖?action 的发生,在工作流生命期内有至一个或多个zd?state。这些简单概念展C OSWorkflow 引擎的核心思想Qƈ允许一个简?XML 文g解释工作业务流E?

OSWorkFlow核心概念

概念定义

步骤QStepQ?一?Step 描述的是工作所处的位置。可能从一?Step TranstionQ流转)到另外一?StepQ或者也可以在同一?Step 内流转(因ؓ Step 可以?Status 来细分,形成多个StateQ。一个流E里面可以多个Step?

状态(StatusQ?工作?/a> Status 是用来描q工作流E中具体StepQ步骤)状态的字符丌ӀOSWorkflow 的有 UnderwayQ进行中Q、QueuedQ等候处理中Q、FinishedQ完成)三种 Status。一个实际StateQ状态)真正是由两部分组成:State = (Step + Status) ?

{QTranstionQ?一个State到另一个State的{UR?

动作QActionQ?Action 触发了发生在 Step 内或 Step 间的{Q或者说是基?State 的流转。一?step 里面可以有多个Action。Action 和Step 之间的关pLQStep 说明“在哪里”,Action 说明“去哪里”?一?Action 典型地由两部分组成:可以执行此ActionQ动作)?ConditionQ条ӞQ以及执行此动作后的 ResultQ结果)?

条gQConditionQ类g逻辑判断Q可包含“AND”和“OR”逻辑。比如一个请假流E中的“本部门审批阶段”,该阶D利用“AND”逻辑Q判断流E状态是否ؓ{候处理中Q以及审批者是否ؓ本部门主?

l果QResultQ?Result 代表执行ActionQ动作)后的l果Q指向新?Step 及其 Step StatusQ也可能q入 Split 或?Join。Result 分ؓ两种Q?Contidional-Result Q有条gl果Q,只有条g为真时才使用该结果,?Unconditional-ResultQ无条gl果Q,当条件不满或没有条件时使用该结果?

分离/q接QSplit/JoinQ流E的切分和融合。很单的概念QSplit 可以提供多个 ResultQ结果)QJoin 则判断多?Current Step 的态提供一?ResultQ结果)?

步骤、状态和动作(Step, Status, and Action)

工作?/a>要描q步?Step)、步骤的状?Status)、各个步骤之间的关系以及执行各个步骤的条件和权限Q每个步骤中可以含有一个或多个动作(Action)Q动作将会一个步骤的状态发生改变?

对于一个执行的工作?/a>来讲Q步骤的切换是不可避免的。一个工作流在某一时刻会有一个或多个当前步骤Q每个当前步骤都有一个状态|当前步骤的状态值组成了工作实例的状态倹{一旦完成了一个步骤,那么q个步骤不再是当前步骤Q而是切换C个新的步骤)Q通常一个新的当前步骤将随之建立hQ以保证工作?/a>l箋执行。完成了的步骤的最l状态值是用Old-Status属性指定的Q这个状态值的讑֮发生在切换到其他步骤之前。Old-Status的值可以是L的,但在一般情况下Q我们设|ؓFinished?

切换本n是一个动作(ActionQ的执行l果。每个步骤可以含有多个动作,I竟要蝲入哪个动作是由最l用戗外部事件或者Tiggerd的自动调用决定的。随着动作的完成,一个特定的步骤切换也将发生。动作可以被限制在用戗用L或当前状态。每一个动作都必须包含一个Unconditional Result?个或多个Conditional Results?

所以,M来说Q一个工作流由多个步骤组成。每个步骤有一个当前状态(例如QQueued, Underway or FinishedQ,一个步骤包含多个动作。每个步骤含有多个可以执行的动作。每个动作都有执行的条gQ也有要执行的函数。动作包含有可以改变状态和当前工作步骤的results?

l果、分支和q接(Results, Joins, and Splits)

无条件结?Unconditional Result) 对于每一个动作来Ԍ必须存在一个Unconditional Result。一个result是一pd指oQ这些指令将告诉OSWorkFlow下一个Q务要做什么。这包括使工作流从一个状态切换到另一个状态?

有条件结?Conditional Result) Conditional Result是Unconditional Result的一个扩展。它需要一个或多个Condition子标{。第一个ؓtrue的ConditionalQ用AND或ORcdQ,会指明发生切换的步骤Q这个切换步骤的发生是由于某个用h行了某个动作的结果导致的?

三种不同的Results(conditional or unconditional) 一个新的、单一的步骤和状态的l合。一个分裂成两个或多个步骤和状态的l合。将q个和其他的切换l合成一个新的单一的步骤和状态的l合。每U不同的result对应了不同的xml描述Q你可以阅读http://www.opensymphony.com/osworkflow/workflow_2_7.dtdQ获取更多的信息。注意:通常Q一个split或一个join不会再导致一个split ?join的发生?

自动步骤(Auto actions)

有的时候,我们需要一些动作可以基于一些条件自动地执行。ؓ了达到这个目的,你可以在action中加入auto="true"属性。流E将考察q个动作的条件和限制Q如果条件符合,那么执行这个动作?Auto action是由当前的调用者执行的Q所以将对该动作的调用者执行权限检查?

整合抽象实例(Integrating with Abstract Entities)

在你的核心实体中Q例?Document" ?"Order"Q在内部创徏一个新的属性:workflowId。这P当新?Document" ?"Order"被创建的时候,它能够和一个workflow实例兌h。那么,你的代码可以通过OSWorkflow API查找到这个workflow实例q且得到q个workflow的信息和动作?

工作实例状?Workflow Instance State)

有的时候,为整个workflow实例指定一个状态是很有帮助的,它独立于程的执行步骤。OSWorkflow提供一些workflow实例中可以包含的"meta-states"。这?meta-states"可以是CREATED, ACTIVATED, SUSPENDED, KILLED ?COMPLETED。当一个工作流实例被创建的时候,它将处于CREATED状态。然后,只要一个动作被执行Q它׃自动的变成ACTIVATED状态。如果调用者没有明地改变实例的状态,工作?/a>一直保持这个状态直到工作流l束。当工作不可能再执行Q何其他的动作的时候,工作将自动的变成COMPLETED状态?

然而,?a class="wikipage" >工作?/a>处于ACTIVATED状态的时候,调用者可以终止或挂vq个工作(讄工作的状态ؓKILLED ?SUSPENDEDQ。一个终止了的工作流不能再执行M动作Q而且永q保持着l止状态。一个被挂v了的工作?/a>会被ȝQ他也不能执行Q何的动作Q除非它的状态再变成ACTIVATED?



]]>
վ֩ģ壺 ˶| ˮ| | ɽ| | ƽɽ| | Ӧñر| | | ֦| | Ͽ| | ޵| Ӷ| | | | | ¡| ϻ| ̨| ȫ| | | ũ| ¡| ɽ| ɫ| | | ϰˮ| | ƺ| | | | ˺| ӱ| ˱|