一步一步學JBPM(12)——JBPM流程歷史追蹤

JBPM的使用過程中,由於JBPM完全屏蔽了流程內部的細節。所以有時候很難從全局上掌握流行的運行情況。比如你提交一個請求,只知道請求提交了,通常你是不知道提交到那裏,也不知道你的請求目前在那個位置。這樣必須專門通過程序去查看流程的整體運行情況。查看的方式越簡單明瞭越好。

 

我採用圖片的方式,能夠顯示出流程進過的歷史和當前任務所在的節點。方便用戶查詢。

這個技術分成兩個重要部分。第一個是查詢當前流程的流程定義圖片,將其轉換成輸出流。第二點是將查詢任務經過的節點和當前節點,得到他們的座標。在html中使用圖像標註出來。

 

一:獲得流程定義圖片。

[java] view plaincopy
  1. public InputStream findProcessInstancePic(String processInstanceId) {  
  2.   
  3.         ProcessInstance processInstance = executionService  
  4.                 .findProcessInstanceById(processInstanceId);  
  5.   
  6.         String processDefinitionId = processInstance.getProcessDefinitionId();  
  7.   
  8.         ProcessDefinition processDefinition = repositoryService  
  9.                 .createProcessDefinitionQuery()  
  10.                 .processDefinitionId(processDefinitionId).uniqueResult();  
  11.         return repositoryService.getResourceAsStream(  
  12.                 processDefinition.getDeploymentId(),  
  13.                 processDefinition.getImageResourceName());  
  14. }  

這個方法是通過流程實例ID獲取流程定義,然後將流程定義對應的圖片得到。返回輸出流。流程定義圖片是部署流程的時候和流程定義一起部署到JBPM中的。得到圖片以後,在界面使用img標籤顯示出圖片。

[html] view plaincopy
  1. </center>  
  2.         <img src="${ctx}/service/processInstance/pic.do?processInstanceId=${id }" style="position:absolute;left:0px;top:0px;"/>  
  3.         <c:if test="${activityCoordinates!=null }">  
  4.         <div  
  5.             style="position:absolute;border:3px solid red;left:${activityCoordinates.x }px;top:${activityCoordinates.y }px;width:${activityCoordinates.width }px;height:${activityCoordinates.height}px;"></div>  
  6.         </c:if>  
  7.         <c:if test="${ac!=null }">  
  8.         <c:forEach items="${ac }" var="a">  
  9.             <div  
  10.             style="position:absolute;border:3px solid blue;left:${a.x }px;top:${a.y }px;width:${a.width }px;height:${a.height}px;"></div>  
  11.           
  12.         </c:forEach>  
  13.         </c:if>  
  14.     </body>  
  15.   
  16. </html>  

其中

[html] view plaincopy
  1. <imgsrcimgsrc="${ctx}/service/processInstance/pic.do?processInstanceId=${id }"style="position:absolute;left:0px;top:0px;"/>  

請求一個controller顯示圖片。

controller代碼如下:

[java] view plaincopy
  1. /** 
  2.      * 顯示流程圖片 
  3.      *  
  4.      * @param request 
  5.      * @param response 
  6.      * @param id 
  7.      */  
  8.     @RequestMapping("/service/processInstance/pic.do")  
  9.     public void pic(HttpServletRequest request, HttpServletResponse response,  
  10.             String processInstanceId) {  
  11.         InputStream inputStream = workflowManager  
  12.                 .findProcessInstancePic(processInstanceId);  
  13.         PrintWriter pw = null;  
  14.         if (inputStream == null) {  
  15.             try {  
  16.                 pw = response.getWriter();  
  17.                 pw.write("error");  
  18.             } catch (IOException e) {  
  19.                 e.printStackTrace();  
  20.             } finally {  
  21.                 pw.close();  
  22.             }  
  23.         } else {  
  24.             byte[] b = new byte[1024];  
  25.             int len = -1;  
  26.             ServletOutputStream sos = null;  
  27.             try {  
  28.                 sos = response.getOutputStream();  
  29.                 while ((len = inputStream.read(b, 01024)) != -1) {  
  30.                     sos.write(b, 0, len);  
  31.                 }  
  32.             } catch (IOException e) {  
  33.                 e.printStackTrace();  
  34.             } finally {  
  35.                 if (sos != null) {  
  36.                     try {  
  37.                         sos.close();  
  38.                     } catch (IOException e) {  
  39.                         // TODO Auto-generated catch block  
  40.                         e.printStackTrace();  
  41.                     }  
  42.                 }  
  43.   
  44.             }  
  45.   
  46.         }  
  47.   
  48.     }  

