目次 前 次 PDF


eGenアプリケーション・ジェネレータによるJavaアプリケーションの生成

eGenアプリケーション・ジェネレータによるJavaアプリケーションの生成
このドキュメントは、以下のトピックで構成されています。
eGenアプリケーション・ジェネレータによるJavaアプリケーションの生成
概要
Oracle Tuxedoでは、J2EEアプリケーション・サーバーおよびJCAベースで実行されるCICS Transaction Gateway (CTG)アプリケーションの、シームレスな統合がサポートされています。
この機能に基づいて、Oracle Tuxedoは次の操作を行うツールを提供しています。
したがって、ユーザーはそのクラスをCCI (またはECIでラップされる)インタフェースに渡して、ARTでホストされるCICS呼出しを実行できます。
eGenの理解
eGenアプリケーション・ジェネレータはeGenユーティリティとも呼ばれ、COBOLコピーブックとユーザー定義スクリプト・ファイルからJavaアプリケーションを生成します。
eGenユーティリティでは、作成したeGenスクリプトと呼ばれるスクリプトを処理してJavaアプリケーションを生成できます。Javaデータビューは、スクリプトの最初のセクションで定義されます。このデータビューはアプリケーション・コードでデータ・アクセスとデータ変換、およびその他の様々な機能を提供するために使用されます。実際のアプリケーション・コードは、スクリプトの2つ目のセクションで定義されます。
図1に、eGenユーティリティのしくみを示します。この図は、eGenユーティリティの入力として使用されているeGenスクリプトとCOBOLコピーブック・ファイルを示しています。生成される出力はデータビューです。
図1 eGenユーティリティの理解
COBOLコピーブックの操作
COBOL CICSまたはIMSメインフレーム・アプリケーションは、通常はコピーブック・ソース・ファイルを使用してデータ・レイアウトを定義します。このファイルは、CICSアプリケーションのソース・プログラムのLINKAGE SECTION内にあるCOPYディレクティブまたはIMSプログラムのWORKING-STORAGE SECTIONで指定されます。CICSまたはIMSアプリケーションがコピーブック・ファイルを使用していない場合は、プログラム・ソースに含まれるデータ定義からコピーブック・ファイルを作成する必要があります。
各コピーブックの内容がeGenユーティリティで解析されて、次を実行する機能を提供するデータビュー・サブクラスを生成します。
COBOLコピーブックの取得
eGenユーティリティには、入力として使用するCOBOLコピーブックが必要です。このコピーブックを取得する方法は2つあります。
新しいCOBOLコピーブックの作成
メインフレーム上で新しいアプリケーションを作成するか変更する場合は、1つ以上の新しいコピーブックが必要になることがあります。これらのコピーブックを作成するときは、eGenでサポートされているCOBOL機能とデータ型に注意してください。詳細は、「データビュー・プログラミング・リファレンス」を参照してください。
既存のCOBOLコピーブックの使用
メインフレーム・アプリケーションに既存のDPLまたはAPPCインタフェースがある場合、そのインタフェースのデータは、通常はCOBOLコピーブックで記述されています。既存のCOBOLコピーブックを使用する前に、インタフェースが、eGenでサポートされていないCOBOL機能やデータ型を使用していないことを確認します(「eGenユーティリティの制限」を参照)。
COBOLコピーブックのソース・ファイルの例は、図2を参照してください。
図2 サンプルのemprec.cpy COBOLコピーブック
eGenユーティリティの制限
eGenユーティリティでは、ほとんどのCOBOLコピーブック・データ型とデータ句をJavaの相当するデータ型とデータ句に変換できます。ただし、一部の古い構造体および浮動小数点データ型は変換できません。eGenユーティリティで変換できるCOBOLデータ型の詳細は、「データビュー・プログラミング・リファレンス」を参照してください。eGenユーティリティが構造体またはデータ型を完全にサポートできない場合は、次のようになります。
eGenユーティリティが構造体やデータ型をエラーとしてレポートする場合は、それらを変更して変換できるようにする必要があります。
eGenスクリプトの記述
メインフレーム・アプリケーションのCOBOLコピーブックを取得すると、eGenスクリプトを作成できるようになります。このeGenスクリプトと、データ構造体を記述するCOBOLコピーブックがeGenユーティリティによって処理され、データビューが生成されます。これが、カスタムJavaアプリケーションの基本として機能します。
eGenスクリプトには、次のセクションがあります。
データビュー。スクリプトのデータビュー・セクションでは、COBOLコピーブックからJava データビューを生成します。生成されたコードからコンパイルされるクラス・ファイルによって、Javaデータビュー・クラスが拡張されます。データビューの生成については、以降の項で詳しく説明します。詳細は、「eGenスクリプトのデータビュー・セクションの記述」を参照してください。
eGenスクリプトのデータビュー・セクションの記述
eGenユーティリティはCOBOLコピーブックを解析し、コピーブックで宣言されているデータ・レコードをカプセル化するJavaデータビュー・コードを生成します。この処理は、リスト1 (キーワードは太字)の例のようなデータビュー定義が含まれる、eGenスクリプト・ファイルを解析することによって行われます。
リスト1 eGenスクリプトのデータビュー・セクションの例
generate view examples.CICS.outbound.gateway.EmployeeRecord from emprec.cpy
 
