天天看點

jBPM Developers Guide(jBPM開發指南)--Chapter 3. BPMN 2.0(第六部分)

3.9. Complete example (including console task forms)( 完整示例(包括控制台任務表單))

    Prerequisites: to run the example, we assume that a working jBPM console has been installed on your JBoss server. If not, please run the 'demo.setup.jboss' install script first.

    前提條件:為了運作該示例,我們假設你已經在JBoss server中安裝了jBPM控制台。如果沒有,請先執行'demo.setup.jboss'安裝腳本。

    The business process we're implementing looks as follows:

    我們實作的業務流程如下:

jBPM Developers Guide(jBPM開發指南)--Chapter 3. BPMN 2.0(第六部分)

   You might recognize this example, since we’ve also implemented it in JPDL as an example in our distribution.

    你可能已經看過這個例子了,因為我們也在釋出包中的示例中使用jPDL實作過它了。

    The business process is simple: an employee can start a new process and make a request for a certain amount of vacation days. After the request task has been completed, the manager will find a verification task in its tasklist. The Manager can now decide to accept or reject this request. Depending on the outcome (that’s the little rhombus on the outgoing sequence flow - it means there is a conditional expression on the sequence flow), a rejection message is send or the process ends. Do note that in fact we've used a shortcut here: instead of putting expressions on the outgoing sequence flow of the 'verify request' task, we've could have used an exclusive gateway after the user task to control the flow through the process. Also note that since we haven't implemented swimlanes yet (probably the next release), it's difficult to actually see who does what in the business process.

    業務流程很簡單:一個員工可以啟動一個新流程,申請一定時間的假期。在請求任務完成之後,經理會在任務清單中看到該稽核任務。經理可以決定準許或駁回這個申請。根據outcome(那是外出順序流上的小菱形 - 這意味着在順序流上有條件表達式),會發送一個駁回資訊或者流程結束。注意,實際上我們也可以不在'verify request'任務的外出順序流上設定表達式,而是在使用者任務之後使用一個唯一網關來控制流程的流向。也要注意,因為我們還沒有實作泳道(可能在下一個版本會實作),是以很難看到誰在業務流程中。

    The XML version of this process looks as follows:

    流程的XML版本看起來像下面這樣:

<process id="vacationRequestProcess" name="BPMN2 Example process using task forms">

    <startEvent id="start" />

    <sequenceFlow id="flow1" name="fromStartToRequestVacation"
      sourceRef="start" targetRef="requestVacation" />

    <userTask id="requestVacation" name="Request Vacation"
      implementation="other">
     <potentialOwner resourceRef="user" jbpm:type="group">
        <resourceAssignmentExpression>
          <formalExpression>user</formalExpression>
        </resourceAssignmentExpression>
      </potentialOwner>
      <rendering id="requestForm">
        <jbpm:form>org/jbpm/examples/bpmn/usertask/taskform/request_vacation.ftl</jbpm:form>
      </rendering>
    </userTask>

    <sequenceFlow id="flow2"
      name="fromRequestVacationToVerifyRequest" sourceRef="requestVacation"
      targetRef="verifyRequest" />

    <userTask id="verifyRequest" name="Verify Request"
      implementation="other">
      <potentialOwner resourceRef="user" jbpm:type="group">
        <resourceAssignmentExpression>
          <formalExpression>manager</formalExpression>
        </resourceAssignmentExpression>
      </potentialOwner>
      <rendering id="verifyForm">
        <jbpm:form>org/jbpm/examples/bpmn/usertask/taskform/verify_request.ftl</jbpm:form>
      </rendering>
    </userTask>

    <sequenceFlow id="flow3" name="fromVerifyRequestToEnd"
      sourceRef="verifyRequest" targetRef="theEnd">
      <conditionExpression xsi:type="tFormalExpression">
        ${verificationResult == 'OK'}
      </conditionExpression>
    </sequenceFlow>

    <sequenceFlow id="flow4"
      name="fromVerifyRequestToSendRejectionMessage" sourceRef="verifyRequest"
      targetRef="sendRejectionMessage">
      <conditionExpression xsi:type="tFormalExpression">
        ${verificationResult == 'Not OK'}
      </conditionExpression>
    </sequenceFlow>

    <scriptTask id="sendRejectionMessage" name="Send rejection Message"
      scriptLanguage="bsh">
      <script>
        <![CDATA[System.out.println("Vacation request refused!");]]>
      </script>
    </scriptTask>

    <sequenceFlow id="flow5"
      name="fromSendRejectionMessageToEnd" sourceRef="sendRejectionMessage"
      targetRef="theEnd" />

    <endEvent id="theEnd" name="End" />
</process>
      

    Note: this example is already installed when you've used the demo setup. Also note that we're using a Script Task here, to quickly write something as output instead of sending a real message (the diagram is showing a Service Task). Also note that we've taken some shortcuts here regarding task assignment (will be fixed in the next release).

    注意:當你在安裝demo時該示例也就已經安裝了。也要注意,我們這裡使用了腳本任務(圖形顯示中的service task),為了快速體驗,我們采用了控制台輸出,而不是真正的發送資訊。也要注意,我們這裡在任務配置設定中也做了一些簡化(會在下一個版本進行修複)。

    The constructs used in this implementation are all covered in the previous section. Also note that we're using the taskform functionality here, which is a custom jBPM extension for the rendering element of a User task.

    在這個示例中的結構覆寫了之前章節中的所有内容。也要注意我們這裡使用了一個任務表單功能,這是jBPM一個自定義擴充,可以為使用者任務渲染元素。

