BEA Logo BEA WebLogic Java Adapter for Mainframe Release 4.2

  BEA Home  |  Events  |  Solutions  |  Partners  |  Products  |  Services  |  Download  |  Developer Center  |  WebSUPPORT

 

   JAM Documentation   |   JAM Scenarios Guide   |   Previous Topic   |   Next Topic   |   Contents   |   Index

Developing a Multi-Service Data Entry Servlet

 

This section contains a scenario that shows how to develop a multi-service application for WebLogic Server. The concepts presented for the servlet-only application model described in the BEA WebLogic Java Adapter for Mainframe Programming Guide are used and extended for this scenario

In this scenario, a new application is developed and existing applications are updated. WebLogic Server samples are used to illustrate any existing applications. All discussions are from the application developer's point of view.

Note: Although the sample code in this section represents typical applications, it is intended for example only and is not supported for actual use.

 


Action List

The following table lists the tasks that must be completed to develop a multi-service data entry servlet.

 

Your action...

Refer to...

1

Verify that prerequisite tasks have been completed.

Prerequisites

2

Use eGen COBOL Code Generator to generate an application.

Task 1: Use the eGen COBOL Code Generator to Generate an Application

3

Create your custom application from the generated application.

Task 2: Create Your Custom Application from the Generated Application

4

Update the JAM configurations and update WebLogic Server configuration.

Task 3: Update the JAM Configurations and Update BEA WebLogic Server web.xml File

5

Deploy your application.

Task 4: Deploy Your Application

6

Use the application.

Task 5: Use the Application

The following example creates a servlet that invokes the sample COBOL programs described at the end of this chapter.

 


Prerequisites

Before you begin to develop a multi-service data entry servlet, ensure that the following prerequisites have been completed.

 

Your action...

Refer to...

1

Verify that the required software has been properly installed: WebLogic Server, WebLogic Java Adapter for Mainframe.

BEA WebLogic Server documentation, BEA WebLogic Java Adapter for Mainframe Installation Guide

2

Verify that the environment and the software components have been properly configured.

BEA WebLogic Server documentation, BEA WebLogic Java Adapter for Mainframe Configuration and Administration Guide

3

Verify the appropriate mainframe application is available.

Your mainframe system administrator

4

Review the steps to develop a single service application.

BEA WebLogic Java Adapter for Mainframe Programming Guide

Task 1: Use the eGen COBOL Code Generator to Generate an Application

Identify the mainframe application and obtain its COBOL copybook, usually a CICS DFHCOMAREA or the user data portion of an IMS queue record layout. The copybook's name in this discussion is emprec.cbl, as shown in Listing 1-1.

Listing 1-1 Mainframe Application COBOL Copybook emprec.cbl

02  emp-record.
05 emp-ssn pic 9(9) comp-3.
05 emp-name.
10 emp-name-last pic x(15).
10 emp-name-first pic x(15).
10 emp-name-mi pic x.
05 emp-addr.
10 emp-addr-street pic x(30).
10 emp-addr-st pic x(2).
10 emp-addr-zip pic x(9).

Step 1: Prepare eGen COBOL Script

The script shown in Listing 1-2 generates the emprecData DataView from the copybook named emprec.cbl.

Listing 1-2 Basic eGen script

view empRecData from emprec.cbl

Step 2: Add Service Entries

Add the single line service entries in Listing 1-3 for create, read, update, and delete operations. They all use empRecData as input and return emprecData as output. In this example, a single DataView is used; however, the input and output DataViews could be different.

Listing 1-3 Service Names Associated with Input and Output Views

service empRecCreate accepts empRecData returns empRecData
service empRecRead accepts empRecData returns empRecData
service empRecUpdate accepts empRecData returns empRecData
service empRecDelete accepts empRecData returns empRecData

Step 3: Add Page Declaration in eGen COBOL Script

Multiple pages can be chained together. Any service entries should match services defined elsewhere in the script. The page declarations shown in Listing 1-4 associate buttons on the HTML display with services declared in the previous step.

Listing 1-4 Page Declaration Associating Display Buttons with Services

