Process Instance List and Detail added to Worklist

I have just uploaded an update to the custom BPM worklist sample which adds some new functionality around process instances, including the ability to list process instances:

And also view details for a process instance, including a list of the tasks that are part of that process instance:

The process instance list is currently hardcoded to display open (running) instances only.  I am working on adding the filtering and also a graphical process map – stay tuned for another update soon!

You can access the source code, deployable WAR files and Javadoc on the main worklist page.

This update introduces some interesting new API usage.  The view and controller are much the same as the others, so I will not cover them explicity here.  You can take a look at the source code to see how they work.  Let’s look at the new methods in the MTaskList domain object that support process instance queries.

First, here is the queryInstances method, which will retrieve a list of process instances.  As always, there are more comments in the code in Subversion.

  public static List<IProcessInstance> queryInstances(String user, String state) {
    MLog.log("MTaskList", "Entering queryInstances()");

    try {
      List<Column> displayColumns = new ArrayList<Column>();
      displayColumns.add(IColumnConstants.PROCESS_ID_COLUMN);
      displayColumns.add(IColumnConstants.PROCESS_PROCESSNAME_COLUMN);
      displayColumns.add(IColumnConstants.PROCESS_STATE_COLUMN);
      displayColumns.add(IColumnConstants.PROCESS_TITLE_COLUMN);
      displayColumns.add(IColumnConstants.PROCESS_CREATOR_COLUMN);
      displayColumns.add(IColumnConstants.PROCESS_CREATEDDATE_COLUMN);

      IInstanceQueryInput input = new InstanceQueryInput();
      input.addState(IInstanceQueryInput.PROCESS_STATE_OPEN);
      input.setAssignmentFilter(IInstanceQueryInput.AssignmentFilter.ALL);

      return getBPMServiceClientFactory()
        .getBPMServiceClient()
        .getInstanceQueryService()
        .queryInstances(
            (IBPMContext) ContextCache.getContextCache().get(user),
            displayColumns,
            null,
            null,
            input);

    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

This method shows the use of the InstanceQueryService.queryInstances() API.  The two nulls are for an optional predicate and ordering (sorting).   The code in Subversion has a list of all of the available columns that you can query .  As we did for tasks, we are just querying for the information we need to draw the instance list page, to minimise the load we put on the server.

Here is the method we use to get instance details:


  public static IProcessInstance getInstanceDetails(String user, String instanceId) {
    MLog.log("MTaskList", "Entering getInstanceDetails()");
    MLog.log("MTaskList", "Got request for instanceId " + instanceId);

    try {

      return getBPMServiceClientFactory()
        .getBPMServiceClient()
        .getInstanceQueryService()
        .getProcessInstance(
            (IBPMContext) ContextCache.getContextCache().get(user),
            instanceId);

    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

This method is fairly simple and calls the InstanceQueryService.getProcessInstance() API.  I have not wrapped the process instance like I wrapped the Task yet, but I am planning to do that to simplify the view design.  If you look in the view (instancedetail.jsp) you will see that there are a variety of child objects that we need to go to in order to get the information we want.

Here is a method that will obtain a list of tasks for a given process instance:


  public static List<MTask> findTasksForProcess(String user, String processInstanceId) {
    MLog.log("MTaskList", "Entering findTasksForProcess()");

    try {
      Predicate instancePredicate = new Predicate(TableConstants.WFTASK_INSTANCEID_COLUMN, Predicate.OP_EQ, processInstanceId);
      return getMTasks(user, instancePredicate);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

And this one will find the process instance that owns a given task:


  public static String getProcessInstanceId(String user, String taskNumber) {
    MLog.log("MTaskList", "Entering getProcessInstanceId()");

    try {

      // retrieve context
      ctx = ContextCache.getContextCache().get(user);

      // get task details
      Task task = getTaskQueryService().getTaskDetailsByNumber(ctx, Integer.parseInt(taskNumber));

      // return the process instanceId
      ProcessType processInfo = task.getProcessInfo();
      if(processInfo != null) {
        return processInfo.getInstanceId();
      }
      MLog.log("MTaskList", "Leaving getProcessInstanceId()");

    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

To allow retrieving the tasks for a given process, I made some small changes to my MTaskList.getMTasks() method.  I added a new method signature to allow me to call the method using a Predicate instead of the filter and state, and I updated the method to set default values for filter and state that make sense when we are doing a query for all tasks in a process.  Here is the changed code:


  public static List<MTask> getMTasks(String user, String filter, String state) {
    return getMTasks(user, filter, state, null);
  }

  private static List<MTask> getMTasks(String user, Predicate predicate) {
    return getMTasks(user, null, null, predicate);
  }

  private static List<MTask> getMTasks(String user, String filter, String state, Predicate predicate) {

    MLog.log("MTaskList", "Entering getMTasks()");

    try {

      if (filter == null) filter = "megroup";
      if (state == null) state = "any"

      //    ... continues as before ...

I also had to add two new dependencies in order to use the new APIs that are in this version.

The two JAR files are:

  • Oracle_SOA1\soa\modules\oracle.bpm.project_11.1.1\oracle.bpm.project.model.jar
  • Oracle_SOA1\soa\modules\oracle.bpm.runtime_11.1.1\oracle.bpm.core.jar

I added these to Maven with the following coordinates respectively:

  • com.oracle.soa:bpmproject_model:11.1.1.5
  • com.oralce.soa:bpmcore:11.1.1.5

And of course I added them to my pom, as follows:


       <dependency>
            <groupId>com.oracle.soa</groupId>
            <artifactId>bpmproject_model</artifactId>
            <version>11.1.1.5</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>com.oracle.soa</groupId>
            <artifactId>bpmcore</artifactId>
            <version>11.1.1.5</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

Enjoy!

About Mark Nelson

Mark Nelson is an Architect (an "IC6") in the Fusion Middleware Central Development Team at Oracle. Mark's job is to make Fusion Middleware easy to use in the cloud and at home, for developers and operations folks, with special focus on continuous delivery, configuration management and provisioning - making it simple to manage the configuration of complex environments and applications built with Oracle Database, Fusion Middleware and Fusion Applications, on-premise and in the cloud. Before joining this team, Mark was a senior member of the A-Team since 2010, and worked in Sales Consulting at Oracle since 2006 and various roles at IBM since 1994.
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s