Following on for my previous Java CAPS Tip on Integrating
Work List Manager with Sun DSEE 6.x , found here,
I will further extend the concept and illustrate how we can now build a
simple Visual Web Pack (VWP) based application that allows the user to
View, Accept, Reject or Escalate tasks created by a simple Workflow
application. As with all example it is intentionally kept simple
although I hope it provides enough information for the reader to expand
upon. This posting assumes you have read the previous and if following
them through implement / configure your system to work with DSEE and if
not please read the previous posting.
Resources
A simple Java CAPS eInsight based Workflow
As stated previously this process has intentionally been kept simple. We will trigger the workflow business process using a simple file, it does not matter what the content is we will simply display it, and we will provide a simple summary in the Worklist Manager (WLM) flexString1. The example Java CAPS project can be download from here.
Now that we have built and successfully deployed the Simple JavaCAPS application we will build a VWP based GUI that provides user Login, Task List and Task View screens. The example NB project export can be found here. Although the example project contains some additional functionality not described here, because it is not necessary for the example, the code gives possible layout examples. The step require to implement the three screen example as as follows. Where appropriate notes will be added to highlight certain features and key areas.
Resources
A simple Java CAPS eInsight based Workflow
As stated previously this process has intentionally been kept simple. We will trigger the workflow business process using a simple file, it does not matter what the content is we will simply display it, and we will provide a simple summary in the Worklist Manager (WLM) flexString1. The example Java CAPS project can be download from here.
- Create a new Project
- Create a new Business Process bpWLM as below.

The key component of this Business Process is the WLM API User Activity which will cause the BP to be suspended until the WLM activity is completed.
- In the first Business Rule Map the content of the File to the
WLMTask Input and a simple static String to the Flex String1

- The User Activity can be configured by Right-Clicking on it and
editing the properties and selecting Assignments Tab. You will need to
connect to your DSEE instance and then select a number of users or
group to assign the task to.


- The second Business rule should be modified to copy the content
of the WLM Task output to the file write.

- You should not create an environment configuring the WLM external
to match that define in the previous article
build a connectivity map and then deploy to your integration server.

Now that we have built and successfully deployed the Simple JavaCAPS application we will build a VWP based GUI that provides user Login, Task List and Task View screens. The example NB project export can be found here. Although the example project contains some additional functionality not described here, because it is not necessary for the example, the code gives possible layout examples. The step require to implement the three screen example as as follows. Where appropriate notes will be added to highlight certain features and key areas.
- Before we can attempt to build the application we must first
import our WorkflowServiceClient.jar file create in the previous article.
This is done, within NetBeans, by selecting Services Tab->Enterprise
Beans(2.x)->Right-Click->Add Set of Session EJBs. This will allow
you to import and configure the interface to the EJB.


In the second Wizard page you will notice that a number of the methods are highlighted with a warning and we will need to configure the return types for these as follows: - getAllSubordinates - java.lang.Object
- getAuditHistory - java.lang.Object
- getDistinctValues - java.lang.Object
- getGroups - java.lang.Object
- getManagers - java.lang.Object
- getTasks - com.stc.bpms.wlm.model.Task
- getTasksForUser - com.stc.bpms.wlm.model.Task (This method
exists twice)
- getUserActivities - java.lang.Object
- getUserRoles - java.lang.Object
- Now we can create a new Web project (WorkListManager)
- We now create, rename the default Page1, a Login Page that
contain simply a username TextField, a password PasswordField and a
button.


