Sun Java System Portal Server 7.2 Developer's Guide

Chapter 39 Simple API for Workflow

This chapter introduces the Simple API for Workflow (SAW) and explains how to implement SAW in Portal server 7.2 release. SAW is a generic workflow API to perform human workflow interaction with various workflow engines. SAW provides a framework to plug-in any business process specific implementation that implements SAW interfaces. SAW is shipped with a default implementation for Sun Java Composite Application Platform Suite. You can have similar SAW implementations for other business processes such as JBoss Business Process Management (jBPM), Open Enterprise Service Bus (OpenESB) and so on.

This chapter includes the following sections:

Prerequisites

Before you implement SAW in Portal Server 7.2, you need to install the following components:

Configuring SAW

Follow the steps to configure SAW.

ProcedureTo Configure SAW

  1. Create a new Java project.

  2. Ensure that client stubs generated out of the workflow service of Sun Java Composite Application Platform Suite is in the classpath.

  3. Add the saw-api-0.7.jar and saw-impl-jcaps-0.8.jar files to the classpath of the project.

  4. Ensure that the javaee.jar is in classpath.


    Note –

    The saw-api-0.7.jar file should be in compile time and runtime classpath, whereas the saw-impl-jcaps-0.8.jar, WorkflowServiceClient.jar, and javaee.jar files should be only in runtime classpath.

    All these .jar files are available at https://saw.dev.java.net/


  5. Add WorkflowConfig.properties file in the project classpath.


    Tip –

    Sample entries for WorkflowConfig.properties file:

    • sawworkflowimplclass = com.sun.saw.impls.jcaps.JCAPSWorkflow (This entry means that you are using SAW Workflow implementation class, JCAPSWorkflow.)

    Sample entries for WorkflowConfig.properties file:

    • com.sun.saw.impls.jcaps.JCAPSWorkflow.appserverhost = points to the machine where the Java CAPS Business Process is deployed.

    • com.sun.saw.impls.jcaps.JCAPSWorkflow.iiopserverport = port on which the IIOP lookup for the EJB happens.

    • com.sun.saw.impls.jcaps.JCAPSWorkflow.appserverusername = admin user id and password for the server on which Java CAPS Business Process is running.

    • com.sun.saw.impls.jcaps.JCAPSWorkflow.appserverpassword = admin user id and password for the server on which Java CAPS Business Process is running.

    • com.sun.saw.impls.jcaps.JCAPSWorkflow.contextfactory = com.sun.jndi.cosnaming.CNCtxFactory

    • com.sun.saw.impls.jcaps.JCAPSWorkflow.serviceJndi = Java Naming and Directory Interface (JNDI) name of the deployed Java CAPS Business Process.


  6. The ImplementationType.properties file is required to run SAW Application, when you create using NetBeans plug-in. The ImplementationType.properties file should contain the keyword, ImplementationType=JCAPS.


    Note –

    The client of the SAW API should get the reference of the workflow implementation object (in this case the JCAPSWorkflow) through the WorkflowFactory class. The client should call the getWorkflowInstance() or getWorkflowInstance(java.util.Properties) method on the WorkflowFactory to get an instance of the SAW Workflow Implementation class. The WorkflowFactory reads the sawworkflowimplclass key from the WorkflowConfig.properties file and finds out which SAW Workflow Implementation class to use. The getWorkflowInstance() looks for the WorkflowConfig.properties in classpath. This properties file will have the values for the necessary attributes that are required. The getWorkflowInstance(java.util.Properties) uses the properties object is provided to it as the argument and does not look for the WorkflowConfig.properties. Once the client has the reference to the SAW Workflow Implementation class, the client can call methods on that instance.


Sample Scenario

In order to explain how to use SAW APIs, you can consider the following Business Process use case, where a user wants to do the following tasks:

Checking out a Task

Add the following code to your test class, to check out a task.


private com.sun.saw.vo.OutputVO checkoutTasks
(String userId,java.util.List taskIdList,Workflow workflowImpl)
throws com.sun.saw.WorkflowException {

   com.sun.saw.vo.CheckoutTaskVO checkoutTaskVO = new com.sun.saw.vo.CheckoutTaskVO();
   checkoutTaskVO.setTaskIdList(taskIdList);
   checkoutTaskVO.setUserId(userId);

   com.sun.saw.vo.OutputVO outputVO = null;
   outputVO = workflowImpl.checkoutTasks(checkoutTaskVO);

   return outputVO;
  }

//Call the above method from the main(). For example

public static void main(String args) {
TestClient client = new TestClient();
List taskIdList = new ArrayList();
taskIdList.add("4ce71ee0:11420e51eca:-6388");
Workflow workflowImpl = this.getWorkflowImpl();
try {
client.checkoutTasks("CPina", taskIdList,workflowImpl);
} catch (com.sun.saw.WorkflowException e) {
e.printStackTrace();
}
}

private com.sun.saw.Workflow getWorkflowImpl() throws com.sun.saw.WorkflowException{

// This assumes that the property file is there in classpath.

com.sun.saw.Workflow workflow = null;
com.sun.saw.WorkflowFactory workflowFactory = WorkflowFactory.getInstance();
workflow = workflowFactory.getWorkflowInstance();
return workflow;
}

