OSWorkflow的第二支程式


這裡將介紹如何在流程裡加上限制,首先修改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> 
 
      </pre-functions> 
 
      <results> 
 
        <unconditional-result old-status="Finished" status="Queued" 
 
step="1" owner="${caller}" /> 
 
      </results> 
 
    </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.java及LeaveAction.java,讓啟動流程的人和送出假單的人可以不同。
    Leave.java

package tw.idv.idealist; 
 

import com.opensymphony.workflow.InvalidActionException; 
 
import com.opensymphony.workflow.InvalidEntryStateException; 
 
import com.opensymphony.workflow.InvalidInputException; 
 
import com.opensymphony.workflow.InvalidRoleException; 
 
import com.opensymphony.workflow.Workflow; 
 
import com.opensymphony.workflow.WorkflowException; 
 
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 員工編號 
 
* @return 工作流編號 
 
*/ 
 
public long start(String employee) { 
 
Workflow workflow = new BasicWorkflow(employee); 
 
DefaultConfiguration config = new DefaultConfiguration(); 
 
workflow.setConfiguration(config); 
 
long workflowId = -1; 
 
try { 
 
//leave是workflowx.xml中定的名稱 
 
workflowId = workflow.initialize("leave", 0, 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(); 
 
} 
 

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(); 
 
} 
 
} 
 
} 
 
    LeaveAction.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"); 
 
long workflowId = leave.start(employee); 
 
leave.send(workflowId, "someone"); // <<== 非啟動流程的人送出假單 
 
resp.sendRedirect("allow.jsp?workflowId=" + workflowId); 
 
} 
 

} 
 
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"); 
 
long workflowId = leave.start(employee); 
 
leave.send(workflowId, "someone"); // <<== 非啟動流程的人送出假單 
 
resp.sendRedirect("allow.jsp?workflowId=" + workflowId); 
 
} 
 

}


啟動Tomcat,並執行leave.jsp後,會出現如下exception,確實OSWorkflow偵測到啟動流程的人和送出假單的人不同。

com.opensymphony.workflow.InvalidActionException: Action 1 is invalid 
 
at com.opensymphony.workflow.AbstractWorkflow.doAction(AbstractWorkflow.java:546) 
 
at tw.idv.idealist.Leave.send(Leave.java:56) 
 
at tw.idv.idealist.actions.LeaveAction.doPost(LeaveAction.java:25) 
 
at tw.idv.idealist.actions.LeaveAction.doGet(LeaveAction.java:17) 
 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740) 
 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853) 
 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:247) 
 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193) 
 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:256) 
 
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643) 
 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) 
 
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) 
 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) 
 
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643) 
 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) 
 
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) 
 
at org.apache.catalina.core.StandardContext.invoke(StandardContext.java:2422) 
 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:180) 
 
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643) 
 
at org.apache.catalina.valves.ErrorDispatcherValve.invoke(ErrorDispatcherValve.java:171) 
 
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641) 
 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:163) 
 
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:641) 
 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) 
 
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) 
 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:174) 
 
at org.apache.catalina.core.StandardPipeline$StandardPipelineValveContext.invokeNext(StandardPipeline.java:643) 
 
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:480) 
 
at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:995) 
 
at org.apache.coyote.tomcat4.CoyoteAdapter.service(CoyoteAdapter.java:199) 
 
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:828) 
 
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:700) 
 
at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:584) 
 
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683) 
 
at java.lang.Thread.run(Thread.java:534)