bea.com | products | dev2dev | support | askBEA |
|
e-docs > WebLogic Java Adapter for Mainframe > Programming Guide > Performing Your Own Data Translation |
Programming Guide |
Performing Your Own Data Translation
This section discusses the following topics:
Why Perform Your Own Data Translation?
The automatic data translation provided by DataViews can usually fill your needs. The eGen-generated DataViews relieve your application of the burden of translating data between the mainframe EBCDIC environment and the Java runtime environment. In addition, native mainframe data types that are not supported in Java (such as packed, zoned decimal, etc.) are automatically mapped to appropriate Java data types. However, occasionally you may want to bypass these features and create your own data translation. Following are some advantages of bypassing the eGen/DataView infrastructure:
If the data has been acquired in the appropriate format, it can simply be transmitted to the mainframe bypassing the DataView translation overhead.
In some cases, this may be preferable to a DataView generated from a copybook containing numerous REDEFINES representing various record types.
Simple interfaces are provided for translating data both from and to the mainframe. In addition, a simple callService() method is available for making mainframe service requests.
Using EgenClient Directly
EgenClient is the WebLogic JAM class responsible for making service calls from WebLogic Server to the mainframe. This class is the foundation of all WebLogic Server to Mainframe communication by eGen-created EJB and Servlet objects. EgenClient may also be used directly by applications to issue mainframe service requests. Listing 6-1 shows the public methods available for your use:
Listing 6-1 EgenClient Public Interface
package com.bea.jam.egen;
import java.io.IOException;
import com.bea.sna.jcrmgw.snaException;
public class EgenClient
{
public EgenClient();
public EgenClient(String serverURL);
public void setServerURL(String serverURL);
public byte[] callService(String service, byte[] in)
throws snaException, IOException;
public void setUserID(String userid);
public void setPassword(String password);
}
Table 6-1 lists the definitions of the public interface methods:
Table 6-1 EgenClient Public Interface Methods
How EgenClient Locates a WebLogic JAM Gateway The EgenClient class requires a connection to a WebLogic Server running a WebLogic JAM Gateway to communicate with a mainframe. This connection is accomplished via a URL provided by the caller identifying the server, or cluster of servers, hosting the WebLogic JAM Gateway(s). The EgenClient class attempts to obtain this URL from the following sources (listed in priority order):
Using EgenClient to Make a Mainframe Request
Listing 6-2 illustrates calling a mainframe service via the EgenClient class. This example assumes that a properly formatted mainframe buffer is passed as a parameter, and that the URL of a correctly configured WebLogic JAM Gateway is set via the jam.url property.
Listing 6-2 Mainframe Request Using EgenClient
import com.bea.jam.egen.EgenClient;
import com.bea.sna.jcrmgw.snaException;
import java.io.IOException;
.
.
public byte[] getPurchaseOrder(byte[] poNum)
throws IOException
{
try
{
return(new EgenClient().callService("GetPO", poNum));
}
catch (snaException e)
{
throw new IOException(e.getMessage());
}
}
The sections that follow provide information on dynamically creating mainframe buffers and interpreting the responses from mainframe services.
Translating Buffers from Java to Mainframe Representation
Support for creating buffers for input to a mainframe service is provided by the com.bea.base.io.MainframeWriter class. This class functions similar to a Java java.io.DataOutputStream object. It translates Java data types and all mainframe-native data types. For numeric data types, this translation service provides a conversion from Java native numeric types to those available on the mainframe. For string data types, a translation is performed from UNICODE to EBCDIC by default, although the output codepage used is configurable.
MainframeWriter Public Interface
Listing 6-3 shows the public methods provided by the MainframeWriter class.
Listing 6-3 MainframeWriter Class Public Methods
package com.bea.base.io;
public class MainframeWriter
{
public MainframeWriter();
public MainframeWriter(String codepage);
public void setDefaultCodepage(String cp)
public byte[] toByteArray();
public void writeRaw(byte[] bytes
throws IOException;
public void writeFloat(float value)
throws IOException;
public void writeDouble(double value)
throws IOException;
public void write(char c)
throws IOException;
public void writePadded(String s, char padChar, int length)
throws IOException;
public void write16bit(int value)
throws IOException;
public void write16bitUnsigned(int value)
throws IOException;
public void write16bit(long value, int scale)
throws IOException, ArithmeticException;
public void write16bitUnsigned(long value, int scale)
throws IOException, ArithmeticException;
public void write32bit(int value)
throws IOException;
public void write32bitUnsigned(long value)
throws IOException;
public void write32bit(long value, int scale)
throws IOException, ArithmeticException;
public void write32bitUnsigned(long value, int scale)
throws IOException, ArithmeticException;
public void write64bit(long value)
throws IOException;
public void write64bitUnsigned(long value)
throws IOException;
public void write64bitBigUnsigned(BigDecimal value)
throws IOException;
public void write64bit(long value, int scale)
throws IOException, ArithmeticException;
public void write64bit(BigDecimal value, int scale)
throws IOException, ArithmeticException;
public void write64bitUnsigned(long value, int scale)
throws IOException, ArithmeticException;
public void write64bitUnsigned(BigDecimal value, int scale)
throws IOException, ArithmeticException;
public void writePacked(BigDecimal value, int digits,
int precision, int scale)
throws ArithmeticException, IOException;
public void writePackedUnsigned(BigDecimal value,
int digits, int precision, int scale)
throws ArithmeticException, IOException;
}
Following are the definitions of these methods:
Table 6-2 MainframeWriter Class Public Method Definitions
Using MainframeWriter to Create Data Buffers As an example of using the MainframeWriter class to create a mainframe data buffer, assume we have a mainframe service which accepts the data record shown in Listing 6-4: Listing 6-4 Data Record Listing 6-5 shows a Java test program that creates a buffer matching this record layout using the MainframeWriter translation class: Listing 6-5 Java Test Program The output of running this sample program is: This buffer breaks down as follows:
01 INPUT-DATA-REC.
05 FIRST-NAME PIC X(10).
05 LAST-NAME PIC X(10).
05 AGE PIC S9(4) COMP.
05 HOURLY-RATE PIC S9(3)V9(2) COMP-3.import java.math.BigDecimal;
import com.bea.base.io.MainframeWriter;
public class MakeBuffer
{
public static void main(String[] args) throws Exception
{
MainframeWriter mf = new MainframeWriter();
mf.writePadded("Edgar", ' ', 10); // first name
mf.writePadded("Jones", ' ', 10); // last name
mf.write16bit(22); // age
mf.writePacked(new BigDecimal(22.50), 5, 2, 0); // hourly rate
byte[] buffer = mf.toByteArray();
System.out.println(getHexString(buffer));
} private static String getHexString(byte[] buffer)
{
StringBuffer hexStr = new StringBuffer(buffer.length * 2);
for (int i = 0; i < buffer.length; ++i)
{
int n = buffer[i] & 0xff;
hexStr.append(hex[n >> 4]);
hexStr.append(hex[n & 0x0f]);
}
return(hexStr.toString());
} private static char[] hex =
{
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
}C5848781994040404040D1969585A24040404040001602250C
FIRST-NAME C5848781994040404040 "Edgar" + 5 spaces in EBCDIC
LAST-NAME D1969585A24040404040 "Jones" + 5 spaces in EBCDIC
AGE 0016 22 as 16 bit integer
HOURLY-RATE 02250C 22.50 positive packed number
(decimal point is assumed)
Translating Buffers from Mainframe Format to Java
Support for translating data received from the mainframe to Java data types is provided by the com.bea.base.io.MainframeReader class. This class operates in a manner similar to a Java jam.io.DataInputStream, and performs translations from mainframe data types to equivalent types usable by a Java program. Like the MainframeWriter class, the codepage used for string translations may be configured and defaults to EBCDIC.
MainframeReader Public Interface
Listing 6-6 shows the public methods provided by the MainframeReader class.
Listing 6-6 MainframeReader Class Public Methods
package com.bea.base.io;
public class MainframeReader
{
public MainframeReader(byte[] buffer);
public MainframeReader(byte[] buffer, String codepage);
public void setDefaultCodepage(String cp);
public byte[] readRaw(int count) throws IOException;
public float readFloat() throws IOException;
public double readDouble() throws IOException;
public char readChar() throws IOException;
public String readPadded(char padChar, int length)
throws IOException;
public short read16bit() throws IOException;
public int read16bitUnsigned() throws IOException;
public long read16bit(int scale) throws IOException;
public int read32bit() throws IOException;
public long read32bit(int scale)
throws IOException;
public long read32bitUnsigned() throws IOException;
public long read32bitUnsigned(int scale) throws IOException;
public long read64bit() throws IOException;
public long read64bitUnsigned()
throws IOException;
public long read64bit(int scale)
throws IOException;
public BigDecimal read64bitBigUnsigned()
throws IOException;
public BigDecimal read64bitBig(int scale)
throws IOException
public BigDecimal readPackedUnsigned(int digits,
int precision, int scale)
throws ArithmeticException, IOException;
public BigDecimal readPacked(int digits,
int precision, int scale)
throws ArithmeticException, IOException;
}
Following are the definitions of these methods:
Table 6-3 MainframeReader Class Public Method Definitions
Using MainframeReader to Translate Data Buffers As an example of using the MainframeReader, class following is a program that translates and displays the fields in the mainframe buffer created above. Our input buffer consists of the binary data: Listing 6-7 shows the sample program used to process this buffer. Listing 6-7 Sample Program When run, the program produces the following output:
C5848781994040404040D1969585A24040404040001602250C
import java.math.BigDecimal;
import com.bea.base.io.MainframeReader;public class ShowBuffer
{
public static void main(String[] args) throws Exception
{
String data =
"C5848781994040404040D1969585A24040404040001602250C";
byte[] buffer = buildBinary(data);
MainframeReader mf = new MainframeReader(buffer);
System.out.println(" First Name: " + mf.readPadded(' ', 10));
System.out.println(" Last Name: " + mf.readPadded(' ', 10));
System.out.println(" Age: " + mf.read16bit());
System.out.println("Hourly Rate: " + mf.readPacked(5, 2, 0));
} private static byte[] buildBinary(String data)
{
byte[] buffer = new byte[data.length() / 2];
for (int i = 0; i < buffer.length; ++i)
{
int msb = hex.indexOf(data.charAt(i * 2));
int lsb = hex.indexOf(data.charAt(i * 2 + 1));
buffer[i] = (byte) (msb << 4 | lsb);
}
return(buffer);
} private static final String hex = "0123456789ABCDEF";
}First Name: Edgar
Last Name: Jones
Age: 22
Hourly Rate: 22.50