page empRecPage "Employee Record" 
{
view empRecData
buttons
{
"Create" service(empRecCreate) shows empRecPage
"Read" service(empRecRead) shows empRecPage
"Update" service(empRecUpdate) shows empRecPage
"Delete" service(empRecDelete) shows empRecPage
}
}

Step 4: Add Servlet Name

As shown in Listing 1-5, empRecServlet is the servlet name to be registered at a URL in the WebLogic Server web.xml file. (Every servlet requires a URL to be registered this way. Refer to WebLogic Server documentation about deploying servlets for more specific information.) Here, the empRecPage is to be displayed when the empRecServlet is invoked.

Listing 1-5 Add Servlet Name

servlet empRecServlet shows empRecPage

The script is saved as emprec.egen.

Step 5: Generate the Java Source Code

Use the eGen COBOL Code Generator to generate the application as shown in Listing 1-6. These classes will be extended in Task 2 to customize the servlet. The empRecData.java is the DataView object for emprec.cbl.

Warning: CLASSPATH should include the WebLogic Server .jar files and the jam.jar file; otherwise, the compile fails.

Note: You can create a script file containing the eGen COBOL command line, along with the javac command to make the invocation easier.

Listing 1-6 Generating the Java Source Code

$egencobol emprec.egen
$ls emp*.java
empRecData.java
empRecServlet.java

$javac emp*.java

Step 6: Review the Java Source Code

Obtain a list of accessors for use later. Look at the eGen COBOL output to become familiar with each of the scenarios presented in this section.

The entire method of customizing the generated output is predicated on derivation from generated code. The application can be regenerated without destroying the custom code.

Note: Each COBOL group item has its own accessor. This is important because the group name represents a nested inner class that must be accessed in order to retrieve the members.

In the Listing 1-7, the output from the grep command shows the relationships in reverse order, for example:

getEmpRecord().getEmpAddr().getEmpAddrSt()

This relationship is illustrated in the actual code example shown in Listing 1-7.

Listing 1-7 Review the Java Source Code

$grep get emp*.java
empRecData.java: public BigDecimal getEmpSsn()
empRecData.java: public String getEmpNameLast()
empRecData.java: public String getEmpNameFirst()
empRecData.java: public String getEmpNameMi()
empRecData.java: public EmpNameV getEmpName()
empRecData.java: public String getEmpAddrStreet()
empRecData.java: public String getEmpAddrSt()
empRecData.java: public String getEmpAddrZip()
empRecData.java: public EmpAddrV getEmpAddr()
empRecData.java: public EmpRecordV getEmpRecord()

Task 2: Create Your Custom Application from the Generated Application

The preferred customization method is to derive a custom class from the generated application.

Step 1: Start with Imports

In Listing 1-8, BigDecimal supports COMP-3 packed data. HttpSession is available for saving limited state. DataView is the base for emprecData. The empRecData and empRecServlet were generated from the COBOL copybook.

Listing 1-8 Using Imports to Start Creating the Custom Application

import java.math.BigDecimal;
import javax.servlet.http.HttpSession;
import bea.dmd.dataview.DataView;
import empRecData;
import empRecServlet;

Step 2: Declare the New Custom Class

Listing 1-9 shows how to extend the generated servlet. This method enables regeneration of the application without destroying customized code. Fields can be added to the copybook without disrupting the customized code.

Listing 1-9 Declaring the New Custom Class

