如前面的請假流程,員工只是請假,但是假有分很多種,事假、病假、婚假、年假…,在workflow中如何區分呢? 我們可以傳值到流程中,並儲存在資料庫中供以後判斷!

  • 程式
        leave.xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE workflow PUBLIC "-//OpenSymphony Group//DTD OSWorkflow 2.7//EN" 
    "http://www.opensymphony.com/osworkflow/workflow_2_7.dtd">
    <workflow>
      <initial-actions>
       <action id="0" name="開始">
          <pre-functions>
     	<function type="class">
     	  <arg name="class.name">com.opensymphony.workflow.util.Caller</arg>
        	</function>
            <function type="beanshell">
               <arg name="script">
                 propertySet.setString("type", transientVars.get("type"));
               </arg>
            </function>
          </pre-functions>
          <results>
            <unconditional-result old-status="Finished" status="Queued" 
    step="1" owner="${caller}" />
          </results>
          <post-functions>
                <function type="class">
                  <arg name="class.name">
                  	tw.idv.idealist.OutputPropertySet
                  </arg>
                  <arg name="author">Steven Shi</arg>
                </function>
          </post-functions>
        </action>
      </initial-actions>
    
      <steps>
        <step id="1" name="填假單">
          <actions>
            <action id="1" name="送出">
              <restrict-to>
                <conditions>
                  <condition type="class">
                    <arg name="class.name">
                      com.opensymphony.workflow.util.AllowOwnerOnlyCondition
                    </arg>
                  </condition>
                </conditions>
              </restrict-to>
              <pre-functions>
    	    <function type="class">
    	      <arg name="class.name">com.opensymphony.workflow.util.Caller</arg>
    	    </function>
              </pre-functions>
              <results>
                <unconditional-result old-status="Finished" status="Queued" 
    step="2"  owner="${caller}" />
              </results>
            </action>
          </actions>
        </step>
    
        <step id="2" name="批假單">
          <actions>
            <action id="2" name="准許">
              <pre-functions>
    	    <function type="class">
    	      <arg name="class.name">com.opensymphony.workflow.util.Caller</arg>
    	    </function>
    	  </pre-functions>
              <results>
                <unconditional-result old-status="Finished" status="Queued" 
    step="3"  owner="${caller}"/>
              </results>
            </action>
    
            <action id="3" name="駁回">
    	  <pre-functions>
    	    <function type="class">
    	      <arg name="class.name">com.opensymphony.workflow.util.Caller</arg>
    	    </function>
              </pre-functions>
              <results>
                <unconditional-result old-status="Finished" status="Queued" 
    step="1"  owner="${caller}"/>
              </results>
            </action>
          </actions>      
        </step>
    
        <step id="3" name="停止" />
      </steps>
    </workflow>
        leave.jsp
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    
    <HTML>
    <HEAD>
    <%@ page language="java" contentType="text/html; charset=BIG5" pageEncoding="BIG5" %>
    <%@ page import="tw.idv.idealist.*" %>
    
    <META http-equiv="Content-Type" content="text/html; charset=BIG5">
    <META http-equiv="Content-Style-Type" content="text/css">
    <TITLE>填寫假單</TITLE>
    <Script Language="JavaScript">
    function DoAction(type) {
    	document.myForm.type.value = type;
    	document.myForm.submit();
    }
    </Script>
    </HEAD>
    <BODY>
    <P>員工請假</P>
    
    <form name="myForm" action="LeaveAction">
    	<input type="hidden" name="type" value="">
    	員工代號: <input type="text" name="employee"><br>
    <input type="button" value="事假" OnClick="DoAction(1)">
    &nbsp;<input type="button" value="病假" OnClick="DoAction(2)">
    </form>
    
    </BODY>
    </HTML>
        Leave.java
    package tw.idv.idealist;
    
    import java.util.HashMap;
    import com.opensymphony.workflow.*;
    import com.opensymphony.workflow.basic.BasicWorkflow;
    import com.opensymphony.workflow.config.DefaultConfiguration;
    import com.opensymphony.workflow.spi.Step;
    
    /**
     * 請假流程
     * @author steven
     */
    public class Leave {
    	/**
    	 * 啟動流程
    	 * @param employee 員工編號
    	 * @param type 假別
    	 * @return 工作流編號
    	 */
    	public long start(String employee, String type) {
    		Workflow workflow = new BasicWorkflow(employee);
    		DefaultConfiguration config = new DefaultConfiguration();
    		workflow.setConfiguration(config);
    		long workflowId = -1;
    		try {
    			HashMap map = new HashMap();
    			map.put("type", type);
    			//leave是workflowx.xml中定的名稱
    			workflowId = workflow.initialize("leave", 0, map); 
    		} catch (InvalidActionException e) {
    			e.printStackTrace();
    		} catch (InvalidRoleException e) {
    			e.printStackTrace();
    		} catch (InvalidInputException e) {
    			e.printStackTrace();
    		} catch (InvalidEntryStateException e) {
    			e.printStackTrace();
    		} catch (WorkflowException e) {
    			e.printStackTrace();
    		}
    		
    		return workflowId;
    	}
    	
    	/**
    	 * 送出假單
    	 * @param workflowId 工作流編號
    	 * @param employee 員工編號
    	 */
    	public void send(long workflowId, String employee) {
    		Workflow workflow = new BasicWorkflow(employee);
    		DefaultConfiguration config = new DefaultConfiguration();
    		workflow.setConfiguration(config);
    		try {
    			workflow.doAction(workflowId, 1, null);
    		} catch (InvalidActionException e) {
    			e.printStackTrace();
    		} catch (InvalidRoleException e) {
    			e.printStackTrace();
    		} catch (InvalidInputException e) {
    			e.printStackTrace();
    		} catch (InvalidEntryStateException e) {
    			e.printStackTrace();
    		} catch (WorkflowException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 准假假單
    	 * @param workflowId 工作流編號
    	 * @param actionId 動作編號, 2 准許, 3 駁回
    	 */
    	public void allow(long workflowId, int actionId) {
    		Workflow workflow = new BasicWorkflow("manager1");
    		DefaultConfiguration config = new DefaultConfiguration();
    		workflow.setConfiguration(config);
    		try {
    			workflow.doAction(workflowId, actionId, null);
    		} catch (InvalidInputException e) {
    			e.printStackTrace();
    		} catch (WorkflowException e) {
    			e.printStackTrace();
    		}
    		catch (InvalidActionException e) {
    			e.printStackTrace();
    		}
    	}	
    }
        LeavaAction.java
    package tw.idv.idealist.actions;
    
    import java.io.IOException;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import tw.idv.idealist.Leave;
    
    /**
     * @author Steven
     */
    public class LeaveAction extends HttpServlet {
    
    	public void doGet(HttpServletRequest req, HttpServletResponse resp)
    		throws ServletException, IOException {
    		doPost(req, resp);
    	}
    
    	public void doPost(HttpServletRequest req, HttpServletResponse resp)
    		throws ServletException, IOException {
    		Leave leave = new Leave();
    		String employee = req.getParameter("employee");
    		String type = req.getParameter("type");
    		long workflowId = leave.start(employee, type);
    		leave.send(workflowId, employee);
    		resp.sendRedirect("allow.jsp?workflowId=" + workflowId);
    	}
    
    }
        OutputPropertySet.java
    package tw.idv.idealist;
    
    import java.util.Map;
    
    import com.opensymphony.module.propertyset.PropertySet;
    import com.opensymphony.workflow.FunctionProvider;
    import com.opensymphony.workflow.WorkflowException;
    
    /**
     * @author steven
     */
    public class OutputPropertySet implements FunctionProvider {
    	public void execute(Map transientVars, Map args, PropertySet ps) 
              throws WorkflowException {
    		if (ps.getString("type").equals("1")) {
    			System.out.println("事假");
    		}
    		else if (ps.getString("type").equals("2")) {
    			System.out.println("病假");
    		}
    		System.out.println("author => " + args.get("author"));
    	}
    }
    
  • 測試
    注意觀察console輸出和資料庫,OutputPropertySet會輸出如下值到console。
    病假
    author => Steven Shi
    
    資料庫Table OS_PROPERTYENTRY則出現如下的值,可以看到假別已存入資料庫。