The above code does the following functions:

Modifying Attributes of a Task

To modify the attributes of a task, call the saveTasks() on the appropriate SAW Workflow Implementation object. Add the following code to your class:


private com.sun.saw.vo.OutputVO saveTasks(String userId,java.util.List taskIdList,
String output,java.util.Map customAttributesMap,com.sun.saw.Workflow workflowImpl) throws com.sun.saw.WorkflowException {
    
    com.sun.saw.vo.OutputVO outputVO = null;
    com.sun.saw.vo.SaveTaskVO saveTaskVO = new com.sun.saw.vo.SaveTaskVO ();
    saveTaskVO.setTaskIdList(taskIdList);
    saveTaskVO.setUserId(userId);
    saveTaskVO.setOutput(output);
    saveTaskVO.setCustomAttributesMap(customAttributesMap); // key is fn, value is the dynamicParamVO.
  
    outputVO = workflowImpl.saveTasks(saveTaskVO);
    return outputVO;
  }


//Call the above method from your main(). For example:
client.saveTasks("CPina", taskIdList,"output",null,workflowImpl);

The output gets saved as a task attribute.

Completing a Task

Once you check out a task and modify the attributes, you may want to mark the status of a task as completed. This marking is called completing a task.

To complete a task, add the following method to a class:


private com.sun.saw.vo.OutputVO completeTasks(String userId,java.util.List taskIdList,
com.sun.saw.Workflow workflowImpl) throws com.sun.saw.WorkflowException {

    com.sun.saw.vo.OutputVO outputVO = null;
    com.sun.saw.vo.CompleteTaskVO completeTaskVO = new com.sun.saw.vo.CompleteTaskVO();
    completeTaskVO.setTaskIdList(taskIdList);
    completeTaskVO.setUserId(userId);

    outputVO = workflowImpl.completeTasks(completeTaskVO);
    return outputVO;

  }
//Call the above method from your main(). For example,.
client.completeTasks("CPina", taskIdList,workflowImpl);

The task is marked as completed.

Getting a Task

To get tasks, add the following method to a class:


public com.sun.saw.vo.OutputVO getTasks(String startDate,String
endDate,java.util.List taskIdList,java.util.List userIdList,
java.util.List taskStatusList,java.util.List groupIdList,String userId,int startRecord,
int recordsPerPage,com.sun.saw.Workflow workflowImpl) throws com.sun.saw.WorkflowException {

com.sun.saw.vo.FilterTaskVO filterTaskVO = new com.sun.saw.vo.FilterTaskVO();
filterTaskVO.setStartDate(startDate);
filterTaskVO.setEndDate(endDate);
filterTaskVO.setTaskIdList(taskIdList);
filterTaskVO.setUserIdList(userIdList);
filterTaskVO.setTaskStatusList(taskStatusList);
filterTaskVO.setGroupIdList(groupIdList);

filterTaskVO.setUserId(userId);
filterTaskVO.setStartRecord(startRecord);
filterTaskVO.setRecordsPerPage(recordsPerPage);

OutputVO outputVO = workflowImpl.getTasks(filterTaskVO);
//System.out.println(outputVO.getTaskVOList().size());

return outputVO;

}


//Call the above method from your main(). For example,.
client.getTasks(null, null, null, null, null, null,userId,1,10,workflowImpl);

Using the Tag Libraries

Tag libraries in SAW are available to:

ProcedureTo Use the Tag Libraries in Your JSP

  1. Ensure that the saw.tld file is in classpath.

  2. Add the declaration on the JSP.


    <%@ taglib uri="http://java.sun.com/saw" prefix="saw"%>
  3. Use the following tag library to get tasks that meet the search criteria.


    <c:catch var="getTasksException">
    <saw:getTasks filterTaskVO="${sessionScope.filterTaskVO}" returnvalue="taskList"/>
    </c:catch>

    It takes the following two attributes

    • filterTaskVO - Instance of the FilterTaskVO object

    • returnvalue - Name under which the list of workflowTaskVOs are available in the JSP, for the user to iterate and print.


    <c:forEach items = "${taskList}"  var ="task">
    </c:forEach>
  4. Use the following tag library to get the count of number of tasks that match the search criteria.


    <saw:countTask filterTaskVO="${sessionScope.filterTaskVO}"
    returnvalue="taskCount" subordinateCount="true"/>

    Besides the filterTaskVO and returnvalue attributes, the count task include another attribute called the subordinateCount. The subordinateCount attribute decides whether the count should include the tasks assigned to the subordinates of the user.

  5. Use the following tag library to get the details of a task.


    <c:catch var="getTasksException">
    <saw:getTaskById filterTaskVO="${sessionScope.filterTaskVO}" returnvalue="taskInfo"/>
    </c:catch>

    Use ${taskInfo.input} to access the task attributes available in the JSP.

  6. All the above taglib calls, optionally take a properties attribute also. If you set this properties attribute value, then the WorkflowFactory does not look for the WorkflowConfig.properties classpath, instead uses this properties object. For example:


    <c:catch var="getTasksException">
    <saw:getTasks filterTaskVO="${sessionScope.filterTaskVO}" returnvalue="taskList"
    properties="${sessionScope.propObject}"/>
    </c:catch>