Behind the Login button we will need to call the authenticateUser method of the ejb. Before editing the code drag the authenticateUser method from the previously imported EJB on to the page and this will cause NetBeans to import the appropriate jars so that the project may be built. Within the SessionBean we should create a username property and bind the display usernameTF to this property. We will use the value within the SessionBean throughout the project. Once this has been do the following should be added to Login Button.
public String loginBtn_action() {
String logon = null;
FacesContext context = getFacesContext();
String username = usernameTF.getValueAsString(context);
String password = passwordPF.getValue().toString();
try {
if (workflowServiceClient.authenticateUser(username, password.toCharArray())) {
logon = "logon";
log("*** APH-I1 Login Successfull"
;
// Get User Display Preferences
SqlTimestampConverter converter = (SqlTimestampConverter)getSessionBean1().getTimestampConverter();
converter.setDateStyle("long"
;
getSessionBean1().getTimestampConverter();
} else {
warn("Invalid Username / Password"
;
log("*** APH-I1 : Invalid Username / Password"
;
}
} catch (Exception e) {
Logger.getLogger(LogonPage.class.getName()).log(Level.SEVERE, "Logon Exception", e);
error(e.getMessage());
}
return logon;
}
The authenticateUser will return true if the user exists and is able to logon. Once successfully logged in the page should navigate to the TaskListPage.

- The TaskList Page should be created and a Table dragged on to the
canvas. Once this has been done we will need to drag the appropriate getTasksForUser method
onto the Page. You can identify which is the appropriate version of the
method by hovering over it with the mouse and look at the tool-tip. The
method we require contains only two input parameters. Once this has bee
done we will need to associate the Table with the defined Data
Provider. THis can be done by selecting the Table Properties and then
selecting the workflowServiceGetTasksForUser
data provider. Select the Priority, Status, Start Date,
Assigned To, flexString1 fields so they are displayed and then add
three additional columns that should be defined as Buttons with the
following text View, Escalate and Accept. Select Ok and the table will
be displayed.
Note:
For some reason within the current release of NetBeans you are unable to go back into the Table Layout option because NetBeans fails to refresh the Data Providers. If you need to do any changes you will have to do it using the Page Navigator.
In addition when importing the EJB you may notice that the classes created for the getTasksForuser method have different names to those in my example export. My export has WorkflowServiceGetTasksForUser2 for the name of the 2 parameter method. If this does occur then simply change the name of the imported class an all references. This seems to be a feature of the EJB import process.
Because the getTaskForUser Method requires two input parameters we need to modify the preprocess and prerender methods to set these correctly so that when the page is display the tasks for the logon user will be displayed. To facility this we will need to modify the methods as follows:
public void preprocess() {
defineTaskFilter();
}
public void prerender() {
defineTaskFilter();
}
private void defineTaskFilter() {
if (stateFilterDD.getSelected() == null | "All".equals(stateFilterDD.getSelected())) {
log("*** APH-I1 : Select All filter"
;
taskFilter = new TaskFilter();
} else {
try {
log("*** APH-I1 : Select " + stateFilterDD.getSelected() + " filter"
;
taskFilter = new TaskFilter(TaskFilter.TaskFilterType_ByTaskStatus, (String) stateFilterDD.getSelected());
} catch (TaskException ex) {
Logger.getLogger(TaskListPage.class.getName()).log(Level.SEVERE, null, ex);
error(ex.getMessage());
}
}
workflowServiceGetTasksForUser.setArg0(getSessionBean1().getUsername());
workflowServiceGetTasksForUser.setArg1(taskFilter);
workflowServiceGetTasksForUser.refresh();
}
The defineTaskFilter method check to see if we need to do Task State filtering in addition to Username filtering. To retrieve all tasks for a user simple assign an empty TaskFilter to Arg1.

The following code should added for each of the buttons.
public String viewBtn_action() {
getSessionBean1().setTaskId((String) getValue("#{currentRow.value['taskId']}"
);
return "viewtask";
}
public String escalateBtn_action() {
try {
String taskId = (String) getValue("#{currentRow.value['taskId']}"
;
List taskIdList = new ArrayList();
taskIdList.add(taskId);
TaskFilter taskFilter = new TaskFilter(TaskFilter.TaskFilterType_ByTaskIdList, taskIdList);
getWorkflowServiceClient().escalateTasks(getSessionBean1().getUsername(), taskFilter);
} catch (Exception ex) {
Logger.getLogger(TaskListPage.class.getName()).log(Level.SEVERE, null, ex);
error(ex.getMessage());
}
getWorkflowServiceGetTasksForUser().refresh();
return null;
}
public String acceptBtn_action() {
try {
String taskId = (String) getValue("#{currentRow.value['taskId']}"
;
List taskIdList = new ArrayList();
taskIdList.add(taskId);
TaskFilter taskFilter = new TaskFilter(TaskFilter.TaskFilterType_ByTaskIdList, taskIdList);
getWorkflowServiceClient().checkoutTasks(getSessionBean1().getUsername(), taskFilter);
getWorkflowServiceClient().setOutput(taskId, "Accept"
;
getWorkflowServiceClient().checkinTasks(getSessionBean1().getUsername(), taskFilter);
getWorkflowServiceClient().completeTasks(getSessionBean1().getUsername(), taskFilter);
} catch (Exception ex) {
Logger.getLogger(TaskListPage.class.getName()).log(Level.SEVERE, null, ex);
error(ex.getMessage());
}
return null;
}
The View Button will simple copy the current taskId to the SessionBean and then call the Task Details page. When the Escalate Button is pressed it will take the current Task and execute the escalateTasks for this user. We could, if we provided multiple select option, escalate multiple tasks by simply building up the list of Task Ids. To accept / authorise a task we will need to first check out the task from the WLM, which indicates that we will be processing this task then update the appropriate fields. Once this has been done the task will be checked in and completed. If a number of screens need to be associated with the Task acceptance on a user needs to lock a task whilst they are processing it then the methods may be called separately.
- The Task Details Page simply displays the input information
associated with the selected Task, identified by the value written to
the taskId property with the Session Bean, its details will be selected
again on entry to the Page.

The fields displayed within this Page are bound to the Task Page property and its sub properties. The following code defines the Task Property and the appropriate button actions. I will say little else about this page and leave you to create your own.
// Properties
private Task task = null;
public Task getTask() {
if (task == null) {
try {
task = getWorkflowServiceClient().getTaskById(getSessionBean1().getTaskId());
} catch (Exception ex) {
Logger.getLogger(TaskListPage.class.getName()).log(Level.SEVERE, null, ex);
error(ex.getMessage());
}
}
return task;
}
public void setTask(Task task) {
this.task = task;
}
private Option[] assignedArray = null;
public Option[] getAssignedArray() {
if (assignedArray == null) {
assignedArray = new Option[getTask().getAssignedTo().size()];
Iterator<String> assignedItr = getTask().getAssignedTo().iterator();
String assignedTo = null;
int optionIdx = 0;
while(assignedItr.hasNext()) {
assignedTo = assignedItr.next();
assignedArray[optionIdx++] = new Option(assignedTo,assignedTo);
}
}
return assignedArray;
}
// Methods
// Button Actions
public String taskListBtn_action() {
// TODO: Process the action. Return value is a navigation
// case name where null will return to the same page.
return "taskList";
}
public String escalateBtn_action() {
try {
String taskId = getSessionBean1().getTaskId();
List taskIdList = new ArrayList();
taskIdList.add(taskId);
TaskFilter taskFilter = new TaskFilter(TaskFilter.TaskFilterType_ByTaskIdList, taskIdList);
getWorkflowServiceClient().escalateTasks(getSessionBean1().getUsername(), taskFilter);
} catch (Exception ex) {
Logger.getLogger(TaskListPage.class.getName()).log(Level.SEVERE, null, ex);
error(ex.getMessage());
}
return "taskList";
}
public String acceptBtn_action() {
try {
String taskId = getSessionBean1().getTaskId();
List taskIdList = new ArrayList();
taskIdList.add(taskId);
TaskFilter taskFilter = new TaskFilter(TaskFilter.TaskFilterType_ByTaskIdList, taskIdList);
getWorkflowServiceClient().checkoutTasks(getSessionBean1().getUsername(), taskFilter);
getWorkflowServiceClient().setOutput(taskId, "Accept"
;
getWorkflowServiceClient().checkinTasks(getSessionBean1().getUsername(), taskFilter);
getWorkflowServiceClient().completeTasks(getSessionBean1().getUsername(), taskFilter);
} catch (Exception ex) {
Logger.getLogger(TaskListPage.class.getName()).log(Level.SEVERE, null, ex);
error(ex.getMessage());
}
return "taskList";
}
public String rejectBtn_action() {
try {
String taskId = getSessionBean1().getTaskId();
List taskIdList = new ArrayList();
taskIdList.add(taskId);
TaskFilter taskFilter = new TaskFilter(TaskFilter.TaskFilterType_ByTaskIdList, taskIdList);
getWorkflowServiceClient().checkoutTasks(getSessionBean1().getUsername(), taskFilter);
getWorkflowServiceClient().setOutput(taskId, "Reject"
;
getWorkflowServiceClient().checkinTasks(getSessionBean1().getUsername(), taskFilter);
getWorkflowServiceClient().completeTasks(getSessionBean1().getUsername(), taskFilter);
} catch (Exception ex) {
Logger.getLogger(TaskListPage.class.getName()).log(Level.SEVERE, null, ex);
error(ex.getMessage());
}
return "taskList";
}
- The
project can now be built and deployed to Application Server running the
WorkflowServices.jar








Hi. Could you help me. I'm trying to figure out how to develop a custom GUI for the WLM and wanted to get your example working, but in my case, my WLM business process is running in a 5.1.2 JCAPS domain. So I downloaded the WorkflowService.zip from the repository, edited the connection.properties, jar'd up the changes, created the client stubs from the JCAPS 5.1.2 domain, deployed the WorkflowService.jar ejb to 5.1.2 JCAPS domain and am trying to get your web app to connect from Netbeans Glassfish server running locally on my workstation. But I seem to be missing a piece. When I click the login button, it's unable to find the EJB context. I assume it's trying to find it locally in the Glassfish domain. I have imported the WorkflowServiceClient.jar into Netbeans. Do I have to modify the client manually to specify the JCAPS domain server and port to get it to find the EJB there?
Posted by sjhunyadi on May 08, 2009 at 08:41 PM GMT #