このコード行の各部分を見てみると、generate viewは、Javaデータビュー・コード・ファイルの生成をeGenユーティリティに指示しています。examples.CICS.outbound.gateway.EmployeeRecordは、データビュー・ファイルEmployeeRecord.javaの呼出しをeGenユーティリティに指示しています。パッケージの名前はexamples.CICS.outbound.gatewayです。EmployeeRecord.javaで定義されているEmployeeRecordクラスは、データビュー・クラスのサブクラスです。from emprec.cpyという語句は、COBOLコピーブックemprec.cpyからEmployeeRecordデータビュー・ファイルを形成することをeGenに指示しています。
アプリケーションで必要なすべてのデータビューを生成するために、別のgenerate view文がeGenスクリプトに追加される可能性があります。また、eGenスクリプトに追加オプションを指定して、データビュー生成の詳細を変更することもあります。たとえば、次のスクリプトは、メインフレーム形式への変換およびメインフレーム形式からの変換で、コードページcp500を使用するデータビュー・クラスを生成します。codepage句が指定されていない場合は、デフォルトのコードページcp037が使用されます。
リスト2 コードページが指定されているデータビュー・セクションの例
generate view examples.CICS.outbound.gateway.EmployeeRecord from emprec.cpy codepage cp500
 
generate view examples.CICS.outbound.gateway.EmployeeRecord from emprec.cpy codepage ASCII
 
リスト3 エンディアンが指定されているデータビュー・セクションの例
generate view examples.CICS.outbound.gateway.EmployeeRecord from emprec.cpy endian little
 
注意:
デフォルトでは、endianbigです。
JoltクライアントがLinux X86-64マシンのTuxedoでCOBOLサービスを呼び出す場合は、リスト4でパラメータcodepage ASCIIとendian littleを指定してeGenで生成されたJavaコードでJoltクライアントをコンパイルする必要があります。
詳細は、「JOLTの例」を参照してください。
リスト4 パラメータcodepageとendianが指定されているデータビュー・セクションの例
generate view examples.CICS.outbound.gateway.EmployeeRecord from emprec.cpy codepage ASCII endian little
 
次のスクリプトは、XMLデータでデータビュー・クラスの使用をサポートする追加の出力を生成します。
リスト5 XMLをサポートするデータビュー・セクションの例
generate view sample.EmployeeRecord from emprec.cpy support xml
 
XMLサポートで生成される追加ファイルを、表1に示します。
 
このデータビューが受け付け、このデータビューで生成されるXMLメッセージのXML DTD。
このデータビューが受け付け、このデータビューで生成されるXMLメッセージのXMLスキーマ。
eGenユーティリティによるeGenスクリプトの処理
eGenスクリプトの作成後、データビューを生成するように処理する必要があります。同じeGenスクリプトには通常データビューの定義が含まれ、これらの定義はスクリプトを1回処理すると生成されます。ただし、このドキュメントでは、実際に生成されたコードを詳細に解析できるように、スクリプトを2ステップで説明しています。
Javaコードを生成およびコンパイルするための環境の構築
eGenスクリプトを処理し、Javaコードを生成する場合は、コード生成およびコンパイル・プロセスで使用されるJavaクラスとアプリケーションへのアクセス権が必要です。CLASSPATHおよびPATH環境変数に正しい要素を追加すると、このアクセス権が得られます。
<TUXDIR>\udataobj\egen.jarCLASSPATHに追加します。
<TUXDIR>\binPATHに追加します。
<TUXDIR>\udataobj\egen.jarCLASSPATHに追加します。
データビュー・クラス・ファイルのパスをCLASSPATHに追加します。Javaアプリケーション・コードをコンパイルするときにこれらのクラスへのアクセス権が必要です。
注意:
Javaデータビュー・コードの生成
リスト1に示されているeGenスクリプトでは、次のシェル・コマンドでコピーブック・ファイルを解析し(図2を参照)、現在のディレクトリにEmployeeRecord.javaソース・ファイルを生成します。
リスト6 サンプルのコピーブック解析コマンド
java com.bea.jam.egen.EgenCobol emprec.egen
 
