OSWorkFlow分析
1.????OSWorkFlow基本概念
????在商用和開(kāi)源世界里,OSWorkflow?都不同于這些已有的工作流系統(tǒng)。最大不同在于?OSWorkflow?有著非常優(yōu)秀的靈活性。在開(kāi)始接觸?OSWorkflow?時(shí)可能較難掌握(有人說(shuō)不適合工作流新手入門(mén)),比如,OSWorkflow?不要求圖形化工具來(lái)開(kāi)發(fā)工作流,而推薦手工編寫(xiě)?xml?格式的工作流程描述符。它能為應(yīng)用程序開(kāi)發(fā)者提供集成,也能與現(xiàn)有的代碼和數(shù)據(jù)庫(kù)進(jìn)行集成。這一切似乎給正在尋找快速“即插即用”工作流解決方案的人制造了麻煩,但研究發(fā)現(xiàn),那些“即插即用”方案也不能在一個(gè)成熟的應(yīng)用程序中提供足夠的靈活性來(lái)實(shí)現(xiàn)所有需求。
2.????OSWorkFlow主要優(yōu)勢(shì)
OSWorkflow?給你絕對(duì)的靈活性。OSWorkflow?被認(rèn)為是一種“低級(jí)別”工作流實(shí)現(xiàn)。與其他工作流系統(tǒng)能用圖標(biāo)表現(xiàn)“Loops(回路)”和“Conditions(條件)”相比,OSWorkflow?只是手工“編碼(Coded)”來(lái)實(shí)現(xiàn)的。但這并不能說(shuō)實(shí)際的代碼是需要完全手工編碼的,腳本語(yǔ)言能勝任這種情形。OSWorkflow?不希望一個(gè)非技術(shù)用戶修改工作流程,雖然一些其他工作流系統(tǒng)提供了簡(jiǎn)單的?GUI?用于工作流編輯,但像這樣改變工作流,通常會(huì)破壞這些應(yīng)用。所以,進(jìn)行工作流調(diào)整的最佳人選是開(kāi)發(fā)人員,他們知道該怎么改變。不過(guò),在最新的版本中,OSWorkflow?也提供了?GUI?設(shè)計(jì)器來(lái)協(xié)助工作流的編輯。
OSWorkflow?基于有限狀態(tài)機(jī)概念。每個(gè)?state?由?step?ID?和?status?聯(lián)合表現(xiàn)(可簡(jiǎn)單理解為?step?及其?status?表示有限狀態(tài)機(jī)的?state)。一個(gè)?state?到另一?state?的?transition?依賴于?action?的發(fā)生,在工作流生命期內(nèi)有至少一個(gè)或多個(gè)活動(dòng)的?state。這些簡(jiǎn)單概念展現(xiàn)了?OSWorkflow?引擎的核心思想,并允許一個(gè)簡(jiǎn)單?XML?文件解釋工作流業(yè)務(wù)流程。
3.????OSWorkFlow核心概念
3.1.????概念定義
?
步驟(Step)
????一個(gè)?Step?描述的是工作流所處的位置。可能從一個(gè)?Step?Transtion(流轉(zhuǎn))到另外一個(gè)?Step,或者也可以在同一個(gè)?Step?內(nèi)流轉(zhuǎn)(因?yàn)?Step?可以通?Status?來(lái)細(xì)分,形成多個(gè)State)。一個(gè)流程里面可以多個(gè)Step。
狀態(tài)(Status)
????工作流?Status?是用來(lái)描述工作流程中具體Step(步驟)狀態(tài)的字符串。OSWorkflow?的有?Underway(進(jìn)行中)、Queued(等候處理中)、Finished(完成)三種?Status。一個(gè)實(shí)際State(狀態(tài))真正是由兩部分組成:State?=?(Step?+?Status)?。
流轉(zhuǎn)(Transtion)
????一個(gè)State到另一個(gè)State的轉(zhuǎn)移。
動(dòng)作(Action)
????Action?觸發(fā)了發(fā)生在?Step?內(nèi)或?Step?間的流轉(zhuǎn),或者說(shuō)是基于?State?的流轉(zhuǎn)。一個(gè)?step?里面可以有多個(gè)Action。Action?和Step?之間的關(guān)系是,Step?說(shuō)明“在哪里”,Action?說(shuō)明“去哪里”。?一個(gè)?Action?典型地由兩部分組成:可以執(zhí)行此Action(動(dòng)作)的
Condition(條件),以及執(zhí)行此動(dòng)作后的?Result(結(jié)果)。????
條件(Condition)
類(lèi)似于邏輯判斷,可包含“AND”和“OR”邏輯。比如一個(gè)請(qǐng)假流程中的“本部門(mén)審批階段”,該階段利用“AND”邏輯,判斷流程狀態(tài)是否為等候處理中,以及審批者是否為本部門(mén)主管。
結(jié)果(Result)
Result?代表執(zhí)行Action(動(dòng)作)后的結(jié)果,指向新的?Step?及其?Step?Status,也可能進(jìn)入?Split?或者?Join。Result?分為兩種,?Contidional-Result?(有條件結(jié)果),只有條件為真時(shí)才使用該結(jié)果,和?Unconditional-Result(無(wú)條件結(jié)果),當(dāng)條件不滿足或沒(méi)有條件時(shí)使用該結(jié)果。
分離/連接(Split/Join)
流程的切分和融合。很簡(jiǎn)單的概念,Split?可以提供多個(gè)?Result(結(jié)果);Join?則判斷多個(gè)?Current?Step?的態(tài)提供一個(gè)?Result(結(jié)果)。
3.2.????步驟、狀態(tài)和動(dòng)作(Step,?Status,?and?Action)
工作流要描述步驟(Step)、步驟的狀態(tài)(Status)、各個(gè)步驟之間的關(guān)系以及執(zhí)行各個(gè)步驟的條件和權(quán)限,每個(gè)步驟中可以含有一個(gè)或多個(gè)動(dòng)作(Action),動(dòng)作將會(huì)使一個(gè)步驟的狀態(tài)發(fā)生改變。
對(duì)于一個(gè)執(zhí)行的工作流來(lái)講,步驟的切換是不可避免的。一個(gè)工作流在某一時(shí)刻會(huì)有一個(gè)或多個(gè)當(dāng)前步驟,每個(gè)當(dāng)前步驟都有一個(gè)狀態(tài)值,當(dāng)前步驟的狀態(tài)值組成了工作流實(shí)例的狀態(tài)值。一旦完成了一個(gè)步驟,那么這個(gè)步驟將不再是當(dāng)前步驟(而是切換到一個(gè)新的步驟),通常一個(gè)新的當(dāng)前步驟將隨之建立起來(lái),以保證工作流繼續(xù)執(zhí)行。完成了的步驟的最終狀態(tài)值是用Old-Status屬性指定的,這個(gè)狀態(tài)值的設(shè)定將發(fā)生在切換到其他步驟之前。Old-Status的值可以是任意的,但在一般情況下,我們?cè)O(shè)置為Finished。
切換本身是一個(gè)動(dòng)作(Action)的執(zhí)行結(jié)果。每個(gè)步驟可以含有多個(gè)動(dòng)作,究竟要載入哪個(gè)動(dòng)作是由最終用戶、外部事件或者Tiggerd的自動(dòng)調(diào)用決定的。隨著動(dòng)作的完成,一個(gè)特定的步驟切換也將發(fā)生。動(dòng)作可以被限制在用戶、用戶組或當(dāng)前狀態(tài)。每一個(gè)動(dòng)作都必須包含一個(gè)Unconditional?Result和0個(gè)或多個(gè)Conditional?Results。
所以,總體來(lái)說(shuō),一個(gè)工作流由多個(gè)步驟組成。每個(gè)步驟有一個(gè)當(dāng)前狀態(tài)(例如:Queued,?Underway?or?Finished),一個(gè)步驟包含多個(gè)動(dòng)作。每個(gè)步驟含有多個(gè)可以執(zhí)行的動(dòng)作。每個(gè)動(dòng)作都有執(zhí)行的條件,也有要執(zhí)行的函數(shù)。動(dòng)作包含有可以改變狀態(tài)和當(dāng)前工作流步驟的results。
3.3.????結(jié)果、分支和連接(Results,?Joins,?and?Splits)
3.3.1.????無(wú)條件結(jié)果(Unconditional?Result)
對(duì)于每一個(gè)動(dòng)作來(lái)講,必須存在一個(gè)Unconditional?Result。一個(gè)result是一系列指令,這些指令將告訴OSWorkFlow下一個(gè)任務(wù)要做什么。這包括使工作流從一個(gè)狀態(tài)切換到另一個(gè)狀態(tài)。
3.3.2.????有條件結(jié)果(Conditional?Result)
Conditional?Result是Unconditional?Result的一個(gè)擴(kuò)展。它需要一個(gè)或多個(gè)Condition子標(biāo)簽。第一個(gè)為true的Conditional(使用AND或OR類(lèi)型),會(huì)指明發(fā)生切換的步驟,這個(gè)切換步驟的發(fā)生是由于某個(gè)用戶執(zhí)行了某個(gè)動(dòng)作的結(jié)果導(dǎo)致的。
3.3.3.????三種不同的Results(conditional?or?unconditional)
一個(gè)新的、單一的步驟和狀態(tài)的組合。
一個(gè)分裂成兩個(gè)或多個(gè)步驟和狀態(tài)的組合。
將這個(gè)和其他的切換組合成一個(gè)新的單一的步驟和狀態(tài)的組合。
每種不同的result對(duì)應(yīng)了不同的xml描述,你可以閱讀
http://www.opensymphony.com/osworkflow/workflow_2_7.dtd,獲取更多的信息。
注意:通常,一個(gè)split或一個(gè)join不會(huì)再導(dǎo)致一個(gè)split?或?join的發(fā)生。
3.4.????自動(dòng)步驟(Auto?actions)
有的時(shí)候,我們需要一些動(dòng)作可以基于一些條件自動(dòng)地執(zhí)行。為了達(dá)到這個(gè)目的,你可以在action中加入auto="true"屬性。流程將考察這個(gè)動(dòng)作的條件和限制,如果條件符合,那么將執(zhí)行這個(gè)動(dòng)作。?Auto?action是由當(dāng)前的調(diào)用者執(zhí)行的,所以將對(duì)該動(dòng)作的調(diào)用者執(zhí)行權(quán)限檢查。
3.5.????整合抽象實(shí)例(Integrating?with?Abstract?Entities)
建議在你的核心實(shí)體中,例如"Document"?或?"Order",在內(nèi)部創(chuàng)建一個(gè)新的屬性:workflowId。這樣,當(dāng)新的"Document"?或?"Order"被創(chuàng)建的時(shí)候,它能夠和一個(gè)workflow實(shí)例關(guān)聯(lián)起來(lái)。那么,你的代碼可以通過(guò)OSWorkflow?API查找到這個(gè)workflow實(shí)例并且得到這個(gè)workflow的信息和動(dòng)作。
3.6.????工作流實(shí)例狀態(tài)(Workflow?Instance?State)
有的時(shí)候,為整個(gè)workflow實(shí)例指定一個(gè)狀態(tài)是很有幫助的,它獨(dú)立于流程的執(zhí)行步驟。OSWorkflow提供一些workflow實(shí)例中可以包含的"meta-states"。這些"meta-states"可以是CREATED,?ACTIVATED,?SUSPENDED,?KILLED?和?COMPLETED。當(dāng)一個(gè)工作流實(shí)例被創(chuàng)建的時(shí)候,它將處于CREATED狀態(tài)。然后,只要一個(gè)動(dòng)作被執(zhí)行,它就會(huì)自動(dòng)的變成ACTIVATED狀態(tài)。如果調(diào)用者沒(méi)有明確地改變實(shí)例的狀態(tài),工作流將一直保持這個(gè)狀態(tài)直到工作流結(jié)束。當(dāng)工作流不可能再執(zhí)行任何其他的動(dòng)作的時(shí)候,工作流將自動(dòng)的變成COMPLETED狀態(tài)。
然而,當(dāng)工作流處于ACTIVATED狀態(tài)的時(shí)候,調(diào)用者可以終止或掛起這個(gè)工作流(設(shè)置工作流的狀態(tài)為KILLED?或?SUSPENDED)。一個(gè)終止了的工作流將不能再執(zhí)行任何動(dòng)作,而且將永遠(yuǎn)保持著終止?fàn)顟B(tài)。一個(gè)被掛起了的工作流會(huì)被凍結(jié),他也不能執(zhí)行任何的動(dòng)作,除非它的狀態(tài)再變成ACTIVATED。
4.????OSWorkFlow包用途分析及代碼片斷
4.1.????com.opensymphony.workflow
該包為整個(gè)OSWorkflow?引擎提供核心接口。例如?com.opensymphony.workflow.Workflow?接口,可以說(shuō),實(shí)際開(kāi)發(fā)中的大部分工作都是圍繞該接口展開(kāi)的,該接口有?BasicWorkflow、EJBWorkflow、OfbizWorkflow?三個(gè)實(shí)現(xiàn)類(lèi)。
4.2.????com.opensymphony.workflow.basic
該包有兩個(gè)類(lèi),BasicWorkflow?與?BasicWorkflowContext。BasicWorkflow?不支持事務(wù),盡管依賴持久實(shí)現(xiàn),事務(wù)也不能包裹它。BasicWorkflowContext?在實(shí)際開(kāi)發(fā)中很少使用。
public?void?setWorkflow(int?userId)?{
????Workflow?workflow?=?new?BasicWorkflow(Integer.toString(userId));
}
4.3.????com.opensymphony.workflow.config
該包有一個(gè)接口和兩個(gè)該接口的實(shí)現(xiàn)類(lèi)。在?OSWorkflow?2.7?以前,狀態(tài)由多個(gè)地方的靜態(tài)字段維護(hù),這種方式很方便,但是有很多缺陷和約束。最主要的缺點(diǎn)是無(wú)法通過(guò)不同配置運(yùn)行多個(gè)?OSWorkflow?實(shí)例。實(shí)現(xiàn)類(lèi)?DefaultConfiguration?用于一般的配置文件載入。而?SpringConfiguration?則是讓?Spring?容器管理配置信息。
public?void?setWorkflow(int?userId)?{
????Workflow?workflow?=?new?BasicWorkflow(Integer.toString(userId));
}
4.4.????com.opensymphony.workflow.ejb
????該包有兩個(gè)接口?WorkflowHome?和?WorkflowRemote。該包的若干類(lèi)中,最重要的是?EJBWorkflow,該類(lèi)和?BasicWorkflow?的作用一樣,是?OSWorkflow?的核心,并利用?EJB?容器管理事務(wù),也作為工作流?session?bean?的包裝器。
4.5.????com.opensymphony.workflow.loader
該包有若干類(lèi),用得最多的是?XxxxDescriptor,如果在工作流引擎運(yùn)行時(shí)需要了解指定的動(dòng)作、步驟的狀態(tài)、名字,等信息時(shí),這些描述符會(huì)起到很大作用。
public?String?findNameByStepId(int?stepId,String?wfName)?{
????WorkflowDescriptor?wd?=?workflow.getWorkflowDescriptor(wfName);
????StepDescriptor?stepDes?=?wd.getStep(stepId);
????return?stepDes.getName();
}
4.6.????com.opensymphony.workflow.ofbiz
????OfbizWorkflow?和?BasicWorkflow?在很多方面非常相似,除了需要調(diào)用?ofbiz?的?TransactionUtil?來(lái)包裝事務(wù)。
4.7.????com.opensymphony.workflow.query
該包主要為查詢而設(shè)計(jì),但不是所有的工作流存儲(chǔ)都支持查詢。通常,Hibernate?和?JDBC?都支持,而內(nèi)存工作流存儲(chǔ)不支持。值得注意的是?Hibernate?存儲(chǔ)不支持混合型查詢(例如,一個(gè)查詢同時(shí)包含了?history?step?上下文和?current?step?上下文)。執(zhí)行一個(gè)查詢,需要?jiǎng)?chuàng)建?WorkflowExpressionQuery?實(shí)例,接著調(diào)用?Workflow?對(duì)象的?query?方法來(lái)得到最終查詢結(jié)果。
public?List?queryDepAdmin(int?userId,int?type)?{
????int[]?arr?=?getSubPerson(userId,type);
????
????//構(gòu)造表達(dá)式
????Expression[]?expressions?=?new?Expression[1?+?arr.length];
????Expression?expStatus?=?new?FieldExpression(FieldExpression.STATUS,
????FieldExpression.CURRENT_STEPS,?FieldExpression.EQUALS,?"Queued");
????expressions[0]?=?expStatus;
????
????for?(int?i?=?0;?i?<?arr.length;?i++)?{
????????Expression?expOwner?=?new?FieldExpression(FieldExpression.OWNER,
????????FieldExpression.CURRENT_STEPS,?FieldExpression.EQUALS,
????????Integer.toString(arr[i]));
????????expressions[i?+?1]?=?expOwner;
????}
????//查詢未完成流編號(hào)
????List?wfIdList?=?null;
????try?{
????????WorkflowExpressionQuery?query?=?new?WorkflowExpressionQuery(
????????new?NestedExpression(expressions,?NestedExpression.AND));
????????wfIdList?=?workflow.query(query);
????}?catch?(Exception?e)?{
????????e.printStackTrace();
????}
}
4.8.????com.opensymphony.workflow.soap
????OSWorkflow?通過(guò)?SOAP?來(lái)支持遠(yuǎn)端調(diào)用。這種調(diào)用借助?WebMethods?實(shí)現(xiàn)。
4.9.????com.opensymphony.workflow.spi
該包可以說(shuō)是?OSWorkflow?與持久層打交道的途徑,如當(dāng)前工作流的實(shí)體,其中包括:EJB、Hibernate、JDBC、Memory、Ofbiz、OJB、Prevayler。
HibernateWorkflowEntry?hwfe?=?(HibernateWorkflowEntry)?getHibernateTemplate()
????.find("from?HibernateWorkflowEntry?where?Id="
????????+?wfIdList.get(i)).get(0);
4.10.????com.opensymphony.workflow.util
該包是?OSWorkflow?的工具包,包括了對(duì)?BeanShell、BSF、EJB?Local、EJB?Remote、JNDI?的支持。
5.????OSWorkFlow表結(jié)構(gòu)分析
5.1.????OS_WFENTRY
工作流主表,存放工作流名稱(chēng)和狀態(tài)
字段名????數(shù)據(jù)類(lèi)型????說(shuō)明
ID????NUMBER????自動(dòng)編號(hào)
NAME????VARCHAR2(20)????工作流名稱(chēng)
STATE????NUMBER????工作流狀態(tài)
5.2.????OS_CURRENTSTEP
當(dāng)前步驟表,存放當(dāng)前正在進(jìn)行步驟的數(shù)據(jù)
字段名????數(shù)據(jù)類(lèi)型????說(shuō)明
ID????NUMBER????自動(dòng)編號(hào)
ENTRY_ID????NUMBER????工作流編號(hào)
STEP_ID????NUMBER????步驟編號(hào)
ACTION_ID????NUMBER????動(dòng)作編號(hào)
OWNER????VARCHAR2(20)????步驟的所有者
START_DATE????DATE????開(kāi)始時(shí)間
FINISH_DATE????DATE????結(jié)束時(shí)間
DUE_DATE????DATE????授權(quán)時(shí)間
STATUS????VARCHAR2(20)????狀態(tài)
CALLER????VARCHAR2(20)????操作人員的帳號(hào)名稱(chēng)
5.3.????OS_CURRENTSTEP_PREV
前步驟表,存放當(dāng)前步驟和上一個(gè)步驟的關(guān)聯(lián)數(shù)據(jù)
字段名????數(shù)據(jù)類(lèi)型????說(shuō)明
ID????NUMBER????當(dāng)前步驟編號(hào)
PREVIOUS????NUMBER????前步驟編號(hào)
5.4.????OS_HISTORYSTEP
歷史步驟表,存放當(dāng)前正在進(jìn)行步驟的數(shù)據(jù)
字段名????數(shù)據(jù)類(lèi)型????說(shuō)明
ID????NUMBER????自動(dòng)編號(hào)
ENTRY_ID????NUMBER????工作流編號(hào)
STEP_ID????NUMBER????步驟編號(hào)
ACTION_ID????NUMBER????動(dòng)作編號(hào)
OWNER????VARCHAR2(20)????步驟的所有者
START_DATE????DATE????開(kāi)始時(shí)間
FINISH_DATE????DATE????結(jié)束時(shí)間
DUE_DATE????DATE????授權(quán)時(shí)間
STATUS????VARCHAR2(20)????狀態(tài)
CALLER????VARCHAR2(20)????操作人員的帳號(hào)名稱(chēng)
5.5.????OS_HISTORYSTEP_PREV
前歷史步驟表,存放歷史步驟和上一個(gè)步驟的關(guān)聯(lián)數(shù)據(jù)
字段名????數(shù)據(jù)類(lèi)型????說(shuō)明
ID????NUMBER????當(dāng)前歷史步驟編號(hào)
PREVIOUS????NUMBER????前歷史步驟編號(hào)
5.6.????OS_PROPERTYENTRY
屬性表,存放臨時(shí)變量
字段名????數(shù)據(jù)類(lèi)型????說(shuō)明
GLOBAL_KEY????VARCHAR2(255)????全局關(guān)鍵字
ITEM_KEY????VARCHAR2(255)????條目關(guān)鍵字
ITEM_TYPE????NUMBER????條目類(lèi)型
STRING_VALUE????VARCHAR2(255)????字符值
DATE_VALUE????DATE????日期值
DATA_VALUE????BLOB????數(shù)據(jù)值
FLOAT_VALUE????FLOAT????浮點(diǎn)值
NUMBER_VALUE????NUMBER????數(shù)字值
posted on 2006-04-12 13:26
有貓相伴的日子 閱讀(1008)
評(píng)論(0) 編輯 收藏 所屬分類(lèi):
workflow