一步一步学JBPM(12)——JBPM流程历史追踪

JBPM的使用过程中,由于JBPM完全屏蔽了流程内部的细节。所以有时候很难从全局上掌握流行的运行情况。比如你提交一个请求,只知道请求提交了,通常你是不知道提交到那里,也不知道你的请求目前在那个位置。这样必须专门通过程序去查看流程的整体运行情况。查看的方式越简单明了越好。

 

我采用图片的方式,能够显示出流程进过的历史和当前任务所在的节点。方便用户查询。

这个技术分成两个重要部分。第一个是查询当前流程的流程定义图片,将其转换成输出流。第二点是将查询任务经过的节点和当前节点,得到他们的坐标。在html中使用图像标注出来。

 

一:获得流程定义图片。

public InputStream findProcessInstancePic(String processInstanceId) {

		ProcessInstance processInstance = executionService
				.findProcessInstanceById(processInstanceId);

		String processDefinitionId = processInstance.getProcessDefinitionId();

		ProcessDefinition processDefinition = repositoryService
				.createProcessDefinitionQuery()
				.processDefinitionId(processDefinitionId).uniqueResult();
		return repositoryService.getResourceAsStream(
				processDefinition.getDeploymentId(),
				processDefinition.getImageResourceName());
}

这个方法是通过流程实例ID获取流程定义,然后将流程定义对应的图片得到。返回输出流。流程定义图片是部署流程的时候和流程定义一起部署到JBPM中的。得到图片以后,在界面使用img标签显示出图片。

</center>
		<img src="${ctx}/service/processInstance/pic.do?processInstanceId=${id }" style="position:absolute;left:0px;top:0px;"/>
		<c:if test="${activityCoordinates!=null }">
		<div
			style="position:absolute;border:3px solid red;left:${activityCoordinates.x }px;top:${activityCoordinates.y }px;width:${activityCoordinates.width }px;height:${activityCoordinates.height}px;"></div>
		</c:if>
		<c:if test="${ac!=null }">
		<c:forEach items="${ac }" var="a">
			<div
			style="position:absolute;border:3px solid blue;left:${a.x }px;top:${a.y }px;width:${a.width }px;height:${a.height}px;"></div>
		
		</c:forEach>
		</c:if>
	</body>

</html>

其中

<imgsrc="${ctx}/service/processInstance/pic.do?processInstanceId=${id }"style="position:absolute;left:0px;top:0px;"/>

请求一个controller显示图片。

controller代码如下:

/**
	 * 显示流程图片
	 * 
	 * @param request
	 * @param response
	 * @param id
	 */
	@RequestMapping("/service/processInstance/pic.do")
	public void pic(HttpServletRequest request, HttpServletResponse response,
			String processInstanceId) {
		InputStream inputStream = workflowManager
				.findProcessInstancePic(processInstanceId);
		PrintWriter pw = null;
		if (inputStream == null) {
			try {
				pw = response.getWriter();
				pw.write("error");
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				pw.close();
			}
		} else {
			byte[] b = new byte[1024];
			int len = -1;
			ServletOutputStream sos = null;
			try {
				sos = response.getOutputStream();
				while ((len = inputStream.read(b, 0, 1024)) != -1) {
					sos.write(b, 0, len);
				}
			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (sos != null) {
					try {
						sos.close();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

			}

		}

	}

二:显示流程坐标。

首先根据流程实例ID查询出该流程实例进过的节点的名称。然后再在流程定义中查询这些节点的坐标。

public ActivityCoordinates findActivityCoordinates(String id) {

		ProcessInstance processInstance = executionService
				.findProcessInstanceById(id);
		if (null==processInstance||processInstance.isSuspended()) {
			return null;
		}
		Set<String> activityNames = processInstance.findActiveActivityNames();

		return repositoryService.getActivityCoordinates(processInstance
				.getProcessDefinitionId(), activityNames.iterator().next());

	}

@Override
	public List<ActivityCoordinates> findHistoryActivityInfo(String processId) {
		List<ActivityCoordinates> activityCoordinates = new ArrayList<ActivityCoordinates>();
		List<HistoryActivityInstance> hisIns = historyService.createHistoryActivityInstanceQuery().processInstanceId(processId).list();
		
		ProcessInstance processInstance = executionService.findProcessInstanceById(processId);
		if (null==processInstance||processInstance.isSuspended()) {
			return null;
		}
		for(Iterator<HistoryActivityInstance> iter = hisIns.iterator();iter.hasNext() ; ){
			activityCoordinates.add(repositoryService.getActivityCoordinates(processInstance.getProcessDefinitionId(), iter.next().getActivityName()));
		}
		return activityCoordinates;
	}

其中第一个方法是返回当前节点坐标,第二个方法是返回进过节点坐标(包括当前节点,这就需要去掉当前的节点),这个操作在controller中完成,然后返回到页面中。


/**
	 * 显示流程坐标
	 * 
	 * @param request
	 * @param id
	 * @return
	 */
	@RequestMapping("service/processInstance/view.do")
	public String view(HttpServletRequest request, String id) {

		// 流程图活动坐标
		ActivityCoordinates activityCoordinates = workflowManager
				.findActivityCoordinates(id);
		List<ActivityCoordinates> ac = null;
		if(activityCoordinates != null){
			 ac = workflowManager.findHistoryActivityInfo(id);
			
			ac.remove(activityCoordinates);

		}
		
		request.setAttribute("ac", ac);
		request.setAttribute("activityCoordinates", activityCoordinates);
		request.setAttribute("id", id);
		return "/mtdev/module/myflow/image";
	}

jsp界面和上面的一样。这里的关键是使用div在图片上标记出节点。给div加上边框,看起来就和图片合在一起一样。

 

下面是效果图。


你可能感兴趣的:(一步一步学JBPM(12)——JBPM流程历史追踪)