エラーまたは警告メッセージが発行されない場合、コピーブックにはeGenとの互換性があり、ソース・ファイルが作成されます。emprec.egenスクリプトを処理しても、アプリケーション・ソース・ファイルは生成されません。これは、このスクリプトにコマンドを生成するアプリケーションがないためです。
次の例は、生成されたJavaソース・ファイルEmployeeRecord.javaを示しています。この例ではわかりやすくするためにコメントと実装の詳細を一部削除しています。
Javaコードのコンパイルに関する特殊な考慮事項
eGenユーティリティによって生成されたJavaコードはコンパイルする必要があります。ただし、考慮が必要となる特別な状況があります。アプリケーション・コードはデータビュー・コードに依存しているため、データビュー・コードをコンパイルし、アプリケーション・コードをコンパイルする前に結果のデータビュー・クラス・ファイルが環境のCLASSPATH内にあるかどうかを確認する必要があります。すべてのデータビュー・クラス・ファイルがアプリケーション・コードのコンパイルで参照可能であることを確認する必要があります。
たとえば、EmployeeRecord.javaをコンパイルすると、次の4つのクラス・ファイルが生成されます。
これらのクラス・ファイルはすべて、アプリケーション・コードのコンパイル時に使用されます。
独自のデータ変換の実行
独自のデータ変換を実行する理由
通常はデータビューが提供する自動データ変換によってニーズは満たされます。eGenによって生成されたデータビューは、メインフレームのEBCDIC環境とJavaランタイム環境の間でデータを変換する際の負担を軽減します。さらに、Javaでサポートされていないメインフレーム固有のデータ型(パック、ゾーン10進数など)は適切なJavaデータ型に自動的にマップされます。ただし、これらの機能をバイパスして独自のデータ変換を作成する場合があります。eGen/データビュー・インフラストラクチャをバイパスする利点を次に示します。
データが適切な形式で取得された場合、データをメインフレームに送信するだけで、データをビュー変換のオーバーヘッドをバイパパスできます。
これは、様々なレコードのタイプを表す多数のREDEFINESが含まれるコピーブックから生成されたデータビューに適している場合があります。
メインフレームとの間のデータ変換用にシンプルなインタフェースが用意されています。また、メインフレーム・サービス・リクエストを作成できるシンプルなcallService()メソッドがあります。
Javaからメインストリーム表現へのバッファの変換
メインフレーム・サービスへの入力用バッファを作成するためのサポートは、com.bea.base.io.MainframeWriterクラスで提供されます。このクラスは、Java java.io.DataOutputStreamオブジェクトと同じように機能します。Javaデータ型とすべてのメインフレーム固有のデータ型を変換します。数値データ型の場合、この変換サービスではJavaネイティブ数値型をメインフレームで使用できる数値型に変換できます。文字列データ型の場合は、デフォルトでUNICODEからEBCDICへの変換が行われますが、使用される出力コードページは構成可能です。
MainframeWriterパブリック・インタフェース
リスト7に、MainframeWriterクラスが提供するパブリック・メソッドを示します。
リスト7 MainframeWriterクラスのパブリック・メソッド
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;
 
 
デフォルトのコンストラクタ。cp037 (EBCDIC)のデフォルト・コード・ページを使用してMainframeWriterを構築します。
データをバイト配列としてMainframeWriterクラスに書き込んで構築された変換済バッファを返します。
文字列を変換し、固定長の文字フィールドに書き込みます。渡された文字列の長さがlen未満の場合、渡されたパッド文字が使用されます。渡された文字列の長さがlenを超えると、len文字まで切り捨てられます。同等のCOBOL句はPIC X(len)です。
暗黙の小数点を左にscale桁移動した後に、符号付き16ビット整数を出力バッファに書き込みます。たとえば、write16bit(100, 1)を呼び出すと、値10が書込まれます。同等のCOBOL picture句はPIC S9(4) COMPです。
暗黙の小数点を左にscale桁移動した後に、符号なし16ビット整数を出力バッファに書き込みます。たとえば、write16bitUnsigned(100, 1)を呼び出すと、値10が書込まれます。同等のCOBOL picture句はPIC 9(4) COMPです。
暗黙の小数点を左にscale桁移動した後に、符号付き32ビット整数を出力バッファに書き込みます。たとえば、write32bit(100L, 1)を呼び出すと、値10が書き込まれます。同等のCOBOL picture句はPIC S9(8) COMPです。
暗黙の小数点を左にscale桁移動した後に、符号なし32ビット整数を出力バッファに書き込みます。たとえば、write32bitUnsigned(100L, 1)を呼び出すと、値10が書込まれます。同等のCOBOL picture句はPIC 9(8) COMPです。
暗黙の小数点を左にscale桁移動した後に、符号付き64ビット整数を出力バッファに書き込みます。たとえば、write64bit(100L, 1)を呼び出すと、値10が書込まれます。同等のCOBOL picture句はPIC S9(15) COMPです。
暗黙の小数点を左にscale桁移動した後に、符号なし64ビット整数を出力バッファに書き込みます。たとえば、write64bitUnsigned(100L, 1)を呼び出すと、値10が書込まれます。同等のCOBOL picture句はPIC 9(15) COMPです。
IBM符号付きパック・データ型として、10進の合計桁数がdigits、小数点以下はprec桁の10進数を書き込みます。変換前に、数値が左側scale桁までスケーリングされます。同等のCOBOL picture句はPIC S9(digits-prec)V9(prec) COMP-3です。
IBM符号なしパック・データ型として、10進の合計桁数がdigits、小数点以下はprec桁の10進数を書き込みます。変換前に、数値が左のscale桁までスケーリングされます。同等のCOBOL picture句はPIC 9(digits-prec)V9(prec) COMP-3です。
MainframeWriterを使用したデータ・バッファの作成
MainframeWriterクラスを使用してメインフレーム・データ・バッファを作成する例として、次に示すようにデータ・レコードを受け入れるメインフレーム・サービスがあるとします。
リスト8 データ・レコード
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.
 
リスト9に、MainframeWriter変換クラスを使用してこのレコード・レイアウトと一致するバッファを作成するJavaテスト・プログラムを示します。
リスト9 Javaテスト・プログラム
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つの空白(EBCDIC)
LAST-NAME D1969585A24040404040"Jones" + 5つの空白(EBCDIC)
AGE 001622 (16ビット整数)
HOURLY-RATE 02250C22.50正のパック数
(小数点が想定されます)
メインストリーム形式からJavaへのバッファの変換
メインフレームから受信されたデータをJavaデータ型に変換するためのサポートは、com.bea.base.io.MainframeReaderクラスにより提供されます。このクラスはJava jam.io.DataInputStreamと同様に動作し、メインフレーム・データ型からJavaプログラムで使用可能な同等のデータ型への変換を実行します。MainframeWriterクラスと同様に、文字列変換に使用されるコードページは構成可能で、EBCDICにデフォルト設定されます。
MainframeReaderパブリック・インタフェース
リスト10に、MainframeReaderクラスが提供するパブリック・メソッドを示します。
リスト10 MainframeReaderクラスのパブリック・メソッド
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;
}
 
これらのメソッドの定義を以下に示します。
 
固定長の文字フィールドを読み取り、変換して、Java文字列として返します。フィールドの長さはlenとして渡されて、フィールドのパッド文字がpadとして渡されます。pad文字の最後のインスタンスが削除されてから、データが返されます。
16ビットの2進整数を読み取り、値を10^スケール分スケーリングします。たとえば、値10がread16bit(1)で読み取られた場合、返される値は100になります。
32ビットの2進整数を読み取り、値を10^スケール分スケーリングします。たとえば、値10read32bit(1)で読み取られた場合、返される値は100になります。
符号なしの32ビットの2進整数を読み取り、値を10^スケール分スケーリングします。たとえば、値10read32bit(1)で読み取られた場合、返される値は100になります。
符号なしの64ビットの2進整数を読み取り、値を10^スケール分スケーリングします。たとえば、値10read32bit(1)で読み取られた場合、返される値は100になります。
precに小数点の右側の桁数を指定したdigits桁数で構成される符号なしパック数を読み取ります。値は10^スケール分スケーリングされ、Java BigDecimalとして返されます。
precに小数点の右側の桁数を指定したdigits桁数で構成される符号付きパック数を読み取ります。値は10^スケール分スケーリングされ、Java BigDecimalとして返されます。
MainframeReaderを使用したデータ・バッファの変換
MainframeReaderクラスを使用した例として、上で作成したメインフレーム・バッファのフィールドを変換および表示するプログラムを次に示します。入力バッファは次のバイナリ・データで構成されます。
C5848781994040404040D1969585A24040404040001602250C
リスト11に、このバッファを処理するために使用されるサンプル・プログラムを示します。
リスト11 サンプル・プログラム
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
データビュー・プログラミング・リファレンス
この項では、生成されたJavaクラスがeGenアプリケーション・ジェネレータ(eGenユーティリティ)で処理された特定のCOBOLコピーブックから取得するフォームを識別するためのルールについて説明します。ルールを理解すると、プログラマは生成されたクラスを使用するカスタム・プログラムを簡単に正しくコーディングできるようになります。
eGenユーティリティはCOBOLコピーブックをJavaクラスにマップします。COBOLコピーブックには、データ・レコードの説明が含まれています。eGenユーティリティは、生成されたJavaクラスをcom.bea.dmd.dataview.DataViewクラス(以降はデータビュー)から派生します。
ここでは、次の項でデータ・マッピングについて説明します。
この項ではCOBOL用語がわかりやすく説明されていますが、必要に応じてCOBOLリファレンス・ブックを使用するか、COBOLプログラマに用語について確認する必要があります。マッピングを理解するために、eGenユーティリティを使用してコピーブックを処理したり、生成されたJavaコードを確認することもできます。
フィールド名のマッピング・ルール
フィールド名が含まれるCOBOLコピーブックを処理すると、eGenユーティリティによってこれらがJava名にマップされます。すべてのアルファベット文字は、次の2つの場合を除いてすべて小文字にマップされます。
ダッシュはすべて削除され、ダッシュに続く文字は大文字にマップされます。
名前に接頭辞が追加されると(フィールド・アクセッサ関数名を作成する場合など)、ベース名の先頭の文字が大文字にマップされます。
表4に、いくつかのマッピングの例を示します。
 
フィールド・タイプのマッピング
COBOLコピーブックを処理すると、フィールドのデータ型はJavaのデータ型にマップされます。マッピングは、次のルールに従ってeGenユーティリティによって実行されます。
1.
グループはデータビュー・サブクラスにマップされます。
2.
英数字フィールドは、すべて文字列型にマップされます。
3.
編集済数値フィールドは、すべて文字列型にマップされます。
4.
SIGN SEPARATEBLANK WHEN ZEROまたはJUSTIFIED RIGHTフィールドは、すべて文字列型にマップされます。
5.
SIGN IS LEADINGはサポートされません。
6.
COMP-1COMP-2COMP-5COMP-XおよびPROCEDURE-POINTER型フィールドはサポートされません(エラー・メッセージが生成されます)。
7.
INDEXフィールドは、すべてJavaのint型にマップされます。
8.
POINTERはJavaのint型にマップされます。
9.
10.
COMP-3 (パック)フィールドは、すべてBigDecimal型にマップされます。
11.
他のすべての数値フィールドは、表5に示すようにマップされます。
 
グループ・フィールド・アクセッサ
COBOLコピーブック内でネストしている各グループは、対応するデータビュー・サブクラスにマップされます。生成されるサブクラスは、コピーブック内のCOBOLグループと同じようにネストされます。また、eGenユーティリティによって、このクラス・タイプのprivateインスタンス変数およびgetアクセッサが生成されます。
たとえば、次のようなコピーブックがあるとします。
リスト12 サンプルのコピーブック
10 MY-RECORD.
20 MY-GRP.
30 ALNUM-FIELD PIC X(20).
次のようなコードが生成されます。
public MyGrp2V getMyGrp();
public static class MyGrp2V extends DataView
{
// Class definition
}
 