public class customCrud 
extends empRecServlet
{
:
:

Step 3: Add Implementation for doGetSetup

Listing 1-10 demonstrates how to provide a new DataView and the http session. The HttpSession(s) can be used to hold a reference to the DataView, ensuring that you are actually in the first pass rather than a browser back arrow. The DataView provided (dv) is a fresh instance of the empRecData DataView. Refer to the BEA WebLogic Java Adapter for Mainframe Programming Guide for more information on doGetSetup.

Listing 1-10 Add Implementation for doGetSetup

public DataView doGetSetup(DataView dv, HttpSession s){ 
empRecData erd = (empRecData)s.getValue("customCrud");
if (erd == null)
erd = (empRecData)dv; // use new dataview

In Listing 1-11, note the use of group level accessors to obtain fields. This code pre-fills fields with data entry hints as to which fields are required or how numeric values should be entered. You can fill form data in any manner required prior to displaying the fields.

Listing 1-11 Continue Implementation for doGetSetup

if(erd.getEmpRecord().getEmpSsn().compareTo(BigDecimal.valueOf(0L)) == 0)
erd.getEmpRecord().setEmpSsn(BigDecimal.valueOf(123121234L));

if (erd.getEmpRecord().getEmpName().getEmpNameLast().length() == 0)
erd.getEmpRecord().getEmpName().setEmpNameLast("Entry Required");

if (erd.getEmpRecord().getEmpName().getEmpNameFirst().trim().length() == 0)
erd.getEmpRecord().getEmpName().setEmpNameFirst("Entry Required");

if (erd.getEmpRecord().getEmpAddr().getEmpAddrStreet().trim().length() == 0)
erd.getEmpRecord().getEmpAddr().setEmpAddrStreet("Entry Required");

if (erd.getEmpRecord().getEmpAddr().getEmpAddrSt().trim().length() == 0)
erd.getEmpRecord().getEmpAddr().setEmpAddrSt("TX");

if (erd.getEmpRecord().getEmpAddr().getEmpAddrZip().trim().length() == 0)
erd.getEmpRecord().getEmpAddr().setEmpAddrZip("123451234");

In Listing 1-12, note the use of the HttpSession putValue to save a reference to the DataView. The doGet() processing continues on return. This data is be presented in the displayed form.

Listing 1-12 Finish Implementation for doGetSetup

s.putValue("customCrud",(Object)erd);
return erd;
}

Step 4: Create Implementation for doPostSetup

In Listing 1-13, the DataView passed in contains values entered into the form by the application user. (The HttpSession is also available for use at this point, if required.) Refer to the BEA WebLogic Java Adapter for Mainframe Programming Guide for more information on doPostSetup.

Listing 1-13 Create Implementation for doPostSetup

public DataView doPostSetup(DataView dv, HttpSession s)
{
empRecData erd = (empRecData)dv;

In Listing 1-14, note the use of group-level accessors to obtain fields. This code checks for original defaults, as well as missing data. SocialSecurity is a BigDecimal object. Validation can be simple or complex as required.

Listing 1-14 Continue implementation for doPostSetup

if(erd.getEmpRecord().getEmpSsn().compareTo(BigDecimal.valueOf(0L)) == 0)
throw new Error("Social Security Number Is Required");
if(erd.getEmpRecord().getEmpSsn().compareTo(BigDecimal.valueOf(123121234L)) == 0)
throw new Error("Social Security Number Is Required");
if (erd.getEmpRecord().getEmpName().getEmpNameLast() == null)
throw new Error("Last Name Is Required");
if (erd.getEmpRecord().getEmpName().getEmpNameLast().trim().length() == 0)
throw new Error("Last Name Is Required");
if (erd.getEmpRecord().getEmpName().getEmpNameLast().trim().compareTo("EntryRequired") == 0)
throw new Error("Last Name Is Required");

In Listing 1-15, note the use of group-level accessors to obtain fields. This code checks for original defaults, as well as missing data. (Validation routines could have been split out by field.)

Listing 1-15 Continue Implementation of doPostSetup

if (erd.getEmpRecord().getEmpName().getEmpNameFirst() == null)
throw new Error("First Name Is Required");
if (erd.getEmpRecord().getEmpName().getEmpNameFirst().trim().length == 0)
throw new Error("First Name Is Required");
if (erd.getEmpRecord().getEmpName().getEmpNameFirst().trim().compareTo("Entry
Required") == 0)
throw new Error("First Name Is Required");
if (erd.getEmpRecord().getEmpAddr().getEmpAddrStreet() == null)
throw new Error("Street Address Is Required");
if (erd.getEmpRecord().getEmpAddr().getEmpAddrStreet().trim().length() == 0)
throw new Error("Street Address Is Required");
if (erd.getEmpRecord().getEmpAddr().getEmpAddrStreet().trim().compareTo("Entry
Required") == 0)
throw new Error("Street Address Is Required");

In Listing 1-16, notice the use of group-level accessors to obtain fields. This code checks for original defaults, as well as missing data. Depending on the application, it may be more advantageous to develop validations as separate methods. This development process enables routines to be developed and tested with a servlet and easily re-used in an EJB.

Listing 1-16 Continue Implementation for doPostSetup

if (erd.getEmpRecord().getEmpAddr().getEmpAddrSt() == null)
throw new Error("State Abreviation Is Required");

if (erd.getEmpRecord().getEmpAddr().getEmpAddrSt().trim().length() == 0)
throw new Error("State Abreviation Is Required");

if (erd.getEmpRecord().getEmpAddr().getEmpAddrSt()
.trim().compareTo("TX") != 0)
throw new Error("Texas Employees ONLY");

if (erd.getEmpRecord().getEmpAddr().getEmpAddrZip() == null)
throw new Error("ZipCode Is Required");

if (erd.getEmpRecord().getEmpAddr().getEmpAddrZip().trim().length() == 0)
throw new Error("ZipCode Is Required");

if erd.getEmpRecord().getEmpAddr().getEmpAddrZip().trim().compareTo
("123451234") == 0)
throw new Error("ZipCode Is Required");

In Listing 1-17, the HttpSession is used to remove a reference to the DataView. This method prevents re-posting the same data twice. The doPost processing continues on return. This data is now passed to the mainframe.

Listing 1-17 Finish Implementation for doPostSetup

else
s.removeValue("customCrud");
return erd;
}

Step 5: Create Implementation for doPostFinal

In Listing 1-18, the doPostFinal occurs after mainframe transmission, but prior to re-display in the browser. This example clears entered data after it is sent to the mainframe. This step completes the custom servlet.

Listing 1-18 Create Implementation for doPostFinal

public DataView doPostFinal(DataView dv, HttpSession s)
{
empRecData erd = (empRecData)dv;
erd.getEmpRecord().setEmpSsn(BigDecimal.valueOf(0L));
erd.getEmpRecord().getEmpName().setEmpNameLast("");
erd.getEmpRecord().getEmpName().setEmpNameFirst("");
erd.getEmpRecord().getEmpName().setEmpNameMi("");
erd.getEmpRecord().getEmpAddr().setEmpAddrStreet("");
erd.getEmpRecord().getEmpAddr().setEmpAddrSt("");
erd.getEmpRecord().getEmpAddr().setEmpAddrZip("");
return erd;
}

Step 6: Update the jcrmgw.cfg File with Service Entries

Listing 1-19 shows definitions of the entries that are used when the corresponding Create/Read/Update/Delete form buttons are pushed; for example, the Create button triggers empRecCreate which invokes DPLDEMOC. The gateway must be restarted for the new services to take effect.

Listing 1-19 Update jcrmgw.cfg File

empRecCreate         RDOM="CICS410"
RNAME="DPLDEMOC"
empRecRead RDOM="CICS410"
RNAME="DPLDEMOR"
empRecUpdate RDOM="CICS410"
RNAME="DPLDEMOU"
empRecDelete RDOM="CICS410"
RNAME="DPLDEMOD"

Step 7: Create Basic Three-Part HTML Frame

In Listing 1-20, the primary frame (identified as "main" in the HTML code) displays the servlet, while an auxiliary frame provides links to HELP pages. The "Built on BEA WebLogic" logo is also displayed. A single line of Java script is used to ensure the window displays in the foreground.

Listing 1-20 Create Basic Three-Part HTML Frame

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<title>eGen</title>
</head>
<script language="javascript">
<!--
if (window.focus) {self.focus();} // -->
</script>
<FRAMESET cols="20%, 80%">
<FRAMESET rows="20%, 80%">
<FRAME src="bea_built_on_wl.gif" name="logo">
<FRAME src="panel.html" name="aux">
</FRAMESET>
<FRAME src="http://machine.domain.com:7001/empRec" name="main">
</FRAMESET>
</html>

Step 8: Create a Series of Links to HELP Pages

Listing 1-21 shows how the HTML can display as a sidebar frame. The intro.html, emprec.html, and create.html can display inside the "main" frame to provide basic HELP.

Listing 1-21 Creating a Series of HELP Page Links

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head> <title>eGen help</title> </head>
<script language="javascript">
<!--
if (window.focus) {self.focus();} // -->
</script>
<body>
<TABLE summary="This table contains links to help pages.">
<TR> <TH>empRec Info</TH>
<TR> <TD><a href="intro.html" target="help">Introduction </a>
<TR> <TD><a href="emprec.html" target="help">EmpRec </a>
<TR> <TD><a href="create.html" target="help">Create </a>
<TR> <TD><a href="read.html" target="help">Read </a>
<TR> <TD><a href="update.html" target="help">Update </a>
<TR> <TD><a href="delete.html" target="help">Delete </a>
</TABLE>
</body>
</html>

Task 3: Update the JAM Configurations and Update BEA WebLogic Server web.xml File

Update the jcrmgw.cfg file with the remote service entries shown in Listing 1-22. The Java gateway must be restarted for new services. The entries are used when the corresponding form button is pushed. For example, the Create button triggers empRecCreate, which invokes DPLDEMOC. The service name must match values in the eGen script. In this example, the RNAME must match an actual CICS program name.

Listing 1-22 Remote Service Entries for Create/Read/Update/Delete

empRecCreate         RDOM="CICS410"
RNAME="DPLDEMOC"
empRecRead RDOM="CICS410"
RNAME="DPLDEMOR"
empRecUpdate RDOM="CICS410"
RNAME="DPLDEMOU"
empRecDelete RDOM="CICS410"
RNAME="DPLDEMOD"

Update the WebLogic Server web.xml file with the entries shown in Listing 1-23. For more information, see the WebLogic Server documentation.

Listing 1-23 Update WebLogic Server web.xml File

<?xml version="1.0" ?> 
<!DOCTYPE web-app (View Source for full doctype...)>
<web-app>
<servlet>
<servlet-name>customCrud</servlet-name>
<servlet-class>customCrud</servlet-class>
</servlet>
- <servlet-mapping>
<servlet-name>customCrud</servlet-name>
<url-pattern>customCrud</url-pattern>
</servlet-mapping>
</web-app>

Task 4: Deploy Your Application

At this point, you have created a basic form capable of receiving data entry, along with some static HTML code for display. For a complete description of how to deploy a servlet, refer to the WebLogic Server documentation. For evaluation purposes, refer to the BEA WebLogic Server Quick Start Guide.

Task 5: Use the Application

Figure 1-1 shows the default servlet with customized code displayed in an HTML frame. This type of servlet is useful for presentation, proof-of-concept, and as a test bed for development.

Figure 1-1 New Data Entry Servlet Display


 

Figure 1-2 shows the servlet with the Create HELP page displayed in a new window on top of the application window.

Figure 1-2 Servlet with HELP Page Displayed


 

Figure 1-3 is an example of the page used for the front end of the new custom servlet.

Figure 1-3 New Data Entry Servlet Front End Page


 

 


Sample COBOL Programs Invoked by the Multi-Service Data Entry Servlet

The following section describe show COBOL programs for each of these button and service combinations:

All of these programs make use of a CICS temporary storage queue for data. This simple technique is useful for testing and demonstrations.

Create

The simple program shown in Listing 1-24 writes a temporary storage queue using the first eight characters of the employee name as the QID.

Listing 1-24 COBOL Program for Create (DPLDEMOC)

IDENTIFICATION DIVISION.
PROGRAM-ID. DPLDEMOC.
INSTALLATION.
DATE-COMPILED.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TSQ-DATA-LENGTH PIC S9(4) COMP VALUE ZERO.
01 TSQ-NAME.
05 TSQ-ID PIC X(8) VALUE SPACES.
05 FILLER PIC X(30) VALUE SPACES.
LINKAGE SECTION.
01 DFHCOMMAREA.
COPY EMPREC.
PROCEDURE DIVISION.
MAINLINE SECTION.
MOVE EMP-NAME TO TSQ-NAME
MOVE LENGTH OF EMP-RECORD
TO TSQ-DATA-LENGTH
EXEC CICS WRITEQ TS
QUEUE(TSQ-ID)
FROM(EMP-RECORD)
LENGTH(TSQ-DATA-LENGTH)
END-EXEC.
EXEC CICS RETURN
END-EXEC.
EXIT.

Read

The simple program shown in Listing 1-25 reads a temporary storage queue using the first eight characters of the employee name as the QID. If the read fails, the COMMAREA is reset so that residual data does not appear as the result of a read.

Listing 1-25 COBOL Program for Read (DPLDEMOR)

IDENTIFICATION DIVISION.
PROGRAM-ID. DPLDEMOR.
INSTALLATION.
DATE-COMPILED.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TSQ-DATA-LENGTH PIC S9(4) COMP VALUE ZERO.
01 TSQ-RESP PIC S9(4) COMP VALUE ZERO.
01 TSQ-NAME.
05 TSQ-ID PIC X(8) VALUE SPACES.
05 FILLER PIC X(30) VALUE SPACES.
LINKAGE SECTION.
01 DFHCOMMAREA.
COPY EMPREC.
PROCEDURE DIVISION.
MAINLINE SECTION.
MOVE EMP-NAME TO TSQ-NAME
MOVE LENGTH OF EMP-RECORD
TO TSQ-DATA-LENGTH
EXEC CICS READQ TS
ITEM(1)
INTO(EMP-RECORD)
QUEUE(TSQ-ID)
LENGTH(TSQ-DATA-LENGTH)
RESP(TSQ-RESP)
END-EXEC.
IF TSQ-RESP NOT EQUAL ZERO
MOVE ZEROS TO EMP-SSN
MOVE SPACES TO EMP-NAME-FIRST
MOVE SPACES TO EMP-NAME-MI
MOVE SPACES TO EMP-ADDR
END-IF
EXEC CICS RETURN
END-EXEC.

Update

The simple program shown in Listing 1-26 deletes a temporary storage queue using the first eight characters of the employee name as the QID. It then creates a new queue with the COMMAREA provided.

Listing 1-26 COBOL Program for Update (DPLDEMOU)

IDENTIFICATION DIVISION.
PROGRAM-ID. DPLDEMOU.
INSTALLATION.
DATE-COMPILED.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TSQ-DATA-LENGTH PIC S9(4) COMP VALUE ZERO.
01 TSQ-NAME.
05 TSQ-ID PIC X(8) VALUE SPACES.
05 FILLER PIC X(30) VALUE SPACES.
LINKAGE SECTION.
01 DFHCOMMAREA.
COPY EMPREC.
PROCEDURE DIVISION.
MAINLINE SECTION.
MOVE EMP-NAME TO TSQ-NAME
MOVE LENGTH OF EMP-RECORD
TO TSQ-DATA-LENGTH
EXEC CICS DELETEQ TS
QUEUE(TSQ-ID)
END-EXEC.
EXEC CICS WRITEQ TS
QUEUE(TSQ-ID)
FROM(EMP-RECORD)
LENGTH(TSQ-DATA-LENGTH)
END-EXEC.
EXEC CICS RETURN
END-EXEC.
EXIT.

Delete

This simple program shown in Listing 1-27 deletes a temporary storage queue using the first eight characters of the employee name as the QID. The COMMAREA is reset so that residual data does not remain after the delete.

Listing 1-27 COBOL Program for Delete (DPLDEMOD)

IDENTIFICATION DIVISION.
PROGRAM-ID. DPLDEMOD.
INSTALLATION.
DATE-COMPILED.
ENVIRONMENT DIVISION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TSQ-DATA-LENGTH PIC S9(4) COMP VALUE ZERO.
01 TSQ-NAME.
05 TSQ-ID PIC X(8) VALUE SPACES.
05 FILLER PIC X(30) VALUE SPACES.
LINKAGE SECTION.
01 DFHCOMMAREA.
COPY EMPREC.
PROCEDURE DIVISION.
MAINLINE SECTION.
MOVE EMP-NAME TO TSQ-NAME
MOVE LENGTH OF EMP-RECORD
TO TSQ-DATA-LENGTH
EXEC CICS DELETEQ TS
QUEUE(TSQ-ID)
END-EXEC.
MOVE SPACES
TO DFHCOMMAREA
MOVE ZEROS TO EMP-SSN
EXEC CICS RETURN
END-EXEC.
EXIT.

 

back to top previous page next page