﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-努力创造未来！-随笔分类-workflow</title><link>http://www.blogjava.net/pdw2009/category/12604.html</link><description>J2EE相关应用技术日志</description><language>zh-cn</language><lastBuildDate>Fri, 23 May 2008 09:21:02 GMT</lastBuildDate><pubDate>Fri, 23 May 2008 09:21:02 GMT</pubDate><ttl>60</ttl><item><title>jbpm最简单的例子(转)</title><link>http://www.blogjava.net/pdw2009/archive/2007/04/11/110027.html</link><dc:creator>有猫相伴的日子</dc:creator><author>有猫相伴的日子</author><pubDate>Wed, 11 Apr 2007 15:48:00 GMT</pubDate><guid>http://www.blogjava.net/pdw2009/archive/2007/04/11/110027.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/110027.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2007/04/11/110027.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/110027.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/110027.html</trackback:ping><description><![CDATA[<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: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">process-definition&nbsp;</span><span style="COLOR: #ff0000">xmlns</span><span style="COLOR: #0000ff">="urn:jbpm.org:jpdl-3.1"</span><span style="COLOR: #ff0000">&nbsp;&nbsp;name</span><span style="COLOR: #0000ff">="example_5"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">start-state&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="开始"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">event&nbsp;</span><span style="COLOR: #ff0000">type</span><span style="COLOR: #0000ff">="node-leave"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">action&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="action1"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">action</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">event</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">transition&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="tr1"</span><span style="COLOR: #ff0000">&nbsp;to</span><span style="COLOR: #0000ff">="工作中"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">transition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">transition&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="tr2"</span><span style="COLOR: #ff0000">&nbsp;to</span><span style="COLOR: #0000ff">="求学中"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">transition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">start-state</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">state&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="工作中"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">event&nbsp;</span><span style="COLOR: #ff0000">type</span><span style="COLOR: #0000ff">="node-enter"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">action&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="工作"</span><span style="COLOR: #ff0000">&nbsp;class</span><span style="COLOR: #0000ff">="com.wide.example5.WorkAction"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">action</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">event</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">transition&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">=""</span><span style="COLOR: #ff0000">&nbsp;to</span><span style="COLOR: #0000ff">="终成正果"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">transition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">state</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">state&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="求学中"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">event&nbsp;</span><span style="COLOR: #ff0000">type</span><span style="COLOR: #0000ff">="node-enter"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">action&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="学习"</span><span style="COLOR: #ff0000">&nbsp;class</span><span style="COLOR: #0000ff">="com.wide.example5.StudyAction"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">action</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">event</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">transition&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">=""</span><span style="COLOR: #ff0000">&nbsp;to</span><span style="COLOR: #0000ff">="终成正果"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">transition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">state</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">end-state&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="终成正果"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">event&nbsp;</span><span style="COLOR: #ff0000">type</span><span style="COLOR: #0000ff">="node-enter"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">action&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="圆满"</span><span style="COLOR: #ff0000">&nbsp;class</span><span style="COLOR: #0000ff">="com.wide.example5.EndAction"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">action</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">event</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">end-state</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">process-definition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br><br></span></div>
这是一个比较简单的jbpm流程模板，通过这几天的学习（基本上是看别人的事子）发现jbpm原来这么的复杂的，好多东西想记下来，特别是一个同行总结出的例子，非常简洁的描述了各个小功能点。以下也是一个很简单的jpdl模板，清楚的描述了note与state的区别。jbpm提供了好几种不同的节点。<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: #0000ff">&lt;?</span><span style="COLOR: #ff00ff">xml&nbsp;version="1.0"&nbsp;encoding="UTF-8"</span><span style="COLOR: #0000ff">?&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">process-definition&nbsp;</span><span style="COLOR: #ff0000">xmlns</span><span style="COLOR: #0000ff">="urn:jbpm.org:jpdl-3.1"</span><span style="COLOR: #ff0000">&nbsp;&nbsp;name</span><span style="COLOR: #0000ff">="example_7"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">start-state&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="start"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">transition&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="tr1"</span><span style="COLOR: #ff0000">&nbsp;to</span><span style="COLOR: #0000ff">="state"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">transition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">transition&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="tr2"</span><span style="COLOR: #ff0000">&nbsp;to</span><span style="COLOR: #0000ff">="node"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">transition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">start-state</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">state&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="state"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #008000">&lt;!--</span><span style="COLOR: #008000">&nbsp;只有签收signal才执行&nbsp;</span><span style="COLOR: #008000">--&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">transition&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">=""</span><span style="COLOR: #ff0000">&nbsp;to</span><span style="COLOR: #0000ff">="end"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">transition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">state</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">node&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="node"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #008000">&lt;!--</span><span style="COLOR: #008000">&nbsp;直接执行，当流转到这节点时，就马上执行transition&nbsp;</span><span style="COLOR: #008000">--&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">transition&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">=""</span><span style="COLOR: #ff0000">&nbsp;to</span><span style="COLOR: #0000ff">="end"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">transition</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">node</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">end-state&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="end"</span><span style="COLOR: #0000ff">&gt;&lt;/</span><span style="COLOR: #800000">end-state</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">process-definition</span><span style="COLOR: #0000ff">&gt;</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: #0000ff">package</span><span style="COLOR: #000000">&nbsp;com.jbpm;<br><br></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;org.jbpm.JbpmConfiguration;<br></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;org.jbpm.JbpmContext;<br></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;org.jbpm.db.GraphSession;<br></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;org.jbpm.graph.def.ProcessDefinition;<br></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;org.jbpm.graph.exe.ProcessInstance;<br></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;org.jbpm.graph.exe.Token;<br><br></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;java.io.</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">;<br><br></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Execute&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;JbpmConfiguration&nbsp;cfg</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">JbpmConfiguration.getInstance();<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">/**</span><span style="COLOR: #008000"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;把流程部署到数据库<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;</span><span style="COLOR: #808080">@param</span><span style="COLOR: #008000">&nbsp;file<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">*/</span><span style="COLOR: #000000"><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;deploy(String&nbsp;file){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JbpmContext&nbsp;jc</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">null</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileInputStream&nbsp;fis&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;FileInputStream(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">src/proc2.xml</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessDefinition&nbsp;pd</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">ProcessDefinition.parseXmlInputStream(fis);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jc</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">cfg.createJbpmContext();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jc.deployProcessDefinition(pd);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #0000ff">catch</span><span style="COLOR: #000000">(Exception&nbsp;e){<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.printStackTrace();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jc.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;main(String&nbsp;args[])</span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000">&nbsp;Exception&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Execute&nbsp;e</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;Execute();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">e.deploy("src/proc2");</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JbpmContext&nbsp;jc</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">cfg.createJbpmContext();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GraphSession&nbsp;gs</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">jc.getGraphSession();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessDefinition&nbsp;pd</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">gs.findLatestProcessDefinition(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">example_5</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessInstance&nbsp;pi</span><span style="COLOR: #000000">=</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ProcessInstance(pd);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Token&nbsp;token</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">pi.getRootToken();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">token--&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">token.getNode().getName());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;token.signal(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">tr1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">tr1--&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">token.getNode().getName());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;token.signal();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">kk-&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">token.getNode().getName());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">是否已结束-&gt;</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">pi.hasEnded());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jc.save(pi);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>}<br></span></div>
以上这个类对应第一个工作流模板，至于该模板里定义的接口，<br>&nbsp;&lt;action name="工作" class="com.wide.example5.WorkAction"&gt;&lt;/action&gt;<br>该class只需要实现ActionHandler接口就行了，具体有啥用我现也没搞懂：）我一直努力着。
<img src ="http://www.blogjava.net/pdw2009/aggbug/110027.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2007-04-11 23:48 <a href="http://www.blogjava.net/pdw2009/archive/2007/04/11/110027.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jbpm流程部署和执行</title><link>http://www.blogjava.net/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.blogjava.net/pdw2009/archive/2007/04/09/109512.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/109512.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2007/04/09/109512.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/109512.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/109512.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;看了这么久jbpm还没有一个头绪，需要继续分析。jbpm把流程部署到数据库有好几种方法，今晚终于调试通过了java直接部署 的子，仅为述于此，不做分析。<br>&nbsp;static JbpmConfiguration cfg=JbpmConfiguration.getInstance(); //jbpm一切一切的基础<br>&nbsp;<br>&nbsp;public void setUp(){<br>&nbsp;&nbsp;//cfg.createSchema();&nbsp; //重建jbpm存储层..<br>&nbsp;}<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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;testDeployProcessDefinition()</span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000">&nbsp;Exception{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertNotNull(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">JbpmConfiguration&nbsp;is&nbsp;null</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,cfg);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileInputStream&nbsp;fis&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessDefinition&nbsp;pd</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">ProcessDefinition.parseXmlInputStream(fis);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertNotNull(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">definition&nbsp;should&nbsp;not&nbsp;be&nbsp;null</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,pd);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JbpmContext&nbsp;jc</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">cfg.createJbpmContext();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jc.deployProcessDefinition(pd);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000">{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jc.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}</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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;testLoadProcessAndInstance()&nbsp;</span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000">&nbsp;Exception&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JbpmContext&nbsp;jbpmContext&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;cfg.createJbpmContext()&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GraphSession&nbsp;graphSession&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;jbpmContext.getGraphSession();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessDefinition&nbsp;processDefinition&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;graphSession.findLatestProcessDefinition(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pro1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessInstance&nbsp;processInstance&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">new</span><span style="COLOR: #000000">&nbsp;ProcessInstance(processDefinition);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Token&nbsp;token&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;processInstance.getRootToken();&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">start</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;token.getNode().getName());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Let's&nbsp;start&nbsp;the&nbsp;process&nbsp;execution</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;token.signal();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertEquals(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">state1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">,&nbsp;token.getNode().getName());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jbpmContext.save(processInstance);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000">&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;Tear&nbsp;down&nbsp;the&nbsp;pojo&nbsp;persistence&nbsp;context.</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jbpmContext.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}</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">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;testLoadInstanceAndDoActionAndEnd()&nbsp;</span><span style="COLOR: #0000ff">throws</span><span style="COLOR: #000000">&nbsp;Exception&nbsp;{<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JbpmContext&nbsp;jbpmContext&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;cfg.createJbpmContext()&nbsp;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GraphSession&nbsp;graphSession&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;jbpmContext.getGraphSession();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessDefinition&nbsp;processDefinition&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;graphSession.findLatestProcessDefinition(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">pro1</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;List&nbsp;processInstances&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;graphSession.findProcessInstances(processDefinition.getId());&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessInstance&nbsp;processInstance&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;&nbsp;(ProcessInstance)&nbsp;processInstances.get(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;this.assertEquals("message",(String)(processInstance.getContextInstance().getVariable("message")));</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processInstance.signal();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assertTrue(processInstance.hasEnded());<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jbpmContext.save(processInstance);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;</span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000">&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;jbpmContext.close();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br>实际上，上面的几段代码中写来写去就这几句话吧。加载流程，生成实例，然后签收执行。<br>明天继续......
<img src ="http://www.blogjava.net/pdw2009/aggbug/109512.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2007-04-09 23:27 <a href="http://www.blogjava.net/pdw2009/archive/2007/04/09/109512.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jbpm表结构部署到oracle</title><link>http://www.blogjava.net/pdw2009/archive/2007/04/09/109487.html</link><dc:creator>有猫相伴的日子</dc:creator><author>有猫相伴的日子</author><pubDate>Mon, 09 Apr 2007 12:01:00 GMT</pubDate><guid>http://www.blogjava.net/pdw2009/archive/2007/04/09/109487.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/109487.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2007/04/09/109487.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/109487.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/109487.html</trackback:ping><description><![CDATA[&nbsp;
<p align=left><span>看了网上挺多例子终于把<span>jbpm的数据库结构部署好，之前部署到mysql ,今晚部署到了oracle。步骤如下：<br>1、在lib目录下建立oracle目录，把oracle 9.1的jdbc驱动class12.jar拷贝进来。<br>2、在src/resources目录下建立oracle目录，把hsqldb目录入的两个文件拷贝进来。<br>3、修改create.db.hibernate.properties</span></span></p>
<p align=left><span>&nbsp;</p>
<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">hibernate.dialect</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">org.hibernate.dialect.Oracle9Dialect<br>#&nbsp;for&nbsp;Oracle&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">&nbsp;compatibility&nbsp;use<br>#hibernate.dialect</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">org.hibernate.dialect.OracleDialect<br>hibernate.connection.driver_class</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">oracle.jdbc.driver.OracleDriver<br>hibernate.connection.url</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">jdbc:oracle:thin:@</span><span style="COLOR: #000000">192.168.0.20</span><span style="COLOR: #000000">:</span><span style="COLOR: #000000">1521</span><span style="COLOR: #000000">:JBPM<br>hibernate.connection.username</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;JBPM<br>hibernate.connection.password</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;JBPM<br>hibernate.show_sql</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">true<br>hibernate.c3p0.min_size</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br>hibernate.c3p0.max_size</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">3</span></div>
<p align=left></span>&nbsp;</p>
<p><span>4、在src目录入copy build.deploy.xml文件到src目录，并改名为build.deploy.oracle.xml，然后修改文件的create.db&nbsp;&nbsp;&nbsp; target。内容如下</span></p>
<p>&nbsp;</p>
<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"><br><br></span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">target&nbsp;</span><span style="COLOR: #ff0000">name</span><span style="COLOR: #0000ff">="create.db"</span><span style="COLOR: #ff0000">&nbsp;depends</span><span style="COLOR: #0000ff">="declare.jbpm.tasks"</span><span style="COLOR: #ff0000">&nbsp;description</span><span style="COLOR: #0000ff">="creates&nbsp;a&nbsp;oracle&nbsp;database&nbsp;with&nbsp;the&nbsp;jbpm&nbsp;tables&nbsp;and&nbsp;loads&nbsp;the&nbsp;processes&nbsp;in&nbsp;there"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br><br>&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">jbpmschema&nbsp;</span><span style="COLOR: #ff0000">actions</span><span style="COLOR: #0000ff">="create"</span><span style="COLOR: #ff0000">&nbsp;properties</span><span style="COLOR: #0000ff">="${basedir}/src/resources/oracle/create.db.hibernate.properties"</span><span style="COLOR: #ff0000">&nbsp;cfg</span><span style="COLOR: #0000ff">="${basedir}/src/config.files/hibernate.cfg.xml"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000">&nbsp;<br><br>&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">loadidentities&nbsp;</span><span style="COLOR: #ff0000">file</span><span style="COLOR: #0000ff">="${basedir}/src/resources/oracle/identity.db.xml"</span><span style="COLOR: #ff0000">&nbsp;properties</span><span style="COLOR: #0000ff">="${basedir}/src/oracle/hsqldb/create.db.hibernate.properties"</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000">&nbsp;<br><br>&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">ant&nbsp;</span><span style="COLOR: #ff0000">antfile</span><span style="COLOR: #0000ff">="build.xml"</span><span style="COLOR: #ff0000">&nbsp;target</span><span style="COLOR: #0000ff">="build.processes"</span><span style="COLOR: #ff0000">&nbsp;inheritall</span><span style="COLOR: #0000ff">="false"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000">&nbsp;<br><br>&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">deploypar&nbsp;</span><span style="COLOR: #ff0000">properties</span><span style="COLOR: #0000ff">="${basedir}/src/resources/oracle/create.db.hibernate.properties"</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br><br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">&lt;</span><span style="COLOR: #800000">fileset&nbsp;</span><span style="COLOR: #ff0000">dir</span><span style="COLOR: #0000ff">="build"</span><span style="COLOR: #ff0000">&nbsp;includes</span><span style="COLOR: #0000ff">="*.par"</span><span style="COLOR: #ff0000">&nbsp;</span><span style="COLOR: #0000ff">/&gt;</span><span style="COLOR: #000000"><br><br>&nbsp;</span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">deploypar</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br><br></span><span style="COLOR: #0000ff">&lt;/</span><span style="COLOR: #800000">target</span><span style="COLOR: #0000ff">&gt;</span><span style="COLOR: #000000"><br></span></div>
<br>至于开发环境就把jbpm本身自带例子中相关jar文件移植到自己新建的celipse Web项目中了。 <br><br>jbpm表名所对应的中文名称:<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">JBPM_ACTION&nbsp;action记录表&nbsp;<br>JBPM_DECISIONCONDITIONS&nbsp;结果条件表&nbsp;<br>JBPM_DELEGATION&nbsp;委托表&nbsp;<br>JBPM_EVENT&nbsp;事件表&nbsp;处理进入或者离开事件&nbsp;<br>JBPM_EXCEPTIONHANDLER&nbsp;异常处理表&nbsp;<br>JBPM_ID_GROUP&nbsp;用户组表&nbsp;<br>JBPM_ID_MEMBERSHIP&nbsp;用户成员表&nbsp;表现用户和组之间的多对多关系&nbsp;<br>JBPM_ID_PERMISSIONS&nbsp;用户权限表&nbsp;<br>JBPM_ID_USER&nbsp;用户表&nbsp;<br>JBPM_MODULEDEFINITION&nbsp;模块定义表&nbsp;<br>JBPM_MODULEINSTANCE&nbsp;模块实例表&nbsp;<br>JBPM_NODE&nbsp;流程节点表&nbsp;<br>JBPM_POOLEDACTOR&nbsp;汇集参与着表&nbsp;<br>JBPM_PROCESSDEFINITION&nbsp;流程定义表&nbsp;<br>JBPM_PROCESSFILE&nbsp;流程文件表&nbsp;<br>JBPM_PROCESSFILEBLOCK&nbsp;流程文件块表&nbsp;<br>JBPM_PROCESSINSTANCE&nbsp;流程实例表&nbsp;<br>JBPM_RUNTIMEACTION&nbsp;运行中行为表&nbsp;<br>JBPM_SCRIPTVARIABLES&nbsp;脚本变量表&nbsp;<br>JBPM_SWIMLANE&nbsp;泳道表&nbsp;<br>JBPM_SWIMLANEINSTANCE&nbsp;泳道实例表&nbsp;<br>JBPM_TASK&nbsp;任务表&nbsp;<br>JBPM_TASKACTORPOOL&nbsp;用户行为汇总&nbsp;<br>JBPM_TASKINSTANCE&nbsp;任务实例&nbsp;<br>JBPM_TIMER&nbsp;计时表&nbsp;<br>JBPM_TOKEN&nbsp;令牌表&nbsp;<br>JBPM_TOKENVARIABLEMAP&nbsp;令牌变量影射表&nbsp;<br>JBPM_TRANSITION&nbsp;转换表&nbsp;<br>JBPM_VARIABLEINSTANCE&nbsp;变量实例表&nbsp;<br>JBPM_VARIABLEINSTANCEBLOCK&nbsp;变量实例块表&nbsp;<br>JBPM_VARIABLEMAPPING&nbsp;变量影射表&nbsp;<br></span></div>
<p>&nbsp;</p>
<p>&nbsp;</p>
<img src ="http://www.blogjava.net/pdw2009/aggbug/109487.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2007-04-09 20:01 <a href="http://www.blogjava.net/pdw2009/archive/2007/04/09/109487.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个值得参考的osworkflow工作流模板</title><link>http://www.blogjava.net/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.blogjava.net/pdw2009/archive/2007/01/15/94002.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/94002.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2007/01/15/94002.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/94002.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/94002.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &lt;?				xml version="1.0" encoding="UTF-8"				?&gt;																		&lt;!				DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.7//EN" "http://www.opensymphony.com/oswork...&nbsp;&nbsp;<a href='http://www.blogjava.net/pdw2009/archive/2007/01/15/94002.html'>阅读全文</a><img src ="http://www.blogjava.net/pdw2009/aggbug/94002.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2007-01-15 17:31 <a href="http://www.blogjava.net/pdw2009/archive/2007/01/15/94002.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工作流管理系统需求</title><link>http://www.blogjava.net/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.blogjava.net/pdw2009/archive/2006/10/17/75677.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/75677.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/10/17/75677.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/75677.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/75677.html</trackback:ping><description><![CDATA[
		<div>
				<font size="3">整理的工作流管理系统的需求列表，想要做一个好东西真的很难。</font>
				<p>
						<br />
						<font size="3">工作流定义 </font>
				</p>
				<p>
						<font size="3">  1.1 工作流定义语法检查<br />  1.2 工作流定义有效性检查 <br />  1.3 流程可视化建模 <br />  1.4 组织机构数据的引用 <br />  1.5 支持离线过程定义 <br />  1.6 工作流数据定义  <br />  1.7 图形打印工作流过程定义图形<br />  1.8 以xml格式保存过程定义文件<br />  1.9 直接对模板库访问操作 <br />  1.10 xml过程定义文件打开编辑 </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 通过文本文件（Text Files）启动<br />  3.3 通过XML消息启动  <br />  3.4 时间事件启动  <br />  3.5 手工启动 <br />  3.6 过程调用启动 <br /> <br />工作流模式 </font>
				</p>
				<p>
						<font size="3">  4.1 顺序（Sequence） <br />  4.2 并行分支（AND-split） <br />  4.3 并行汇聚（AND-join） <br />  4.4 条件分支（Conditional routing）、互斥选择（Exclusive Choice、XOR<br />  4.5 简单汇聚（XOR-join） <br />  4.6 多重选择（OR-split、Conditional routing）<br />  4.7 多重汇聚（？） <br />  4.8 部分汇聚（Partial join）MI<br />  4.9 取消活动  <br />  4.10 取消实例  <br />  4.11 同步/异步子过程 <br /> <br />工作流任务分配 </font>
				</p>
				<p>
						<font size="3">  5.1 任务分配的两种模式（拉和推）<br />  5.2 任务队列（拉模式）<br />  5.3 按工作量分配任务（推模式）<br />  5.4 分配任务给所有人员（部门、角色、工作组）<br />  5.5 按人员优先数分配任务（适合基于角色任务分配）<br />  5.6 先来先做（FCFA），将任务队列中最早创建的任务分配给最先提出执行任务请求的人员<br />  5.7 分配任务给指定人员<br />  5.8 推模式下的任务分配异常处理（任务分配异常时，通知模板所有者或工作流管理员）<br />  5.9 任务重分配（将任务分配给其他用户、指定角色中的用户、角色）<br />  5.10 任务替代者，由人员指定（交办、代办）</font>
				</p>
				<p>
						<font size="3">工作流动作 </font>
				</p>
				<p>
						<font size="3">  5.11 接收任务（状态转换）accept<br />  5.12 退件（回退到上一节点？）decline<br />  5.13 执行任务<br />  5.14 完成任务（状态转换）<br />  5.15 反向回传/抽单/召回（Process Rollback）<br />  5.16 分配任务给指定角色<br />  5.17 分配任务给指定人员<br />  5.18 使用路由表分配任务 <br />  5.19 取消任务分配<br />  5.20 创建子过程（将任务节点用子过程代替？）<br />  5.21 设置任务优先级（动态修改工作流活动优先级）<br />  5.22 设置任务说明<br />  5.23 设置任务期限（设置之时起时间段、指定时间点）<br />  5.24 取消任务<br />  5.25 挂起（暂停）任务<br />  5.26 终止任务<br />  5.27 启动工作流实例<br />  5.28 挂起（暂停）工作流实例<br />  5.29 取消工作流实例<br />  5.30 终止工作流实例<br />  5.31 设置工作流实例说明<br />  5.32 设置工作流实例变量（工作流实例变量赋值），可以作为工作流异常处理的一种方法</font>
				</p>
				<p>
						<font size="3">工作流活动路由 </font>
				</p>
				<p>
						<font size="3">  6.1 基于角色路由（任务分配给角色，职务发生变化，流程设计不需变化）<br />  6.2 基于关系路由（根据相对职务关系路由）<br />  6.3 设定型（Ad hoc）路由（由办理人员指定下一节点办理人）根据流程处理内容，由办理人从指定人员中选择合适的下一步执行人员</font>
				</p>
				<p>
						<font size="3">工作流组织机构 </font>
				</p>
				<p>
						<font size="3">  7.1 支持LDAP目录服务<br />  7.2 支持组（Group）<br />  7.3 循环组<br />  7.4 权重组<br />  7.5 工作职务组（相同职务的人组成一个组）<br />  7.6 支持动态定义组（流程执行过程中定义的组）<br />  7.7 多重角色管理（一人数职）<br />  7.8 相对职务关系<br />  7.9 组织图拥有人（组织结构的分级维护）</font>
				</p>
				<p>
						<font size="3">工作流时间管理 </font>
				</p>
				<p>
						<font size="3">  8.1 非工作日设定<br />  8.2 时间事情启动工作流实例（指定时间点、时间间隔、周期时间）<br />  8.3 任务挂起恢复（指定时间点、时间间隔）<br />  8.4 过程实例挂起恢复（指定时间点、时间间隔）<br />  8.5 任务超时通知<br />  8.6 工作流超时通知<br />  8.7 系统时钟</font>
				</p>
				<p>
						<font size="3">工作流系统通知 </font>
				</p>
				<p>
						<font size="3">  9.1 以邮件方式通知工作超时<br />  9.2 可自订通知邮件（新任务通知）<br />  9.3 主动式邮件通知（相对Web-based被动方式）<br />  9.4 工作流异常通知<br />  9.4 任务取消通知<br />  9.5 工作流取消通知</font>
				</p>
				<p>
						<font size="3">工作流异常处理 </font>
				</p>
				<p>
						<font size="3">  10.1 异常的分类<br />  10.2 不同的异常处理方法<br />  10.3 异常的报告、通知机制<br />  10.4 异常恢复程序的预定义</font>
				</p>
				<p>
						<font size="3">工作流接口需求 </font>
				</p>
				<p>
						<font size="3">  11.1 与Email服务器接口（JMS）<br />  11.2 与文件系统接口（如NTFS、unix-FS）<br />  11.3 与ERP、CRM、HR、SCM等系统接口<br />  11.4 与文档管理系统系统接口<br />  11.5 与其它工作流系统接口<br />  11.6 与其它应用系统接口</font>
				</p>
				<p>
						<font size="3">工作流系统需求 </font>
				</p>
				<p>
						<font size="3">  12.1 支持多个操作系统，包括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 完备的系统日志<br />  12.5 可处理大量流程<br />  12.6 从失败（或错误）中恢复系统（自动、手动）、系统（应用）数据备份<br />  12.7 支持并发处理</font>
				</p>
				<p>
						<font size="3">工作流系统管理 </font>
				</p>
				<p>
						<font size="3">  13.1 图形化流程监控<br />  13.2 流程实例动态修改（修改未执行的过程步骤）<br />  13.3 工作负荷量显示<br />  13.4 工作流统计（流程模板、流程实例、任务统计）<br />  13.5 自定义统计报表<br />  13.6 统计数据图形化显示<br />  13.7 临时更改收件人<br />  13.8 工作重送<br />  13.9 流程实例挂起/恢复<br />  13.10 活动实例挂起/恢复<br />  13.11 代理未来工作<br />  13.12 可指定代理期限<br />  13.13 工作流实例超时统计<br />  13.14 单一步骤超时统计<br />  13.15 可传回子流程统计数据<br />  13.16 服务器定时清理</font>
				</p>
				<p>
						<font size="3">工作流客户端 </font>
				</p>
				<p>
						<font size="3">  14.1 B/S结构客户端界面<br />  14.2 浏览器端的数字认证功能<br />  14.3 单点登录<br />  14.4 按重要程度排列任务清单<br />  14.5 用户查看流程执行状态<br />  14.6 我的任务和共享任务队列（按角色分类）<br />  14.7 从共享任务队列中选取任务<br />  14.8 用户指定/取消代理人<br />  14.9 显示已被代理的工作</font>
				</p>
				<p>
						<font size="3">工作流数据 </font>
				</p>
				<p>
						<font size="3">  15.1 基本数据类型（整型、符点型、字符型、日期型、布尔型）<br />  15.2 复合数据类型（数组）<br />  15.3 XML数据定义<br />  15.4 时间数据（三种类型：时间点、时间间隔、周期时间）<br />  15.5 附件（word、excel等）文件夹的概念（Folder）<br />  15.6 附件的检入/检出 3<br />  15.7 变量作用域（全局变量、过程变量）<br />  15.8 数据的访问控制（读写、读、不可见）<br />  15.9 数据集合（Data Set）（由多个不同类型数据或数据子集合所构成）<br />  15.10 数据的表现（表单）<br />  15.11 子表单（sub-form）<br /></font>
				</p>
				<p>
						<font size="3">想想看，自己实现的太少了！！！只做到了皮毛而已!需继续努力</font>
				</p>
		</div>