基本フィールド・アクセッサ
各基本フィールドは、生成されたデータビュー・サブクラス内でprivateインスタンス変数にマップされます。この変数へのアクセスは、生成された2つのアクセッサ(setおよびget)によって実現されます。
このアクセッサの形式は、次のとおりです。
public void setFieldName(FieldType value);
public FieldType getFieldName();
説明:
FieldTypeの詳細は、「フィールド・タイプのマッピング」という項を参照してください。
FieldNameの詳細は、「フィールド名のマッピング・ルール」という項を参照してください。
たとえば、次のようなコピーブックがあるとします。
10 MY-RECORD.
20 NUMERIC-FIELD PIC S9(5).
20 ALNUM-FIELD PIC X(20).
次のアクセッサが生成されます。
public void setNumericField(int value);
public int getNumericField();
public void setAlnumField(String value);
public String getAlnumField();
配列フィールド・アクセッサ
配列フィールドは、「グループ・フィールド・アクセッサ」および「基本フィールド・アクセッサ」に記載されているフィールド・アクセッサ・ルールに従って処理されます。それに加えて、各アクセッサは、アクセスする配列エントリを指定する追加のint引数を使用します。次に例を示します。
public void setFieldName(int index, FieldType value);
public FieldType getFieldName(int index);
DEPENDING ON句で指定される配列フィールドは、固定サイズの配列と同じように処理されますが、次の特別なルールが適用されます。
データビューと外部フォーマット(メインフレーム・フォーマットなど)との間の変換時に、制御(DEPENDING ON)変数が評価されます。eGenユーティリティでは、制御値より小さい添え字の配列要素のみを変換します。
REDEFINES句で指定されるフィールド
REDEFINESセットに参加するフィールドは、1つの単位として処理されます。private byte[]変数は、基礎となるメインフレーム・データを保持するように宣言されます。private DataView変数も同様です。再定義された各フィールドには、アクセッサがあります。これらのアクセッサは、基礎となるbyte[]データとの間で変換を実行するため、通常のアクセッサより多くのCPUオーバーヘッドが生じます。
たとえば、次のようなコピーブックがあるとします。
リスト13 サンプルのコピーブック
10 MY-RECORD.
20 INPUT-DATA.
30 INPUT-A PIC X(4).
30 INPUT-B PIC X(4).
20 OUTPUT-DATA REDEFINES INPUT-DATA PIC X(8).
 
次のようなJavaコードが生成されます。
private byte[] m_redef23;
private DataView m_redef23DV;
public InputDataV getInputData();
public String getOutputData();
public void setOutputData(String value);
public static class InputDataV extends DataView
{
// Class definition.
}
COBOLデータ型
この項では、TuxedoでサポートされているCOBOLデータ型をまとめています。表6に、eGenユーティリティで認識されるCOBOLデータ項目の定義を示します。表7に、eGenユーティリティで認識される構文機能およびデータ型を示します。COBOL機能がサポート対象外で、表内で「無視」と表記されていない場合は、エラー・メッセージが生成されます。
 
 
生成されたデータビュー・クラスのその他のアクセス方式
eGenでは、次の各項で説明する複数の方法でデータビュー・クラスにアクセスできます。
データビュー・クラスへのメインフレーム・アクセス
この項では、メインフレーム形式のデータをデータビュー・クラスとの間で移動する方法を説明します。eGenアプリケーション・ジェネレータによってこのコードが作成されるため、この情報は参照用です。
メインフレーム形式データはMainframeWriterクラスを使用してデータビュー・クラスから抽出できます。リスト14に、抽出の実行に使用できるコードのサンプルを示します。
リスト14 データビュー・クラスからメインストリーム形式データを抽出するためのサンプル・コード
import com.bea.base.io.MainframeWriter;
import com.bea.dmd.dataview.DataView;
...
/**
* Get mainframe format data from a DataView into a byte[].
*/
byte[] getMainframeData(DataView dv)
{
try
{
MainframeWriter mw = new MainframeWriter();
// To override the DataView's codepage, change the
// above constructor call to something like:
// ...new MainframeWriter("cp1234");
return dv.toByteArray(mw);
}
catch (java.io.IOException e)
{
// Some conversion failure occurred…
}
return null;
}
 
データビューが生成されたときに指定したコードページをオーバーライドする場合は、リスト15のコメントに示されているように、別のコードページをMainframeWriterコンストラクタのString引数として指定できます。
メインフレーム・データのデータビューへのロードも同様のプロセスですが、この場合はMainframeReaderクラスを使用する必要があります。リスト15に、ロードの実行に使用できるコードのサンプルを示します。
リスト15 データビュー・クラスにメインフレーム・データをロードするためのサンプル・コード
import com.bea.base.io.MainframeReader;
import com.bea.dmd.dataview.DataView;
...
/**
* Put a byte[] containing mainframe format data into a DataView.
*/
MyDataViewputMainframeData(byte[] buffer)
{
MainframeReader mr = new MainframeReader(buffer);
// To override the DataView's codepage, change the above
// constructor call to something like:
// …new MainframeReader("cp1234", buffer);
.
.
.
MyDataView dv;
.
.
.
try
{
// Construct a new DataView with the mainframe data.
dv = new MyDataView(mr);
// Or, to load a pre-existing DataView with mainframe data.
// dv.mainframeLoad(mr);
}
catch (java.io.IOException e)
{
// Some conversion failure occurred.
}
return dv;
}
 
