OSWorkflow 的主配置文件為 osworkflow.xml,該文件定義了工作流引擎的持久化策略、工作流定義載入方式等核心設定。以下是一個典型的 JDBC 持久化配置範例:
<osworkflow>
<persistence class="com.opensymphony.workflow.spi.jdbc.JDBCWorkflowStore">
<!-- JDBC 持久化必需屬性 -->
<property key="datasource" value="jdbc/DefaultDS"/>
<!-- McKoi 資料庫序列範例 -->
<property key="entry.sequence" value="SELECT SEQ_OS_WFENTRY.NEXTVAL FROM DUAL"/>
<property key="step.sequence" value="SELECT SEQ_OS_CURRENTSTEPS.NEXTVAL FROM DUAL"/>
<property key="entry.table" value="OS_WFENTRY"/>
<property key="entry.id" value="ID"/>
<property key="entry.name" value="NAME"/>
<property key="entry.state" value="STATE"/>
<property key="history.table" value="OS_HISTORYSTEP"/>
<property key="current.table" value="OS_CURRENTSTEP"/>
<property key="historyPrev.table" value="OS_HISTORYSTEP_PREV"/>
<property key="currentPrev.table" value="OS_CURRENTSTEP_PREV"/>
<property key="step.id" value="ID"/>
<property key="step.entryId" value="ENTRY_ID"/>
<property key="step.stepId" value="STEP_ID"/>
<property key="step.actionId" value="ACTION_ID"/>
<property key="step.owner" value="OWNER"/>
<property key="step.caller" value="CALLER"/>
<property key="step.startDate" value="START_DATE"/>
<property key="step.finishDate" value="FINISH_DATE"/>
<property key="step.dueDate" value="DUE_DATE"/>
<property key="step.status" value="STATUS"/>
<property key="step.previousId" value="PREVIOUS_ID"/>
</persistence>
<factory class="com.opensymphony.workflow.loader.XMLWorkflowFactory">
<property key="resource" value="workflows.xml" />
</factory>
</osworkflow>
OSWorkflow 支援多種持久化機制,透過 persistence 節點的 class 屬性指定:
採用 JDBC 方式時,必須配置工作流相關的資料表名稱與序列名稱,開發者可根據需求自訂表名與序列取值邏輯。OSWorkflow 使用 JNDI 定位 JDBC 資料源,相關設定請參考 Tomcat 資料源配置指南。
factory 節點決定工作流定義文件的儲存方式,支援以下四種:
範例中的 workflows.xml 定義了兩個工作流:
<workflows>
<workflow name="example" type="resource" location="example1.xml"/>
<workflow name="example" type="resource" location="example2.xml"/>
</workflows>
工作流定義中,每個 Action 的 restrict-to 節點可定義條件限制。例如:
<condition type="class">
<arg name="class.name">os.TestCondition</arg>
<arg name="group">foos</arg>
</condition>
開發者需實作 com.opensymphony.workflow.Condition 接口,核心方法為 passesCondition:
public interface Condition {
boolean passesCondition(Map transientVars, Map args, PropertySet ps) throws WorkflowException;
}
三個參數說明:
WorkflowContext、WorkflowEntry、WorkflowStore 及當前操作員 caller。group=foos。實作範例:判斷操作員是否屬於指定群組:
public class TestCondition implements Condition {
public boolean passesCondition(Map transientVars, Map args, PropertySet ps) {
try {
WorkflowContext context = (WorkflowContext) transientVars.get("context");
String caller = context.getCaller();
User user = UserManager.getInstance().getUser(caller);
String group = (String) args.get("group");
return user.inGroup(group);
} catch (EntityNotFoundException e) {
return false;
}
}
}
OSWorkflow 本身無工作項概念,但提供 FunctionProvider 接口讓開發者自行實作。接口定義:
public interface FunctionProvider {
void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException;
}
步驟如下:
workitem 資料表,欄位包含:ID、Entry_ID、Step_ID、Type(參與者類型)、Value(參與者實際值)。<pre-functions> 中註冊自訂 Function:<step id="6" name="approve">
<pre_functions>
<function type="class">
<arg name="class.name">os.TestFunctionProvider</arg>
<arg name="type">group</arg>
<arg name="value">zte</arg>
</function>
</pre_functions>
<actions>...</actions>
</step>
TestFunctionProvider,於流程進入步驟時將工作項寫入資料庫:public class TestFunctionProvider implements FunctionProvider {
public void execute(Map transientVars, Map args, PropertySet ps) {
WorkflowEntry entry = (WorkflowEntry) transientVars.get("entry");
String entryId = entry.getId();
String stepId = (String) args.get("stepId");
String type = (String) args.get("type");
String value = (String) args.get("value");
// 執行 SQL 寫入 workitem 表
transientVars.put("caller", context.getCaller());
}
}
透過查詢 workitem 表即可取得待辦工作項列表。