Jbpm4經常使用操做

 

Jbpm4 經常使用操做
 
    1、 ProcessEngine :流程引擎。是 JBPM 上層類,至關於 Hibernate SessionFactory 級別。
    // 得到方式:
    ProcessEngine processEngine = Configuration.getProcessEngine();
       /*Configuration 類會讀取 classpath 下的 jbpm.cfg.xml 文件進行流程引擎的加載。 ProcessEngine 是單例模式,即整個系統只會有一個 processEngine 實例。 */
           
 
    2、流程定義
    1. 部署流程定義
       ProcessEngine processEngine = Configuration.getProcessEngine();
       RepositoryService repositoryService = processEngine .getRepositoryService();
    
    例:佈署文件中的流程
       // 佈署當前目錄下 pd.jpdl.xml 文件
       String deploymentId = repositoryService.createDeployment()
                             .addResourceFromClasspath( "process.jpdl.xml" ).deploy();
       /* deploymentId 是發佈的流程返回的 ID */
 
 
    2. 刪除流程定義
       ProcessDefinition 包含以下屬性:
           ID :流程定義 ID
           DeploymentId :流程定義的佈署 ID
           Key :關鍵字
           name :流程名
           version :版本號
     
       數據以下
           ID          Key       名稱       版本
           hello-1     hello     hello     1
 
       // 獲取類 ProcessDefinition 的屬性 ID
       String deploymentId = request.getParameter( "deploymentId" );
       // 根據流程 ID 獲取流程定義實例
       ProcessDefinition pd = repositoryService .createProcessDefinitionQuery()
                              .processDefinitionId( deploymentId ).uniqueResult();
       // 根據流程定義的佈署 ID 號,刪除該流程定義(根據流程定義的 ID 號級聯刪除)
       // 注意 :jbpm4 是不容許直接根據流程定義的 ID 來直接刪除流程定義的,由於還要刪除其它配置數據
       repositoryService.deleteDeploymentCascade(pd.getDeploymentId());
 
    3. 獲取所有流程定義
      根據流程名獲取全部流程定義
       List<ProcessDefinition> processDefinitions = repositoryService
        .createProcessDefinitionQuery().orderAsc( ProcessDefinitionQuery.PROPERTY_NAME).list();
 
    // 還能夠根據如下順序進行排序 (org.jbpm.api.ProcessDefinitionQuery)
    public static final java.lang.String     PROPERTY_DEPLOYMENT_TIMESTAMP      "deployment.timestamp"
    public static final java.lang.String     PROPERTY_ID      "idProperty.stringValue"
    public static final java.lang.String     PROPERTY_KEY      "keyProperty.stringValue"
    public static final java.lang.String     PROPERTY_NAME      "idProperty.objectName"
    public static final java.lang.String     PROPERTY_VERSION     "versionProperty.longValue"
 
    2、流程實例
 
    1. 啓動一個流程實例
    1.1 根據 key 啓動流程實例
       // 用戶必須爲新啓動的流程實例分配一個 key 這個 key 是用戶執行的時候定義的且惟一。一般在業務流程領域找到這種 key 好比,一個訂單 id 或者一個保險單號。
       ProcessInstance processInstance = executionService.startProcessInstanceByKey( "ICL" , "CL92837" );
 
       //key 能夠用來建立流程實例的 id 格式爲 {process-key}.{execution-id} 因此上面的代碼會建立一個 id ICL.CL92837 的流向 execution )。
 
    1.2 根據數據庫主鍵啓動流程實例
       // 若是沒有提供用戶定義的 key ,數據庫就會把主鍵做爲 key 這樣能夠使用以下方式得到 id
       ProcessInstance processInstance =       executionService.startProcessInstanceByKey( "ICL" );
       String pid = processInstance .getId();
       // 最好使用一個用戶定義的 key 。提供給一個用戶定義的 key 你能夠組合流向的 id ,而不是執行一個基於流程變量的搜索 - 那種方式太消耗資源了。
 
    1.3 根據變量啓動流程實例
       // 爲一個新的流程實例啓動時就提供一組對象參數。 將這些參數放在 variables 變量裏, 而後能夠在流程實例建立和啓動時使用。
       Map <String,Object> variables = new HashMap<String,Object>();
       variables.put( "customer" , "John Doe" );
       variables.put( "type" , "Accident" );
       variables.put( "amount" , new Float(763.74));
       ProcessInstance processInstance = executionService.startProcessInstanceByKey( "ICL" , variables);
       //
       //JBPM4.4 支持變量歷史
       // 變量能夠被標記爲做爲歷史記錄保存。這意味着,當流程實例結束, 它的運行階段的信息被刪除,歷史細節依然會被保存。
       // 經過公共 API ExecutionService 啓用變量的歷史功能
       void createVariable(String executionId, String name, Object value, boolean historyEnabled);
       void createVariables(String executionId, Map<String, ?> variables, boolean historyEnabled);
       // 經過變量定義
       <variable name= "declaredVar" type= "string" init-expr= "testing declared variable" history= "true" />
 
    2. 根據流程定義,查看流程實例
       // 根據類 ProcessDefinition 的屬性 ID ,查看該流程的全部實例
       String processDefinitionId = request.getParameter( "processDefinitionId" );
       return executionService.createProcessInstanceQuery().processDefinitionId(processDefinitionId).list();
 
    3. 執行實例
       // 根據類 ProcessInstance 的屬性 ID( 流程實例 ID) ,執行流程實例
       String processInstanceId = request.getParameter( "processInstanceId" );
       executionService.signalExecutionById(processInstanceId);
 
    . 任務
    // 假設流程定義 4-1 以下:
    <process name= "TaskAssignee" >
       <start>
          <transition to= "review" />
       </start>
       <task name= "review" assignee= "#{order.owner}" >
          <transition to= "work" />
       </task>
       <task name= "review" assignee= "de style=" color: rgb(255, 102, 0); ">johndoede>" >
          <transition to= "wait" />
       </task>
       <state name= "wait" />
    </process>
 
    assignee= "johndoe"
       // 表示任務會被分配給用戶 ID "johndoe" 的人。
    assignee= "#{order.owner}"
       // 任務被分配給 #{order.owner} 。表示經過 Order 對的 getOwner() 方法會用來得到用戶 id ,該用戶負責完成這個任務。
    public class Order implements Serializable {
       String owner;  public Order(String owner) {
          this .owner = owner;
       }
       public String getOwner() {
          return owner;
       }
       public void setOwner(String owner) {
          this .owner = owner;
       }
    }
 
    1. 獲取任務列表
    1.1 根據用戶 ID 獲取任務列表
       List<Task> taskList = taskService.findPersonalTasks( "johndoe" );
 
    1.2 根據任務候選人或候選組獲取任務列表
       任務可能被分配給一組用戶。 其中的一個用戶應該接受這個任務並完成它。
       candidate-groups :一個使用逗號分隔的組 id 列表。 全部組內的用戶將會成爲這個任務的候選人。
       candidate-users :一個使用逗號分隔的用戶 id 列表。 全部的用戶將會成爲這個任務的候選人。
       例如:
       <task name= "review" candidate-groups= "sales-dept" >
          <transition to= "wait" />
       </task>
       假設: sales-dept 有兩個成員: johndoe joesmoe
 
       // 這個任務被建立時,不顯示在任何人的我的任務列表中。 下面的任務列表會是空的。
       taskService.getAssignedTasks( "johndoe" );
       taskService.getAssignedTasks( "joesmoe" );
 
       分組任務列表中,用戶接口必須只接受對這些任務的 接受 操做。
       taskService.takeTask(task.getDbid(), "johndoe" );
       當一個用戶接受了一個任務,這個任務的分配人就會變成當前用戶。任務會從全部候選人的分組任務列表中消失,它會出如今用戶的已分配列表中。
 
    1.3 在一個列表中顯示該某人的全部任務
       包括他的我的任務,候選任務,這時直接用 jbpm4 提供的 api 完成不了該功能要求。因而能夠使用如下方式進行擴展:
        /**
             * 取得用戶的對應的任務列表
             * @param userId
             * @return
             */
            public List<TaskImpl> getTasksByUserId(String userId){
                AppUser user=(AppUser)getHibernateTemplate().load(AppUser. class , new Long(userId));
                Iterator<AppRole> rolesIt=user.getRoles().iterator();
                StringBuffer groupIds= new StringBuffer();
               int i=0;
               while (rolesIt.hasNext()){
                   if (i>0)groupIds.append( "," );
                   groupIds.append( "'" +rolesIt.next().getRoleId().toString()+ "'" );
               }
               /**
                * select * from `jbpm4_task` task
                   left join jbpm4_participation pt on task.`DBID_`=pt.`TASK_`
                   where task.`ASSIGNEE_`='1' or ( pt.`TYPE_` = 'candidate' and (pt.`USERID_`='1')
                   or pt.`GROUPID_`in ('1'))
                */
               StringBuffer hqlSb= new StringBuffer();
               hqlSb.append( "select task from org.jbpm.pvm.internal.task.TaskImpl task left join task.participations pt where task.assignee=?" );
               hqlSb.append( " or (pt.type = 'candidate' and ((pt.userId=?)" );
               
               if (user.getRoles().size()>0){
                   hqlSb.append( " or (pt.groupId in (" +groupIds.toString()+ "))" );
               }
               hqlSb.append( "))" );
               hqlSb.append( " order by task.priority desc" );
       
               return findByHql(hqlSb.toString(), new Object[]{userId,userId});
               
           }
 
    2 分配任務
       若是在流程定義文件中將任務指定到了我的,則 jbpm 自動分配給我的。不然須要進行指定
    2.1 給用戶組的用戶分配任務
    流程定義文件
       <task name= "review" candidate-groups= "sales-dept" >
          <transition to= "wait" />
       </task>
       假設: sales-dept 有兩個成員: johndoe joesmoe
 
       分組任務列表中,用戶接口必須只接受對這些任務的 接受 操做。
       taskService.takeTask(task.getDbid(), "johndoe" );
       當一個用戶接受了一個任務,這個任務的分配人就會變成當前用戶。任務會從全部候選人的分組任務列表中消失,它會出如今用戶的已分配列表中。
 
    2.2 任務分配處理器分配任務
       一個 AssignmentHandler 能夠經過編程方式來計算 一個任務的分配人和候選人
       public interface AssignmentHandler extends Serializable { 
          void assign(Assignable assignable, OpenExecution execution) throws Exception;
       }
       Assignable 是任務和泳道的通用接口。 因此任務分配處理器能夠使用在任務, 也能夠用在泳道中。
 
    包含任務分配處理器的流程定義 4-2 以下:
    <process name= "TaskAssignmentHandler" xmlns= "http://jbpm.org/4.2/jpdl" >
       <start g= "20,20,48,48" >
          <transition to= "review" />
       </start>
       <task name= "review" g= "96,16,127,52" >
          <assignment-handler class = "org.jbpm.examples.task.assignmenthandler.AssignTask" >
             <field name= "assignee" >
                <string value= "johndoe" />
             </field>
          </assignment-handler>
          <transition to= "wait" />
      </task>
      <state name= "wait" g= "255,16,88,52" />
    </process>
 
    AssignTask 代碼以下
    public class AssignTask implements AssignmentHandler {
       String assignee ;
       public void assign(Assignable assignable, OpenExecution execution) {
          assignable.setAssignee( assignee );
       }
    }
       請注意,默認 AssignmentHandler 實現能夠使用使用流程變量,任何其餘 Java API 能夠訪問資源 ,像你的應用數據庫來計算分配人和候選人用戶和組。
       啓動一個 TaskAssignmentHandler 的新流程實例 , 會當即讓新流程實例運行到任務節點。 一個新 review 任務被建立,在這個時候 AssignTask 的分配處理器被調用 。這將設置 johndoe 爲分配人。 因此 John Doe 將在他本身的任務列表中找到這個任務
 
    2.3 給泳道分配任務
    任務泳道以下面的流程文件 4 -3
    <process name= "TaskSwimlane" xmlns= "http://jbpm.org/4.2/jpdl" >
      <swimlane name= "sales representative" candidate-groups= "sales-dept" />
      <start>
        <transition to= "enter order data" />
      </start>
      <task name= "enter order data" swimlane= "sales representative" >
        <transition to= "calculate quote" />
      </task>
      <task name= "calculate quote" swimlane= "sales representative" >
      </task>
    </process>
 
    在這個例子中,咱們在身份組件中 建立了下面的信息
       identityService.createGroup( "sales-dept" );
       identityService.createUser( "johndoe" , "johndoe" , "John" , "Doe" );
       identityService.createMembership( "johndoe" , "sales-dept" );
 
       在啓動一個新流程實例後,用戶 johndoe 將成爲 enter order data 的一個候選人 。仍是像上一個流程候選人例子同樣, John Doe 能夠像這樣接收任務
       taskService.takeTask(task.getDbid(), "johndoe" );
 
       接收這個任務將讓 johndoe 成爲任務的負責人。 直到任務與泳道 sales representative 關聯 分配人 johndoe 也會關聯到泳道中做爲負責人。接下來, John Doe 能夠像下面這樣完成任務
       taskService.completeTask(taskDbid);
 

       完成任務會將流程執行到下一個任務,下一個任務是calculate quote這個任務也關聯着泳道。所以,任務會分配給johndoejava

相關文章
相關標籤/搜索