<userTask id="verifyRequest" name="Verify Request"
       implementation="other">
  <potentialOwner resourceRef="user" jbpm:type="group">
    <resourceAssignmentExpression>
      <formalExpression>user</formalExpression>
    </resourceAssignmentExpression>
  </potentialOwner>
  <rendering id="verifyForm">
    <jbpm:form>org/jbpm/examples/bpmn/usertask/taskform/verify_request.ftl</jbpm:form>
  </rendering>
</userTask>
      

     The mechanism regarding task forms for BPMN 2.0 is complete equivalent to that of JPDL. The form itself is a Freemarker template file that needs to be incorporated in the deployment. For example, the 'verify_request.ftl' form looks like as follows.

    BPMN 2.0裡任務表單的機制與jPDL裡完全一樣。表單自身是一個Freemarker模闆檔案,需要放在釋出中。比如,'verify_request.ftl'表單看起來像下面這樣:

<html>
  <body>

    <form action="${form.action}" method="POST" enctype="multipart/form-data">
    
      <h3>Your employee, ${employee_name} would like to go on vacation</h3>
      Number of days: ${number_of_days}<br/>
      
      <hr>
      
      In case you reject, please provide a reason:<br/>
      <input type="textarea" name="reason"/><br/>
     
      <input type="submit" name="verificationResult" value="OK">
      <input type="submit" name="verificationResult" value="Not OK">
      
    </form>
  </body>
</html> 
           

     Note that process variables can be accessed using the ${my_process_variable} construct. Also note that named input controls (eg. input field, submit button) can be used to define new process variables. For example, the text input of the following field will be stored as the process variable 'reason'

    注意,流程變量可以使用 ${my_process_variable}來通路。也要注意對輸入控件進行命名(比如,文本輸入框,送出按鈕),名稱用來 定義新流程變量。 比如,下面的文本輸入會被儲存為流程變量'reason'。

<input type="textarea" name="reason"/>           

     Note that there are two submit buttons (which makes sense if you look at the 'OK' and 'Not OK' sequence flows going out the 'request vacation' task. By pressing one of these buttons, the process variable 'verificationResult' will be stored. It can then be used to evaluate the outgoing sequence flow:

    注意這裡有兩個送出按鈕(這是當然的,因為'request vacation'任務裡有兩個外出順序流'OK'和'Not OK')。通過點選其中一個按鈕,流程變量'verificationResult'會被儲存起來。它可以用來執行外出的順序流:

<sequenceFlow id="flow3" name="fromVerifyRequestToEnd"
      sourceRef="verifyRequest" targetRef="theEnd">
  <conditionExpression xsi:type="tFormalExpression">
    ${verificationResult == 'OK'}
  </conditionExpression>
</sequenceFlow>
      

     The process can now be deployed. You can use the ant deploy task for this (see examples), or you can point your jBPM configuration to the database of the console. To deploy your process programmatically, you need to add the task forms to your deployment:

    流程現在可以釋出了。你可以使用ant的釋出任務來做這些事情(參考示例),或者你可以指定你的jBPM配置到控制台的資料庫。為了用程式設計的方式釋出你的流程,你需要把任務表單添加到你的釋出中:

NewDeployment deployment = repositoryService.createDeployment();
deployment.addResourceFromClasspath("org/jbpm/examples/bpmn/usertask/taskform/vacationrequest.bpmn.xml");
deployment.addResourceFromClasspath("org/jbpm/examples/bpmn/usertask/taskform/request_vacation.ftl");
deployment.addResourceFromClasspath("org/jbpm/examples/bpmn/usertask/taskform/verify_request.ftl");
deployment.deploy();
           

     You can now embed (or run on a standalone server) this business process, by using the familiar jBPM API operations. For example, process instances can now be started using the key (ie. the process id for BPMN 2.0):

    通過調用熟悉的jBPM API操作你現在可以嵌入(或在單獨的伺服器中)這個業務流程。比如,流程執行個體現在可以使用 key來啟動(比如,BPMN 2.0的流程id):

ProcessInstance pi = executionService.startProcessInstanceByKey("vacationRequestProcess");           

     Or tasks list can be retrieved:

    任務清單可以這樣獲得:

Task requestTasktask = taskService.createTaskQuery().candidate("peter").uniqueResult();           

     When deploying to the jBPM console database, you should see our new business process popping up.

    當在jBPM控制器資料庫部署後,你應該看到我們的新業務流程了。

jBPM Developers Guide(jBPM開發指南)--Chapter 3. BPMN 2.0(第六部分)

   After you start a new process, a new task should be available in the employee's tasklist. When clicking on 'view', the task form will be displayed, requesting to fill in some variables for further use in the process.

    在你啟動一個新流程後,一個新任務應該在員工的任務清單中了。 當點選'view'以後,任務表單會被顯示出來, 在這裡填寫了會在流程中使用的變量。

jBPM Developers Guide(jBPM開發指南)--Chapter 3. BPMN 2.0(第六部分)

    After task completion, the manager will find a new verification task in his task list. He can now accept or reject the vacation request, based on the input of the employee.

    在任務結束之後,經理會在他的任務清單中看到新的稽核任務。他現在可以基于員工的輸入同意或駁回該請假申請。

jBPM Developers Guide(jBPM開發指南)--Chapter 3. BPMN 2.0(第六部分)

    Since the database schema remains unchanged when we added BPMN 2.0 on top of the jBPM PVM, all existing reports can be applied to our new BPMN 2.0 processes.

    因為資料庫表結構沒有變化,我們隻是在jBPM PVM上面添加了BPMN 2.0,是以所有已存的報表都可以用于我們的新BPMN 2.0流程中。

jBPM Developers Guide(jBPM開發指南)--Chapter 3. BPMN 2.0(第六部分)