Implementing the Task List

This post is part of a series on building a custom worklist for BPM/SOA 11g.

In the previous posts, we built the model and skeleton pages.  Now we will implement the Controller and View for the Task List.

Let’s take a look at the com.oracle.ateam.TaskListController code:

package com.oracle.ateam;

import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.oracle.ateam.domain.*;
import com.oracle.ateam.util.MLog;

import java.util.List;
import java.util.Map;
import java.util.HashMap;

public class TaskListController extends SimpleSuccessFailureController {

 @Override
 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
 throws Exception {
   MLog.log("TaskListController", "Entering handleRequest()");
   String filter = request.getParameter("x_assignee");
   String state = request.getParameter("x_state");
   if ((filter == null) || (filter.length() < 1)) filter = "megroup";
   if ((state == null) || (state.length() < 1)) state = "assigned";
   MLog.log("TaskListController", "Got filter=" + filter + ", state=" + state);
   Map<String, Object> model = new HashMap<String, Object>();
   List tasks = MTaskList.getMTasks(request.getUserPrincipal().getName(), filter, state);
   MLog.log("TaskListController", "Found " + ((tasks == null) ? "0" : tasks.size()) + " tasks.");
   model.put("tasks", tasks);
   return new ModelAndView("/WEB-INF/jsp/tasklist.jsp", "model", model);
 }

}

This is a simple Spring Controller that extends the SimpleSucessFailureController we saw earlier.  First we obtain the x_assignee and x_state parameters passed in from the caller.  These are used to determine the filtering of tasks in the list.  If these are empty, we set default values.

Next, we create a HashMap<String, Object> to hold the model.

Then, we call the List<MTask> MTaskList.getMTasks(user, filter, state) method in our domain package to obtain the list of tasks.  Note that this will give us back a list of partially populated tasks, as we discussed earlier.

We then add these tasks into the model.  Note that the line model.put(“tasks”, tasks) will add the List<MTask> tasks object to the model using the key (name) “tasks”.  This means we will be able to access it in the view using Expression Language such as ${model.tasks} and we will be able to access properties in MTask using the property name (abbreviated getter name), e.g. ${task.title}.  We will see this in the view shortly.  Note that the Express Language express {$task.title} means call the getTitle() method on the task object.

Finally, we return a new ModelAndView passing the view name and adding the model object, calling it “model”.

There are also some logging in there, and again, the code in Subversion has more comments.

The Controller is relatively simple as we have encapsulated the code that deals with the BPM API in our com.oracle.ateam.domain package.

Now, let’s take a look at the view.  Here is the code:

<%@ page import="com.oracle.ateam.util.MLog" %>
<%@ page import="com.oracle.ateam.domain.MTask" %>
<%@ page import="java.util.List" %>
<%@ include file="/WEB-INF/jsp/common/head.jspf" %>

<%
 MLog.log("tasklist.jsp", "Entered tasklist.jsp");
 String x_ass = request.getParameter("x_assignee");
 String x_st = request.getParameter("x_state");
 if ((x_ass == null) || (x_ass.length() < 1)) x_ass = "megroup";
 if ((x_st == null) || (x_st.length() < 1)) x_st = "assigned";
%>
 <form action="tasklist.do" method="POST">
 Filter by assignee:
 <select name="x_assignee">
<%      if ("me".compareTo(x_ass) == 0) {
%>      <option value="me" selected>Me</option>
<%      } else {
%>        <option value="me">Me</option>
<%      };
 if ("group".compareTo(x_ass) == 0) {
%>        <option value="group" selected>Group</option>
<%      } else {
%>        <option value="group">Group</option>
<%      };
 if ("megroup".compareTo(x_ass) == 0) {
%>        <option value="megroup" selected>Me and Group</option>
<%      } else {
%>        <option value="megroup">Me and Group</option>
<%      };
 if ("previous".compareTo(x_ass) == 0) {
%>        <option value="previous" selected>Previous</option>
<%      } else {
%>        <option value="previous">Previous</option>
<%      };
 if ("reviewer".compareTo(x_ass) == 0) {
%>        <option value="reviewer" selected>Reviewer</option>
<%      } else {
%>        <option value="reviewer">Reviewer</option>
<%      };
%>
 </select>
 and state:
 <select name="x_state">
<%      if ("any".compareTo(x_st) == 0) {
%>        <option value="any" selected>Any</option>
<%      } else {
%>        <option value="any">Any</option>
<%      };
 if ("assigned".compareTo(x_st) == 0) {
%>        <option value="assigned" selected>Assigned</option>
<%      } else {
%>        <option value="assigned">Assigned</option>
<%      };
 if ("completed".compareTo(x_st) == 0) {
%>        <option value="completed" selected>Completed</option>
<%      } else {
%>        <option value="completed">Completed</option>
<%      };
if ("suspended".compareTo(x_st) == 0) {
%>        <option value="suspended" selected>Suspended</option>
<%      } else {
%>        <option value="suspended">Suspended</option>
<%      };
 if ("withdrawn".compareTo(x_st) == 0) {
%>        <option value="withdrawn" selected>Withdrawn</option>
<%      } else {
%>        <option value="withdrawn">Withdrawn</option>
<%      };
 if ("expired".compareTo(x_st) == 0) {
%>        <option value="expired" selected>Expired</option>
<%      } else {
%>        <option value="expired">Expired</option>
<%      };
 if ("errored".compareTo(x_st) == 0) {
%>        <option value="errored" selected>Errored</option>
<%      } else {
%>        <option value="errored">Errored</option>
<%      };
 if ("alerted".compareTo(x_st) == 0) {
%>        <option value="alerted" selected>Alerted</option>
<%      } else {
%>        <option value="alerted">Alerted</option>
<%      };
 if ("info".compareTo(x_st) == 0) {
%>        <option value="info" selected>Information Requested</option>
<%      } else {
%>        <option value="info">Information Requested</option>
<%      };
%>    </select>
 <input type="submit" value="Update"/>
 </form>
 <table border="0" width="100%">
 <tr>
 <th class="tl-head" width="*">Title</th>
 <th class="th-head" width="150">Task Number</th>
 <th class="th-head" width="150">Outcome</th>
 <th class="th-head" width="150">Priority</th>
 <th class="th-head" width="150">State</th>
 </tr>
 </table>
 <table border="0" width="100%">
 <c:forEach var="task" items="${model.tasks}">
 <tr>
 <td class="th-row" width="*"><img src="images/task_untouched_16x16.png" height="13"/><c:out value="${task.id}"/></td>
 <td class="th-row" width="150"><a href="taskdetail.do?x_tasknumber=<c:out value="${task.number}"/>"><c:out value="${task.number}"/></a></td>
 <td class="th-row" width="150"><c:out value="${task.outcome}"/></td>
 <td class="th-row" width="150"><c:out value="${task.priority}"/></td>
 <td class="th-row" width="150"><c:out value="${task.state}"/></td>
 </tr>
 </c:forEach>
 </table>
<%@ include file="/WEB-INF/jsp/common/tail.jspf" %>
<%
 MLog.log("tasklist.jsp", "Done");
%>

The View technology is JSP with JSTL.  You can see at the start of the View, we have some import statements, and then we include /WEB-INF/jsp/common/head.jspf.  This JSP fragment handles the header and menu.  We created it in an earlier post.

<%@ page import="com.oracle.ateam.util.MLog" %>
<%@ page import="com.oracle.ateam.domain.MTask" %>
<%@ page import="java.util.List" %>
<%@ include file="/WEB-INF/jsp/common/head.jspf" %>

Next, we retrieve the x_assignee and x_state parameters from the request.  If the user selects a different option from the drop down lists, these will be passed back to us in these parameters, as we will see shortly.  If there are no values, we assign default values.

 String x_ass = request.getParameter("x_assignee");
 String x_st = request.getParameter("x_state");
 if ((x_ass == null) || (x_ass.length() < 1)) x_ass = "megroup";
 if ((x_st == null) || (x_st.length() < 1)) x_st = "assigned";

The next part of the page creates those two drop down filters.  You can see in the first part of that code (below) that it will post back to the same view.  The if/then/else logic in this section works out which item in the drop down list should be selected, based on the value that was passed in (or defaulted above).  This means that the user will see the current set of filter settings in the drop down boxes when they look at the page.

 <form action="tasklist.do" method="POST">
 Filter by assignee:
 <select name="x_assignee">
<%      if ("me".compareTo(x_ass) == 0) {
%>      <option value="me" selected>Me</option>
<%      } else {
%>        <option value="me">Me</option>
<%      };
 if ("group".compareTo(x_ass) == 0) {
%>        <option value="group" selected>Group</option>
<%      } else {
%>        <option value="group">Group</option>
<%      };

Next, we have the main part of the page, the table that displays the information about the tasks.  Here is the relevant section of the page:

 <table border="0" width="100%">
 <tr>
 <th class="tl-head" width="*">Title</th>
 <th class="th-head" width="150">Task Number</th>
 <th class="th-head" width="150">Outcome</th>
 <th class="th-head" width="150">Priority</th>
 <th class="th-head" width="150">State</th>
 </tr>
 </table>
 <table border="0" width="100%">
 <c:forEach var="task" items="${model.tasks}">
 <tr>
 <td class="th-row" width="*"><img src="images/task_untouched_16x16.png" height="13"/><c:out value="${task.id}"/></td>
 <td class="th-row" width="150"><a href="taskdetail.do?x_tasknumber=<c:out value="${task.number}"/>"><c:out value="${task.number}"/></a></td>
 <td class="th-row" width="150"><c:out value="${task.outcome}"/></td>
 <td class="th-row" width="150"><c:out value="${task.priority}"/></td>
 <td class="th-row" width="150"><c:out value="${task.state}"/></td>
 </tr>
 </c:forEach>
 </table>

Here we use JSTL to loop through the tasks in the model.  The construct c:forEach var=”task” items=”${model.tasks}” will repeat the enclosed HTML for each item in the List<MTask> that we put in the model using the key “tasks” back in the controller.

Within the loop, the current item is known as task, as set by the var=”task” part of that statement.  We can then access properties of the task using the syntax ${task.number} as we see in the sample above.

Note that the Task Number column contains an hyperlink to taskdetail.do and passes the task number as a parameter named x_tasknumber.

Finally, we also include the /WEB-INF/jsp/common/tail.jspf fragment to add the copyright notice and finish the page.

The CSS styles that we set up earlier will handle the look and feel of the page.

In the next post, we will build the Task Details Controller and View.

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