データビュー・クラスへのXMLアクセス
XMLデータをデータビュー・クラスとの間で移動するための機能が提供されています。これらの操作は、XmlLoaderクラストXmlUnloaderクラスを使用して実行します。
次のリストは、XMLデータをデータビューにロードするために使用されるコード例を示しています。
リスト16 データビューにXMLデータをロードするためのサンプル・コード
import com.bea.dmd.dataview.DataView;
import com.bea.dmd.dataview.XmlLoader;
...
void loadXmlData(String xml, DataView dv)
{
XmlLoader xl = new XmlLoader();
try
{
// Load the xml. Note that the xml argument may be either
// a String or a org.w3c.dom.Element object.
xl.load(xml, dv);
}
catch (Exception e)
{
// Some conversion error occurred.
}
}
 
次のリストに、データビューをXMLにアンロードするために使用されるコードの例を示します。
リスト17 データビューをXMLにアンロードするためのサンプル・コード
import com.bea.dmd.dataview.DataView;
import com.bea.dmd.dataview.XmlUnloader;
...
String unloadXmlData(DataView dv)
{
XmlUnloader xu = new XmlUnloader();
try
{
String xml = xu.unload(dv);
return xml;
}
catch (Exception e)
{
// Some conversion error occurred.
}
return null;
}
 
データビュー・クラスへのハッシュ表アクセス
Oracle Tuxedoには、ハッシュ表オブジェクトを使用してデータビュー・オブジェクトをロードおよびアンロードする機能もあります。ほとんどの場合、ハッシュ表オブジェクトは、データをあるデータビューから別の類似したデータビューに移動するために使用されます。
データビュー・フィールドがハッシュ表に移動すると、各フィールドにはオリジナルのコピーブック・データ構造内のフィールドの位置を示す文字列であるキーが与えられます。
リスト18に、COBOLコピーブックのサンプルを示します。
リスト18 サンプルのemprec.cpy COBOLコピーブック
1 *------------------------------------------------------
2 * emprec.cpy
3 * An employee record.
4 *------------------------------------------------------
5
6 02 emp-record.
7
8 04 emp-ssn pic 9(9) comp-3.
9
10 04 emp-name.
11 06 emp-name-last pic x(15).
12 06 emp-name-first pic x(15).
13 06 emp-name-mi pic x.
14
15 04 emp-addr.
16 06 emp-addr-street pic x(30).
17 06 emp-addr-st pic x(2).
18 06 emp-addr-zip pic x(9).
19
20 * End
 
リスト18のCOBOLコピーブックのフィールドは、表8に示されるようにハッシュ表に格納されます。
 
ハッシュ表をアンロードおよびロードするためのコード
次に、データビューをハッシュ表にアンロードするために使用されるコードの例を示します。
Hashtable ht = new HashtableUnloader().unload(dv);
次に、ハッシュ表を既存のデータビューにロードするために使用されるコードの例を示します。
new HashtableLoader().load(dv);
ハッシュ表のアンロードおよびロードに関するルール
ハッシュ表のアンロードの基本ルールは次のとおりです。
各データ項目は、Java型のオブジェクトとして格納されます。int/short/long型の要素はInteger/Short/Longに変換されます。
ハッシュ表のロードの基本ルールは次のとおりです。
誤った型のハッシュ表メンバーがあると、ClassCastExceptionがスローされます。
名前変換インタフェース機能
名前変換インタフェース機能を使用して、ハッシュ表名前マッピングを実行できます。HashtableLoaderHashtableUnloaderの両方に、com.bea.dmd.dataview.NameTranslator型の引数を受け入れるコンストラクタが用意されています。表9に、実装する必要があるパブリック・インタフェース・メソッドの説明を示します。
 
このメソッドはStringオブジェクトを入力パラメータとして受け取り、Stringオブジェクトを返します。
このインタフェースをアプリケーション用に実装するクラスを作成できます。これらの実装は、ハッシュ表にアクセスする前にキー文字列を変換するために使用されます。
次に、egen.jarに含まれている有用な実装を示します。
 
HashtableLoaderHashtableUnloader、および様々な名前変換クラスがcom.bea.dmd.dataviewパッケージに含まれます。
COBOLコピーブックを使用するeGenの既知の制限
次に、このバージョンのeGenの既知の制限を示します。
継続行はCOBOLコピーブックで認識されません。これは、VALUES句内に長い文字リテラルが存在する場合にのみ発生する問題です。この問題を修正するには、関連の句をコメント・アウトします。
OCCURS DEPENDING ON句のある配列(表)データ項目を含むCOBOLコピーブックは、依存するカウンタ・データ項目が配列を含むデータ項目と同じグループ・データ項目内に含まれないように構成する必要があります。
COBOLコピーブック内のグループ・データ項目のUSAGE句は、その下位メンバー・データ項目に正しく伝播されません。
プログラム開発
プログラム開発は、リスト19に示されるようなプログラム・スニペットと、ここでその概要が示されるクラスのネーミング・ルールに従って行われます。ただし、カスタマの要件に応じて調整可能です。
リスト19 プログラム・スニペット
try
{
InitialContext context = new InitialContext();
ECIConnectionSpec connSpec = new ECIConnectionSpec();
connSpec.setUserName("TESOP01");
connSpec.setPassword("");
Connection connection = connectionFactory.getConnection(connSpec);
Interaction interaction = connection.createInteraction();
// Create inputBean
K294Bean inRec = new K294Bean();
inRec.setI__Entete__TranId("K294");
inRec.setI__Entete__Vers("0101");
inRec.setI__Entete__Statut("99");
inRec.setI__Entete__Nb__Enreg((short)40);
inRec.setI__Entete__User("TESOP01");
inRec.setI__Entete__Date("2012-01-16");
// Data
inRec.setI__restea__nupy(1);
inRec.setI__restea__cdea(2);
inRec.setI__restea__cdea1(1);
K294Bean outRec = new K294Bean();
// Create InteractionSpec
InteractionSpec interactionSpec = new ECIInteractionSpec();
((ECIInteractionSpec)interactionSpec).setFunctionName("COMPT294");
((ECIInteractionSpec)interactionSpec).setTranName("K294");
((ECIInteractionSpec)interactionSpec).setCommareaLength(7132);
((ECIInteractionSpec)interactionSpec).setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);
// execute transaction
interaction.execute((ECIInteractionSpec)interactionSpec, inRec, outRec);
// Close all
interaction.close();
connection.close();
// List Data
K294bean_output__message_t__o__data__data data[] = outRec.getT__o__data__data();
// Load List
for (int i=0; i<data.length;i++)
{
if (data[i].getT__o__data__data__o__restea__cdea()!=0)
{
out.println(data[i]);
}
}
}
catch (Exception e)
{
System.out.println("Error : " + e.getMessage());
e.printStackTrace();
}
 
重要な分野
次のリストに、プログラム開発における重要な分野を示します。フィールド名のマッピングは異なる場合があります。
リスト20 接続の設定
ECIConnectionSpec connSpec = new ECIConnectionSpec();
connSpec.setUserName("TESOP01");
connSpec.setPassword("");
Connection connection = connectionFactory.getConnection(connSpec);
Interaction interaction = connection.createInteraction();
// Create InteractionSpec
InteractionSpec interactionSpec = new ECIInteractionSpec();
((ECIInteractionSpec)interactionSpec).setFunctionName("COMPT294");
((ECIInteractionSpec)interactionSpec).setTranName("K294");
((ECIInteractionSpec)interactionSpec).setCommareaLength(7132);
((ECIInteractionSpec)interactionSpec).setInteractionVerb(ECIInteractionSpec.SYNC_SEND_RECEIVE);
 
リスト21 入力Beanの使用方法
// Create inputBean
K294Bean inRec = new K294Bean();
inRec.getDfhcommarea().
getInputMessage().
getIEntete().setIEnteteTranId("K294");
inRec.getDfhcommarea().
getInputMessage().
getIEntete().setIEnteteVers("0101");
inRec.getDfhcommarea().
getInputMessage().
getIEntete().setIEnteteStatut("99");
inRec.getDfhcommarea().
getInputMessage().
getIEntete().setIEnteteNbEnreg((short)40);
// reserve outputBean
K294Bean outRec = new K294Bean();
 
リスト22 サービスの呼出し
// execute transaction
interaction.execute((ECIInteractionSpec)interactionSpec, inRec, outRec);
 
リスト23 出力Beanの使用方法
K294bean_output__message_t__o__data__data data[] = outRec.getDfhcommarea().getOutputMessage().getTODataData();
 
JOLTの例
次にCOBOLコピーブックemprec.cpyを示します。
リスト24 サンプルCOBOLコピーブックemprec.cpy
01 emp-record.
04 emp-ssn pic 9(9) comp-3.
04 emp-name.
06 emp-name-last pic x(15).
06 emp-name-first pic x(15).
06 emp-name-mi pic x.
 
04 emp-addr.
06 emp-addr-street pic x(30).
06 emp-addr-st pic x(2).
06 emp-addr-zip pic x(9).
 
generate view test.EmployeeRecord from emprec.cpy codepage ASCII endian little
次に、eGenスクリプトemprec.egenを次のように処理すると、JavaファイルEmployeeRecord.javaが生成されます。
java com.bea.jam.egen.EgenCobol emprec.egen
次に、EmployeeRecord.javaをコンパイルすると、4つのJavaクラス・ファイルが生成されます。
EmployeeRecord$EmpRecord1V$EmpAddr7V.class
EmployeeRecord$EmpRecord1V$EmpName3V.class
EmployeeRecord$EmpRecord1V.class
EmployeeRecord.class
次に、JoltクライアントJavaコードをEmployeeRecord.javaを使用して作成できます。簡単な例は以下を参照してください。
リスト25 Javaコードのサンプル
import bea.jolt.*;
import java.math.BigDecimal;
import com.bea.base.io.MainframeWriter;
import com.bea.base.io.MainframeReader;
import java.io.IOException;
import com.bea.sna.jcrmgw.snaException;
import test.*;
 
 
public class jc {
public static void main ( String[] args ) {
JoltSession jses;
 
try {
JoltSessionAttributes jattr;
JoltRemoteService toupper,addsvc;
JoltTransaction trans;
String name=null;
String pass=null;
String apass=null;
String urole="myapp";
String outstr,addr;
test.EmployeeRecord egenclass;
BigDecimal value;
 
jattr = new JoltSessionAttributes();
 
//jattr.setString(jattr.APPADDRESS, "//lcdux2:5555");
jattr.setString(jattr.APPADDRESS, "//"+args[0]);
jattr.setInt(jattr.IDLETIMEOUT, 300);
jattr.setString(jattr.TRUSTSTORE, "wallet/trust.jks");
jattr.setString(jattr.TSPASSPHRASE, "abcd1234");
jses = new JoltSession(jattr, name, urole, pass, apass);
 
String testString = new String("john");
 
egenclass = new test.EmployeeRecord();
value = new BigDecimal("123456789");
egenclass.getEmpRecord().setEmpSsn(value);
egenclass.getEmpRecord().getEmpName().setEmpNameFirst(testString);
byte[] inputBuffer = egenclass.toByteArray(new MainframeWriter());
toupper = new JoltRemoteService("CSIMPSRV", jses);
toupper.setBytes("DATAFLOW", inputBuffer, inputBuffer.length);
toupper.call(null);
byte[] rawResult= null;
rawResult = toupper.getBytesDef("DATAFLOW", null);
test.EmployeeRecord result = new test.EmployeeRecord(new MainframeReader(rawResult));
value = result.getEmpRecord().getEmpSsn();
System.out.println("after call emp-ssn is " + value.toString() );
jses.endSession();
System.exit(0);
} // end of try block
catch (SessionException e )
{
System.err.println(e);
System.exit(1);
} // catch of try block
catch (IOException ioe )
{
System.err.println(ioe);
System.exit(1);
}
} // of main
} // public class jc
 
 
Tuxedoサーバー・サイトで、同じコピーブックemprec.cpyを使用するTuxedo COBOLサーバーを作成できます。簡単な例は以下を参照してください。
リスト26 Tuxedoサーバー・サイトのサンプル
*
IDENTIFICATION DIVISION.
PROGRAM-ID. CSIMPSRV.
AUTHOR. TUXEDO DEVELOPMENT.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
*
SPECIAL-NAMES. CONSOLE IS CRT.
*
DATA DIVISION.
WORKING-STORAGE SECTION.
copy 'emprec'.
*****************************************************
* Tuxedo definitions
*****************************************************
01 TPSVCRET-REC.
COPY TPSVCRET.
*
01 TPTYPE-REC.
COPY TPTYPE.
*
01 TPSTATUS-REC.
COPY TPSTATUS.
*
01 TPSVCDEF-REC.
COPY TPSVCDEF.
*****************************************************
* Log messages definitions
*****************************************************
01 LOGMSG.
05 FILLER PIC X(10) VALUE "CSIMPSRV :".
05 LOGMSG-TEXT PIC X(50).
01 LOGMSG-LEN PIC S9(9) COMP-5.
*****************************************************
* User defined data records
*****************************************************
01 RECV-STRING PIC X(100).
01 SEND-STRING PIC X(100).
*
LINKAGE SECTION.
*
PROCEDURE DIVISION.
*
START-FUNDUPSR.
MOVE LENGTH OF LOGMSG TO LOGMSG-LEN.
MOVE "Started" TO LOGMSG-TEXT.
PERFORM DO-USERLOG.
 
*****************************************************
* Get the data that was sent by the client
*****************************************************
MOVE LENGTH OF RECV-STRING TO LEN.
CALL "TPSVCSTART" USING TPSVCDEF-REC
TPTYPE-REC
emp-record
TPSTATUS-REC.
 
IF NOT TPOK
MOVE "TPSVCSTART Failed" TO LOGMSG-TEXT
PERFORM DO-USERLOG
PERFORM EXIT-PROGRAM
END-IF.
 
IF TPTRUNCATE
MOVE "Data was truncated" TO LOGMSG-TEXT
PERFORM DO-USERLOG
PERFORM EXIT-PROGRAM
END-IF.
 
MOVE emp-ssn TO LOGMSG-TEXT.
PERFORM DO-USERLOG.
 
MOVE 987654321 to emp-ssn.
 
MOVE emp-name-first TO LOGMSG-TEXT.
PERFORM DO-USERLOG.
 
MOVE "Success" TO LOGMSG-TEXT.
PERFORM DO-USERLOG.
SET TPSUCCESS TO TRUE.
COPY TPRETURN REPLACING
DATA-REC BY emp-record.
 
*****************************************************
* Write out a log err messages
*****************************************************
DO-USERLOG.
CALL "USERLOG" USING LOGMSG
LOGMSG-LEN
TPSTATUS-REC.
*****************************************************
* EXIT PROGRAM
*****************************************************
EXIT-PROGRAM.
MOVE "Failed" TO LOGMSG-TEXT.
PERFORM DO-USERLOG.
SET TPFAIL TO TRUE.
COPY TPRETURN REPLACING
DATA-REC BY emp-record.
 
 
export COBDIR=/opt/cobol-it-64
export TM_COBOLIT_VERSION=3.7
export COBOLIT_LICENSE=$COBDIR/citlicense.xml
export PATH=$COBDIR/bin:$PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$COBDIR/lib
export COBCPY=$TUXDIR/cobinclude
buildserver -C -o CSIMPSRV -f CSIMPSRV.cbl -f TPSVRINIT.cbl -s CSIMPSRV

Copyright ©1994, 2017,Oracle and/or its affiliates. All rights reserved