Terry.Li-彬

          虛其心,可解天下之問;專其心,可治天下之學;靜其心,可悟天下之理;恒其心,可成天下之業。

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            143 隨筆 :: 344 文章 :: 130 評論 :: 0 Trackbacks
           

          一個JBPM工作流管理示例

          一個JBPM工作流管理示例

          示例:
          在某一公司中,部門員工要休假的話需要部門主管的批準。如果休假天數大于10天的話,在部門主管的同意后,還必須上級主管批準。如果是部門主管要休假只要上級主管批準即可。在休假被批準之前,申請人可以撤銷休假申請。
          每個員工還有多少天休假必須管理起來,在員工提交休假申請時要檢查申請天數是否超過可用天數。申請批準后,要在可用天數里減去申請天數。每次休假申請結束之后,不管通過未通過或是否取消,都必須記錄下來。主管在批復申請之后,系統要將批復結果Email給申請人。對于大于10天的申請,如果部門主管已批準同意而上級主管還未批準,這時申請人撤銷申請后,系統應發Email通知部門主管申請已撤銷。 
            processdefinition.xml如下:
          <?xml version="1.0" encoding="UTF-8"?>
          <!-- edited with XMLSPY v2004 rel. 3 U (http://www.xmlspy.com) by keller (zju) -->
          <!DOCTYPE process-definition PUBLIC
              "-//jBpm/jBpm Mapping DTD 2.0//EN"
              "http://jbpm.org/dtd/processdefinition-2.0.dtd">
          <process-definition  name="RequestLeave">
           <swimlane name="requester">
            <description>
          申請者</description>
           </swimlane>
           <swimlane name="chief">
            <description>部門主管</description>
            <delegation class="kellerdu.jbpm.delegation.ChiefSwimlane"/>
           </swimlane>
           <swimlane name="boss">
            <description>上級主管</description>
            <delegation class="kellerdu.jbpm.delegation.BossSwimlane"/>
           </swimlane>
           <start-state name="request" swimlane="requester">
            <transition to="BeginRequest"/>
           </start-state>
           <fork name="BeginRequest">
            <transition to="RequesterCancel"/>
            <transition to="IsChief"/>
           </fork>
           <decision name="IsChief">
            <delegation class="kellerdu.jbpm.delegation.ChiefDecision"/>
            <transition name="BossApprove"  to="BossApprove"/>
            <transition name="ChiefApprove"  to="ChiefApprove"/>
           </decision>
           <state name="RequesterCancel">
            <assignment swimlane="requester"/>
            <transition name="cancel" to="Decided">
             <action>
              <!-- 將請假的狀態改變為“取消”-->
              <delegation class="kellerdu.jbpm.action.RequestCancel"/>
             </action>
            </transition>
           </state>
           <state name="ChiefApprove">
            <assignment swimlane="chief"/>
            <transition name="approve" to="NeedBossApprove">
             <action>
              <!-- 將請假的狀態改變為“主管批準”-->
              <delegation class="kellerdu.jbpm.action.ChiefApprove"/>
             </action>
            </transition>
            <transition name="disapprove" to="Decided">
             <action>
              <!-- 將請假的狀態改變為“主管否決”-->
              <delegation class="kellerdu.jbpm.action.ChiefDisapprove"/>
             </action>
            </transition>
           </state>
           <state name="BossApprove">
            <assignment swimlane="boss"/>
            <transition name="approve" to="Decided">
             <action>
              <!-- 將請假的狀態改變為“老板批準”-->
              <delegation class="kellerdu.jbpm.action.BossApprove"/>
             </action>
            </transition>
            <transition name="disapprove" to="Decided">
             <action>
              <!-- 將請假的狀態改變為“老板否決”-->
              <delegation class="kellerdu.jbpm.action.BossDisapprove"/>
             </action>
            </transition>
           </state>
           <decision name="NeedBossApprove">
            <!-- 請假天數大于10天的要老板批準  -->
            <delegation class="kellerdu.jbpm.delegation.NeedBossApproveDecision"/>
            <transition name="need" to="BossApprove"/>
            <transition name="notNeed" to="Decided"/>
           </decision>
           <join name="Decided">
            <description>有一個先到達即進行父Token</description>
            <delegation class="kellerdu.jbpm.delegation.DecidedJoin"/>
            <transition to="DoSomething"/>
           </join>
           <decision name="DoSomething">
            <description>
              根據請求的狀態決定。
              (1)“主管或者老板批準”-‘approve’:修改員工休假的總天數,設定發給用戶E-Mail的信息。
              (2)“主管或者老板否決”-“disapprove”:設定發給用戶E-Mail的信息。
              (3)“撤銷”-"cancel"-設定發給用戶E-Mail的信息。如果主管批準,要發給主管消息說明已經撤銷。
              </description>
            <delegation class="kellerdu.jbpm.delegation.DoSomethingDecision"/>
            <transition name="disapprove" to="Finished">
             <action>
              <delegation class="kellerdu.jbpm.action.Disapprove"/>
             </action>
            </transition>
            <transition name="approve" to="Finished">
             <action>
              <delegation class="kellerdu.jbpm.action.Approve"/>
             </action>
            </transition>
            <transition name="cancel" to="Finished">
             <action>
              <delegation class="kellerdu.jbpm.action.Cancel"/>
             </action>
            </transition>
           </decision>
           <end-state name="Finished"/>
           <action event-type="process-end">
            <!-- 發送E-Mail消息給申請者,記錄請假日志 -->
            <delegation class="kellerdu.jbpm.action.ProcessEndAction"/>
           </action>
          </process-definition>

          Action指明的是當前狀態要執行的一些額外的操作,如記錄log、發郵件等。
          (1)Swimline的delegation要做的就是判別當前Actor的身份。
          package kellerdu.jbpm.delegation;

          import org.jbpm.delegation.*;
          import kellerdu.jbpm.LogsFactory;
          import org.apache.commons.logging.Log;

          public class BossSwimlane implements AssignmentHandler {
              public BossSwimlane() {
              }

              /**
               *
          當前的狀態有哪個actor來具體負責處理,選擇是老板的actor來處理。
               *
               * 如果王林是老板,那么他請假可以用他的名稱來開始一個請假流程,當他檢查他需要批示的
               * 請假時,使用actorId=boss來找出所有的批示。這時selectActor返回的值就是一個常量“boss”
               *
               *
               * @param assignmentContext AssignmentContext
               * @return String
               * @todo Implement this org.jbpm.delegation.AssignmentHandler method
               */
              public String selectActor(AssignmentContext assignmentContext) {
                  Log log = LogsFactory.getLogInstance(this.getClass());
                  log.info("任務分配給老板");
                  return "boss";
              }
          }
          ========================================
          ackage kellerdu.jbpm.delegation;

          import org.jbpm.delegation.*;
          import kellerdu.jbpm.LogsFactory;
          import org.apache.commons.logging.Log;

          public class ChiefSwimlane implements AssignmentHandler {
              public ChiefSwimlane() {
              }

              /**
               * selectActor
               * @see BossSwimlane
               *
               * @param assignmentContext AssignmentContext
               * @return String
               * @todo Implement this org.jbpm.delegation.AssignmentHandler method
               */
              public String selectActor(AssignmentContext assignmentContext) {
                 Log log = LogsFactory.getLogInstance(this.getClass());
                  log.info("
          任務分配給上級主管");
                 return "chief";
              }
          }

          (二)Decision
          package kellerdu.jbpm.delegation;

          import org.jbpm.delegation.*;
          import kellerdu.jbpm.LogsFactory;
          import org.apache.commons.logging.Log;
          import kellerdu.jbpm.Constants;

          public class ChiefDecision implements DecisionHandler {
              public ChiefDecision() {
              }

              /**
               *
          判斷是否需要主管批準,決定下一個要進行的transition
               *
               * @param executionContext ExecutionContext
               * @return String
               * @todo Implement this org.jbpm.delegation.DecisionHandler method
               */
              public String decide(ExecutionContext executionContext) {
                  Log log=LogsFactory.getLogInstance(this.getClass());
                  String ac=(String)executionContext.getVariable(Constants.USER_NAME);
                  if(ac!=null&&(ac.equals("dali")||ac.equals("wang"))){
                      log.info(ac+"需要老板批準!");
                      return "BossApprove";
                  }else{
                      log.info(ac+"需要先經主管批準");
                      return "ChiefApprove";
                  }
              }
          }
          =======================
          (三)fork
          package kellerdu.jbpm.delegation;

          import org.jbpm.*;
          import org.jbpm.delegation.*;
          import org.jbpm.model.execution.*;
          import java.util.*;

          public class DecidedJoin implements JoinHandler {
              public DecidedJoin() {
              }

              /**
               * fork
          ,只要一個分支到達,即可進行下一步操作,同時取消其它同時進行的分支。
               * 這里就是用戶如果取消,請假就取消。如果用戶請假批準,則用戶不能取消。
               *
               * @param forkContext ForkContext
               * @throws ExecutionException
               * @todo Implement this org.jbpm.delegation.ForkHandler method
               */
              public void join(JoinContext joinContext) throws ExecutionException {
                  Iterator it=joinContext.getConcurrentTokens().values().iterator();
                  Token arrivingToken = joinContext.getToken();
                  while(it.hasNext()){
                      Token to=(Token)it.next();
                      if(to.getId().equals(arrivingToken.getId())){
                          //取消其它執行的Token
                          joinContext.getExecutionService().cancelToken(to.getId());
                      }
                  }
                   // reactivate the parent token.
                    joinContext.reactivateToken( arrivingToken.getParent() );
              }
          }

          (一) 開始一個請假流程
                 //user是請假人的actorId
                 ExecutionService es=JbpmServiceFactory.getInstance().openExecutionService(user);
                  HashMap vs=new HashMap();
                 //一些參數
                  vs.put(Constants.REQUEST_STATUS,String.valueOf(0));
                  vs.put(Constants.REQUEST_RETURN_INFO,"No info!");
                  vs.put(Constants.USER_NAME,EncodeTransfer.toISO(user));
                  vs.put(Constants.REQUEST_DAYS,String.valueOf(rea.getDays()));
                  try {
                     //開啟請假流程
                      es.startProcessInstance(Constants.WORK_NAME, vs);
                      log.info("["+user+"]"+"申請假期開始!請假"+rea.getDays()+"天!");
                      return am.findForward("main");
                  } catch (ExecutionException ex) {
                      ex.printStackTrace();
                      log.error("請假進程無法開始!");
                      return am.findForward("error");
                  }finally{
                      es.close();
                  }
          (二)當前執行任務
              對于部門經理或者老板,找到要處理的請假。
                 String actorId = (String) req.getSession().getAttribute(Constants.USER);
                      if(actorId.equals("wang")){
                          actorId="boss";
                      }else if(actorId.equals("bigli")){
                          actorId="chief";
                      }
                      // get the execution service
                      ExecutionService executionService = JbpmServiceFactory.getInstance().
                                                          openExecutionService(actorId);

                      // get the tasklist from jbpm for user
                      List tasks = new ArrayList();
                      // add the jbpm tasks
                      tasks.addAll(executionService.getTaskList(actorId));
                      // put the tasklist into the form
                      mf.setTasks(tasks);
                      // get the tasklist from jbpm for user
                      List definitions = new ArrayList();
                      // add the jbpm definitions
                      definitions.addAll(executionService.getLatestDefinitions());
                      // put the tasklist into the form
                      mf.setRequests(definitions);
                      // close the execution service
                      executionService.close();
                      req.getSession().setAttribute("mainForm",mf);
                      log.debug("
          任務: " + tasks);
                      log.debug("當前可以執行的請求: " + definitions);
          (三)處理請假
                     String actorId = (String) reqrest.getSession().getAttribute(Constants.
                              USER);
                      Long tokenId=new Long(req.getParameter("tokenId"));
                      // get the execution service
                      ExecutionService executionService = JbpmServiceFactory.getInstance().
                                                          openExecutionService(actorId);
                      Map hm=executionService.getVariables(tokenId);//變量
                      String act=req.getParameter("action");//進行轉換的transition
                      executionService.endOfState(tokenId,hm,act);
                      executionService.close();

          v
          posted on 2007-09-06 18:13 禮物 閱讀(680) 評論(0)  編輯  收藏 所屬分類: Jbpm
          主站蜘蛛池模板: 贵溪市| 宜宾县| 会同县| 霍州市| 聂荣县| 吉隆县| 合作市| 高州市| 钟祥市| 巫山县| 托里县| 涡阳县| 罗源县| 常德市| 阿鲁科尔沁旗| 罗平县| 寻甸| 汉源县| 民乐县| 阳江市| 正蓝旗| 汉阴县| 黑水县| 灌云县| 疏附县| 紫阳县| 荥阳市| 宣武区| 冷水江市| 响水县| 防城港市| 佛山市| 班玛县| 涟水县| 荣成市| 武宣县| 辉县市| 宜良县| 惠安县| 建始县| 湖南省|