<img src ="http://www.blogjava.net/pdw2009/aggbug/75677.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-10-17 16:26 <a href="http://www.blogjava.net/pdw2009/archive/2006/10/17/75677.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>工作流系统功能特性描述</title><link>http://www.blogjava.net/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.blogjava.net/pdw2009/archive/2006/09/12/69127.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/69127.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/09/12/69127.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/69127.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/69127.html</trackback:ping><description><![CDATA[
		<div 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">工作流系统功能特性描述</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">编写：</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">创建日期：</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">版次：</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">流程在流转过程中需要确定的为下一环节以及该环节的相应的参与者</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">人或应用程序</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">，所有的流程操作均是围绕这两方面进行。</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'">对事项进行签收表明该流程步骤进行生效阶段，说明当前人员已将事项从待办状态切换为了在办状态。</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'">直流为流程操作中最为简单的一种操作，直流为当前环节往下仅有一个环节，不存在分支的流转，在直流过程中可确定的是流程下一环节，不可确定的是执行此环节的人员</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'">。</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'">分流在流程操作中也很常见，分流为当前环节往下具有一个以上的环节可供选择，即存在分支的流转，在此种情况下往往需要提供选择环节的页面以供用户确定需要发往哪个环节。</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'">并流</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">并流为当前环节往下具有一个以上的环节可供选择，即存在分支的流转，但并不需要用户选择往哪个环节的一种流转操作，在并流的情况下系统将自动往所有的分支环节流转，并等待所有分支环节办理完毕后汇总至他们共同的下一环节。</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'">条件流转</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">10</span>
						<span style="FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-hansi-font-family: 'Times New Roman'">万的时候至经理审批，而大于</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'">万的时候则需递交至副总经理审批。</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'">审批人员收到申请事项后发现申请条件不符或资料不齐等时需要退回当前申请事项至申请人或上一环节受理人，这种流程操作通常称为退回。</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'">当审批人员发现申请事项发送给了一个不合适的办理人员时，如该办理人员尚未签收该事项，则审批人员可将此申请事项取回，避免不必要的麻烦。</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'">挂起</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>
				</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'">终止</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'">由于申请事项的不合理或申请人员需要撤销该事项的申请时，可对该流程进行终止或撤销申请操作。</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'">申请事项需要几个人员按顺序的进行审批，事项将按顺序依次发送给相应的人员进行事项的审批。举例来说，事项需要进行会签，选择人员分别为张三、李四、王五，那么张三首先接收到该事项，张三填写意见后进行发送，系统将自动发送至李四进行处理，李四处理完毕后系统自动发送至王五，王五处理完毕后进入实现的下一处理环节处理。</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'">事项审批过程中的审批人员如觉得该事项在某一个审批人员处停留时间太长的话可对其进行催促，以提醒其迅速办理该事项，在流程操作上称为催办。</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'">竞争办理的概念为当两个用户都收到某事项时，谁先签收了该事项则为谁对该事项进行办理，同时该事项也将从另一用户的待办列表中移除。</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'">联审为流程操作中较复杂的一种，事项发送后将发送至当前环节的下面所有环节，这时的环节通常由一个子流程构成，在各自的子流程执行完毕后统一回至主流程的下一环节中，此种流转过程称为联审。</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'">审批人员在进行事项审批时，觉得该事项不需要经过流程图上所示意的其下的环节而可直接跳转到下面的其他任意一个环节进行流转。</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; 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'">审批人员在进行事项审批时，觉得需要将该事项传送给相关人员进行查看，此流转过程称为传阅，相关人员在接收到此事项后只可查看不可进行审批。</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'">传阅办理与传阅的不同之处在于接收到此事项的人员可选择对此事项进行办理或不办理，而事项的流转并不等待此传阅办理过程的结束。</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'">事项的审批人员在事项已经发送至后续环节办理的过程中均可进行意见的补签，此操作称为意见补签。</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'">在流程执行的过程中根据流程的执行状态等等可对该流程事项进行调度，将事项调度至相应的环节中。</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'">对流程事项进行监控，包括查看流程的执行过程</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'">、流程执行过程中的相关信息</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'">。</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'">根据流程事项的关键字对流程事项进行简单或综合的查询。</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'">统计分析</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>
				</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'">标题，时间等等</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">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'">在已办列表中列出经过当前用户办理但目前尚未办结归档的所有事项，用户可通过此对这些事项的办理状况进行监控，同时也可对事项进行催办操作。</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'">已办结列表</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>
				</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'">组织机构的接口</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>
				</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'">在流程设计时需配置相应环节的参与角色，此时需调用应用提供的角色接口，接口中需提供获取该流程事项类型的角色、创建该流程事项类型的角色的功能，或者也可以采用在设计阶段不调用应用接口，当流程部署至应用时同时创建所需的角色。</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'">表单使得流程系统有了实际的应用意义，表单作为流转过程中的载体，与流程系统的接口至关重要，涉及到表单的存储方式，表单数据的获取方式，流程环节中表单的挂接，流程信息与表单信息构成的相关数据表。</span>
				</p>
		</div>
