Best Practices from Oracle Development's A‑Team

Adding Process Instance Audit Images to the Worklist

Mark Nelson


I have just made another update to worklist sample.

Main Article

I have just uploaded another update for the custom BPM worklist sample, the second one this week!  This update adds the ‘process instance audit image’ to the ‘process instance detail’ page.  That means the a picture of the actual process model with the path that this instance of the process has followed (so far) highlighted in green.

Here are a couple of examples so you can see what I mean:


And another:


As always, you can download the source code from Subversion and the Javadoc and WARs from the main worklist page.

This update adds some interesting new API usage, which we will discuss in this article.  It also requires the addition of some more libraries into your Maven repository to allow you to build with the necessary dependencies.  There are getting to be enough of these now, that I thought it was time to write a script to save you some work.  You can download the script from here (for Windows) or here (Unix-like).  Warning:  The scripts are not ‘thoroughly tested’ so please check the results carefully.  Please leave a comment if you have problems with them.

You will also need one more JAR file that I am making available for download here.  This file contains a utility class that you will need to use to get the image.  We do not currently have a working API in the product (i.e. as of to get the process instance audit image.  This JAR file contains a utility class from Oracle that will allow you to get the image, and its API is fairly similar to what we have planned for the real API we plan to introduce in a future release.  Hopefully this will minimise any changes you need to make in the future should we release a real API.

Please note, as for the worklist as a whole, this JAR file is a sample, that is provided “as is” without any warranty or support.

This JAR file contains a class called oracle.bpm.example.util.ProcessDiagramUtil.  This class has a constructor that takes the BPMServiceClient which we have seen before, and a method called InputStream getProcessAuditDiagram(IBPMContext ctx, String instanceId) which retrieves the actual image in PNG format.

Here is the basic usage of this utility class:

# Copyright 2012 Oracle Corporation. # All Rights Reserved. # # Provided on an 'as is' basis, without warranties or conditions of any kind, # either express or implied, including, without limitation, any warranties or # conditions of title, non-infringement, merchantability, or fitness for a # particular purpose. You are solely responsible for determining the # appropriateness of using and assume any risks. You may not redistribute.  // get the utility class which will retrieve the image for us   ProcessDiagramUtil pdu = new ProcessDiagramUtil(       getBPMServiceClientFactory().getBPMServiceClient());   // get the image for the requested instance   InputStream auditDiagramData = pdu.getProcessAuditDiagram(       (IBPMContext) ContextCache.getContextCache().get(user), instanceId);

We need to create an instance of the class, passing the constructor the BPMServiceClient.  Then we are able to get the instance audit image (in PNG format) as an InputStream.

The controller in this case is also a little different, so it is presented here.  It is just returning the PNG image, without a ‘page’ wrapped around it, so the intention is that it is called from and img tag, not from the browser URL.  We will see this later in the view.

Here is the controller code:

package com.oracle.ateam; import org.springframework.web.servlet.ModelAndView; import java.io.InputStream; import java.io.OutputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.ServletOutputStream; import oracle.bpel.services.workflow.client.util.WorkflowAttachmentUtil; import oracle.bpel.services.workflow.verification.IWorkflowContext; import com.oracle.ateam.util.MLog; import com.oracle.ateam.domain.ContextCache; import com.oracle.ateam.domain.MTaskList; /**     A Controller that will display the grpahical audit image for a given process instance.     This controller should only be called in an 'img' tag - not the main application window.  */ public class AuditImageController extends SimpleSuccessFailureController {   private static final int IO_BUFFER_SIZE = 1;   public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)       throws Exception {     MLog.log("AuditImageController", "Entering handleRequest()");     // get parameters from request     String xProcessId = request.getParameter("x_processid");     InputStream image = null;     try {       image = MTaskList.getAuditImage(request.getUserPrincipal().getName(), xProcessId);       if (image == null) {         MLog.log("AuditImageController", "image is null");         return null;       }     } catch (Exception e) {       MLog.log("AuditImageController", "Got an exception in the call to MTaskList.getAuditImage(), bailing out...");       e.printStackTrace();       return null;     }     // set up the response     response.setContentType("image/png");     ServletOutputStream out = response.getOutputStream();     copy(image, out);     out.flush();     out.close();     return null;   }   private static void copy(InputStream in, OutputStream out) throws IOException {     byte[] b = new byte[IO_BUFFER_SIZE];     int read;     while ((read = in.read(b)) != -1) {       out.write(b, 0, read);     }   } }

This controller uses a similar approach to the one we used in the DownloadAttachmentController.  We set the ContentType of the HttpServletResponse and then write the image data directly into the ServletOutputStream and return null from the controller.  This is how we deliver binary data to the browser in the Spring Web MVC framework.

Here is the part of the view that calls this controller:

<h2 class="td-h2">Process Audit Image for this Instance</h2>   <img src="auditimage.do?x_processid=<c:out value="${model.instance.systemAttributes.processInstanceId}"/>"  />

Good luck and enjoy!

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha