Code review

This section describes the code used to launch queries against the query table API of the WebSphere Process Server. For a quick start, you can simply select the name of a predefined query table that is shipped with the server. Optionally, you can use any query table of your choice by typing in the name of that query table.

The code snippets provided in this section have been extracted from the queryTablesEAR.ear enterprise application that is available from the Download section of this sample.

There are two source files that make up the core of this sample:

  1. index.jsp
    This JSP file implements the simple user interface for specifying a query and for rendering the result from the server. The file contains one HTML form with all control elements to let the user specify the query in detail. The Submit button of the form issues an HTTP Get request to the QueryServlet servlet class, thereby transmitting the actual parameter values to the servlet class.
    You can select the name of the query table via radio button, specify optional parameters for restricting the columns and/or rows, and then submit the query.

    Hint:

    For simplicity, the names of the predefined query tables are duplicated in the source code of this sample. This list can be found in the Information Center section Predefined query tables. Note that starting with WebSphere Process Server 6.2.0.1, you can query the list predefined query tables dynamically, using the API method findQueryTableMetaData as described in the section Query table queries for meta data retrieval.

    The column headers and the actual rows are retrieved from the result object and then rendered as html table.
    Finally, this JSP file will render the Java code that is used for the actual calls to the query table API. When the input parameters are changed, the rendered Java code snippet is updated accordingly. However, the complete code that is actually run on the server can be found in the Java file QueryServlet.java.
    All the elements of the JSP file are for the purpose to create HTML code dynamically; these are not explained here in more detail.

  2. QueryServlet.java
    This Java file contains the actual calls to the query table API. It extracts the query table name and the optional parameters as String values from the HTTP request, translates these parameters into the appropriate filter options and then uses the method queryEntities to do the actual call.
    On success, the result is passed back to the HTTP request; on failure, the exception details are passed back instead.

As mentioned, all the following explanations are focussing on the API calls used inside the QueryServlet.java file. If you need more details about the configuration needed to use the Business Flow Manager API, refer to the samples EJB API - Overview and EJB API - Details in the same samples category 'Interaction with processes and human tasks'.

Note: In the following code sections, exception handling is left out. A detailed description of the exceptions thrown by the particular commands can be found in the Javadoc.

QueryServlet.java

As mentioned, the file QueryServlet.java contains the actual code that uses the query table API. This servlet is implemented by inheriting from the Servlet class and thereby overwriting the doGet and the doPost methods; these methods do implement the behaviour when HTTP GET and HTTP POST are issued against this servlet. Here, we want identical behaviour for GET and the POST requests, thus we can simply reuse the code of the POST method for the GET method:

public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
  doPost(req, resp);
}

The doPost method now will do the actual work.
In that method, first the parameter strings are extracted from the HTTP request:

  String queryTable     = request.getParameter("selection");
  String selAttributes  = request.getParameter("attributes");
  String queryCondition = request.getParameter("condition");
  String other          = request.getParameter("other");

The query table name was specified as radio button setting and passed in the URL as parameter "selection", with one exception: when the user has selected "[OTHER]" then the name should rather be extracted from the text field named "other":

  if (queryTable!=null && queryTable.equals("[OTHER]")) {
    // special case, use parameter "other" instead
    queryTable = other;
  }

The query table name is attached, even if null, as attribute to HTTP request. Therefore the caller JSP will be able to see what was understood after extracting, removing escape chars, etc.:

  request.setAttribute("queryTable", queryTable);

The JNDI lookup for the remote EJB and the initialization of the session bean for the Business Flow Manager EJB is encapsulated in the auxiliary method that is defined at the end of this java file. Refer to the sample EJB API - Overview for more details. The auxiliary method is called now:

    BusinessFlowManagerService bfmService = getBFMService();

Next, filter options for the query are prepared and filled with the optional parameters if they were set by the user. In addition, a threshold for a maximum of 20 records is specified:

    FilterOptions filterOpts = new FilterOptions();
    filterOpts.setLocale(request.getLocale());
    filterOpts.setThreshold(new Integer(20));
    if (selAttributes!=null) {
      filterOpts.setSelectedAttributes(selAttributes.trim());
    }
    if (queryCondition!=null) {
      filterOpts.setQueryCondition(queryCondition.trim());
    }

In case that a userid with admin privileges is logged in, AdminAuthorizationOptions are created that will be passed to the query table call later on. This allows to query both instance data and template data. Without passing AdminAuthorizationOptions, queries for instance data will work, but queries for template data will be rejected with error "CWWBE0027E: No authorization for the requested action."
By default, null will be passed as AuthorizationOptions parameter:

    AdminAuthorizationOptions authOpts = null;

For users in the BPESystemAdministrator J2EE role only, the AdminAuthorizationOptions class is instantiated. There is no need to call any setters, just passing this instance as AuthorizationOptions parameter is sufficient to get access to template data:

    if (bfmService.isBusinessProcessAdministrator()) {
      // grant privileges to look at template data:
      authOpts = new AdminAuthorizationOptions();
    }

Finally, the call to the query table is issued:

    EntityResultSet ers = bfmService.queryEntities(queryTable, filterOpts, authOpts, null);

If no exception occurred, the result is attached to the HTTP request:

    request.setAttribute("result", ers);

Otherwise, if an exception has occurred, simple error handling is performed instead:

  try {
    ...
  } catch (Exception e) {
    e.printStackTrace(System.out);
    request.setAttribute("exception", e.getMessage());
  }

Click on the links to see the complete source code of the index.jsp and the QueryServlet.java.