<img src ="http://www.blogjava.net/pdw2009/aggbug/69127.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-09-12 12:31 <a href="http://www.blogjava.net/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.blogjava.net/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.blogjava.net/pdw2009/archive/2006/06/09/51671.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/51671.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/06/09/51671.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/51671.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/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在用户管理方面所提供的功能，主要包括用户的创建、群组的定义、用户验证、以及对step执行人的跟踪记录和执行权限的判断等等。 
<form id="Form1" name="Form1" onsubmit="javascript:return WebForm_OnSubmit();" action="447742.aspx" method="post"><div class="pagelayout"><div class="centercolumn"><div class="post"><div class="postText"><div class="post"><div class="storycontent"><p>用户/群组的管理是由UserManager来完成的，它包含于一个单独的jar包内。我们可以这样使用UserManager：</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执行人的跟踪，首先我们可以在创建流程的时候传入调用者（caller）名称，比如：</p><p class="prettycode">Workflow wf = new BasicWorkflow((String) session.getAttribute("username")); </p><p>BasicWorkflow会负责创建一个实现了WorkflowContext接口的实例，其中记录了caller的信息。利用com.opensymphony.workflow.util.Caller，可以将WorkflowContext中的caller随时植入transientVars中，以供后续的条件判断。为此，我们需要在流程定义文件中的适当位置加入如下定义（比如initial-actions中的pre-functions节点处）：</p><p class="prettycode">&lt;pre-functions&gt;<br />　&lt;function type="class"&gt;<br />　　&lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;<br />　&lt;/function&gt;<br />&lt;/pre-functions&gt; </p><p>Caller是一个FunctionProvider，其excute方法中包含了如下代码：</p><p class="prettycode">WorkflowContext context = (WorkflowContext) transientVars.get("context");<br />transientVars.put("caller", context.getCaller()); </p><p>同时，我们还可以指定流程中某个step的执行人（owner），只需要在action的results节点处为其指定owner属性：</p><p class="prettycode">&lt;step id="2″ name="Edit Doc"&gt;<br />　&lt;actions&gt;<br />　　&lt;action id="2″ name="Sign Up For Editing"&gt;<br />　　　……<br />　　　&lt;results&gt;<br />　　　　&lt;unconditional-result old-status="Finished” status="Underway” step="2″ owner="${caller}"/&gt;<br />　　　&lt;/results&gt; </p><p>利用caller和owner信息，我们可以在流程定义文件的condition节点中以多种形式指定限定条件，比如，利用脚本限定只允许caller为test的用户触发某结果：</p><p class="prettycode">&lt;result old-status="Finished"&gt;<br />　&lt;condition type="beanshell"&gt;<br />　　&lt;arg name="script"&gt;<br />　　　propertySet.getString("caller").equals("test")<br />　　&lt;/arg&gt;<br />　&lt;/condition&gt;<br />　……<br />&lt;/result&gt; </p><p>又比如，利用util包中的OSUserGroupCondition限定仅当caller为foos群组中的用户时，才触发action：</p><p class="prettycode">&lt;action id="1″ name="Start Workflow"&gt;<br />　……<br />　&lt;condition type="class"&gt;<br />　　&lt;arg name="class.name"&gt;com.opensymphony.workflow.util.OSUserGroupCondition&lt;/arg&gt;<br />　　&lt;arg name="group"&gt;foos&lt;/arg&gt;<br />　&lt;/condition&gt; </p><p>再比如：利用util包中的AllowOwnerOnlyCondition限定仅当caller等于owner时，才触发action：</p><p class="prettycode">&lt;action id="1″ name="Start Workflow"&gt;<br />　……<br />　&lt;condition type="class"&gt;<br />　　&lt;arg name="class.name"&gt;com.opensymphony.workflow.util.AllowOwnerOnlyCondition&lt;/arg&gt;<br />　&lt;/condition&gt; </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=79#comments"><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 class="date">11/29/2004</div><div class="post"><h3 class="xstorytitle" id="post-78"><a title="Permanent Link: OSWorkflow解读之八" href="http://morningspace.51.net/weblog/index.php?p=78" rel="bookmark">OSWorkflow解读之八</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 10:21 am </div><div class="storycontent"><p>WorkflowQuery及其有关查询类&gt;&gt;</p><p>我们知道，通常人们总是希望了解流程当前的运行状况，因此就需要工作流引擎在提供流程流转的基本功能的同时，还需要提供查询功能。在osworkflow中，查询功能是由WorkflowQuery及其相关类提供的。</p><p>WorkflowQuery提供了两种类型的构造函数：</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>我们可以利用第一个构造函数创建基本的WorkflowQuery实例，然后利用第二个构造函数组织装配。以查询执行者是“test”且状态是“Underway”的step实例为例：</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>装配好的查询条件，将会传入AbstractoWorkflow的query方法中，然后再由WorkflowStore的query方法执行具体查询操作。不同的WorkflowStore实例其查询方式不尽相同，以MemoryWorkflowStore为例，它将遍历所有位于cache中的流程，然后将满足条件的流程ID放入一个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) &amp;&amp; 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>这里的queryBasic再次使用了递归调用的方式，详细情况可以查看osworkflow的源代码。通过这样的方式，可以满足任意复杂的流程查询条件指定。 </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=78#comments"><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 class="date">11/28/2004</div><div class="post"><h3 class="xstorytitle" id="post-74"><a title="Permanent Link: OSWorkflow解读之七" href="http://morningspace.51.net/weblog/index.php?p=74" rel="bookmark">OSWorkflow解读之七</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 4:32 pm </div><div class="storycontent"><p>Descriptors&gt;&gt;</p><p>在osworkflow的很多地方都会看到Descriptor的使用，最重要的一个是前面提到的WorkflowDescriptor。除此以外还有，ActionDescriptor、ConditionsDescriptor、ConditionDescriptor、FunctionDescriptor、PermissionDescriptor等等。这些类均位于com.opensymphony.workflow.loader包中。它们的作用，除了提供getter方法外（类似model的角色），还负责xml文件的读取与写入。WorkflowDescriptor在执行xml文件的读写时，如果涉及具体的流程定义元素，将会交由对应的Descriptor类来完成。比如，在WorkflowDescriptor的writeXML方法中，对initial action的序列化是这么实现的：</p><p class="prettycode">XMLUtil.printIndent(out, indent++);<br />out.println("&lt;initial-actions&gt;");<br />for (int i = 0; i &lt; initialActions.size(); i++) {<br />　ActionDescriptor action = (ActionDescriptor) initialActions.get(i);<br />　action.writeXML(out, indent);<br />}<br />XMLUtil.printIndent(out, –indent);<br />out.println("&lt;/initial-actions&gt;"); </p><p>实际上，这是典型的Interpreter Pattern的运用，下面是类图总结。<br /><a title="点击查看大图" href="http://morningspace.51.net/weblog/wp-content/osworkflow-desc.jpg"><img height="177" alt="" src="http://morningspace.51.net/weblog/wp-content/osworkflow-desc.jpg" width="580" border="0" /></a></p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=74#comments"><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 class="date">11/27/2004</div><div class="post"><h3 class="xstorytitle" id="post-71"><a title="Permanent Link: OSWorkflow解读之六" href="http://morningspace.51.net/weblog/index.php?p=71" rel="bookmark">OSWorkflow解读之六</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 10:53 am </div><div class="storycontent"><p>pre function和post function&gt;&gt;</p><p>pre function和post function是osworkflow提供的又一特色，它为某项执行逻辑提供了前驱和后继处理，运用十分灵活。并且，osworkflow为许多元件的执行逻辑都配备了pre function和post function的调用时机。这一点也可以从AbstractWorkflow.doAction的执行逻辑中看到。可以使用和pre function和post function的元件包括：action，result/unconditional result，step，split，join。</p><p>ScriptVariableParser&gt;&gt;</p><p>作为osworkflow的一个util class，ScriptVariableParser的主要功能是将给定字串中的${var}替换成相应的value。这意味着我们可以在许多地方使用类似于Ant中引用property的语法，来进一步提高灵活性。比如：<br />&lt;results&gt;<br />　&lt;unconditional -result old-status="Finished” status="Underway” step="1″ owner="${caller}"/&gt;<br />&lt;/results&gt;<br />在这里，unconditional result的owner属性将被caller的实际值所替代。</p><p>TransientVars和PropertySet&gt;&gt;</p><p>在osworkflow的流程流转过程中，时常会用到Transient Vars和Property Set。这两个工具用来暂存一些临时信息或者在step间传递一些共享信息，比如：context信息，workflow entry信息，以及上面提到的${var}的value，等等。</p><p>Transient Vars实际上就是一个普通的Map，至于Property Set，则是opensymphony的另一个独立模块，需要单独下载jar包。与Transient Vars将信息暂存与内存不同，Property Set还支持数据库存储（JDBCPropertySet）</p><p>Register&gt;&gt;</p><p>为了更进一步提高灵活性，osworkflow还提供了Register功能。我们可以定义自己的Register，以执行特殊任务，并在流程定义文件中注明，该Register便会被动态注册到Transient Vars中，以备随时取用。以下便是一个典型的使用场景：</p><div class="prettycode ">&lt;registers&gt;<br />　&lt;register type="class” variable-name="log"&gt;<br />　　&lt;arg name="class.name"&gt;com.opensymphony.workflow.util.LogRegister&lt;/arg&gt;<br />　　&lt;arg name="addInstanceId"&gt;true&lt;/arg&gt;<br />　&lt;/register&gt;<br />&lt;/registers&gt; </div><div class="prettycode ">&lt;function type="beanshell” name="bsh.function"&gt;<br />　&lt;arg name="script"&gt;transientVars.get("log").info("function called");&lt;/arg&gt;<br />&lt;/function&gt; </div><p>此外，为了方便使用，osworkflow的util包中还预定义了大量的Condition和FunctionProvider，以及其他的一些辅助类，比如：StatusCondition、AllowOwnerOnlyCondition、BeanShellCondition、Caller、EJBInvoker、ScheduleJob。</p><p>借助这些设施，osworkflow的扩展性、灵活性、易用性，得到了极大的体现。 </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=71#comments"><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 class="date">11/26/2004</div><div class="post"><h3 class="xstorytitle" id="post-75"><a title="Permanent Link: OSWorkflow解读之五" href="http://morningspace.51.net/weblog/index.php?p=75" rel="bookmark">OSWorkflow解读之五</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 12:00 am </div><div class="storycontent"><p>Schedule&gt;&gt;</p><p>在osworkflow中提供了定时执行某项任务的功能，这主要得益于opensymphony的另一个项目——Quatz，该项目为工作的定期执行提供了底层设施支持。为此，我们需要引用quatrz.jar包，好在osworkflow的下载包中已经包含了该文件。</p><p>为了实现任务定时，我们需要在流程定义文件中做类似如下的配置：</p><div class="prettycode">&lt;function type="class"&gt;<br />　&lt;arg name="class.name"&gt;com.opensymphony.workflow.util.ScheduleJob&lt;/arg&gt;<br />　&lt;arg name="triggerId"&gt;1&lt;/arg&gt;<br />　&lt;arg name="jobName"&gt;testJob&lt;/arg&gt;<br />　&lt;arg name="triggerName"&gt;testTrigger&lt;/arg&gt;<br />　&lt;arg name="groupName"&gt;test&lt;/arg&gt;<br />　&lt;arg name="repeat"&gt;10&lt;/arg&gt;<br />　&lt;arg name="repeatDelay"&gt;2000&lt;/arg&gt;<br />　&lt;arg name="cronExpression"&gt;0,5,10,15,20,25,30,35,40,45,50,55 * * * * ?&lt;/arg&gt;<br />　&lt;arg name="username"&gt;test&lt;/arg&gt;<br />　&lt;arg name="password"&gt;test&lt;/arg&gt;<br />　&lt;arg name="local"&gt;true&lt;/arg&gt;<br />　&lt;arg name="schedulerStart"&gt;true&lt;/arg&gt;<br />&lt;/function&gt; </div><p>ScheduleJob是一个FunctionProiver，因此具有execute方法。在该方法执行期间，ScheduleJob将会读取这些配置参数，创建好job实例（实际上是一个JobDetail实例）和trigger实例，然后启动schedule。大致流程如下：<br />- 根据传入的shedulerName参数，利用org.quartz.impl.StdSchedulerFactory的getScheduler方法创建sheduler实例，该实例实现了org.quartz.Scheduler接口；<br />- 根据传入的jobClass参数，决定创建何种Job实例，osworkflow自身提供了两种选择：WorkflowJob和LocalWorkflowJob。前者支持SOAP协议，后者则是本地调用，它们都实现了org.quartz.Job接口。<br />- 创建一个描述Job信息的JobDetail实例，并做好初始设置；<br />- 若传入参数中未指定cronExpression，则创建SimpleTrigger，并设置好startDate、endDate、repeat，否则创建CronTrigger<br />- 在jobDetail和trigger准备完毕后，就可以启动schedule了：</p><p class="prettycode">s.addJob(jobDetail, true);<br />s.scheduleJob(trigger);<br />s.start(); </p><p>scheduler中应该可以同时维护多个job和trigger，当trigger的触发条件满足后，将会激活真正的job实例。由于，scheduler中只保存了jobDetail的实例，因此我猜想，job实例的真正创建是由jobDetail完成的。job实例（WorkflowJob、LocalWorkflowJob或者是其他自定义扩展类）激活后，其excute方法将会被执行。其内部的执行逻辑大体是获得指定的Workflow实例，然后执行该实例的executeTriggerFunction方法。trigger function的执行与先前在流程定义文件中所出现过的普通function大同小异。当然，我们还需要在流程定义文件中加入对trigger function的描述，大致格式如下：</p><p class="prettycode">&lt;trigger-functions&gt;<br />　&lt;trigger-function id="1″ &gt;<br />　&lt;function&gt;<br />　　…<br />　&lt;/function&gt;<br />&lt;/trigger-functions&gt; </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=75#comments"><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 class="date">11/25/2004</div><div class="post"><h3 class="xstorytitle" id="post-73"><a title="Permanent Link: osworkflow解读之四" href="http://morningspace.51.net/weblog/index.php?p=73" rel="bookmark">osworkflow解读之四</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 9:38 am </div><div class="storycontent"><p>流程启动&gt;&gt;</p><p>前面分析流程流转的执行逻辑时，并没有讲到流程的启动。实际上，有了前面的基础，再加上对流程定义文件加载的过程有清晰认识之后，流程启动逻辑是很容易理解的。大致情况如下：<br />- 调用DefaultConfiguration的getWorkflow，传入流程名称，然后返回一个WorkflowDescriptor实例，流程定义文件的加载就是在这个时候完成的；<br />- 然后做一些准备工作，比如：获取WorkflowStore实例、准备好transientVars和propertySet等等；<br />- 调用WorkflowDescriptor的getInitialAction方法，获取initial action（如果有的话），注意此前的第一步中，流程定义文件已经成功加载；<br />- 调用transitionWorkflow，执行流程的流转（就是前面提到doAction执行逻辑时调用的那个重要的方法）；</p><p>在transitionWorkflow方法中，与流程启动后step间的流转稍有不同的是：当发现action为initial action时，将会把流程设置为activated状态，表示流程启动。就是下面这段代码：</p><p class="prettycode">if ((wf.getInitialAction(action.getId()) != null) &amp;&amp; (entry.getState() != WorkflowEntry.ACTIVATED)) {<br />　changeEntryState(entry.getId(), WorkflowEntry.ACTIVATED);<br />} </p><p>WorkflowStore和WorkflowEntry&gt;&gt;</p><p>前面提到过，在AbstractWorkflow中，包含流程流转关键逻辑的transitionWorkflow方法，会创建新的step。而这一创建工作是通过调用另一个member method实现的，也就是createNewCurrentStep。其执行逻辑大致如下：</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>从这段代码中，我们首先可以看到，osworkflow可以支持step节点自身再次被“激活”的行为，也就是重复执行某个step。而另一方面，随后的创建工作则是调用了store.createCurrentStep。</p><p>这个store变量就是一个实现了WorkflowStore接口的实例变量，缺省是MemoryWorkflowStore。WorkflowStore除了创建step之外，还提供了一系列find和query方法。在其内部分别保存着step的历史记录（history steps）以及当前处于“激活”状态的step（current steps），以MemoryWorkflowStore为例，分别对应了两个HashMap，而JDBCWorkflowStore则利用数据库表来记录这些信息。</p><p>实际上，WorkflowStore可以同时保存多个流程的记录，这样就可以满足同时存在多个流程的情况。为此，osworkflow提供了一个WorkflowEntry接口用来描述流程信息，其中包含了流程名称、流程ID、当前状态等等。WorkflowEntry中定义了如下几个流程状态常量：</p><p class="prettycode">public static final int CREATED = 0; //创建<br />public static final int ACTIVATED = 1; // 激活<br />public static final int SUSPENDED = 2; // 挂起<br />public static final int KILLED = 3; // 异常终止<br />public static final int COMPLETED = 4; // 正常结束<br />public static final int UNKNOWN = -1; </p><p>在WorkflowStore提供的接口方法中有如下几个方法供维护WorkflowEntry使用：</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>具体的方法实现，各个具现类有所不同。比如。在MemoryWorkflowStore中，是通过维护一个存储SimpleWorkflowEntry实例（实现了WorkflowEntry接口）的HashMap达到目的的。 </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=73#comments"><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 class="date">11/24/2004</div><div class="post"><h3 class="xstorytitle" id="post-72"><a title="Permanent Link: OSWorkflow解读之三" href="http://morningspace.51.net/weblog/index.php?p=72" rel="bookmark">OSWorkflow解读之三</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 9:48 am </div><div class="storycontent"><p>初始配置加载及工作流定义文件加载&gt;&gt;</p><p>AbstractWorkflow首先会取得一个Configuration实例，缺省时为DefaultConfiguration（实现了Configuration接口），该实例负责系统配置的加载。AbstractWorkflow会调用其load方法，该方法内部会查找一个名为osworkflow.xml的配置文件，并对其解析。osworkflow.xml文件中一般会指定persistence class和factory class，比如：</p><p class="prettycode">&lt;osworkflow&gt;<br />　&lt;persistence class="com.opensymphony.workflow.spi.memory.MemoryWorkflowStore"/&gt;<br />　&lt;factory class="com.opensymphony.workflow.loader.XMLWorkflowFactory"&gt;<br />　　&lt;property key="resource” value="workflows.xml” /&gt;<br />　&lt;/factory&gt;<br />&lt;/osworkflow&gt; </p><p>load方法会动态加载这些class，还可以指定一些参数，在它们初始化的时候传入。在这里，我们指定了XMLWorkflowFactory，实际上还有其他种类的WorkflowFactory，比如JDBCWorkflowFactory、URLWorkflowFactory，它们均派生自AbstractWorkflowFactory，其共同职责是通过某种媒介加载流程定义。</p><p>以XMLWorkflowFactory为例，其相应实例在load方法内部完成初始化的过程中，将会查找一个名为workflows.xml的文件，可以在该文件中定义多个流程，每个流程指明其对应的xml定义文件。比如：</p><p class="prettycode">&lt;workflows&gt;<br />　&lt;workflow name="example” type="resource” location="example.xml"/&gt;<br />&lt;/workflows&gt; </p><p>在XMLWorkflowFactory内部维护了一个Map，保存着流程名称与其对应的文件路径（实际上是一个WorkflowConfig实例，不过这只是细节）。然后，DefaultConfiguration调用XMLWorkflowFactory.getWorkflow方法，并传入流程名称。</p><p>getWorkflow方法内部又会将流程加载的具体执行逻辑转交给一个名为WorkflowLoader的类（调用WorkflowLoader.load方法），由WorkflowLoader实现流程定义文件读取。不过，真正的xml文件解析是由WorkflowDescriptor类完成的。它将平面的xml流转化为osworkflow内部所使用的具有真正意义的对象。此类有很多get方法，在osworkflow的许多地方都将会用到这个类的get方法，以获取具体的对象，比如：getAction，getJoin，getStep等等。</p><p>最终，代表example.xml流程定义文件的WorkflowDescriptor实例将会被逐层返回，直至AbstractWorkflow。至此，流程定义文件加载完毕，整个初始化过程也就基本完成了。 </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=72#comments"><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 class="date">11/23/2004</div><div class="post"><h3 class="xstorytitle" id="post-70"><a title="Permanent Link: OSWorkflow解读之二" href="http://morningspace.51.net/weblog/index.php?p=70" rel="bookmark">OSWorkflow解读之二</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 9:09 am </div><div class="storycontent"><p>多种方式定制逻辑&gt;&gt;</p><p>osworkflow的几个基本元件都具有很好的扩展性，它们分别是：condition，function，register，validator。以condition为例，我们可以为触发action的condition定义任意复杂的逻辑，而这种逻辑可以包含在一个java class中，也可以采用bsf，或者bean shell，还有local ejb和remote ejb。只要流程定义文件做相应配置即可，以java class和bean shell为例：</p><p class="prettycode">&lt;action id="1″ name="Start Workflow"&gt;<br />　&lt;restrict-to&gt;<br />　　&lt;conditions type="AND"&gt;<br />　　　&lt;condition type="beanshell"&gt;<br />　　　　&lt;arg name="script"&gt;true&lt;/arg&gt;<br />　　　&lt;/condition&gt;<br />　　　&lt;condition type="class"&gt;<br />　　　　&lt;arg name="class.name"&gt;com.opensymphony.workflow.util.OSUserGroupCondition&lt;/arg&gt;<br />　　　　&lt;arg name="group"&gt;foos&lt;/arg&gt;<br />　　　&lt;/condition&gt;<br />　　&lt;/conditions&gt;<br />　&lt;/restrict-to&gt;<br />　…<br />&lt;/action&gt; </p><p>在osworkflow的许多地方都可以见到类似如下的代码（此处以function为例）：</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会动态加载相应的具现处理类（比如BSFFunctionProvider），并转换为基类类型（比如FunctionProvider），然后调用相应的执行逻辑（比如provider.execute）。这一模式屡试不爽。 </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=70#comments"><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 class="date">11/22/2004</div><div class="post"><h3 class="xstorytitle" id="post-68"><a title="Permanent Link: OSWorkflow解读之一" href="http://morningspace.51.net/weblog/index.php?p=68" rel="bookmark">OSWorkflow解读之一</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 9:35 am </div><div class="storycontent"><p>AbstractWorkflow&gt;&gt;</p><p>osworkflow中有关工作流流转的所有核心代码都在AbstractWorkflow中，BasicWorkflow就是派生自它，不过这个BasicWorkflow基本上没做什么事情。也许我们还可以从AbstractWorkflow派生自己的Workflow类以加入扩展功能，大概这也算是osworkflow所体现的一种灵活性了，即：允许对工作流流转的执行逻辑进行修改。AbstractWorkflow实现了Workflow接口，该接口包含了有关工作流的核心方法，最重要的是doAction方法，AbstractWorkflow实现了该方法，后面会提及，其他还有一些getter和query method。</p><p>流程流转的执行逻辑&gt;&gt;</p><p>当流程执行到的某个step时，可能有一个或多个action可供用户选择执行。一旦确定执行某个action后，我们需要调用AbstractWorkflow.doAction，并传入流程id和action的id。以下是对doAction的执行逻辑的一个不太严紧的算法描述：</p><p>*　　*　　*</p><p>- 　根据流程id，获得所有当前的step，这种情况往往发生在有split的时候，此时会有多个step等待执行；<br />- 　根据传入的action的id，检查是否是global action；<br />- 　若不是global action，则遍历所有当前的step，对每个step的每个action调用isActionAvailable方法，检查该action是否可用（记住step和action是一对多的关系）；<br />- 　所谓可用是指，通过执行passesConditions，逐个检查action的condition：若是OR的关系，则有一个condition为真即为可用，AND关系则类推；<br />- 　若action可用，则调用transitionWorkflow，这是流程流转处理的关键部分；<br />　执行transitionWorkflow时：<br />　- 　首先获取当前step，存在有多个当前step的情况，比如split，此时获取首个isAvailableAction为真的step；<br />　- 　调用verifyInputs验证输入（如果action有validator的话）；<br />　- 　执行当前step的post function（因为该step即将结束）；<br />　- 　执行action的pre function；<br />　- 　判断当前step所属的result中的所有condition是否满足要求，判断方法类似action的condition；<br />　- 　一旦满足，则获取result的pre function和post function；<br />　- 　否则即是unconditional result，获取相应的pre function和post function；<br />　- 　在没有split和join的情况下<br />　　-　 会根据在result中指定的下一个step的id，创建一个新的step，作为当前的step；<br />　　- 　从current steps中移除原来的当前step，并添加到history steps中；<br />　　- 　如果新的step有pre function，则会马上执行；<br />　- 　执行result的post function；<br />　- 　执行action的post function；<br />　- 　若action是intial action，则将流程设置为activated状态；<br />　- 　若action是finish action，则将流程设置为completed状态，返回true；<br />　- 　寻找auto action，若有的话，则执行之，执行方法是调用doAction本身；<br />　- 　返回false；<br />- 　根据transitionWorkflow的返回值判断流程是否结束；<br />- 　若返回false，则调用checkImplicitFinish检查是否存在implicit finish，即：当前没有一个step的action可用时，就认为流程应该结束；</p><p>*　　*　　*</p><p>-　若存在split，则会创建多个新的step，并且在创建之前先执行split的pre function，在创建之后执行split的post function；<br />-　创建step的过程和上面描述的普通状况相同：维护好current steps和history steps，并执行新的step的pre function；</p><p>*　　*　　*</p><p>-　若存在join，先结束当前step，并将该step添加至history steps和join steps；<br />-　查找history steps，对每个已完成的step，查看是否在其result或unconditional result中有join一项，若有则加入join steps中；<br />-　检查join是否已经满足：可以使用Bean Shell，在xml定义文件的join节点中，通过引用一个名为“jn”的特殊变量来指定join的满足条件，jn记录了有关join的关键信息；<br />-　若条件满足，则执行join的pre function，维护好history steps，并创建下一个step，然后执行join的post function；</p><p>*　　*　　*</p><p>-　对于条件循环的情况，可以通过将result的某个action的下一个step指定为自身来加以实现，这只是在xml定义文件中做文章，流程执行逻辑无需做特殊处理； </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=68#comments"><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 class="date">11/20/2004</div><div class="post"><h3 class="xstorytitle" id="post-67"><a title="Permanent Link: time granulrity,issue tracking,tools vs. human" href="http://morningspace.51.net/weblog/index.php?p=67" rel="bookmark">time granulrity,issue tracking,tools vs. human</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Software Engineering" href="http://morningspace.51.net/weblog/index.php?cat=3"><font size="2">Software Engineering</font></a></li></ul>— site admin @ 10:12 pm </div><div class="storycontent"><p>time granulrity：</p><p>作为时间的一种度量单位，或小时记，或天记，都是灵活的和因人而异的。比如你完全可以将8个小时理解为1天。但是，粒度的确定并非没有原则：为任务分配时间是一种预估，这样的估计如果易变而不准确，那么多半也就失去了意义。一般而言，只有在对所做的工作十分了解的前提下，才能够准确估计。对于一个易变的的环境，陌生的环境，时常被打断的环境，或者时常冒出些“障碍”的环境（比如某个艰深的bug fix），时间的粒度就不亦过细，至少在迭代的初期是如此。随着时间的推移和经验的积累，估计的粒度也就会相应改进。</p><p>issue tracking</p><p>issue tracking至关重要，否则事态就可能滑入不可控的危险，team member就会失去对项目状况的全景认识，这也是我的切身体会。实际上，不单是bug，feature，defact，……，很多东西都是需要有tracking的。比如某此会议中的一个idea，如果没有某种形式的tracking，很容易就会消失在大家的记忆中，直到哪次再被大家带着一种似曾相识的感情从被遗忘的角落里重新提起。</p><p>tools vs. human</p><p>我始终觉得，在一个开发团队中，对于工具的使用，总是二等考量，更为重要的是人的因素。因为，即使有趁手的工具，也依然有可能存在缺乏交流的team member，以及由这些team member参加的冗长的缺乏主题的会议。 </p></div><div class="feedback"><a href="http://morningspace.51.net/weblog/index.php?p=67#comments"><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 class="date">11/17/2004</div><div class="post"><h3 class="xstorytitle" id="post-66"><a title="Permanent Link: OSWorkflow开篇" href="http://morningspace.51.net/weblog/index.php?p=66" rel="bookmark">OSWorkflow开篇</a></h3><div class="meta">Filed under: 
<ul class="post-categories"><li><a title="View all posts in Workflow" href="http://morningspace.51.net/weblog/index.php?cat=6"><font size="2">Workflow</font></a></li></ul>— site admin @ 11:04 pm </div><div class="storycontent"><p>刚刚下载了OSWorkflow，这里摘录的是联机文档中的开篇部分，也就是OSWorkflow的核心概念了：</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 class="postFoot"><script src="http://writeblog.csdn.net/PromoteIcon.aspx?Id=447742"></script>
[<a href="javascript:StorePage()">点击此处收藏本文</a>]   发表于 2005年08月07日 16:29:00 </div></div><link href="http://blog.csdn.net/yun15291li/Services/Pingback.aspx" 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();}]]&gt;</script><script type="text/javascript"><![CDATA[ocument.write("<img src=http://counter.csdn.net/pv.aspx?id=24 border=0 width=0 height=0>");]]&gt;</script><img height="0" src="http://counter.csdn.net/pv.aspx?id=24" width="0" border="0" /><br /><div id="comments"><h3><p>h3 定义条件和函数</p><p>你也许已经注意到，到目前为止，我们定义的条件和函数类型都是"class""""""""""""""""""""class.name"""""""""""FunctionProvider或Condition接口的完整类名。</p><p>在osworkflow里面也有一些其他内置的类型，包括beanshell，无状态的session bean，JNDI树上的函数等。我们在下面的例子里使用beanshell类型。</p><p>h3 Property sets</p><p>我们可能需要在工作流的任意步骤持久化一些少量数据。在osworkflow里，这是通过OpenSymphony的PropertySet library来实现。一个PropertySet基本上是一个可以持久化的类型安全map，你可以添加任意的数据到propertyset（一个工作流实例对应一个propertyset），并在以后的流程中再读取这些数据。除非你特别指定操作，否则propertyset中的数据不会被清空或者被删除。任意的函数和条件都可以和propertyset交互，以beanshell script来说，可以在脚本上下文中用"propertyset"""""""""""""""""""""""""""""""""""Start First Draft""""pre-functions里面：</p><div class="code"><div class="codeContent"><pre class="code-xml"><span class="code-tag">&lt;function type=<span class="code-quote">"beanshell"</span>&gt;</span><span class="code-tag">&lt;arg name=<span class="code-quote">"script"</span>&gt;</span>propertySet.setString(<span class="code-quote">"foo"</span>, <span class="code-quote">"bar"</span>)<span class="code-tag">&lt;/arg&gt;</span><span class="code-tag">&lt;/function&gt;</span></pre></div></div><p>这样我们就添加了一个持久化的属性"foo"""""""bar""""""""""""""""""""""""</p><p>h3 Transient Map 临时变量</p><p>另外一个和propertyset变量相对的概念是临时变量："transientVars""""""""""""map，只是在当前的工作流调用的上下文内有效。它包括当前的工作流实例，工作流定义等对应值的引用。你可以通过FunctionProvider的javadoc来查看这个map有那些可用的key。</p><p>还记得我们在教程的第2部分传入的那个null吗？如果我们不传入null的话，那么这些输入数据将会被添加到临时变量的map里。</p><p>h3 inputs 输入</p><p>每次调用workflow的动作时可以输入一个可选的map，可以在这个map里面包含供函数和条件使用的任何数据，它不会被持久化，只是一个简单的数据传递。</p><p>h3 Validators 校验器</p><p>为了让工作流能够校验输入的数据，引入了校验器的概念。一个校验器和函数，条件的实现方式非常类似（比如，它可以是一个class，脚本，或者EJB）。在这个教程里面，我们将会定义一个校验器，在"finish first draft""""""""""""""""working.title"""""30个字符。这个校验器看起来是这样的：</p><div class="code"><div class="codeContent"><pre class="code-java"><span class="code-keyword">package</span> com.mycompany.validators;

<span class="code-keyword">public</span> class TitleValidator <span class="code-keyword">implements</span> Validator
{
  <span class="code-keyword">public</span> void validate(Map transientVars, Map args, PropertySet ps) 
        <span class="code-keyword">throws</span> InvalidInputException, WorkflowException
  {
    <span class="code-object">String</span> title = (<span class="code-object">String</span>)transientVars.get(<span class="code-quote">"working.title"</span>); 
    <span class="code-keyword">if</span>(title == <span class="code-keyword">null</span>)
      <span class="code-keyword">throw</span><span class="code-keyword">new</span> InvalidInputException(<span class="code-quote">"Missing working.title"</span>);
    <span class="code-keyword">if</span>(title.length() &gt; 30)
      <span class="code-keyword">throw</span><span class="code-keyword">new</span> InvalidInputException(<span class="code-quote">"Working title too <span class="code-object">long</span>"</span>);
  }
}</pre></div></div><p>然后通过在流程定义文件添加validators元素，就可以登记这个校验器了：</p><div class="code"><div class="codeContent"><pre class="code-xml"><span class="code-tag">&lt;validators&gt;</span><span class="code-tag">&lt;validator type=<span class="code-quote">"class"</span>&gt;</span><span class="code-tag">&lt;arg name=<span class="code-quote">"class.name"</span>&gt;</span>
      com.mycompany.validators.TitleValidator
    <span class="code-tag">&lt;/arg&gt;</span><span class="code-tag">&lt;/validator&gt;</span><span class="code-tag">&lt;/validators&gt;</span></pre></div></div><p>这样，当我们执行动作2的时候，这个校验器将会被调用，并且检验我们的输入。这样在测试代码里面，如果加上：</p><div class="code"><div class="codeContent"><pre class="code-java">Map inputs = <span class="code-keyword">new</span> HashMap();
inputs.put(<span class="code-quote">"working.title"</span>, 
  <span class="code-quote">"the quick brown fox jumped over the lazy dog,"</span> +
  <span class="code-quote">" thus making <span class="code-keyword">this</span> a very <span class="code-object">long</span> title"</span>);
workflow.doAction(workflowId, 2, inputs);</pre></div></div><p>我们将会得到一个InvalidInputException，这个动作将不会被执行。减少输入的title字符，将会让这个动作成功执行。</p><p>我们已经介绍了输入和校验，下面来看看寄存器。</p><p>h3 Registers 寄存器</p><p>寄存器是一个工作流的全局变量。和propertyset类似，它可以在工作流实例的任意地方被获取。和propertyset不同的是，它不是一个持久化的数据，而是每次调用时都需要重新计算的数据。</p><p>它可以被用在什么地方呢？在我们的文档管理系统里面，如果定义了一个"document""""""""""""""""""""""""""""""""""""""""""""</p><p>寄存器地值会被放在临时变量（transientVars map）里，这样能够在任意地方获得它。</p><p>定义一个寄存器和函数、条件的一个重要区别是，它并不是依靠特定的调用（不用关心当前的步骤，或者是输入数据，它只是简单地暴露一些数据而已），所以它不用临时变量里的值。</p><p>寄存器必须实现Register接口，并且被定义在流程定义文件的头部，在初始化动作之前。</p><p>举例来说，我们将会使用一个osworkflow内置的寄存器:LogRegister。这个寄存器简单的添加一个"log""""""""""Jakarta的commons-logging输出日志信息。它的好处是会在每条信息前添加工作流实例的ID。</p><div class="code"><div class="codeContent"><pre class="code-xml"><span class="code-tag">&lt;registers&gt;</span><span class="code-tag">&lt;register type=<span class="code-quote">"class"</span> variable-name=<span class="code-quote">"log"</span>&gt;</span><span class="code-tag">&lt;arg name=<span class="code-quote">"class.name"</span>&gt;</span>
      com.opensymphony.workflow.util.LogRegister
    <span class="code-tag">&lt;/arg&gt;</span><span class="code-tag">&lt;arg name=<span class="code-quote">"addInstanceId"</span>&gt;</span>true<span class="code-tag">&lt;/arg&gt;</span><span class="code-tag">&lt;arg name=<span class="code-quote">"Category"</span>&gt;</span>workflow<span class="code-tag">&lt;/arg&gt;</span><span class="code-tag">&lt;/register&gt;</span><span class="code-tag">&lt;/registers&gt;</span></pre></div></div><p>这样我们定义了一个可用的"log"""""""""""pre－function的脚本里面使用它：</p><div class="code"><div class="codeContent"><pre class="code-xml"><span class="code-tag">&lt;function type=<span class="code-quote">"beanshell"</span>&gt;</span><span class="code-tag">&lt;arg name=<span class="code-quote">"script"</span>&gt;</span>transientVars.get(<span class="code-quote">"log"</span>).info(<span class="code-quote">"executing action 2"</span>)<span class="code-tag">&lt;/arg&gt;</span><span class="code-tag">&lt;/function&gt;</span></pre></div></div><p>日志输出将会在前面添加工作流实例的ID</p><p>h3 结论</p><p>这个教程的目的是希望可以阐明一些主要的osworkflow概念。你还可以通过API和流程定义格式去获取更多的信息。有一些更高级的特性没有在此提到，比如splits 分支、joins 连接, nested conditions 复合条件、auto stpes 自动步骤等等。你可以通过阅读手册来获得更进一步的理解。</p><p>如果你遇到任何的困难，可以在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 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.blogjava.net/pdw2009/aggbug/51671.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-06-09 13:26 <a href="http://www.blogjava.net/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.blogjava.net/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.blogjava.net/pdw2009/archive/2006/04/22/42509.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/42509.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/22/42509.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/42509.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/42509.html</trackback:ping><description><![CDATA[
		<p>限制是指的是当前作动的执行人!<br /><br /><br /><br />&lt;!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.8//EN" "<a href="http://www.opensymphony.com/osworkflow/workflow_2_8.dtd">http://www.opensymphony.com/osworkflow/workflow_2_8.dtd</a>"&gt;</p>
		<p>&lt;workflow&gt;<br />   &lt;initial-actions&gt;<br />      &lt;action id="0" name="开始"&gt;<br />        &lt;pre-functions&gt;<br />           &lt;functions type="class"&gt;<br />            &lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;<br />           &lt;/functions&gt;<br />        &lt;/pre-functions&gt;<br />         &lt;results&gt;<br />          &lt;unconditional-result old-status="Finished" status="Queued" step="1" owner="${caller}" /&gt;<br />         &lt;/results&gt;<br />      &lt;/action&gt;<br />      <br />   &lt;/initial-actions&gt;<br />   &lt;steps&gt;<br />     &lt;step id="1" name="送假单"&gt;<br />        &lt;actions&gt;<br />          &lt;action id="1" name="送出"&gt;<br />              &lt;restrict-to&gt;<br />                   &lt;conditions&gt;<br />                     &lt;condition type="class"&gt;<br />                              &lt;arg name="class.name"&gt;<br />                                com.opensymphony.workflow.util.AllowOwnerOnlyCondition<br />                              &lt;/arg&gt;<br />                           &lt;/condition&gt;<br />                  &lt;/conditions&gt;<br />              &lt;/restrict-to&gt;<br />           &lt;pre-functions&gt;<br />            &lt;function type="class"&gt;<br />          &lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;<br />         &lt;/function&gt;<br />           &lt;/pre-functions&gt;<br />           &lt;results&gt;<br />            &lt;unconditional-result old-status="Finished" status="Queued" step="2" owner="${caller}"/&gt;<br />           &lt;/results&gt;<br />          <br />          &lt;/action&gt;<br />        &lt;/actions&gt;<br />     &lt;/step&gt; <br />     &lt;step id="2" name="送假单"&gt;<br />      &lt;actions&gt;<br />       &lt;action id="2" name="批准"&gt;<br />        &lt;pre-functions&gt;<br />         &lt;function type="class"&gt;<br />          &lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;<br />         &lt;/function&gt;<br />        &lt;/pre-functions&gt;<br />        &lt;results&gt;<br />         &lt;unconditional-result old-status="finished" status="Queued" step="3" owner="${caller}"/&gt;<br />        &lt;/results&gt;<br />       &lt;/action&gt;<br />       &lt;action id="3" name="驳回"&gt;<br />        &lt;pre-functions&gt;<br />         &lt;function type="class"&gt;<br />          &lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;<br />         &lt;/function&gt;<br />        &lt;/pre-functions&gt;<br />        &lt;results&gt;<br />         &lt;unconditional-result old-status="finished" status="Queued" step="1" owner="${caller}"/&gt;<br />        &lt;/results&gt;<br />       &lt;/action&gt;<br />      &lt;/actions&gt;<br />     &lt;/step&gt;<br />     &lt;step id="3" name="停止"  /&gt;<br />   &lt;/steps&gt;<br />&lt;/workflow&gt;<br />这是请假单的第二个演变，添加了:<br />  &lt;restrict-to&gt;<br />                   &lt;conditions&gt;<br />                     &lt;condition type="class"&gt;<br />                              &lt;arg name="class.name"&gt;<br />                                com.opensymphony.workflow.util.AllowOwnerOnlyCondition<br />                              &lt;/arg&gt;<br />                           &lt;/condition&gt;<br />                  &lt;/conditions&gt;<br />              &lt;/restrict-to&gt;<br />这个配置。这段配置就是用来限定下一步的执行人必须是这一步的发起人。<br /><br />osworkflow限制的用法有：<br />事實上OSWorkflow 2.7版提供了以下四種限制條件。<br /></p>
		<ul>
				<li>
						<b>OSUserGroupCondition</b>：限制由隸屬某指定Group的人執行。<br /></li>
				<li>
						<b>StatusCondition</b>：限制step的status為某個值時才能執行。<br /></li>
				<li>
						<b>AllowOwnerOnlyCondition</b>：只允許Owner執行。<br /></li>
				<li>
						<b>DenyOwnerCondition</b>：只有Owner不能執行。<br /></li>
		</ul>
<img src ="http://www.blogjava.net/pdw2009/aggbug/42509.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-22 18:16 <a href="http://www.blogjava.net/pdw2009/archive/2006/04/22/42509.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>学习（史帝芬）osworkflow入门教程后的一些体会</title><link>http://www.blogjava.net/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.blogjava.net/pdw2009/archive/2006/04/18/41658.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/41658.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/18/41658.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/41658.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/41658.html</trackback:ping><description><![CDATA[
		<p>可以这么说史帝芬的<a href="http://my.so-net.net.tw/idealist/OSWorkflow/osworkflow">http://my.so-net.net.tw/idealist/OSWorkflow/osworkflow</a>资料是目前华文osworkflow资料中最好的一份入门教程。去面的时候在mssql中中实践过这份入门资料，感觉非常顺利。但感觉按作者的顺序把教程中的例子跑完了，还不完全清楚的明白osworkflow的架构。前些在mysql5.0中重做一次，遇到了挺多问题，我通过一步一步的跟踪原代码调试终于把这些问题搞定。下图是把osworkflow所提供的mysql下的数据表的ER图:<br /><br /><img style="WIDTH: 176px; HEIGHT: 159px" height="115" alt="t_osworkflow.jpg" src="http://www.blogjava.net/images/blogjava_net/pdw2009/8326/t_osworkflow.jpg" width="120" border="0" /><br /><br />如果你的osworkflow持久化到mysql中你的osworkflow.xml文件内如必需按如下格式来写:<br /><br />&lt;osworkflow&gt;<br />&lt;persistence class="com.opensymphony.workflow.spi.jdbc.MySQLWorkflowStore"&gt;<br /> &lt;property key="datasource" value="jdbc/DefaultDS"/&gt;<br /> <br />    &lt;property key="step.sequence.increment"  value="INSERT INTO OS_STEPIDS (ID) values (null)"/&gt;<br />    &lt;property key="step.sequence.retrieve"   value="SELECT count(ID) FROM OS_STEPIDS"/&gt;<br />    &lt;property key="entry.sequence.increment" value="INSERT INTO OS_ENTRYIDS (ID) values (null)"/&gt;<br />    &lt;property key="entry.sequence.retrieve"  value="SELECT count(ID) FROM OS_ENTRYIDS"/&gt;<br />    <br /> &lt;property key="entry.table" value="OS_WFENTRY"/&gt;<br /> &lt;property key="entry.id" value="ID"/&gt;<br /> &lt;property key="entry.name" value="NAME"/&gt;<br /> &lt;property key="entry.state" value="STATE"/&gt;<br /> </p>
		<p>
				<br /> &lt;property key="history.table" value="OS_HISTORYSTEP"/&gt;<br /> &lt;property key="current.table" value="OS_CURRENTSTEP"/&gt;<br /> &lt;property key="historyPrev.table" value="OS_HISTORYSTEP_PREV"/&gt;<br /> &lt;property key="currentPrev.table" value="OS_CURRENTSTEP_PREV"/&gt;<br /> &lt;property key="step.id" value="ID"/&gt;<br /> &lt;property key="step.entryId" value="ENTRY_ID"/&gt;<br /> &lt;property key="step.stepId" value="STEP_ID"/&gt;<br /> &lt;property key="step.actionId" value="ACTION_ID"/&gt;<br /> &lt;property key="step.owner" value="OWNER"/&gt;<br /> &lt;property key="step.caller" value="CALLER"/&gt;<br /> &lt;property key="step.startDate" value="START_DATE"/&gt;<br /> &lt;property key="step.finishDate" value="FINISH_DATE"/&gt;<br /> &lt;property key="step.dueDate" value="DUE_DATE"/&gt;<br /> &lt;property key="step.status" value="STATUS"/&gt;<br /> &lt;property key="step.previousId" value="PREVIOUS_ID"/&gt;</p>
		<p>     <br /> &lt;/persistence&gt;<br /> <br /> &lt;factory class="com.opensymphony.workflow.loader.XMLWorkflowFactory"&gt;<br />  &lt;property key="resource" value="workflows.xml"/&gt;<br /> &lt;/factory&gt;<br />&lt;/osworkflow&gt;<br />propertyset.xml文件格式如下：<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;propertysets&gt;<br />    &lt;propertyset name="jdbc" <br />      class="com.opensymphony.module.propertyset.database.JDBCPropertySet"&gt;<br />        &lt;arg name="datasource" value="java:comp/env/jdbc/DefaultDS"/&gt;<br />        &lt;arg name="table.name" value="OS_PROPERTYENTRY"/&gt;<br />        &lt;arg name="col.globalKey" value="GLOBAL_KEY"/&gt;<br />        &lt;arg name="col.itemKey" value="ITEM_KEY"/&gt;<br />        &lt;arg name="col.itemType" value="ITEM_TYPE"/&gt;<br />        &lt;arg name="col.string" value="STRING_VALUE"/&gt;<br />        &lt;arg name="col.date" value="DATE_VALUE"/&gt;<br />        &lt;arg name="col.data" value="DATA_VALUE"/&gt;<br />        &lt;arg name="col.float" value="FLOAT_VALUE"/&gt;<br />        &lt;arg name="col.number" value="NUMBER_VALUE"/&gt;<br />    &lt;/propertyset&gt;<br />&lt;/propertysets&gt;<br />workflows.xml文件格式如下：<br /><br />&lt;workflows&gt;<br />  &lt;workflow name="leave" type="resource" location="leave.xml"/&gt;<br />&lt;/workflows&gt;<br /><br />osuser.xml文件格式如下：<br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;opensymphony-user&gt;<br />         &lt;provider class="com.opensymphony.user.provider.jdbc.JDBCAccessProvider"&gt;<br />         &lt;property name="user.table"&gt;os_user&lt;/property&gt;<br />         &lt;property name="group.table"&gt;os_group&lt;/property&gt;<br />         &lt;property name="membership.table"&gt;os_membership&lt;/property&gt;<br />         &lt;property name="user.name" &gt;username&lt;/property&gt;<br />         &lt;property name="user.password"&gt;passwordhash&lt;/property&gt;<br />         &lt;property name="group.name"&gt;groupname&lt;/property&gt;<br />         &lt;property name="membership.userName" &gt;username&lt;/property&gt;<br />         &lt;property name="membership.groupName"&gt;groupname&lt;/property&gt;<br />         &lt;property name="datasource"&gt;java:comp/env/jdbc/DefaultDS&lt;/property&gt;<br />       &lt;/provider&gt;<br />       &lt;provider class="com.opensymphony.user.provider.jdbc.JDBCCredentialsProvider"&gt;<br />         &lt;property name="user.table"&gt;os_user&lt;/property&gt;<br />         &lt;property name="group.table"&gt;os_group&lt;/property&gt;<br />         &lt;property name="membership.table"&gt;os_membership&lt;/property&gt;<br />         &lt;property name="user.name" &gt;username&lt;/property&gt;<br />         &lt;property name="user.password"&gt;passwordhash&lt;/property&gt;<br />         &lt;property name="group.name"&gt;groupname&lt;/property&gt;<br />         &lt;property name="membership.userName" &gt;username&lt;/property&gt;<br />         &lt;property name="membership.groupName"&gt;groupname&lt;/property&gt;<br />         &lt;property name="datasource"&gt;java:comp/env/jdbc/DefaultDS&lt;/property&gt;<br />       &lt;/provider&gt;<br />       &lt;provider class="com.opensymphony.user.provider.jdbc.JDBCProfileProvider"&gt;<br />         &lt;property name="user.table"&gt;os_user&lt;/property&gt;<br />         &lt;property name="group.table"&gt;os_group&lt;/property&gt;<br />         &lt;property name="membership.table"&gt;os_membership&lt;/property&gt;<br />         &lt;property name="user.name" &gt;username&lt;/property&gt;<br />         &lt;property name="user.password"&gt;passwordhash&lt;/property&gt;<br />         &lt;property name="group.name"&gt;groupname&lt;/property&gt;<br />         &lt;property name="membership.userName" &gt;username&lt;/property&gt;<br />         &lt;property name="membership.groupName"&gt;groupname&lt;/property&gt;<br />         &lt;property name="datasource"&gt;java:comp/env/jdbc/DefaultDS&lt;/property&gt;<br />       &lt;/provider&gt;<br />       &lt;authenticator class="com.opensymphony.user.authenticator.SmartAuthenticator" /&gt;<br />     &lt;/opensymphony-user&gt;</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里配置的工作流名称<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  工作编号，2 准许，3 驳回<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-&gt;"+actionId);<br />   System.out.println("workflowId-&gt;"+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 class="pagetitle">这是上面的这个例子的一个说明</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 id="wikitext">看完<a href="http://my.so-net.net.tw/idealist/OSWorkflow/program01.html">第一支程式</a>，相信讀者會有許多疑問，這些先就流程的設定做初步的介紹。首先，讀者應該注意到了，第一支程式的用到三個xml設定檔，沒錯，這三個是設定流程的設定檔。<br /><ul><li><b><i>osworkflow.xml</i></b>：這個檔案是設定流程是否存在資料庫或存在記憶體，前面的內容是存在MS SQL Server的寫法。<br /></li><li><b><i>leave.xml</i></b>：請假流程寫在這個檔案，這也是osworkflow的重點之一。<br /></li><li><b><i>workflows.xml</i></b>：指定系統啟動時要載入那些流程。<br /></li></ul><br />這裡針對leave.xml做些說明…<br /><ul><li><b>initial-actions</b>：每個流程都至少需定義一個initial-actions，這是流程的起點。<br /></li><li><b>action</b>：導致流程變動的動作，每個action都有個編號，且不能重複。<br /></li><li><b>step</b>：雖然它的名稱是步驟，似乎它會有動作? 其實將它視為流程位置可能比較恰當，osworkflow真正的動作在action發生。<br /></li><li><b>result</b>：執行動作後的結果，result有兩種conditional-result和unconditional-result，每個result一定有unconditional-result，當conditional-result的條件都不滿足時，就執行unconditional-result。<br /></li><li><b>status</b>：流程在某個action時的狀態。<br /></li><li><b>old-status</b>：流程執行某個action後的狀態。<br /></li><li><b>caller</b>：這是OSWorkflow的保留字，可取得呼叫此工作流的user，即Workflow workflow = new BasicWorkflow(caller); 在資料庫中會記錄於Table OS_HISTORYSTEP如下:<br /><img src="http://my.so-net.net.tw/idealist/OSWorkflow/caller.jpg" /><br />記得在pre-functions加上如下設定…<br /><pre>&lt;pre-functions&gt;
  &lt;function type="class"&gt;
    &lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;
  &lt;/function&gt;
&lt;/pre-functions&gt;</pre></li></ul></div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/pdw2009/aggbug/41658.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-18 15:43 <a href="http://www.blogjava.net/pdw2009/archive/2006/04/18/41658.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>osworkflow分析</title><link>http://www.blogjava.net/pdw2009/archive/2006/04/12/40622.html</link><dc:creator>有猫相伴的日子</dc:creator><author>有猫相伴的日子</author><pubDate>Wed, 12 Apr 2006 05:27:00 GMT</pubDate><guid>http://www.blogjava.net/pdw2009/archive/2006/04/12/40622.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/40622.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/12/40622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/40622.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/40622.html</trackback:ping><description><![CDATA[OSWorkFlow分析<br />1.    OSWorkFlow基本概念<br />    在商用和开源世界里，OSWorkflow 都不同于这些已有的工作流系统。最大不同在于 OSWorkflow 有着非常优秀的灵活性。在开始接触 OSWorkflow 时可能较难掌握（有人说不适合工作流新手入门），比如，OSWorkflow 不要求图形化工具来开发工作流，而推荐手工编写 xml 格式的工作流程描述符。它能为应用程序开发者提供集成，也能与现有的代码和数据库进行集成。这一切似乎给正在寻找快速“即插即用”工作流解决方案的人制造了麻烦，但研究发现，那些“即插即用”方案也不能在一个成熟的应用程序中提供足够的灵活性来实现所有需求。<br />2.    OSWorkFlow主要优势<br />OSWorkflow 给你绝对的灵活性。OSWorkflow 被认为是一种“低级别”工作流实现。与其他工作流系统能用图标表现“Loops(回路)”和“Conditions(条件)”相比，OSWorkflow 只是手工“编码(Coded)”来实现的。但这并不能说实际的代码是需要完全手工编码的，脚本语言能胜任这种情形。OSWorkflow 不希望一个非技术用户修改工作流程，虽然一些其他工作流系统提供了简单的 GUI 用于工作流编辑，但像这样改变工作流，通常会破坏这些应用。所以，进行工作流调整的最佳人选是开发人员，他们知道该怎么改变。不过，在最新的版本中，OSWorkflow 也提供了 GUI 设计器来协助工作流的编辑。<br /><br />OSWorkflow 基于有限状态机概念。每个 state 由 step ID 和 status 联合表现（可简单理解为 step 及其 status 表示有限状态机的 state）。一个 state 到另一 state 的 transition 依赖于 action 的发生，在工作流生命期内有至少一个或多个活动的 state。这些简单概念展现了 OSWorkflow 引擎的核心思想，并允许一个简单 XML 文件解释工作流业务流程。<br />3.    OSWorkFlow核心概念<br />3.1.    概念定义<br /> <br />步骤（Step）<br />    一个 Step 描述的是工作流所处的位置。可能从一个 Step Transtion（流转）到另外一个 Step，或者也可以在同一个 Step 内流转（因为 Step 可以通 Status 来细分，形成多个State）。一个流程里面可以多个Step。<br /><br />状态（Status）<br />    工作流 Status 是用来描述工作流程中具体Step（步骤）状态的字符串。OSWorkflow 的有 Underway（进行中）、Queued（等候处理中）、Finished（完成）三种 Status。一个实际State（状态）真正是由两部分组成：State = (Step + Status) 。<br /><br />流转（Transtion）<br />    一个State到另一个State的转移。<br /><br />动作（Action）<br />    Action 触发了发生在 Step 内或 Step 间的流转，或者说是基于 State 的流转。一个 step 里面可以有多个Action。Action 和Step 之间的关系是，Step 说明“在哪里”，Action 说明“去哪里”。 一个 Action 典型地由两部分组成：可以执行此Action（动作）的<br />Condition（条件），以及执行此动作后的 Result（结果）。    <br /><br />条件（Condition）<br />类似于逻辑判断，可包含“AND”和“OR”逻辑。比如一个请假流程中的“本部门审批阶段”，该阶段利用“AND”逻辑，判断流程状态是否为等候处理中，以及审批者是否为本部门主管。<br /><br />结果（Result）<br />Result 代表执行Action（动作）后的结果，指向新的 Step 及其 Step Status，也可能进入 Split 或者 Join。Result 分为两种， Contidional-Result （有条件结果），只有条件为真时才使用该结果，和 Unconditional-Result（无条件结果），当条件不满足或没有条件时使用该结果。<br /><br />分离/连接（Split/Join）<br />流程的切分和融合。很简单的概念，Split 可以提供多个 Result（结果）；Join 则判断多个 Current Step 的态提供一个 Result（结果）。<br />3.2.    步骤、状态和动作(Step, Status, and Action)<br />工作流要描述步骤(Step)、步骤的状态(Status)、各个步骤之间的关系以及执行各个步骤的条件和权限，每个步骤中可以含有一个或多个动作(Action)，动作将会使一个步骤的状态发生改变。<br /><br />对于一个执行的工作流来讲，步骤的切换是不可避免的。一个工作流在某一时刻会有一个或多个当前步骤，每个当前步骤都有一个状态值，当前步骤的状态值组成了工作流实例的状态值。一旦完成了一个步骤，那么这个步骤将不再是当前步骤（而是切换到一个新的步骤），通常一个新的当前步骤将随之建立起来，以保证工作流继续执行。完成了的步骤的最终状态值是用Old-Status属性指定的，这个状态值的设定将发生在切换到其他步骤之前。Old-Status的值可以是任意的，但在一般情况下，我们设置为Finished。<br /><br />切换本身是一个动作（Action）的执行结果。每个步骤可以含有多个动作，究竟要载入哪个动作是由最终用户、外部事件或者Tiggerd的自动调用决定的。随着动作的完成，一个特定的步骤切换也将发生。动作可以被限制在用户、用户组或当前状态。每一个动作都必须包含一个Unconditional Result和0个或多个Conditional Results。<br /><br />所以，总体来说，一个工作流由多个步骤组成。每个步骤有一个当前状态（例如：Queued, Underway or Finished），一个步骤包含多个动作。每个步骤含有多个可以执行的动作。每个动作都有执行的条件，也有要执行的函数。动作包含有可以改变状态和当前工作流步骤的results。<br />3.3.    结果、分支和连接(Results, Joins, and Splits)<br />3.3.1.    无条件结果(Unconditional Result)<br />对于每一个动作来讲，必须存在一个Unconditional Result。一个result是一系列指令，这些指令将告诉OSWorkFlow下一个任务要做什么。这包括使工作流从一个状态切换到另一个状态。<br />3.3.2.    有条件结果(Conditional Result)<br />Conditional Result是Unconditional Result的一个扩展。它需要一个或多个Condition子标签。第一个为true的Conditional（使用AND或OR类型），会指明发生切换的步骤，这个切换步骤的发生是由于某个用户执行了某个动作的结果导致的。<br />3.3.3.    三种不同的Results(conditional or unconditional)<br />一个新的、单一的步骤和状态的组合。<br />一个分裂成两个或多个步骤和状态的组合。<br />将这个和其他的切换组合成一个新的单一的步骤和状态的组合。<br />每种不同的result对应了不同的xml描述，你可以阅读<a href="http://www.opensymphony.com/osworkflow/workflow_2_7.dtd">http://www.opensymphony.com/osworkflow/workflow_2_7.dtd</a>，获取更多的信息。<br />注意：通常，一个split或一个join不会再导致一个split 或 join的发生。<br />3.4.    自动步骤(Auto actions)<br />有的时候，我们需要一些动作可以基于一些条件自动地执行。为了达到这个目的，你可以在action中加入auto="true"属性。流程将考察这个动作的条件和限制，如果条件符合，那么将执行这个动作。 Auto action是由当前的调用者执行的，所以将对该动作的调用者执行权限检查。<br />3.5.    整合抽象实例(Integrating with Abstract Entities)<br />建议在你的核心实体中，例如"Document" 或 "Order"，在内部创建一个新的属性：workflowId。这样，当新的"Document" 或 "Order"被创建的时候，它能够和一个workflow实例关联起来。那么，你的代码可以通过OSWorkflow API查找到这个workflow实例并且得到这个workflow的信息和动作。<br />3.6.    工作流实例状态(Workflow Instance State)<br />有的时候，为整个workflow实例指定一个状态是很有帮助的，它独立于流程的执行步骤。OSWorkflow提供一些workflow实例中可以包含的"meta-states"。这些"meta-states"可以是CREATED, ACTIVATED, SUSPENDED, KILLED 和 COMPLETED。当一个工作流实例被创建的时候，它将处于CREATED状态。然后，只要一个动作被执行，它就会自动的变成ACTIVATED状态。如果调用者没有明确地改变实例的状态，工作流将一直保持这个状态直到工作流结束。当工作流不可能再执行任何其他的动作的时候，工作流将自动的变成COMPLETED状态。<br /><br />然而，当工作流处于ACTIVATED状态的时候，调用者可以终止或挂起这个工作流（设置工作流的状态为KILLED 或 SUSPENDED）。一个终止了的工作流将不能再执行任何动作，而且将永远保持着终止状态。一个被挂起了的工作流会被冻结，他也不能执行任何的动作，除非它的状态再变成ACTIVATED。<br />4.    OSWorkFlow包用途分析及代码片断<br />4.1.    com.opensymphony.workflow<br />该包为整个OSWorkflow 引擎提供核心接口。例如 com.opensymphony.workflow.Workflow 接口，可以说，实际开发中的大部分工作都是围绕该接口展开的，该接口有 BasicWorkflow、EJBWorkflow、OfbizWorkflow 三个实现类。<br />4.2.    com.opensymphony.workflow.basic<br />该包有两个类，BasicWorkflow 与 BasicWorkflowContext。BasicWorkflow 不支持事务，尽管依赖持久实现，事务也不能包裹它。BasicWorkflowContext 在实际开发中很少使用。<br /><br />public void setWorkflow(int userId) {<br />    Workflow workflow = new BasicWorkflow(Integer.toString(userId));<br />}<br /><br />4.3.    com.opensymphony.workflow.config<br />该包有一个接口和两个该接口的实现类。在 OSWorkflow 2.7 以前，状态由多个地方的静态字段维护，这种方式很方便，但是有很多缺陷和约束。最主要的缺点是无法通过不同配置运行多个 OSWorkflow 实例。实现类 DefaultConfiguration 用于一般的配置文件载入。而 SpringConfiguration 则是让 Spring 容器管理配置信息。<br /><br />public void setWorkflow(int userId) {<br />    Workflow workflow = new BasicWorkflow(Integer.toString(userId));<br />}<br />4.4.    com.opensymphony.workflow.ejb<br />    该包有两个接口 WorkflowHome 和 WorkflowRemote。该包的若干类中，最重要的是 EJBWorkflow，该类和 BasicWorkflow 的作用一样，是 OSWorkflow 的核心，并利用 EJB 容器管理事务，也作为工作流 session bean 的包装器。<br />4.5.    com.opensymphony.workflow.loader<br />该包有若干类，用得最多的是 XxxxDescriptor，如果在工作流引擎运行时需要了解指定的动作、步骤的状态、名字，等信息时，这些描述符会起到很大作用。<br /><br />public String findNameByStepId(int stepId,String wfName) {<br />    WorkflowDescriptor wd = workflow.getWorkflowDescriptor(wfName);<br />    StepDescriptor stepDes = wd.getStep(stepId);<br />    return stepDes.getName();<br />}<br />4.6.    com.opensymphony.workflow.ofbiz<br />    OfbizWorkflow 和 BasicWorkflow 在很多方面非常相似，除了需要调用 ofbiz 的 TransactionUtil 来包装事务。<br />4.7.    com.opensymphony.workflow.query<br />该包主要为查询而设计，但不是所有的工作流存储都支持查询。通常，Hibernate 和 JDBC 都支持，而内存工作流存储不支持。值得注意的是 Hibernate 存储不支持混合型查询（例如，一个查询同时包含了 history step 上下文和 current step 上下文）。执行一个查询，需要创建 WorkflowExpressionQuery 实例，接着调用 Workflow 对象的 query 方法来得到最终查询结果。<br /><br />public List queryDepAdmin(int userId,int type) {<br />    int[] arr = getSubPerson(userId,type);<br />    <br />    //构造表达式<br />    Expression[] expressions = new Expression[1 + arr.length];<br />    Expression expStatus = new FieldExpression(FieldExpression.STATUS,<br />    FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, "Queued");<br />    expressions[0] = expStatus;<br />    <br />    for (int i = 0; i &lt; arr.length; i++) {<br />        Expression expOwner = new FieldExpression(FieldExpression.OWNER,<br />        FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS,<br />        Integer.toString(arr[i]));<br />        expressions[i + 1] = expOwner;<br />    }<br /><br />    //查询未完成流编号<br />    List wfIdList = null;<br />    try {<br />        WorkflowExpressionQuery query = new WorkflowExpressionQuery(<br />        new NestedExpression(expressions, NestedExpression.AND));<br />        wfIdList = workflow.query(query);<br />    } catch (Exception e) {<br />        e.printStackTrace();<br />    }<br />}<br />4.8.    com.opensymphony.workflow.soap<br />    OSWorkflow 通过 SOAP 来支持远端调用。这种调用借助 WebMethods 实现。<br />4.9.    com.opensymphony.workflow.spi<br />该包可以说是 OSWorkflow 与持久层打交道的途径，如当前工作流的实体，其中包括：EJB、Hibernate、JDBC、Memory、Ofbiz、OJB、Prevayler。<br /><br />HibernateWorkflowEntry hwfe = (HibernateWorkflowEntry) getHibernateTemplate()<br />    .find("from HibernateWorkflowEntry where Id="<br />        + wfIdList.get(i)).get(0);<br />4.10.    com.opensymphony.workflow.util<br />该包是 OSWorkflow 的工具包，包括了对 BeanShell、BSF、EJB Local、EJB Remote、JNDI 的支持。<br />5.    OSWorkFlow表结构分析<br />5.1.    OS_WFENTRY<br />工作流主表，存放工作流名称和状态<br /><br />字段名    数据类型    说明<br />ID    NUMBER    自动编号<br />NAME    VARCHAR2(20)    工作流名称<br />STATE    NUMBER    工作流状态<br /><br />5.2.    OS_CURRENTSTEP<br />当前步骤表，存放当前正在进行步骤的数据<br /><br />字段名    数据类型    说明<br />ID    NUMBER    自动编号<br />ENTRY_ID    NUMBER    工作流编号<br />STEP_ID    NUMBER    步骤编号<br />ACTION_ID    NUMBER    动作编号<br />OWNER    VARCHAR2(20)    步骤的所有者<br />START_DATE    DATE    开始时间<br />FINISH_DATE    DATE    结束时间<br />DUE_DATE    DATE    授权时间<br />STATUS    VARCHAR2(20)    状态<br />CALLER    VARCHAR2(20)    操作人员的帐号名称<br /><br />5.3.    OS_CURRENTSTEP_PREV<br />前步骤表，存放当前步骤和上一个步骤的关联数据<br /><br />字段名    数据类型    说明<br />ID    NUMBER    当前步骤编号<br />PREVIOUS    NUMBER    前步骤编号<br /><br />5.4.    OS_HISTORYSTEP<br />历史步骤表，存放当前正在进行步骤的数据<br /><br />字段名    数据类型    说明<br />ID    NUMBER    自动编号<br />ENTRY_ID    NUMBER    工作流编号<br />STEP_ID    NUMBER    步骤编号<br />ACTION_ID    NUMBER    动作编号<br />OWNER    VARCHAR2(20)    步骤的所有者<br />START_DATE    DATE    开始时间<br />FINISH_DATE    DATE    结束时间<br />DUE_DATE    DATE    授权时间<br />STATUS    VARCHAR2(20)    状态<br />CALLER    VARCHAR2(20)    操作人员的帐号名称<br /><br />5.5.    OS_HISTORYSTEP_PREV<br />前历史步骤表，存放历史步骤和上一个步骤的关联数据<br /><br />字段名    数据类型    说明<br />ID    NUMBER    当前历史步骤编号<br />PREVIOUS    NUMBER    前历史步骤编号<br /><br />5.6.    OS_PROPERTYENTRY<br />属性表，存放临时变量<br /><br />字段名    数据类型    说明<br />GLOBAL_KEY    VARCHAR2(255)    全局关键字<br />ITEM_KEY    VARCHAR2(255)    条目关键字<br />ITEM_TYPE    NUMBER    条目类型<br />STRING_VALUE    VARCHAR2(255)    字符值<br />DATE_VALUE    DATE    日期值<br />DATA_VALUE    BLOB    数据值<br />FLOAT_VALUE    FLOAT    浮点值<br />NUMBER_VALUE    NUMBER    数字值<br /><br /><img src ="http://www.blogjava.net/pdw2009/aggbug/40622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-12 13:27 <a href="http://www.blogjava.net/pdw2009/archive/2006/04/12/40622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>osworkflow分析</title><link>http://www.blogjava.net/pdw2009/archive/2006/04/12/40621.html</link><dc:creator>有猫相伴的日子</dc:creator><author>有猫相伴的日子</author><pubDate>Wed, 12 Apr 2006 05:26:00 GMT</pubDate><guid>http://www.blogjava.net/pdw2009/archive/2006/04/12/40621.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/40621.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/12/40621.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/40621.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/40621.html</trackback:ping><description><![CDATA[OSWorkFlow分析<br />1.    OSWorkFlow基本概念<br />    在商用和开源世界里，OSWorkflow 都不同于这些已有的工作流系统。最大不同在于 OSWorkflow 有着非常优秀的灵活性。在开始接触 OSWorkflow 时可能较难掌握（有人说不适合工作流新手入门），比如，OSWorkflow 不要求图形化工具来开发工作流，而推荐手工编写 xml 格式的工作流程描述符。它能为应用程序开发者提供集成，也能与现有的代码和数据库进行集成。这一切似乎给正在寻找快速“即插即用”工作流解决方案的人制造了麻烦，但研究发现，那些“即插即用”方案也不能在一个成熟的应用程序中提供足够的灵活性来实现所有需求。<br />2.    OSWorkFlow主要优势<br />OSWorkflow 给你绝对的灵活性。OSWorkflow 被认为是一种“低级别”工作流实现。与其他工作流系统能用图标表现“Loops(回路)”和“Conditions(条件)”相比，OSWorkflow 只是手工“编码(Coded)”来实现的。但这并不能说实际的代码是需要完全手工编码的，脚本语言能胜任这种情形。OSWorkflow 不希望一个非技术用户修改工作流程，虽然一些其他工作流系统提供了简单的 GUI 用于工作流编辑，但像这样改变工作流，通常会破坏这些应用。所以，进行工作流调整的最佳人选是开发人员，他们知道该怎么改变。不过，在最新的版本中，OSWorkflow 也提供了 GUI 设计器来协助工作流的编辑。<br /><br />OSWorkflow 基于有限状态机概念。每个 state 由 step ID 和 status 联合表现（可简单理解为 step 及其 status 表示有限状态机的 state）。一个 state 到另一 state 的 transition 依赖于 action 的发生，在工作流生命期内有至少一个或多个活动的 state。这些简单概念展现了 OSWorkflow 引擎的核心思想，并允许一个简单 XML 文件解释工作流业务流程。<br />3.    OSWorkFlow核心概念<br />3.1.    概念定义<br /> <br />步骤（Step）<br />    一个 Step 描述的是工作流所处的位置。可能从一个 Step Transtion（流转）到另外一个 Step，或者也可以在同一个 Step 内流转（因为 Step 可以通 Status 来细分，形成多个State）。一个流程里面可以多个Step。<br /><br />状态（Status）<br />    工作流 Status 是用来描述工作流程中具体Step（步骤）状态的字符串。OSWorkflow 的有 Underway（进行中）、Queued（等候处理中）、Finished（完成）三种 Status。一个实际State（状态）真正是由两部分组成：State = (Step + Status) 。<br /><br />流转（Transtion）<br />    一个State到另一个State的转移。<br /><br />动作（Action）<br />    Action 触发了发生在 Step 内或 Step 间的流转，或者说是基于 State 的流转。一个 step 里面可以有多个Action。Action 和Step 之间的关系是，Step 说明“在哪里”，Action 说明“去哪里”。 一个 Action 典型地由两部分组成：可以执行此Action（动作）的<br />Condition（条件），以及执行此动作后的 Result（结果）。    <br /><br />条件（Condition）<br />类似于逻辑判断，可包含“AND”和“OR”逻辑。比如一个请假流程中的“本部门审批阶段”，该阶段利用“AND”逻辑，判断流程状态是否为等候处理中，以及审批者是否为本部门主管。<br /><br />结果（Result）<br />Result 代表执行Action（动作）后的结果，指向新的 Step 及其 Step Status，也可能进入 Split 或者 Join。Result 分为两种， Contidional-Result （有条件结果），只有条件为真时才使用该结果，和 Unconditional-Result（无条件结果），当条件不满足或没有条件时使用该结果。<br /><br />分离/连接（Split/Join）<br />流程的切分和融合。很简单的概念，Split 可以提供多个 Result（结果）；Join 则判断多个 Current Step 的态提供一个 Result（结果）。<br />3.2.    步骤、状态和动作(Step, Status, and Action)<br />工作流要描述步骤(Step)、步骤的状态(Status)、各个步骤之间的关系以及执行各个步骤的条件和权限，每个步骤中可以含有一个或多个动作(Action)，动作将会使一个步骤的状态发生改变。<br /><br />对于一个执行的工作流来讲，步骤的切换是不可避免的。一个工作流在某一时刻会有一个或多个当前步骤，每个当前步骤都有一个状态值，当前步骤的状态值组成了工作流实例的状态值。一旦完成了一个步骤，那么这个步骤将不再是当前步骤（而是切换到一个新的步骤），通常一个新的当前步骤将随之建立起来，以保证工作流继续执行。完成了的步骤的最终状态值是用Old-Status属性指定的，这个状态值的设定将发生在切换到其他步骤之前。Old-Status的值可以是任意的，但在一般情况下，我们设置为Finished。<br /><br />切换本身是一个动作（Action）的执行结果。每个步骤可以含有多个动作，究竟要载入哪个动作是由最终用户、外部事件或者Tiggerd的自动调用决定的。随着动作的完成，一个特定的步骤切换也将发生。动作可以被限制在用户、用户组或当前状态。每一个动作都必须包含一个Unconditional Result和0个或多个Conditional Results。<br /><br />所以，总体来说，一个工作流由多个步骤组成。每个步骤有一个当前状态（例如：Queued, Underway or Finished），一个步骤包含多个动作。每个步骤含有多个可以执行的动作。每个动作都有执行的条件，也有要执行的函数。动作包含有可以改变状态和当前工作流步骤的results。<br />3.3.    结果、分支和连接(Results, Joins, and Splits)<br />3.3.1.    无条件结果(Unconditional Result)<br />对于每一个动作来讲，必须存在一个Unconditional Result。一个result是一系列指令，这些指令将告诉OSWorkFlow下一个任务要做什么。这包括使工作流从一个状态切换到另一个状态。<br />3.3.2.    有条件结果(Conditional Result)<br />Conditional Result是Unconditional Result的一个扩展。它需要一个或多个Condition子标签。第一个为true的Conditional（使用AND或OR类型），会指明发生切换的步骤，这个切换步骤的发生是由于某个用户执行了某个动作的结果导致的。<br />3.3.3.    三种不同的Results(conditional or unconditional)<br />一个新的、单一的步骤和状态的组合。<br />一个分裂成两个或多个步骤和状态的组合。<br />将这个和其他的切换组合成一个新的单一的步骤和状态的组合。<br />每种不同的result对应了不同的xml描述，你可以阅读<a href="http://www.opensymphony.com/osworkflow/workflow_2_7.dtd">http://www.opensymphony.com/osworkflow/workflow_2_7.dtd</a>，获取更多的信息。<br />注意：通常，一个split或一个join不会再导致一个split 或 join的发生。<br />3.4.    自动步骤(Auto actions)<br />有的时候，我们需要一些动作可以基于一些条件自动地执行。为了达到这个目的，你可以在action中加入auto="true"属性。流程将考察这个动作的条件和限制，如果条件符合，那么将执行这个动作。 Auto action是由当前的调用者执行的，所以将对该动作的调用者执行权限检查。<br />3.5.    整合抽象实例(Integrating with Abstract Entities)<br />建议在你的核心实体中，例如"Document" 或 "Order"，在内部创建一个新的属性：workflowId。这样，当新的"Document" 或 "Order"被创建的时候，它能够和一个workflow实例关联起来。那么，你的代码可以通过OSWorkflow API查找到这个workflow实例并且得到这个workflow的信息和动作。<br />3.6.    工作流实例状态(Workflow Instance State)<br />有的时候，为整个workflow实例指定一个状态是很有帮助的，它独立于流程的执行步骤。OSWorkflow提供一些workflow实例中可以包含的"meta-states"。这些"meta-states"可以是CREATED, ACTIVATED, SUSPENDED, KILLED 和 COMPLETED。当一个工作流实例被创建的时候，它将处于CREATED状态。然后，只要一个动作被执行，它就会自动的变成ACTIVATED状态。如果调用者没有明确地改变实例的状态，工作流将一直保持这个状态直到工作流结束。当工作流不可能再执行任何其他的动作的时候，工作流将自动的变成COMPLETED状态。<br /><br />然而，当工作流处于ACTIVATED状态的时候，调用者可以终止或挂起这个工作流（设置工作流的状态为KILLED 或 SUSPENDED）。一个终止了的工作流将不能再执行任何动作，而且将永远保持着终止状态。一个被挂起了的工作流会被冻结，他也不能执行任何的动作，除非它的状态再变成ACTIVATED。<br />4.    OSWorkFlow包用途分析及代码片断<br />4.1.    com.opensymphony.workflow<br />该包为整个OSWorkflow 引擎提供核心接口。例如 com.opensymphony.workflow.Workflow 接口，可以说，实际开发中的大部分工作都是围绕该接口展开的，该接口有 BasicWorkflow、EJBWorkflow、OfbizWorkflow 三个实现类。<br />4.2.    com.opensymphony.workflow.basic<br />该包有两个类，BasicWorkflow 与 BasicWorkflowContext。BasicWorkflow 不支持事务，尽管依赖持久实现，事务也不能包裹它。BasicWorkflowContext 在实际开发中很少使用。<br /><br />public void setWorkflow(int userId) {<br />    Workflow workflow = new BasicWorkflow(Integer.toString(userId));<br />}<br /><br />4.3.    com.opensymphony.workflow.config<br />该包有一个接口和两个该接口的实现类。在 OSWorkflow 2.7 以前，状态由多个地方的静态字段维护，这种方式很方便，但是有很多缺陷和约束。最主要的缺点是无法通过不同配置运行多个 OSWorkflow 实例。实现类 DefaultConfiguration 用于一般的配置文件载入。而 SpringConfiguration 则是让 Spring 容器管理配置信息。<br /><br />public void setWorkflow(int userId) {<br />    Workflow workflow = new BasicWorkflow(Integer.toString(userId));<br />}<br />4.4.    com.opensymphony.workflow.ejb<br />    该包有两个接口 WorkflowHome 和 WorkflowRemote。该包的若干类中，最重要的是 EJBWorkflow，该类和 BasicWorkflow 的作用一样，是 OSWorkflow 的核心，并利用 EJB 容器管理事务，也作为工作流 session bean 的包装器。<br />4.5.    com.opensymphony.workflow.loader<br />该包有若干类，用得最多的是 XxxxDescriptor，如果在工作流引擎运行时需要了解指定的动作、步骤的状态、名字，等信息时，这些描述符会起到很大作用。<br /><br />public String findNameByStepId(int stepId,String wfName) {<br />    WorkflowDescriptor wd = workflow.getWorkflowDescriptor(wfName);<br />    StepDescriptor stepDes = wd.getStep(stepId);<br />    return stepDes.getName();<br />}<br />4.6.    com.opensymphony.workflow.ofbiz<br />    OfbizWorkflow 和 BasicWorkflow 在很多方面非常相似，除了需要调用 ofbiz 的 TransactionUtil 来包装事务。<br />4.7.    com.opensymphony.workflow.query<br />该包主要为查询而设计，但不是所有的工作流存储都支持查询。通常，Hibernate 和 JDBC 都支持，而内存工作流存储不支持。值得注意的是 Hibernate 存储不支持混合型查询（例如，一个查询同时包含了 history step 上下文和 current step 上下文）。执行一个查询，需要创建 WorkflowExpressionQuery 实例，接着调用 Workflow 对象的 query 方法来得到最终查询结果。<br /><br />public List queryDepAdmin(int userId,int type) {<br />    int[] arr = getSubPerson(userId,type);<br />    <br />    //构造表达式<br />    Expression[] expressions = new Expression[1 + arr.length];<br />    Expression expStatus = new FieldExpression(FieldExpression.STATUS,<br />    FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, "Queued");<br />    expressions[0] = expStatus;<br />    <br />    for (int i = 0; i &lt; arr.length; i++) {<br />        Expression expOwner = new FieldExpression(FieldExpression.OWNER,<br />        FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS,<br />        Integer.toString(arr[i]));<br />        expressions[i + 1] = expOwner;<br />    }<br /><br />    //查询未完成流编号<br />    List wfIdList = null;<br />    try {<br />        WorkflowExpressionQuery query = new WorkflowExpressionQuery(<br />        new NestedExpression(expressions, NestedExpression.AND));<br />        wfIdList = workflow.query(query);<br />    } catch (Exception e) {<br />        e.printStackTrace();<br />    }<br />}<br />4.8.    com.opensymphony.workflow.soap<br />    OSWorkflow 通过 SOAP 来支持远端调用。这种调用借助 WebMethods 实现。<br />4.9.    com.opensymphony.workflow.spi<br />该包可以说是 OSWorkflow 与持久层打交道的途径，如当前工作流的实体，其中包括：EJB、Hibernate、JDBC、Memory、Ofbiz、OJB、Prevayler。<br /><br />HibernateWorkflowEntry hwfe = (HibernateWorkflowEntry) getHibernateTemplate()<br />    .find("from HibernateWorkflowEntry where Id="<br />        + wfIdList.get(i)).get(0);<br />4.10.    com.opensymphony.workflow.util<br />该包是 OSWorkflow 的工具包，包括了对 BeanShell、BSF、EJB Local、EJB Remote、JNDI 的支持。<br />5.    OSWorkFlow表结构分析<br />5.1.    OS_WFENTRY<br />工作流主表，存放工作流名称和状态<br /><br />字段名    数据类型    说明<br />ID    NUMBER    自动编号<br />NAME    VARCHAR2(20)    工作流名称<br />STATE    NUMBER    工作流状态<br /><br />5.2.    OS_CURRENTSTEP<br />当前步骤表，存放当前正在进行步骤的数据<br /><br />字段名    数据类型    说明<br />ID    NUMBER    自动编号<br />ENTRY_ID    NUMBER    工作流编号<br />STEP_ID    NUMBER    步骤编号<br />ACTION_ID    NUMBER    动作编号<br />OWNER    VARCHAR2(20)    步骤的所有者<br />START_DATE    DATE    开始时间<br />FINISH_DATE    DATE    结束时间<br />DUE_DATE    DATE    授权时间<br />STATUS    VARCHAR2(20)    状态<br />CALLER    VARCHAR2(20)    操作人员的帐号名称<br /><br />5.3.    OS_CURRENTSTEP_PREV<br />前步骤表，存放当前步骤和上一个步骤的关联数据<br /><br />字段名    数据类型    说明<br />ID    NUMBER    当前步骤编号<br />PREVIOUS    NUMBER    前步骤编号<br /><br />5.4.    OS_HISTORYSTEP<br />历史步骤表，存放当前正在进行步骤的数据<br /><br />字段名    数据类型    说明<br />ID    NUMBER    自动编号<br />ENTRY_ID    NUMBER    工作流编号<br />STEP_ID    NUMBER    步骤编号<br />ACTION_ID    NUMBER    动作编号<br />OWNER    VARCHAR2(20)    步骤的所有者<br />START_DATE    DATE    开始时间<br />FINISH_DATE    DATE    结束时间<br />DUE_DATE    DATE    授权时间<br />STATUS    VARCHAR2(20)    状态<br />CALLER    VARCHAR2(20)    操作人员的帐号名称<br /><br />5.5.    OS_HISTORYSTEP_PREV<br />前历史步骤表，存放历史步骤和上一个步骤的关联数据<br /><br />字段名    数据类型    说明<br />ID    NUMBER    当前历史步骤编号<br />PREVIOUS    NUMBER    前历史步骤编号<br /><br />5.6.    OS_PROPERTYENTRY<br />属性表，存放临时变量<br /><br />字段名    数据类型    说明<br />GLOBAL_KEY    VARCHAR2(255)    全局关键字<br />ITEM_KEY    VARCHAR2(255)    条目关键字<br />ITEM_TYPE    NUMBER    条目类型<br />STRING_VALUE    VARCHAR2(255)    字符值<br />DATE_VALUE    DATE    日期值<br />DATA_VALUE    BLOB    数据值<br />FLOAT_VALUE    FLOAT    浮点值<br />NUMBER_VALUE    NUMBER    数字值<br /><br /><img src ="http://www.blogjava.net/pdw2009/aggbug/40621.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-12 13:26 <a href="http://www.blogjava.net/pdw2009/archive/2006/04/12/40621.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>osworkflow代码分析</title><link>http://www.blogjava.net/pdw2009/archive/2006/04/11/40480.html</link><dc:creator>有猫相伴的日子</dc:creator><author>有猫相伴的日子</author><pubDate>Tue, 11 Apr 2006 08:03:00 GMT</pubDate><guid>http://www.blogjava.net/pdw2009/archive/2006/04/11/40480.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/40480.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/11/40480.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/40480.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/40480.html</trackback:ping><description><![CDATA[
		<p>1.com.opensymphony.workflow.Workflow 工作流的用户接口。</p>
		<p>       主要定义了用户对工作流的操作方法和用户获得工作流信息的方法。如doAction(long id, int actionId, Map inputs)方法可以执行工作流的Action并产生transaction；用户调用getAvailableActions(long id, Map inputs)可以获得知道工作流实例中符合条件的可以执行的Action。</p>
		<p>2.com.opensymphony.workflow.WorkflowContext 工作流的Context接口。</p>
		<p>      只有两个方法，其中getCaller()获得调用者，setRollbackOnly()可以回滚Action造成的transaction。</p>
		<p>      setRollbackOnly()方法非常重要，可以在此方法中实现工作流数据与业务数据的事务处理。由于工作流引擎将流程数据与业务数据分离开管理，所以工作流数据与业务数据之间的事务处理往往比较困难，甚至有很多商业的工作流引擎都没有解决这个问题，造成软件上的漏洞。可惜在BasicWorkflowContext中并没有实现回滚时的事务处理，但实现起来应该不会很困难，在以后会单独考虑。</p>
		<p>3.com.opensymphony.workflow.spi.WorkflowEntry 工作流实例的接口。</p>
		<p>     定义了获得工作流实例信息的方法。</p>
		<p>4.com.opensymphony.workflow.config.Configuration 工作流配置接口。</p>
		<p>      获得osworkflw的配置信息和流程的定义信息， osworkflow中的例子就是使用此接口的默认实现。如果想让osworkflw与自己的系统更好的整合，这个接口需要自己实现。</p>
		<p>5.com.opensymphony.workflow.loader.AbstractWorkflowFactory 流程定义的解析器。</p>
		<p>      osworkflow中提供了此抽象类的3种实现，最常用的是XMLWorkflowFactory，可以对编写的工作流定义xml文件进行解析。</p>
		<p>6.com.opensymphony.workflow.spi.WorkflowStore 工作流存储接口。</p>
		<p>      实现此接口可以实现用多种途径保存工作流信息，jdbc,hibernate,ejb,memory.........<br /><br /></p>
		<p>AbstractWorkflow类是workflow接口的最基本的实现。</p>
		<p>1.public int[] getAvailableActions(long id, Map inputs)方法：</p>
		<p>返回当前可以执行的Ation。</p>
		<ul>
				<li>得到工作流流程实例。 
</li>
				<li>得到工作流实例的定义。 
</li>
				<li>得到工作流实例的PropertySet。 
</li>
				<li>得到工作流的当前Step。 
</li>
				<li>产生TransientVars。 
</li>
				<li>得到Global Actions。 
</li>
				<li>判断可以执行的Global Action增加到可执行Action列表中。 
</li>
				<li>获得当前Steps中的可执行Action并添加到可执行Action列表中。 
</li>
				<li>返回可执行Actions。 </li>
		</ul>
		<p>2. public void setConfiguration(Configuration configuration)方法：</p>
		<p>设置工作流配置方法。</p>
		<p>3.public Configuration getConfiguration()方法：</p>
		<p>返回工作流配置方法，如果没有获得配置信息，初始化配置信息。</p>
		<p>4.public List getCurrentSteps(long id)：</p>
		<p>获得工作流当前所在步骤。</p>
		<p>5.public int getEntryState(long id):</p>
		<p>获得工作流的状态。</p>
		<p>6.public List getHistorySteps(long id)</p>
		<p>获得工作流的历史步骤。</p>
		<p>7. public Properties getPersistenceProperties()</p>
		<p>获得设置的持久化参数。</p>
		<p>8.public PropertySet getPropertySet(long id)</p>
		<p>得到工作流的PropertySet，调用store中的方法。</p>
		<p>9.public List getSecurityPermissions(long id)</p>
		<p>得到工作流当前Step的permissions。</p>
		<p>10.public WorkflowDescriptor getWorkflowDescriptor(String workflowName)</p>
		<p>得到工作流的定义。</p>
		<p>11.public String getWorkflowName(long id)</p>
		<p>根据工作流实例返回工作流定义名。</p>
		<p>12. public String[] getWorkflowNames()</p>
		<p>返回系统中配置的所有工作流的名字。</p>
		<p>13.public boolean canInitialize(String workflowName, int initialAction)，public boolean canInitialize(String workflowName, int initialAction, Map inputs)，private boolean canInitialize(String workflowName, int initialAction, Map transientVars, PropertySet ps) throws WorkflowException</p>
		<p>判断指定的工作流初始化Action是不是可以执行。</p>
		<p>14.public boolean canModifyEntryState(long id, int newState)</p>
		<p>判断工作流是不是可以转换到指定状态。</p>
		<ul>
				<li>不可以转换到CREATED状态。 
</li>
				<li>CREATED，SUSPENDED可以转换到ACTIVATED状态。 
</li>
				<li>ACTIVATED可以转换到SUSPENDED状态。 
</li>
				<li>CREATED，ACTIVATED，SUSPENDED 可以转换到KILLED状态。 </li>
		</ul>
		<p>15.public void changeEntryState(long id, int newState) throws WorkflowException</p>
		<p>转换工作流状态。</p>
		<p>16.public void doAction(long id, int actionId, Map inputs) throws WorkflowException</p>
		<p>执行Action。</p>
		<ul>
				<li>获得工作流store，和流程实例entry。 
</li>
				<li>判断是不是活动的工作流，不是就返回。 
</li>
				<li>获得工作流的定义。 
</li>
				<li>获得工作流当前所再Steps。 
</li>
				<li>获得工作流PropertySet。 
</li>
				<li>生成transientVars。 
</li>
				<li>从GlobalActions中和当前Steps的普通Actions中判断执行的Action是否试可执行的。 
</li>
				<li>完成Action的Transition。 </li>
		</ul>
		<p>17.public void executeTriggerFunction(long id, int triggerId) throws WorkflowException</p>
		<p>调用工作流的Trigger Function</p>
		<p>18.public long initialize(String workflowName, int initialAction, Map inputs) throws InvalidRoleException, InvalidInputException, WorkflowException</p>
		<p>初始化一个新的流程实例。返回流程实例id。</p>
		<p>19.public List query(WorkflowQuery query)，public List query(WorkflowExpressionQuery query)</p>
		<p>查询流程实例。</p>
		<p>20.public boolean removeWorkflowDescriptor(String workflowName) throws FactoryException</p>
		<p>删除已经配置的工作流定义。</p>
		<p>21.public boolean saveWorkflowDescriptor(String workflowName, WorkflowDescriptor descriptor, boolean replace) throws FactoryException </p>
		<p>保存工作流定义。</p>
		<p>22.protected List getAvailableActionsForStep(WorkflowDescriptor wf, Step step, Map transientVars, PropertySet ps) throws WorkflowException</p>
		<p>获得指定步骤的可用Actions。</p>
		<p>23.protected int[] getAvailableAutoActions(long id, Map inputs)</p>
		<p>返回可执行的AutoActions。</p>
		<p>24.protected List getAvailableAutoActionsForStep(WorkflowDescriptor wf, Step step, Map transientVars, PropertySet ps) throws WorkflowException </p>
		<p>返回指定Step中可执行的AutoActions。</p>
		<p>25.protected WorkflowStore getPersistence() throws StoreException</p>
		<p>返回配置的store。</p>
		<p>26.protected void checkImplicitFinish(long id) throws WorkflowException</p>
		<p>判断工作流是不是还有可执行的Action，如果没有，完成此工作流实例。</p>
		<p>27.protected void completeEntry(long id, Collection currentSteps) throws StoreException</p>
		<p>结束工作流实例，就是把改变流程实例的状态并把当前的Steps都放入到历史表中。 </p>
		<p>28.protected boolean passesCondition(ConditionDescriptor conditionDesc, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowException</p>
		<p>29.protected boolean passesCondition(ConditionDescriptor conditionDesc, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowException，protected boolean passesConditions(String conditionType, List conditions, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowException </p>
		<p>判断条件是不是符合。</p>
		<p>30.protected void populateTransientMap(WorkflowEntry entry, Map transientVars, List registers, Integer actionId, Collection currentSteps) throws WorkflowException</p>
		<p>产生临时变量transientVars，包含context，entry，store，descriptor，actionId，currentSteps，以及定义的register和用户的输入变量。</p>
		<p>31.protected void verifyInputs(WorkflowEntry entry, List validators, Map transientVars, PropertySet ps) throws WorkflowException</p>
		<p>验证用户的输入。</p>
		<p>32.private boolean isActionAvailable(ActionDescriptor action, Map transientVars, PropertySet ps, int stepId) throws WorkflowException</p>
		<p>判断Action是否可用。</p>
		<p>33.private Step getCurrentStep(WorkflowDescriptor wfDesc, int actionId, List currentSteps, Map transientVars, PropertySet ps) throws WorkflowException </p>
		<p>获得Action所在Step。</p>
		<p>34.private boolean canInitialize(String workflowName, int initialAction, Map transientVars, PropertySet ps) throws WorkflowException</p>
		<p>判断工作流是不是可以实例化。</p>
		<p>35.private Step createNewCurrentStep(ResultDescriptor theResult, WorkflowEntry entry, WorkflowStore store, int actionId, Step currentStep, long[] previousIds, Map transientVars, PropertySet ps) throws WorkflowException </p>
		<p>产生新的当前Step。</p>
		<ul>
				<li>从resulte中获得nextStep，如果为-1，nextStep为当前Step。 
</li>
				<li>获得定义中的owner，oldStatus，status。 
</li>
				<li>完成当前Step，并且将当前Step保存到历史库中。 
</li>
				<li>生成新的Step。 </li>
		</ul>
		<p>36.private void executeFunction(FunctionDescriptor function, Map transientVars, PropertySet ps) throws WorkflowException</p>
		<p>执行Function。</p>
		<p>37.private boolean transitionWorkflow(WorkflowEntry entry, List currentSteps, WorkflowStore store, WorkflowDescriptor wf, ActionDescriptor action, Map transientVars, Map inputs, PropertySet ps) throws WorkflowException </p>
		<p>完成工作流的transation。<br /><br /></p>
		<div>DefaultConfiguration是Configuration接口的默认实现，用于初始化系统的基本配置信息。</div>
		<div>1.public WorkflowDescriptor getWorkflow(String name) throws FactoryException</div>
		<div>根据工作流的定义名获得工作流的定义。</div>
		<div>2.public WorkflowStore getWorkflowStore() throws StoreException </div>
		<div>获得配置的持久化类Store。</div>
		<div>3.public void load(URL url) throws FactoryException</div>
		<div>装载配置信息。</div>
		<ul>
				<li>得到配置文件流，并解析。 
</li>
				<li>获得持久化信息，包括持久化类的路径和持久化类初始化参数。 
</li>
				<li>获得工作流信息解析类路径，并初始化。 </li>
		</ul>
		<p>4. public WorkflowStore getWorkflowStore() throws StoreException </p>
		<p>获得工作流初始化类。<br /><br /></p>
		<div>XMLWorkflowFactory用于解析工作流定义xml文件，获得工作流信息。</div>
		<div>1.public WorkflowDescriptor getWorkflow(String name) throws FactoryException </div>
		<div>根据工作流定义名获得工作流定义。</div>
		<div>2.public String[] getWorkflowNames()</div>
		<div>得到所有已经定义的工作流名称。</div>
		<div>3.public void initDone() throws FactoryException</div>
		<div>初始化workflows.xml文件中列出的工作流定义文件信息。<br /><br />转自于ch(耐心)</div>
<img src ="http://www.blogjava.net/pdw2009/aggbug/40480.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-11 16:03 <a href="http://www.blogjava.net/pdw2009/archive/2006/04/11/40480.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>osworkflow概念</title><link>http://www.blogjava.net/pdw2009/archive/2006/04/11/40478.html</link><dc:creator>有猫相伴的日子</dc:creator><author>有猫相伴的日子</author><pubDate>Tue, 11 Apr 2006 07:55:00 GMT</pubDate><guid>http://www.blogjava.net/pdw2009/archive/2006/04/11/40478.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/40478.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/11/40478.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/40478.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/40478.html</trackback:ping><description><![CDATA[
		<p>1. Step：工作流所在的位置，整个工作流的步骤，也可以是一系列工作中的某个工作，比如某个审批流程中的文件交到某个领导处审批，此过程可能包括接收秘书交来的文件、然后阅读、提出自己的意见、签字、叫给秘书继续处理，这整个过程可以是一个Step。但并不是FSM中的Status。</p>
		<p>2. Status：某个Step的状态，每个Step可以有多个Status。比如上例中阅读，等待提意见，等待签字，等待交秘书处理，都是Step的状态。Step＋Status共同组成了工作流的状态，也就实现了FSM中的Status。Step的Status在OSWorkflow中就是一段文本，状态的判断其实就是自定义的一段文本的比较，非常灵活。</p>
		<p>3. Action：造成工作流状态转换的动作，比如”阅读文件“动作，造成了工作流状态从”领导审批＋等待阅读"转换成“领导审批＋等待提出意见”。由于工作流的状态是Step＋Status，所以Action可以造成Stats的变化，也可以造成Step的变化。</p>
		<p>4. Result：工作流状态的转换，也就是Action造成的结果。也就是FSM中的Transition。每个Action中至少包含一个unconditional result和包含0或多个conditional result，Result的优先级顺序是 第一个符合条件的conditional result &gt; 其他符合条件的conditional result  &gt; unconditional result。</p>
		<p>5.Split/Join:字面意思就可以解释。Split可以产生多个unconditional result；而Join可以判断多个Step的状态，如果都满足条件的时候，Join产生一个unconditional result。可以用来实现其他工作流产品定义中的同步区的作用，比如一个投标文件的评标过程，分别要在技术方面和商务方面对标书进行评分，这样就可以使用Split将工作流分开进入商务评标组和技术评标组分别进行评标，当两个评标过程都完成后使用Join将两个流程合并，并对两个评标做的评分进行汇总。</p>
		<p>6.External Functions：执行的功能和动作。任何的工作流引擎都要与实际的业务操作相结合，External Functions就是OSWorkflow中执行业务操作的部分，比如审批流程中，领导填写意见后将领导的意见更新到业务数据库中的过程。Functions有两种类型，pre step function和post step function，分别发生转移前和发生转移后执行。Functions可以被定义到Step中和Action中。</p>
		<p>7.Trigger Functions，一种不是定义在Action中的Function，依靠计划自动执行。</p>
		<p>8.Validators：用来检验用户输入是否符合条件，只有符合条件，Action对应的转移才能执行，如果不符合条件，返回<em>InvalidInputException</em>异常。<br /><br />转于:ch(耐心)</p>
<img src ="http://www.blogjava.net/pdw2009/aggbug/40478.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-11 15:55 <a href="http://www.blogjava.net/pdw2009/archive/2006/04/11/40478.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在myeclipse下配置osworkflow的环境</title><link>http://www.blogjava.net/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.blogjava.net/pdw2009/archive/2006/04/11/40475.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/40475.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/11/40475.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/40475.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/40475.html</trackback:ping><description><![CDATA[1 新建一个名为oswf的Web Projcet 项目,并添加项目的  struts capabilities,并把osworkflow所需要jar文件拷贝到lib目录下.<br /><br />2 在tomcat的servers.xml文件中配置一个项目连接到我们所在的myeclipse工作区中所建立的oswf项目下的WebRoot目录下.在servers.xml中添加如下代码:<br /><br />&lt;Context path="/oswf" docBase="D:\peidw\workplace\osworkflow\WebRoot" debug="5" reloadable="true" crossContext="true"&gt;<br />        &lt;Resource name="jdbc/oswf" auth="Container" type="javax.sql.DataSource"/&gt;<br />          &lt;ResourceParams name="jdbc/oswf"&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;factory&lt;/name&gt;<br />            &lt;value&gt;org.apache.commons.dbcp.BasicDataSourceFactory&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;driverClassName&lt;/name&gt;<br />            &lt;value&gt;com.mysql.jdbc.Driver&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;url&lt;/name&gt;<br />            &lt;value&gt;jdbc:mysql://localhost:3306/osworkflow&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;username&lt;/name&gt;<br />            &lt;value&gt;root&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;password&lt;/name&gt;<br />            &lt;value&gt;&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;maxActive&lt;/name&gt;<br />            &lt;value&gt;20&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;maxIdle&lt;/name&gt;<br />            &lt;value&gt;2&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;maxWait&lt;/name&gt;<br />            &lt;value&gt;-1&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;removeAbandoned&lt;/name&gt;<br />            &lt;value&gt;true&lt;/value&gt;<br />          &lt;/parameter&gt;<br />          &lt;parameter&gt;<br />            &lt;name&gt;removeAbandonedTimeout&lt;/name&gt;<br />            &lt;value&gt;300&lt;/value&gt;<br />          &lt;/parameter&gt;<br />        &lt;/ResourceParams&gt;<br />        &lt;/Context&gt;<br /><br />3  在src目录需要建立三个文件来配置OSWorkflow的相关配置.首先是osworkflow.xml文件,至于文件的作用一看就明白,内容如下:<br />       &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;osworkflow&gt;<br /> &lt;persistence class="com.opensymphony.workflow.spi.jdbc.JDBCWorkflowStore"&gt;<br />     &lt;property key="datasource" value="jdbc/oswf"/&gt;<br />     <br />     &lt;property key="entry.sequence" value="select max(id)+1 from os_wfentry"/&gt;<br />     &lt;property key="entry.id" value="id"/&gt;<br />     &lt;property key="entry.name" value="name" /&gt;<br />     &lt;property key="entry.state" value="state"/&gt;<br />     <br />     &lt;property key="step.sequence" value="select max(id)+1 from os_stepids"/&gt;<br />     &lt;property key="step.sequence.increment" value="insert into os_stepids(id) values(null) "/&gt;<br />     &lt;property key="step.sequence.retrieve" value="select max(id) from os_stepids"/&gt;<br />     <br />     &lt;property key="history.table" value="os_historystep"/&gt;<br />     &lt;property key="current.table" value="os_currentstep"/&gt;<br />     &lt;property key="histroyPrev.table" value="os_historystep_prev"/&gt;<br />     &lt;property key="currentPrev.table" value="os_currentstep_prev"/&gt;<br />     <br />     &lt;property key="step.id" value="ID"/&gt;<br />        &lt;property key="step.entryId" value="ENTRY_ID"/&gt;<br />        &lt;property key="step.stepId" value="STEP_ID"/&gt;<br />        &lt;property key="step.actionId" value="ACTION_ID"/&gt;<br />        &lt;property key="step.owner" value="OWNER"/&gt;<br />        &lt;property key="step.caller" value="CALLER"/&gt;<br />        &lt;property key="step.startDate" value="START_DATE"/&gt;<br />        &lt;property key="step.finishDate" value="FINISH_DATE"/&gt;<br />        &lt;property key="step.dueDate" value="DUE_DATE"/&gt;<br />        &lt;property key="step.status" value="STATUS"/&gt;<br />        &lt;property key="step.previousId" value="PREVIOUS_ID"/&gt;<br />     <br /> &lt;/persistence&gt;<br /> <br /> &lt;factory class="com.opensymphony.workflow.loader.JDBCWorkflowFactory"&gt;<br />  &lt;property key="resource" value="workflows.xml"/&gt;<br /> &lt;/factory&gt;<br />&lt;/osworkflow&gt;<br />在src目录下新建一个propertyset.xml来存储相应的字段配置信息:<br /><br />  &lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;propertysets&gt;<br />    &lt;propertyset name="jdbc" <br />      class="com.opensymphony.module.propertyset.database.JDBCPropertySet"&gt;<br />        &lt;arg name="datasource" value="jdbc/oswf"/&gt;<br />        &lt;arg name="table.name" value="OS_PROPERTYENTRY"/&gt;<br />        &lt;arg name="col.globalKey" value="GLOBAL_KEY"/&gt;<br />        &lt;arg name="col.itemKey" value="ITEM_KEY"/&gt;<br />        &lt;arg name="col.itemType" value="ITEM_TYPE"/&gt;<br />        &lt;arg name="col.string" value="STRING_VALUE"/&gt;<br />        &lt;arg name="col.date" value="DATE_VALUE"/&gt;<br />        &lt;arg name="col.data" value="DATA_VALUE"/&gt;<br />        &lt;arg name="col.float" value="FLOAT_VALUE"/&gt;<br />        &lt;arg name="col.number" value="NUMBER_VALUE"/&gt;<br />    &lt;/propertyset&gt;<br />&lt;/propertysets&gt;<br />还要新建一个流程的配置文件,该文件的命名与osworkflow.xml的factory节点里的值有关,如:<br /><br />&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />&lt;workflows&gt;<br />  &lt;workflow name="leave" type="resource" location="leave.xml"/&gt;<br />&lt;/workflows&gt;<br /><br />那么leave.xml就是一个工作流的真正配置文件。其内容如下：<br /><br /><pre>&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.7//EN" 
"http://www.opensymphony.com/osworkflow/workflow_2_7.dtd"&gt;
&lt;workflow&gt;
  &lt;initial-actions&gt;
   &lt;action id="0" name="開始"&gt;
      &lt;results&gt;
        &lt;unconditional-result old-status="Finished" status="Queued" step="1" /&gt;
      &lt;/results&gt;
    &lt;/action&gt;
  &lt;/initial-actions&gt;

  &lt;steps&gt;
    &lt;step id="1" name="填假單"&gt;
      &lt;actions&gt;
        &lt;action id="1" name="送出"&gt;
	  &lt;pre-functions&gt;
	    &lt;function type="class"&gt;
	      &lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;
	    &lt;/function&gt;
	  &lt;/pre-functions&gt;
          &lt;results&gt;
            &lt;unconditional-result old-status="Finished" status="Queued" 
step="2"  owner="User100" /&gt;
          &lt;/results&gt;
        &lt;/action&gt;
      &lt;/actions&gt;
    &lt;/step&gt;

    &lt;step id="2" name="批假單"&gt;
      &lt;actions&gt;
        &lt;action id="2" name="准許"&gt;
	  &lt;pre-functions&gt;
	    &lt;function type="class"&gt;
	      &lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;
	    &lt;/function&gt;
	  &lt;/pre-functions&gt;
          &lt;results&gt;
            &lt;unconditional-result old-status="Finished" status="Queued" 
step="3"  owner="${caller}"/&gt;
          &lt;/results&gt;
        &lt;/action&gt;

        &lt;action id="3" name="駁回"&gt;
	  &lt;pre-functions&gt;
	    &lt;function type="class"&gt;
	      &lt;arg name="class.name"&gt;com.opensymphony.workflow.util.Caller&lt;/arg&gt;
	    &lt;/function&gt;
	  &lt;/pre-functions&gt;
          &lt;results&gt;
            &lt;unconditional-result old-status="Finished" status="Queued" 
step="1"  owner="${caller}"/&gt;
          &lt;/results&gt;
        &lt;/action&gt;
      &lt;/actions&gt;      
    &lt;/step&gt;

    &lt;step id="3" name="停止" /&gt;
  &lt;/steps&gt;
&lt;/workflow&gt;</pre><br /><br />这样就可以配置OSworkflow持久化进mysql中.<img src ="http://www.blogjava.net/pdw2009/aggbug/40475.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-11 15:40 <a href="http://www.blogjava.net/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.blogjava.net/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.blogjava.net/pdw2009/archive/2006/04/11/40474.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/40474.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/11/40474.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/40474.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/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 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>活动的：1 
</li>
												<li>挂起的：2 
</li>
												<li>中止的：3 
</li>
												<li>完成的：4 
</li>
												<li>未知的：－1</li>
										</ul>
								</td>
						</tr>
				</tbody>
		</table>
 <img src ="http://www.blogjava.net/pdw2009/aggbug/40474.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-11 15:28 <a href="http://www.blogjava.net/pdw2009/archive/2006/04/11/40474.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>OSWorkflow概况</title><link>http://www.blogjava.net/pdw2009/archive/2006/04/11/40473.html</link><dc:creator>有猫相伴的日子</dc:creator><author>有猫相伴的日子</author><pubDate>Tue, 11 Apr 2006 07:26:00 GMT</pubDate><guid>http://www.blogjava.net/pdw2009/archive/2006/04/11/40473.html</guid><wfw:comment>http://www.blogjava.net/pdw2009/comments/40473.html</wfw:comment><comments>http://www.blogjava.net/pdw2009/archive/2006/04/11/40473.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pdw2009/comments/commentRss/40473.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pdw2009/services/trackbacks/40473.html</trackback:ping><description><![CDATA[
		<h1 class="pagename">
				<a name="Top">
				</a>OSWorkflow</h1>
		<h2 id="section-OSWorkflow-OSWorkflow_E6_A6_82_E5_86_B5">OSWorkflow概况</h2>OSWorkflow是一个灵活的工作流引擎，可嵌入到企业应用程序中。它提供了许多的持久化API支持包括：<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=EJB">EJB</a>,<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=Hibernate">Hibernate</a>,<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=JDBC">JDBC</a>和其它。OSWorkflow还可以与<a class="editpage" title="Create 'Spring'" href="http://wiki.matrix.org.cn/Edit.jsp?page=Spring">Spring</a>集成。 
<p>在商用和开源世界里，OSWorkflow 都不同于这些已有的工作流系统。最大不同在于 OSWorkflow 有着非常优秀的灵活性。 </p><h2 id="section-OSWorkflow-OSWorkflow_E7_9A_84_E4_BC_98_E5_8A_BF">OSWorkflow的优势</h2>OSWorkflow 给你绝对的灵活性。OSWorkflow 被认为是一种“低级别”<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>实现。与其他工作流系统能用图标表现“Loops(回路)”和“Conditions(条件)”相比，OSWorkflow 只是手工“编码(Coded)”来实现的。但这并不能说实际的代码是需要完全手工编码的，脚本语言能胜任这种情形。OSWorkflow 不希望一个非技术用户修改工作流程，虽然一些其他工作流系统提供了简单的 GUI 用于工作流编辑，但像这样改变<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>，通常会破坏这些应用。所以，进行<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>调整的最佳人选是开发人员，他们知道该怎么改变。不过，在最新的版本中，OSWorkflow 也提供了 <a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=GUI">GUI</a> 设计器来协助工作流的编辑。 
<p>OSWorkflow 基于<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E6%9C%89%E9%99%90%E7%8A%B6%E6%80%81%E6%9C%BA">有限状态机</a>概念。每个 state 由 step ID 和 status 联合表现（可简单理解为 step 及其 status 表示有限状态机的 state）。一个 state 到另一 state 的 transition 依赖于 action 的发生，在工作流生命期内有至少一个或多个活动的 state。这些简单概念展现了 OSWorkflow 引擎的核心思想，并允许一个简单 <a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=XML">XML</a> 文件解释工作流业务流程。 </p><h2 id="section-OSWorkflow-OSWorkFlow_E6_A0_B8_E5_BF_83_E6_A6_82_E5_BF_B5">OSWorkFlow核心概念</h2><h3 id="section-OSWorkflow-_E6_A6_82_E5_BF_B5_E5_AE_9A_E4_B9_89">概念定义</h3>步骤（Step） 一个 Step 描述的是工作流所处的位置。可能从一个 Step Transtion（流转）到另外一个 Step，或者也可以在同一个 Step 内流转（因为 Step 可以通 Status 来细分，形成多个State）。一个流程里面可以多个Step。 
<p>状态（Status） <a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a> Status 是用来描述工作流程中具体Step（步骤）状态的字符串。OSWorkflow 的有 Underway（进行中）、Queued（等候处理中）、Finished（完成）三种 Status。一个实际State（状态）真正是由两部分组成：State = (Step + Status) 。 </p><p>流转（Transtion） 一个State到另一个State的转移。 </p><p>动作（Action） Action 触发了发生在 Step 内或 Step 间的流转，或者说是基于 State 的流转。一个 step 里面可以有多个Action。Action 和Step 之间的关系是，Step 说明“在哪里”，Action 说明“去哪里”。 一个 Action 典型地由两部分组成：可以执行此Action（动作）的 Condition（条件），以及执行此动作后的 Result（结果）。 </p><p>条件（Condition）类似于逻辑判断，可包含“AND”和“OR”逻辑。比如一个请假流程中的“本部门审批阶段”，该阶段利用“AND”逻辑，判断流程状态是否为等候处理中，以及审批者是否为本部门主管。 </p><p>结果（Result） Result 代表执行Action（动作）后的结果，指向新的 Step 及其 Step Status，也可能进入 Split 或者 Join。Result 分为两种， Contidional-Result （有条件结果），只有条件为真时才使用该结果，和 Unconditional-Result（无条件结果），当条件不满足或没有条件时使用该结果。 </p><p>分离/连接（Split/Join）流程的切分和融合。很简单的概念，Split 可以提供多个 Result（结果）；Join 则判断多个 Current Step 的态提供一个 Result（结果）。 </p><h3 id="section-OSWorkflow-_E6_AD_A5_E9_AA_A4_E7_8A_B6_E6_80_81_E5_92_8C_E5_8A_A8_E4_BD_9CStepStatusAndAction">步骤、状态和动作(Step, Status, and Action)</h3><a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>要描述步骤(Step)、步骤的状态(Status)、各个步骤之间的关系以及执行各个步骤的条件和权限，每个步骤中可以含有一个或多个动作(Action)，动作将会使一个步骤的状态发生改变。 
<p>对于一个执行的<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>来讲，步骤的切换是不可避免的。一个工作流在某一时刻会有一个或多个当前步骤，每个当前步骤都有一个状态值，当前步骤的状态值组成了工作流实例的状态值。一旦完成了一个步骤，那么这个步骤将不再是当前步骤（而是切换到一个新的步骤），通常一个新的当前步骤将随之建立起来，以保证<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>继续执行。完成了的步骤的最终状态值是用Old-Status属性指定的，这个状态值的设定将发生在切换到其他步骤之前。Old-Status的值可以是任意的，但在一般情况下，我们设置为Finished。 </p><p>切换本身是一个动作（Action）的执行结果。每个步骤可以含有多个动作，究竟要载入哪个动作是由最终用户、外部事件或者Tiggerd的自动调用决定的。随着动作的完成，一个特定的步骤切换也将发生。动作可以被限制在用户、用户组或当前状态。每一个动作都必须包含一个Unconditional Result和0个或多个Conditional Results。 </p><p>所以，总体来说，一个工作流由多个步骤组成。每个步骤有一个当前状态（例如：Queued, Underway or Finished），一个步骤包含多个动作。每个步骤含有多个可以执行的动作。每个动作都有执行的条件，也有要执行的函数。动作包含有可以改变状态和当前工作流步骤的results。 </p><h3 id="section-OSWorkflow-_E7_BB_93_E6_9E_9C_E5_88_86_E6_94_AF_E5_92_8C_E8_BF_9E_E6_8E_A5ResultsJoinsAndSplits">结果、分支和连接(Results, Joins, and Splits)</h3>无条件结果(Unconditional Result) 对于每一个动作来讲，必须存在一个Unconditional Result。一个result是一系列指令，这些指令将告诉OSWorkFlow下一个任务要做什么。这包括使工作流从一个状态切换到另一个状态。 
<p>有条件结果(Conditional Result) Conditional Result是Unconditional Result的一个扩展。它需要一个或多个Condition子标签。第一个为true的Conditional（使用AND或OR类型），会指明发生切换的步骤，这个切换步骤的发生是由于某个用户执行了某个动作的结果导致的。 </p><p>三种不同的Results(conditional or unconditional) 一个新的、单一的步骤和状态的组合。一个分裂成两个或多个步骤和状态的组合。将这个和其他的切换组合成一个新的单一的步骤和状态的组合。每种不同的result对应了不同的xml描述，你可以阅读<a class="external" href="http://www.opensymphony.com/osworkflow/workflow_2_7.dtd">http://www.opensymphony.com/osworkflow/workflow_2_7.dtd</a><img class="outlink" alt="" src="http://wiki.matrix.org.cn/images/out.png" />，获取更多的信息。注意：通常，一个split或一个join不会再导致一个split 或 join的发生。 </p><h3 id="section-OSWorkflow-_E8_87_AA_E5_8A_A8_E6_AD_A5_E9_AA_A4AutoActions">自动步骤(Auto actions)</h3>有的时候，我们需要一些动作可以基于一些条件自动地执行。为了达到这个目的，你可以在action中加入auto="true"属性。流程将考察这个动作的条件和限制，如果条件符合，那么将执行这个动作。 Auto action是由当前的调用者执行的，所以将对该动作的调用者执行权限检查。 
<h3 id="section-OSWorkflow-_E6_95_B4_E5_90_88_E6_8A_BD_E8_B1_A1_E5_AE_9E_E4_BE_8BIntegratingWithAbstractEntities">整合抽象实例(Integrating with Abstract Entities)</h3>建议在你的核心实体中，例如"Document" 或 "Order"，在内部创建一个新的属性：workflowId。这样，当新的"Document" 或 "Order"被创建的时候，它能够和一个workflow实例关联起来。那么，你的代码可以通过OSWorkflow API查找到这个workflow实例并且得到这个workflow的信息和动作。 
<h3 id="section-OSWorkflow-_E5_B7_A5_E4_BD_9C_E6_B5_81_E5_AE_9E_E4_BE_8B_E7_8A_B6_E6_80_81WorkflowInstanceState">工作流实例状态(Workflow Instance State)</h3>有的时候，为整个workflow实例指定一个状态是很有帮助的，它独立于流程的执行步骤。OSWorkflow提供一些workflow实例中可以包含的"meta-states"。这些"meta-states"可以是CREATED, ACTIVATED, SUSPENDED, KILLED 和 COMPLETED。当一个工作流实例被创建的时候，它将处于CREATED状态。然后，只要一个动作被执行，它就会自动的变成ACTIVATED状态。如果调用者没有明确地改变实例的状态，<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>将一直保持这个状态直到工作流结束。当工作流不可能再执行任何其他的动作的时候，工作流将自动的变成COMPLETED状态。 
<p>然而，当<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>处于ACTIVATED状态的时候，调用者可以终止或挂起这个工作流（设置工作流的状态为KILLED 或 SUSPENDED）。一个终止了的工作流将不能再执行任何动作，而且将永远保持着终止状态。一个被挂起了的<a class="wikipage" href="http://wiki.matrix.org.cn/Wiki.jsp?page=%E5%B7%A5%E4%BD%9C%E6%B5%81">工作流</a>会被冻结，他也不能执行任何的动作，除非它的状态再变成ACTIVATED。 </p><img src ="http://www.blogjava.net/pdw2009/aggbug/40473.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pdw2009/" target="_blank">有猫相伴的日子</a> 2006-04-11 15:26 <a href="http://www.blogjava.net/pdw2009/archive/2006/04/11/40473.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>