1.OSWorkFlow基本概念
在商用和開源世界里,OSWorkflow 都不同於這些已有的工作流系統。最大不同在於 OSWorkflow 有着非常優秀的靈活性。在開始 接觸 OSWorkflow 時可能較難掌握(有人說不適合工作流新手入門),比如,OSWorkflow 不要求圖形化工具來開發工作流,而推薦手工編 寫 xml 格式的工作流程描述符。它能為應用程序開發者提供集成,也能與現有的代碼和數據庫進行集成。這一切似乎給正在尋找快速“即插即用”工作流解決 方案的人制造了麻煩,但研究發現,那些“即插即用”方案也不能在一個成熟的應用程序中提供足夠的靈活性來實現所有需求。
2. OSWorkFlow主要優勢
OSWorkflow 給你絕對的靈活性。OSWorkflow 被認為是一種“低級別”工作流實現。與其他工作流系統能用圖標表現“Loops(回 路)”和“Conditions(條件)”相比,OSWorkflow 只是手工“編碼(Coded)”來實現的。但這並不能說實際的代碼是需要完全手工 編碼的,腳本語言能勝任這種情形。OSWorkflow 不希望一個非技術用戶修改工作流程,雖然一些其他工作流系統提供了簡單的 GUI 用於工作流編 輯,但像這樣改變工作流,通常會破壞這些應用。所以,進行工作流調整的最佳人選是開發人員,他們知道該怎么改變。不過,在最新的版本 中,OSWorkflow 也提供了 GUI 設計器來協助工作流的編輯。
OSWorkflow 基於有限狀態機概念。每個 state 由 step ID 和 status 聯合表現(可簡單理解為 step 及 其 status 表示有限狀態機的 state)。一個 state 到另一 state 的 transition 依賴於 action 的發生, 在工作流生命期內有至少一個或多個活動的 state。這些簡單概念展現了 OSWorkflow 引擎的核心思想,並允許一個簡單 XML 文件解釋工 作流業務流程。
3. OSWorkFlow核心概念
3.1. 概念定義
步驟(Step)
一個 Step 描述的是工作流所處的位置。可能從一個 Step Transtion(流轉)到另外一個 Step,或者也可以在同一個 Step 內流轉(因為 Step 可以通 Status 來細分,形成多個State)。一個流程里面可以多個Step。
狀態(Status)
工作流 Status 是用來描述工作流程中具體Step(步驟)狀態的字符串。OSWorkflow 的有 Underway(進行中)、 Queued(等候處理中)、Finished(完成)三種 Status。一個實際State(狀態)真正是由兩部分組 成:State = (Step + Status) 。
流轉(Transtion)
一個State到另一個State的轉移。
動作(Action)
Action 觸發了發生在 Step 內或 Step 間的流轉,或者說是基於 State 的流轉。一個 step 里面可以有多個 Action。Action 和Step 之間的關系是,Step 說明“在哪里”,Action 說明“去哪里”。 一個 Action 典型地由兩部 分組成:可以執行此Action(動作)的
Condition(條件),以及執行此動作后的 Result(結果)。
條件(Condition)
類似於邏輯判斷,可包含“AND”和“OR”邏輯。比如一個請假流程中的“本部門審批階段”,該階段利用“AND”邏輯,判斷流程狀態是否為等候處理中,以及審批者是否為本部門主管。
結果(Result)
Result 代表執行Action(動作)后的結果,指向新的 Step 及其 Step Status,也可能進入 Split 或者 Join。 Result 分為兩種, Contidional-Result (有條件結果),只有條件為真時才使用該結果,和 Unconditional- Result(無條件結果),當條件不滿足或沒有條件時使用該結果。
分離/連接(Split/Join)
流程的切分和融合。很簡單的概念,Split 可以提供多個 Result(結果);Join 則判斷多個 Current Step 的態提供一個 Result(結果)。
3.2. 步驟、狀態和動作(Step, Status, and Action)
工作流要描述步驟(Step)、步驟的狀態(Status)、各個步驟之間的關系以及執行各個步驟的條件和權限,每個步驟中可以含有一個或多個動作(Action),動作將會使一個步驟的狀態發生改變。
對於一個執行的工作流來講,步驟的切換是不可避免的。一個工作流在某一時刻會有一個或多個當前步驟,每個當前步驟都有一個狀態值,當前步驟的狀態值組成了 工作流實例的狀態值。一旦完成了一個步驟,那么這個步驟將不再是當前步驟(而是切換到一個新的步驟),通常一個新的當前步驟將隨之建立起來,以保證工作流 繼續執行。完成了的步驟的最終狀態值是用Old-Status屬性指定的,這個狀態值的設定將發生在切換到其他步驟之前。Old-Status的值可以是 任意的,但在一般情況下,我們設置為Finished。
切換本身是一個動作(Action)的執行結果。每個步驟可以含有多個動作,究竟要載入哪個動作是由最終用戶、外部事件或者Tiggerd的自動調用決定 的。隨着動作的完成,一個特定的步驟切換也將發生。動作可以被限制在用戶、用戶組或當前狀態。每一個動作都必須包含一個 Unconditional Result和0個或多個Conditional Results。
所以,總體來說,一個工作流由多個步驟組成。每個步驟有一個當前狀態(例如:Queued, Underway or Finished),一個步驟包含 多個動作。每個步驟含有多個可以執行的動作。每個動作都有執行的條件,也有要執行的函數。動作包含有可以改變狀態和當前工作流步驟的results。
3.3. 結果、分支和連接(Results, Joins, and Splits)
3.3.1. 無條件結果(Unconditional Result)
對於每一個動作來講,必須存在一個Unconditional Result。一個result是一系列指令,這些指令將告訴OSWorkFlow下一個任務要做什么。這包括使工作流從一個狀態切換到另一個狀態。
3.3.2. 有條件結果(Conditional Result)
Conditional Result是Unconditional Result的一個擴展。它需要一個或多個Condition子標簽。第一個為 true的Conditional(使用AND或OR類型),會指明發生切換的步驟,這個切換步驟的發生是由於某個用戶執行了某個動作的結果導致的。
3.3.3. 三種不同的Results(conditional or unconditional)
一個新的、單一的步驟和狀態的組合。
一個分裂成兩個或多個步驟和狀態的組合。
將這個和其他的切換組合成一個新的單一的步驟和狀態的組合。
每種不同的result對應了不同的xml描述,你可以閱讀http://www.opensymphony.com/osworkflow/workflow_2_7.dtd,獲取更多的信息。
注意:通常,一個split或一個join不會再導致一個split 或 join的發生。
3.4. 自動步驟(Auto actions)
有的時候,我們需要一些動作可以基於一些條件自動地執行。為了達到這個目的,你可以在action中加入auto="true"屬性。流程將考察這個動作 的條件和限制,如果條件符合,那么將執行這個動作。 Auto action是由當前的調用者執行的,所以將對該動作的調用者執行權限檢查。
3.5. 整合抽象實例(Integrating with Abstract Entities)
建議在你的核心實體中,例如"Document" 或 "Order",在內部創建一個新的屬性:workflowId。這樣,當新 的"Document" 或 "Order"被創建的時候,它能夠和一個workflow實例關聯起來。那么,你的代碼可以通過 OSWorkflow API查找到這個workflow實例並且得到這個workflow的信息和動作。
3.6. 工作流實例狀態(Workflow Instance State)
有的時候,為整個workflow實例指定一個狀態是很有幫助的,它獨立於流程的執行步驟。OSWorkflow提供一些workflow實例中可以包含 的"meta-states"。這些"meta-states"可以是 CREATED, ACTIVATED, SUSPENDED, KILLED 和 COMPLETED。當一個工作流實例被創建的時候,它將處於 CREATED狀態。然后,只要一個動作被執行,它就會自動的變成ACTIVATED狀態。如果調用者沒有明確地改變實例的狀態,工作流將一直保持這個狀 態直到工作流結束。當工作流不可能再執行任何其他的動作的時候,工作流將自動的變成COMPLETED狀態。
然而,當工作流處於ACTIVATED狀態的時候,調用者可以終止或掛起這個工作流(設置工作流的狀態為KILLED 或 SUSPENDED)。一個終 止了的工作流將不能再執行任何動作,而且將永遠保持着終止狀態。一個被掛起了的工作流會被凍結,他也不能執行任何的動作,除非它的狀態再變成 ACTIVATED。
4. OSWorkFlow包用途分析及代碼片斷
4.1. com.opensymphony.workflow
該包為整個OSWorkflow 引擎提供核心接口。例如 com.opensymphony.workflow.Workflow 接口,可以說,實際 開發中的大部分工作都是圍繞該接口展開的,該接口有 BasicWorkflow、EJBWorkflow、OfbizWorkflow 三個實現類。
4.2. com.opensymphony.workflow.basic
該包有兩個類,BasicWorkflow 與 BasicWorkflowContext。BasicWorkflow 不支持事務,盡管依賴持久實現,事務也不能包裹它。BasicWorkflowContext 在實際開發中很少使用。
- public void setWorkflow(int userId) {
- Workflow workflow = new BasicWorkflow(Integer.toString(userId));
- }
4.3. com.opensymphony.workflow.config
該包有一個接口和兩個該接口的實現類。在 OSWorkflow 2.7 以前,狀態由多個地方的靜態字段維護,這種方式很方便,但是有很多缺陷和約束。 最主要的缺點是無法通過不同配置運行多個 OSWorkflow 實例。實現類 DefaultConfiguration 用於一般的配置文件載入。 而 SpringConfiguration 則是讓 Spring 容器管理配置信息。
- public void setWorkflow(int userId) {
- Workflow workflow = new BasicWorkflow(Integer.toString(userId));
- }
4.4. com.opensymphony.workflow.ejb
該包有兩個接口 WorkflowHome 和 WorkflowRemote。該包的若干類中,最重要的是 EJBWorkflow,該類 和 BasicWorkflow 的作用一樣,是 OSWorkflow 的核心,並利用 EJB 容器管理事務,也作為工作 流 session bean 的包裝器。
4.5. com.opensymphony.workflow.loader
該包有若干類,用得最多的是 XxxxDescriptor,如果在工作流引擎運行時需要了解指定的動作、步驟的狀態、名字,等信息時,這些描述符會起到很大作用。
- public String findNameByStepId(int stepId,String wfName) {
- WorkflowDescriptor wd = workflow.getWorkflowDescriptor(wfName);
- StepDescriptor stepDes = wd.getStep(stepId);
- return stepDes.getName();
- }
4.6. com.opensymphony.workflow.ofbiz
OfbizWorkflow 和 BasicWorkflow 在很多方面非常相似,除了需要調用 ofbiz 的 TransactionUtil 來包裝事務。
4.7. com.opensymphony.workflow.query
該包主要為查詢而設計,但不是所有的工作流存儲都支持查詢。通常,Hibernate 和 JDBC 都支持,而內存工作流存儲不支持。值得注意的 是 Hibernate 存儲不支持混合型查詢(例如,一個查詢同時包含了 history step 上下文和 current step 上下文)。 執行一個查詢,需要創建 WorkflowExpressionQuery 實例,接着調用 Workflow 對象的 query 方法來得到最終查詢 結果。
- public List queryDepAdmin(int userId,int type) {
- int[] arr = getSubPerson(userId,type);
- //構造表達式
- Expression[] expressions = new Expression[1 + arr.length];
- Expression expStatus = new FieldExpression(FieldExpression.STATUS,
- FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS, "Queued");
- expressions[0] = expStatus;
- for (int i = 0; i < arr.length; i++) {
- Expression expOwner = new FieldExpression(FieldExpression.OWNER,
- FieldExpression.CURRENT_STEPS, FieldExpression.EQUALS,
- Integer.toString(arr[i]));
- expressions[i + 1] = expOwner;
- }
- //查詢未完成流編號
- List wfIdList = null;
- try {
- WorkflowExpressionQuery query = new WorkflowExpressionQuery(
- new NestedExpression(expressions, NestedExpression.AND));
- wfIdList = workflow.query(query);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
4.8. com.opensymphony.workflow.soap
OSWorkflow 通過 SOAP 來支持遠端調用。這種調用借助 WebMethods 實現。
4.9. com.opensymphony.workflow.spi
該包可以說是 OSWorkflow 與持久層打交道的途徑,如當前工作流的實體,其中包括: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 的工具包,包括了對 BeanShell、BSF、EJB Local、EJB Remote、JNDI 的支持。
5. OSWorkFlow表結構分析
5.1. OS_WFENTRY
工作流主表,存放工作流名稱和狀態
字段名 數據類型 說明
ID NUMBER 自動編號
NAME VARCHAR2(20) 工作流名稱
STATE NUMBER 工作流狀態
5.2. OS_CURRENTSTEP
當前步驟表,存放當前正在進行步驟的數據
字段名 數據類型 說明
ID NUMBER 自動編號
ENTRY_ID NUMBER 工作流編號
STEP_ID NUMBER 步驟編號
ACTION_ID NUMBER 動作編號
OWNER VARCHAR2(20) 步驟的所有者
START_DATE DATE 開始時間
FINISH_DATE DATE 結束時間
DUE_DATE DATE 授權時間
STATUS VARCHAR2(20) 狀態
CALLER VARCHAR2(20) 操作人員的帳號名稱
5.3. OS_CURRENTSTEP_PREV
前步驟表,存放當前步驟和上一個步驟的關聯數據
字段名 數據類型 說明
ID NUMBER 當前步驟編號
PREVIOUS NUMBER 前步驟編號
5.4. OS_HISTORYSTEP
歷史步驟表,存放當前正在進行步驟的數據
字段名 數據類型 說明
ID NUMBER 自動編號
ENTRY_ID NUMBER 工作流編號
STEP_ID NUMBER 步驟編號
ACTION_ID NUMBER 動作編號
OWNER VARCHAR2(20) 步驟的所有者
START_DATE DATE 開始時間
FINISH_DATE DATE 結束時間
DUE_DATE DATE 授權時間
STATUS VARCHAR2(20) 狀態
CALLER VARCHAR2(20) 操作人員的帳號名稱
5.5. OS_HISTORYSTEP_PREV
前歷史步驟表,存放歷史步驟和上一個步驟的關聯數據
字段名 數據類型 說明
ID NUMBER 當前歷史步驟編號
PREVIOUS NUMBER 前歷史步驟編號
5.6. OS_PROPERTYENTRY
屬性表,存放臨時變量
字段名 數據類型 說明
GLOBAL_KEY VARCHAR2(255) 全局關鍵字
ITEM_KEY VARCHAR2(255) 條目關鍵字
ITEM_TYPE NUMBER 條目類型
STRING_VALUE VARCHAR2(255) 字符值
DATE_VALUE DATE 日期值
DATA_VALUE BLOB 數據值
FLOAT_VALUE FLOAT 浮點值
osworkflow代碼分析
1.com.opensymphony.workflow.Workflow 工作流的用戶接口。
主要定義了用戶對工作流的操作方法和用戶獲得工作流信息的方法。如doAction(long id, int actionId, Map inputs)方法可以執行工作流的Action並產生transaction;用戶調用getAvailableActions(long id, Map inputs)可以獲得知道工作流實例中符合條件的可以執行的Action。
2.com.opensymphony.workflow.WorkflowContext 工作流的Context接口。
只有兩個方法,其中getCaller()獲得調用者,setRollbackOnly()可以回滾Action造成的transaction。
setRollbackOnly()方法非常重要,可以在此方法中實現工作流數據與業務數據的事務處理。由於工作流引擎將流程數據與業務數據分離開管理, 所以工作流數據與業務數據之間的事務處理往往比較困難,甚至有很多商業的工作流引擎都沒有解決這個問題,造成軟件上的漏洞。可惜在 BasicWorkflowContext中並沒有實現回滾時的事務處理,但實現起來應該不會很困難,在以后會單獨考慮。
3.com.opensymphony.workflow.spi.WorkflowEntry 工作流實例的接口。
定義了獲得工作流實例信息的方法。
4.com.opensymphony.workflow.config.Configuration 工作流配置接口。
獲得osworkflw的配置信息和流程的定義信息, osworkflow中的例子就是使用此接口的默認實現。如果想讓osworkflw與自己的系統更好的整合,這個接口需要自己實現。
5.com.opensymphony.workflow.loader.AbstractWorkflowFactory 流程定義的解析器。
osworkflow中提供了此抽象類的3種實現,最常用的是XMLWorkflowFactory,可以對編寫的工作流定義xml文件進行解析。
6.com.opensymphony.workflow.spi.WorkflowStore 工作流存儲接口。
實現此接口可以實現用多種途徑保存工作流信息,jdbc,hibernate,ejb,memory.........
AbstractWorkflow類是workflow接口的最基本的實現。
1.public int[] getAvailableActions(long id, Map inputs)方法:
返回當前可以執行的Ation。
- 得到工作流流程實例。
- 得到工作流實例的定義。
- 得到工作流實例的PropertySet。
- 得到工作流的當前Step。
- 產生TransientVars。
- 得到Global Actions。
- 判斷可以執行的Global Action增加到可執行Action列表中。
- 獲得當前Steps中的可執行Action並添加到可執行Action列表中。
- 返回可執行Actions。
2. public void setConfiguration(Configuration configuration)方法:
設置工作流配置方法。
3.public Configuration getConfiguration()方法:
返回工作流配置方法,如果沒有獲得配置信息,初始化配置信息。
4.public List getCurrentSteps(long id):
獲得工作流當前所在步驟。
5.public int getEntryState(long id):
獲得工作流的狀態。
6.public List getHistorySteps(long id)
獲得工作流的歷史步驟。
7. public Properties getPersistenceProperties()
獲得設置的持久化參數。
8.public PropertySet getPropertySet(long id)
得到工作流的PropertySet,調用store中的方法。
9.public List getSecurityPermissions(long id)
得到工作流當前Step的permissions。
10.public WorkflowDescriptor getWorkflowDescriptor(String workflowName)
得到工作流的定義。
11.public String getWorkflowName(long id)
根據工作流實例返回工作流定義名。
12. public String[] getWorkflowNames()
返回系統中配置的所有工作流的名字。
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
判斷指定的工作流初始化Action是不是可以執行。
14.public boolean canModifyEntryState(long id, int newState)
判斷工作流是不是可以轉換到指定狀態。
- 不可以轉換到CREATED狀態。
- CREATED,SUSPENDED可以轉換到ACTIVATED狀態。
- ACTIVATED可以轉換到SUSPENDED狀態。
- CREATED,ACTIVATED,SUSPENDED 可以轉換到KILLED狀態。
15.public void changeEntryState(long id, int newState) throws WorkflowException
轉換工作流狀態。
16.public void doAction(long id, int actionId, Map inputs) throws WorkflowException
執行Action。
- 獲得工作流store,和流程實例entry。
- 判斷是不是活動的工作流,不是就返回。
- 獲得工作流的定義。
- 獲得工作流當前所再Steps。
- 獲得工作流PropertySet。
- 生成transientVars。
- 從GlobalActions中和當前Steps的普通Actions中判斷執行的Action是否試可執行的。
- 完成Action的Transition。
17.public void executeTriggerFunction(long id, int triggerId) throws WorkflowException
調用工作流的Trigger Function
18.public long initialize(String workflowName, int initialAction, Map inputs) throws InvalidRoleException, InvalidInputException, WorkflowException
初始化一個新的流程實例。返回流程實例id。
19.public List query(WorkflowQuery query),public List query(WorkflowExpressionQuery query)
查詢流程實例。
20.public boolean removeWorkflowDescriptor(String workflowName) throws FactoryException
刪除已經配置的工作流定義。
21.public boolean saveWorkflowDescriptor(String workflowName, WorkflowDescriptor descriptor, boolean replace) throws FactoryException
保存工作流定義。
22.protected List getAvailableActionsForStep(WorkflowDescriptor wf, Step step, Map transientVars, PropertySet ps) throws WorkflowException
獲得指定步驟的可用Actions。
23.protected int[] getAvailableAutoActions(long id, Map inputs)
返回可執行的AutoActions。
24.protected List getAvailableAutoActionsForStep(WorkflowDescriptor wf, Step step, Map transientVars, PropertySet ps) throws WorkflowException
返回指定Step中可執行的AutoActions。
25.protected WorkflowStore getPersistence() throws StoreException
返回配置的store。
26.protected void checkImplicitFinish(long id) throws WorkflowException
判斷工作流是不是還有可執行的Action,如果沒有,完成此工作流實例。
27.protected void completeEntry(long id, Collection currentSteps) throws StoreException
結束工作流實例,就是把改變流程實例的狀態並把當前的Steps都放入到歷史表中。
28.protected boolean passesCondition(ConditionDescriptor conditionDesc, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowException
29.protected boolean passesCondition(ConditionDescriptor conditionDesc, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowException,protected boolean passesConditions(String conditionType, List conditions, Map transientVars, PropertySet ps, int currentStepId) throws WorkflowException
判斷條件是不是符合。
30.protected void populateTransientMap(WorkflowEntry entry, Map transientVars, List registers, Integer actionId, Collection currentSteps) throws WorkflowException
產生臨時變量transientVars,包含context,entry,store,descriptor,actionId,currentSteps,以及定義的register和用戶的輸入變量。
31.protected void verifyInputs(WorkflowEntry entry, List validators, Map transientVars, PropertySet ps) throws WorkflowException
驗證用戶的輸入。
32.private boolean isActionAvailable(ActionDescriptor action, Map transientVars, PropertySet ps, int stepId) throws WorkflowException
判斷Action是否可用。
33.private Step getCurrentStep(WorkflowDescriptor wfDesc, int actionId, List currentSteps, Map transientVars, PropertySet ps) throws WorkflowException
獲得Action所在Step。
34.private boolean canInitialize(String workflowName, int initialAction, Map transientVars, PropertySet ps) throws WorkflowException
判斷工作流是不是可以實例化。
35.private Step createNewCurrentStep(ResultDescriptor theResult, WorkflowEntry entry, WorkflowStore store, int actionId, Step currentStep, long[] previousIds, Map transientVars, PropertySet ps) throws WorkflowException
產生新的當前Step。
- 從resulte中獲得nextStep,如果為-1,nextStep為當前Step。
- 獲得定義中的owner,oldStatus,status。
- 完成當前Step,並且將當前Step保存到歷史庫中。
- 生成新的Step。
36.private void executeFunction(FunctionDescriptor function, Map transientVars, PropertySet ps) throws WorkflowException
執行Function。
37.private boolean transitionWorkflow(WorkflowEntry entry, List currentSteps, WorkflowStore store, WorkflowDescriptor wf, ActionDescriptor action, Map transientVars, Map inputs, PropertySet ps) throws WorkflowException
完成工作流的transation。
- 得到配置文件流,並解析。
- 獲得持久化信息,包括持久化類的路徑和持久化類初始化參數。
- 獲得工作流信息解析類路徑,並初始化。
4. public WorkflowStore getWorkflowStore() throws StoreException
獲得工作流初始化類。
1. Step:工作流所在的位置,整個工作流的步驟,也可以是一系列工作中的某個工作,比如某個審批流程中的文件交到某個領導處審批,此過程可能包括接收秘書 交來的文件、然后閱讀、提出自己的意見、簽字、叫給秘書繼續處理,這整個過程可以是一個Step。但並不是FSM中的Status。
2. Status:某個Step的狀態,每個Step可以有多個Status。比如上例中閱讀,等待提意見,等待簽字,等待交秘書處理,都是Step的狀態。 Step+Status共同組成了工作流的狀態,也就實現了FSM中的Status。Step的Status在OSWorkflow中就是一段文本,狀態 的判斷其實就是自定義的一段文本的比較,非常靈活。
3. Action:造成工作流狀態轉換的動作,比如”閱讀文件“動作,造成了工作流狀態從”領導審批+等待閱讀"轉換成“領導審批+等待提出意見”。由於工作流的狀態是Step+Status,所以Action可以造成Stats的變化,也可以造成Step的變化。
4. Result:工作流狀態的轉換,也就是Action造成的結果。也就是FSM中的Transition。每個Action中至少包含一個 unconditional result和包含0或多個conditional result,Result的優先級順序是 第一個符合條件的conditional result > 其他符合條件的conditional result > unconditional result。
5.Split/Join:字面意思就可以解釋。Split可以產生多個unconditional result;而Join可以判斷多個Step的狀態,如果都滿足條件的時候,Join產生一個unconditional result。可以用來實現其他工作流產品定義中的同步區的作用,比如一個投標文件的評標過程,分別要在技術方面和商務方面對標書進行評分,這樣就可以使 用Split將工作流分開進入商務評標組和技術評標組分別進行評標,當兩個評標過程都完成后使用Join將兩個流程合並,並對兩個評標做的評分進行匯總。
6.External Functions:執行的功能和動作。任何的工作流引擎都要與實際的業務操作相結合,External Functions就是OSWorkflow中執行業務操作的部分,比如審批流程中,領導填寫意見后將領導的意見更新到業務數據庫中的過程。 Functions有兩種類型,pre step function和post step function,分別發生轉移前和發生轉移后執行。Functions可以被定義到Step中和Action中。
7.Trigger Functions,一種不是定義在Action中的Function,依靠計划自動執行。
8.Validators:用來檢驗用戶輸入是否符合條件,只有符合條件,Action對應的轉移才能執行,如果不符合條件,返回InvalidInputException異常。
配置OSWorkFlow通過Hibernate持久化
1.修改WEB-INF/classes/目錄下的osworkflow.xml,改為
- <persistence class="com.opensymphony.workflow.spi.hibernate.HibernateWorkflowStore">
- lt;/persistence>
2.將下面的Hibernate.cfg.xml加到WEB-INF/classes/下面,這里使用mysql數據庫。
- <?xml version='1.0' encoding='utf-8'?>
- <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <!-- properties -->
- <property name="connection.driver_class">org.gjt.mm.mysql.Driver</property>
- <property name="connection.url">jdbc:mysql://redhat:3306/osworkflow</property>
- <property name="connection.username">redhat</property>
- <property name="connection.password">redhat</property>
- <property name="dialect">net.sf.hibernate.dialect.MySQLDialect</property>
- <property name="show_sql">true</property>
- <property name="use_outer_join">true</property>
- <property name="connection.pool_size">10</property>
- <property name="statement_cache.size">25</property>
- <property name="hibernate.hbm2ddl.auto">update</property>
- <mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateCurrentStep.hbm.xml"></mapping>
- <mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateHistoryStep.hbm.xml"></mapping>
- <mapping resource="com/opensymphony/workflow/spi/hibernate/HibernateWorkflowEntry.hbm.xml"></mapping>
- <mapping resource="com/opensymphony/module/propertyset/hibernate/PropertySetItemImpl.hbm.xml"></mapping>
- </session-factory>
- </hibernate-configuration>
3.把hibernate的jar及hibernate所有要到的jar,到WEB-INF/lib/
4.OSWorkflow要求客戶端提供SessionFactory,自主控制session和transaction。在容器里可以直接生成 SessionFactory然后注入到workflow中。這里只是演示,所以直接修改.jsp文件,生成SessionFactory,傳入 workflow中。
- Workflow wf = new BasicWorkflow((String) session.getAttribute("username"));
- // osworkflow和hibernate竟然都是通過Configuration類來進行配置的,沒辦法,誰讓大家都需要進行配置而就那么幾個單詞呢
- com.opensymphony.workflow.config.Configuration conf = new DefaultConfiguration();
- SessionFactory sessionFactory = new net.sf.hibernate.cfg.Configuration().configure().buildSessionFactory();
- conf.getPersistenceArgs().put("sessionFactory", sessionFactory);
- wf.setConfiguration(conf);
5.基本搞定。