ComplexValue 類型,並通過 Variable 的構造函數創建一個 Variable 對象,其第一個參數為 BPD 中定義的變數的名稱。
由前述代碼可以看到,在構建 vars[3] 也就是 mailContents 的時候,做了一部分額外的處理,這裡涉及到 ComplexValue 的結構。ComplexValue 是一個複雜的數據類型,它根據被反序列化的 XML 內容的結構,其層次可以是一個嵌套的很深的 N 叉樹。當複雜結構的內容中出現了本身就是 XML 的情況時,也就是說數據本身是 XML 數據,比如出現 HTML 標籤,則需要像上面一樣做額外處理,否則標籤數據會被”吞掉”,代碼如下:
|
vars[3] = makeContentList(contents); // dispose the complex value ComplexValue cv = (ComplexValue)vars[3].getValue(); MessageElement arrayOfStr = cv.get_any()[0].getRealElement(); if(null != arrayOfString){ List<MessageElement> elementList = arrayOfStr.getChildren(); for(MessageElement strEle : stringElementList){ Text e = (Text) strEle.getChildren().get(0); e.setValue(mailContent); } }
|
如上面所示,代碼第三行先獲取 Variable 對象中的 ComplexValue 對象,接下來的代碼是通過調試確定你當前的 ComplexValue 對象實際存儲值的位置,該位置與被反序列化的 XML 的結構內容有關,也就是說上面的代碼不是通用的。最後找到真正存儲值的位置將需要的值設置進去,即最後 setValue 的調用。
所有的參數設置完畢後,調用 WebAPI 將參數轉入對應的流程實例,如下代碼所示:
|
// get process instance by its ID ProcessInstance proIn = webAPI.getProcessInstance(instanceID); logger.info(“Process Instance : ” + proIn.getName()+ ” start to be disposed”); if (null != proIn) { Task[] tasks = proIn.getTasks(); if (null != tasks && tasks.length > 0) { // get the index task currentTask = tasks[0]; if (!checkTaskAttribute(currentTask)) { // just the the return result retResult = false; } else { // forward the task retResult = webAPI.completeTask(currentTask.getId(), vars); } } }
|
上面代碼第二行,通過流程實例的 ID 獲取 ProcessInstance 的對象,通過 getTasks 方法拿到該流程當前可查詢的所有任務,上面的代碼獲取了第一個 Task,即”COCE_GIW_ALL_Index”中的任務,最後調用 completeTask 方法將參數傳入對應的 Task 並完成任務,將流程推到下一個活動中。
該 Servlet 對應的頁面代碼可查看 basic_index.jsp 及 basic_index_form.js。此時發票錄入的 Web 模塊創建完成。
審核模塊與前述的發票錄入模塊類似,詳細代碼可查看 ApproverServlet.java、approver.jsp 及 approver_form.js。
所有 Web 功能模塊定義完成後,需要定義後台程序以查詢新出現的文檔並啟動相應的流程實例。InitServlet 和 FileLoadDaemon 即完成這樣的工作,詳細代碼可查看 InitServlet.java 及 FileLoadDaemon.java。InitServlet 的關鍵代碼如下:
|
// start the daemon thread daemon=new FileLoadDaemon(properties,doctype_url_mappings,application); Thread tDeamon = new Thread(daemon); if (null != tDeamon) { /* daemonT.setDaemon(true); */ tDeamon.start(); }
|
上述代碼創建了一個 FileLoadDaemon,該實例是一個線程,當 Servlet 的 Init 方法退出時,該線程會一直循環下去,直到伺服器退出。FileLoadDaemon 關鍵代碼如下所示:
清單 10. FileLoadDaemon.java 代碼片段
|
while (alive) { if (null == dirPath || “”.equals(dirPath)) { if (null != properties) { String contextpath = properties.get(“contextPath”); String dir = properties.get(“base_dir”); // make dirPath from context path and base dir dirPath = contextpath + dir; } // if inner } // if outer File fileDir = new File(dirPath); if (!dirValidation(fileDir)) { break; } File[] files = fileDir.listFiles(); if (null != files && files.length > 0 && isFileModified(fileDir)) { for (File f : files) { if (f.isDirectory()) { continue; } startProcessInstance(f.getPath()); } // for loop } // if outer } // while loop
|
該程序首先獲取需要檢查的伺服器目錄,如果目錄有新文檔加入,其調用 startProcessInstance 方法,該方法創建一個 StartPIThread 的實例,該實例也是一個線程,該線程將會啟動一個流程實例,並將啟動實例時所需的參數傳入,本例中為文檔的存儲路徑,詳細代碼可查看 StartPIThread.java。關鍵代碼如下:
清單 11. StartPIThread.java 代碼片段
|
// get Process instance Process pro; try { pro = webAPI.getProcessBySystemId(appAcronym, systemID); // launch the ProcessInstance instance proInst = webAPI.startProcess(pro, vars); logger.info(proInst.getName() + “has been launched”); } catch (RemoteException e) { e.printStackTrace(); }
|
首先通過 WebAPI 的 getProcessBySystemId 方法獲取對應的流程定義,該方法需要兩個參數,第一個為 Process App 的簡短名稱,即前述創建 Process App 時填寫的首字母縮寫,此處為”RAPSIM2″。第二個參數為該 Process 的系統 ID。獲取 Process 對象之後,通過 startProcess 即可啟動一個流程實例,其中第一個參數為 Process 對象,第二個參數為需要傳遞的參數,是一個 Variable 數組類型的數據對象。
所有模塊構建完畢之後,即可運行該 BPM 應用程序。首先啟動所使用的 Web 伺服器。如果 IBM BPM 的伺服器沒有啟動,需要先等待 IBM BPM 伺服器啟動,並通過 Authoring Environment 查看流程運行情況。此時,在控制台視圖中,可以查看到如圖 15 所示的信息:
上面的信息顯示有 6 個實例被啟動,ID 分別從 301 到 306. 實例啟動的個數與文檔的個數相同。打開 Authoring Environment 的檢查器,可以看見啟動的 6 個實例,如圖 16 所示:
打開瀏覽器,在地址欄輸入 http://localhost:8080/LombardiSimulation/indexer/index_list.jsp 可看到當前所有的活動實例的列表,如圖 18 所示:
以下文章點擊率最高
Loading…