二:顯示流程座標。

首先根據流程實例ID查詢出該流程實例進過的節點的名稱。然後再在流程定義中查詢這些節點的座標。

[java] view plaincopy
  1. public ActivityCoordinates findActivityCoordinates(String id) {  
  2.   
  3.         ProcessInstance processInstance = executionService  
  4.                 .findProcessInstanceById(id);  
  5.         if (null==processInstance||processInstance.isSuspended()) {  
  6.             return null;  
  7.         }  
  8.         Set<String> activityNames = processInstance.findActiveActivityNames();  
  9.   
  10.         return repositoryService.getActivityCoordinates(processInstance  
  11.                 .getProcessDefinitionId(), activityNames.iterator().next());  
  12.   
  13.     }  

[java] view plaincopy
  1. @Override  
  2.     public List<ActivityCoordinates> findHistoryActivityInfo(String processId) {  
  3.         List<ActivityCoordinates> activityCoordinates = new ArrayList<ActivityCoordinates>();  
  4.         List<HistoryActivityInstance> hisIns = historyService.createHistoryActivityInstanceQuery().processInstanceId(processId).list();  
  5.           
  6.         ProcessInstance processInstance = executionService.findProcessInstanceById(processId);  
  7.         if (null==processInstance||processInstance.isSuspended()) {  
  8.             return null;  
  9.         }  
  10.         for(Iterator<HistoryActivityInstance> iter = hisIns.iterator();iter.hasNext() ; ){  
  11.             activityCoordinates.add(repositoryService.getActivityCoordinates(processInstance.getProcessDefinitionId(), iter.next().getActivityName()));  
  12.         }  
  13.         return activityCoordinates;  
  14.     }  

其中第一個方法是返回當前節點座標,第二個方法是返回進過節點座標(包括當前節點,這就需要去掉當前的節點),這個操作在controller中完成,然後返回到頁面中。


[java] view plaincopy
  1. /** 
  2.      * 顯示流程座標 
  3.      *  
  4.      * @param request 
  5.      * @param id 
  6.      * @return 
  7.      */  
  8.     @RequestMapping("service/processInstance/view.do")  
  9.     public String view(HttpServletRequest request, String id) {  
  10.   
  11.         // 流程圖活動座標  
  12.         ActivityCoordinates activityCoordinates = workflowManager  
  13.                 .findActivityCoordinates(id);  
  14.         List<ActivityCoordinates> ac = null;  
  15.         if(activityCoordinates != null){  
  16.              ac = workflowManager.findHistoryActivityInfo(id);  
  17.               
  18.             ac.remove(activityCoordinates);  
  19.   
  20.         }  
  21.           
  22.         request.setAttribute("ac", ac);  
  23.         request.setAttribute("activityCoordinates", activityCoordinates);  
  24.         request.setAttribute("id", id);  
  25.         return "/mtdev/module/myflow/image";  
  26.     }  

jsp界面和上面的一樣。這裏的關鍵是使用div在圖片上標記出節點。給div加上邊框,看起來就和圖片合在一起一樣。

 

下面是效果圖。

更好更多地JBPM博客地址:http://blog.csdn.net/lsh6688/article/category/1189610

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章