程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> OsWorkflow初探

OsWorkflow初探

編輯:關於JAVA

OSWorkflow的主配置文件為:osworkflow.xml

<osworkflow>
<persistence class="com.opensymphony.workflow.spi.jdbc.JDBCWorkflowStore">
   <!-- For jdbc persistence, all are required.-->
   <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屬性指定):

1.通過ejb存儲

2.通過jdbc進行存儲

3.內存存儲,主要用於測試

4.通過Hibernate進行存儲

5.通過ofbiz提供的方式進行存儲

6.通過ojb進行存儲

7.通過prelayer進行存儲.

該示例中選擇的是jdbc存儲方式.如果是jdbc存儲,則必須配置工作流相關的表名,和sequence名,采用這樣的配置,開發者完全可以根據自己的需要修改這些表名,和sequence的取值方式.

Osworkflow采用jndi的方式來定位jdbc,請參閱<Tomcat中配置jdbc>一文.

Factory節點主要是工作流定義文件存儲方式的選擇,OSWorkflow支持一下幾種:

1.存儲在數據庫中

2.存儲在XML中

3.存儲在URL中.

4.存儲在資源文件中

該示例是存儲在XML中,XML的名稱為workflows.xml,下面看一下workflows.xml:

<workflows>
<workflow name="example" type="resource" location="example1.xml"/>
<workflow name="example" type="resource" location="example2.xml"/>
</workflows>

這裡定義了兩個工作流定義example1.xml和example2.xml.

和權限系統的整合

流程定義詳細過程,這裡先不列出,這裡的重點是如何與Osworkflow其它的權限系統進行整合.流程定義中每個Action的restrict-to節點都會有condition的定義,如下:

<condition type="class">
        <arg name="class.name">os.TestCondition</arg>
        <arg name="group">foos</arg>
</condition>

其中的os.TestCondition既是我們需要實現的,osworkflow系統實現了一個簡單的權限系統osuser,基於osuser它實現了一套簡單的約束條件.如果想實現自己的工作流參與人的約束條件,必須實現OSWorkflow提供的com.opensymphony.workflow.Condition接口.改接口定義如下:

/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.workflow;
import com.opensymphony.module.propertyset.PropertySet;
import java.util.Map;
/**
* Interface that must be implemented to define a java-based condition in your workflow definition.
*
* @author <a href="mailto:[email protected]">Patrick Lightbody</a>
* @version $Revision: 1.7 $
*/
public interface Condition {
   public boolean passesCondition(Map transientVars, Map args, PropertySet ps) throws WorkflowException;
}

該接口有一個方法需要實現passesCondition,下面對它的幾個參數加以闡述:

1.transientVars :存放了當前流程運轉的所有信息,比如,流程的上下文信息,流程的定義,流程的存儲,在我們的實現裡我們可以得到一下信息:

WorkflowContext context = (WorkflowContext) transientVars.get("context");
   WorkflowEntry entry = (WorkflowEntry) transientVars.get("entry");
WorkflowStore store = (WorkflowStore) transientVars.get("store");
//取得當前登陸操作員
String caller = context.getCaller();

2.args裡存儲了流程定義裡的參數.在該示例裡是:

<arg name="group">foos</arg>

3.是PropertySet對象,記錄了流程實例所需要保存的數據,可以理解成osworkflow所描述的流程相關數據

3.如果我們想該Action必須是group為foos組裡的成員,那麼我們可以這樣實現我們的os.TestCondition.下面是示例代碼:

public class TestCondtion implements Condition {
   //~ Methods ////////////////////////////////////////////////////////////////
   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本身沒有工作項的概念,,但它提供了靈活的機制,使開發者能夠實現自己的工作項,我們可以在steps裡定義一個<pre-functions>來實現這一功能.如果開發自己的function必須實現OSWorkflow提供的接口: com.opensymphony.workflow.FunctionProvider,該接口的定義如下:

package com.opensymphony.workflow;
import com.opensymphony.module.propertyset.PropertySet;
import java.util.Map;
/**
* Interface to be implemented by any class that are to be called from within a workflow as a function,
* either as a pre-function or a post-function.The args nested elements within the function xml call
* will be mapped to the properties parameter.
*
* @author <a href="mailto:[email protected]">Pat Lightbody</a>
* @version $Revision: 1.5 $
*/
public interface FunctionProvider {
   //~ Methods ////////////////////////////////////////////////////////////////
   public void execute(Map transientVars, Map args, PropertySet ps) throws WorkflowException;
}

該接口也只有一個方法,方法的參數同Condition.

我們首先要定義一個workitem表,用來存放我們的工作項列表.這裡列出該表的一些必須的字段.

Create table workitem
(
Id      number, --主鍵
Entry_ID   number, --流程實例ID
Step_ID   number, --step id
Type     char(1), --參與者的類型 0 為某員工,某個角色,某個group,
--某個前step的執行者.
Value  number, -- 參與者的實際值,可以是員工的ID,角色的ID,group的ID
)

在數據庫裡創建該表後,修改我們的流程定義.舉個例子來說:

<step id=”6” name=”approve”>
  <pre_functions>
    <function type=”class”>
    <arg name=”class.name”>os.TestFunctionProvider</args>
    <arg name=”type”>group</arg>
    <arg name=”value”>zte</arg>
    </function>
  </pre_functions>
  <actions>
  …
  <actions>
</step>

下面是我們需要實現的os.TestFunctionProvider偽碼:

public class TestFunctionProvider implements FunctionProvider {
   //~ Methods ////////////////////////////////////////////////////////////////
public void execute(Map transientVars, Map args, PropertySet ps) {
WorkflowEntry entry = (WorkflowEntry) transientVars.get("entry");
//得到流程實例ID
String entry_id = entry.getId ();
//得到當前的stepId
   String stepIdVal = (String) args.get("stepId");
   //得到流程參與者的類型
     String type = (String)args.get (“type”);
     //得到流程參與者的值.
     String value = (String)args.get(“value”);
     //執行sql操作,把相關值存到數據庫的workitem中
     transientVars.put("caller", context.getCaller());
   }
}

通過查詢workitem表,就可以得到工作項了.

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved