Java 包装器类

当请求将某个程序部件生成为 Java™ 包装器时,EGL 会为下列每一项生成包装器类:

在后面的描述中,将给定程序的包装器类称为程序包装器类参数包装器类动态数组包装器类具有子结构的项数组包装器类

EGL 为每个参数包装器类、动态数组包装器类或具有子结构的项数组包装器类生成一个 BeanInfo 类。BeanInfo 类允许将相关包装器类用作与 Java 相符的 Java bean。您基本上不会与 BeanInfo 类进行交互操作。

在生成包装器时,被调用程序的参数列表不能包括类型为 BLOB、CLOB、STRING、Dictionary、ArrayDictionary 或非固定记录的参数。

关于如何使用包装器类的概述

要使用包装器类来与通过 VisualAge® Generator 生成的程序进行通信,在本机 Java 程序中执行下列操作:
  • 将类(CSOPowerServer 的子类)实例化以提供中间件服务,例如,在本机 Java 代码与生成的程序之间转换数据:
      import com.ibm.javart.v6.cso.*;
    
      public class MyNativeClass
      {
        /* declare a variable for middleware */
        CSOPowerServer powerServer = null;
        
        try
        {
      	   powerServer = new CSOLocalPowerServerProxy();
        }
        catch (CSOException exception)
        {
          System.out.println("Error initializing middleware"
            + exception.getMessage());
          System.exit(8);
        }
      }
  • 将程序包装器类实例化以执行下列操作:
    • 分配数据结构,包括动态数组(如果有的话)
    • 实现对方法的访问,而这些方法又访问生成的程序
    对构造函数的调用包括中间件对象:
      myProgram = new MyprogramWrapper(powerServer);
  • 声明基于参数包装器类的变量:
      Mypart  myParm = myProgram.getMyParm();
      Mypart2 myParm2 = myProgram.getMyParm2(); 
    如果程序带有动态数组参数,则声明其它每个都基于动态数组包装器类的变量:
      myRecArrayVar myParm3 = myProgram.getMyParm3();

    有关与动态数组进行交互的详细信息,请参阅动态数组包装器类

  • 在大多数情况下(如上一个步骤所述),使用参数变量来引用和更改在程序包装器对象中分配的内存
  • 设置用户标识和密码,但只有在下列情况下才这样做:
    • Java 包装器通过 iSeries™ Toolbox for Java 来访问基于 iSeries 的程序;或者
    • 生成的程序在认证远程访问的 CICS® for z/OS® 区域中运行。

    用户标识和密码不用于数据库访问。

    通过使用程序对象的 callOptions 变量来设置和查看用户标识和密码,如以下示例所示:
      myProgram.callOptions.setUserID("myID");
      myProgram.callOptions.setPassword("myWord");
      myUserID = myProgram.callOptions.getUserID();
      myPassword = myProgram.callOptions.getPassword();
  • 访问生成的程序(在大多数情况下,通过调用程序包装器对象的 execute 方法来执行此操作):
      myProgram.execute();
  • 使用中间件对象来建立数据库事务控制,但是仅在以下情况下才执行此操作:
    • 程序包装器对象正在访问 CICS for z/OS 上生成的程序,或者正在通过 IBM® Toolbox for Java 来访问基于 iSeries 的 COBOL 程序。在后一种情况下,该调用的 remoteComType 值是 JAVA400。
    • 在用来生成包装器类的链接选项部件中,指定了数据库工作单元受客户机(在这种情况下,是包装器)控制;有关详细信息,请参阅“对 callLink 元素中的 luwControl 的引用”。
    如果数据库工作单元受客户机控制,则处理包括使用中间件对象的 commit 和 rollback 方法:
      powerServer.commit();
      powerServer.rollback();
  • 关闭中间件对象,并允许进行垃圾回收:
      if (powerServer != null)
      {
        try
        {
          powerServer.close();
          powerServer = null;
        }
    
        catch(CSOException error)
        {
          System.out.println("Error closing middleware"
            + error.getMessage());
          System.exit(8);
        }
      }

程序包装器类

程序包装器类包含生成的程序中的每个参数的专用实例变量。如果参数是记录或表单,则变量表示相关参数包装器类的实例。如果参数是数据项,则变量具有基本 Java 类型。

本帮助页面末尾的表描述了 EGL 与 Java 类型之间的转换。

程序包装器对象包含下列公用方法:
  • 每个参数的 getset 方法,其名称的格式如下所示:
      purposeParmname()
    purpose
    getset
    Parmname
    数据项、记录或表单的名称;第一个字母是大写的,其它字母的特征由Java 包装器类的命名约定描述的命名约定确定
  • 用于调用程序的 execute 方法;如果将要作为调用自变量传递的数据位于为程序包装器对象分配的内存中,则使用此方法
可以不对实例变量赋值,而是执行下列操作:
  • 为参数包装器对象、动态数组包装器对象以及基本类型分配内存
  • 对分配的内存赋值
  • 通过调用程序包装器对象的 call 方法而不是 execute 方法来将这些值传递给程序
程序包装器对象还包含 callOptions 变量,该变量具有下列用途:
  • 如果您生成 Java 包装器以便在生成时设置调用的链接选项,则 callOptions 变量包含链接信息。有关何时设置链接选项的详细信息,请参阅“callLink 元素中的 remoteBind”。
  • 如果您生成 Java 包装器以便在运行时设置调用的链接选项,则 callOptions 变量包含链接属性文件的名称。文件名为 LO.properties,其中 LO 是用于生成的链接选项部件的名称。
  • 在以上任何一种情况下,callOptions 变量都提供下列方法来设置或获取用户标识和密码:
      setPassword(passWord)
      setUserid(userid)
      getPassword()
      getUserid()
    当将 callLink 元素的 remoteComType 属性设置为下列其中一个值时,将使用该用户标识和密码:
    • CICSECI
    • CICSJ2C
    • JAVA400
最后,请参照以下情况:当更改了参数或基本类型时,本机 Java 代码需要通知。为了能够发出这样的通知,通过调用程序包装器对象的 addPropertyChangeListener 方法来将本机代码注册为侦听器。在这种情况下,下列任何一种情况都会触发 PropertyChange 事件,从而导致本机代码在运行时接收到通知:
  • 本机代码对具有基本类型的参数调用 set 方法
  • 生成的程序将已更改的数据返回到具有基本类型的参数中

Sun 公司的 JavaBean 规范对 PropertyChange 事件作了描述。

参数包装器类集

将为生成的程序中的每个被声明为参数的记录生成参数包装器类。在通常情况下,仅使用参数包装器类来声明引用参数的变量,如以下示例所示:
  Mypart myRecWrapperObject = myProgram.getMyrecord();

在此例中,您正在使用由程序包装器对象分配的内存。

也可以使用参数包装器类来声明内存,如果调用程序对象的 call 方法(而不是 execute 方法),则必需执行此操作。

参数包装器类包含一组专用实例变量,如下所示:
  • 对参数的每个低层结构项包含一个具有 Java 基本类型的变量(但是仅对于既不是数组又不在具有子结构的数组中的结构项才如此)
  • 对于每个作为数组并且不具有子结构的 EGL 结构项,包含 Java 基本类型的一个数组
  • 本身不在具有子结构的数组中的每个具有子结构的数组的内部数组类的对象;内部类可以具有嵌套的内部类来表示下级具有子结构的数组
参数包装器类包含几个公用方法:
  • 一组 getset 方法允许您获取和设置每个实例变量。每个方法名的格式如下所示:
      purposesiName()
    purpose
    getset
    siName
    结构项的名称。第一个字母是大写的,其它字母的特征由Java 包装器类的命名约定描述的命名约定确定。
    注: 程序调用包含已声明为填充符的结构项;但是,数组包装器类不包含那些结构项的公用 get 和 set 方法。
  • 方法 equals 允许您确定存储在同一个类的另一个对象中的值是否与存储在参数包装器对象中的值完全相同。仅当类和值完全相同时,该方法才会返回 true
  • 如果当具有 Java 基本类型的变量发生更改时程序需要得到通知,则调用方法 addPropertyChangeListener
  • 第二组 getset 方法允许您获取和设置 SQL 记录参数中的每个结构项的空指示符。这些方法名中的每个方法名的格式如下所示:
      purposesiNameNullIndicator()
    purpose
    getset
    siName
    结构项的名称。第一个字母是大写的,其它字母的特征由Java 包装器类的命名约定描述的命名约定确定。

具有子结构的项数组包装器类集

具有子结构的项数组包装器类是参数类的内部类,它表示相关参数中具有子结构的数组。具有子结构的项数组包装器类包含一组专用实例变量,这些变量表示数组本身以及该数组下面具有的结构项:
  • 对数组的每个低层结构项包含一个具有 Java 基本类型的变量(但是仅对于既不是数组又不在具有子结构的数组中的结构项才如此)
  • 对于每个作为数组并且不具有子结构的 EGL 结构项,包含 Java 基本类型的一个数组
  • 本身不在具有子结构的数组中的每个具有子结构的数组的内部具有子结构的项数组包装器类的对象;内部类可以具有嵌套的内部类来表示下级具有子结构的数组
具有子结构的项数组包装器类包含下列方法:
  • 每个实例变量的一组 getset 方法
    注: 程序调用使用已声明为无名填充符的结构项;但是,具有子结构的项数组包装器类不包含那些结构项的公用 get 和 set 方法。
  • 方法 equals 允许您确定存储在同一个类的另一个对象中的值是否与存储在具有子结构的项数组包装器对象中的值完全相同。仅当类和值完全相同时,该方法才会返回 true
  • 方法 addPropertyChangeListener,如果当具有 Java 基本类型的变量发生更改时程序需要得到通知,则使用此方法
在大多数情况下,参数包装器类中的最顶层具有子结构的项数组包装器类的名称格式为:
  ParameterClassname.ArrayClassName
请参照以下记录,例如:
  Record CompanyPart type basicRecord
  10 Departments CHAR(20)[5];
     20 CountryCode CHAR(10);
     20 FunctionCode CHAR(10)[3];
        30 FunctionCategory CHAR(4);
        30 FunctionDetail CHAR(6);
  end

如果参数 Company 基于 CompanyPart,则使用字符串 CompanyPart.Departments 作为内部类的名称。

内部类的内部类扩展了点线语法的使用。在此示例中,使用符号 CompanyPart.Departments.Functioncode 来作为 Departments 的内部类名称。

有关如何命名具有子结构的项数组包装器类的其它详细信息,请参阅 Java 包装器生成的输出

动态数组包装器类

将为生成的程序中的每个被声明为参数的动态数组生成动态数组包装器类。请参照以下 EGL 程序特征符:
  Program myProgram(intParms int[], recParms MyRec[])

动态数组包装器类的名称是 IntParmsArray 和 MyRecArray。

使用动态数组包装器类来声明引用动态数组的变量,如以下示例所示:
  IntParmsArray myIntArrayVar = myProgram.getIntParms();
  MyRecArray    myRecArrayVar = myProgram.getRecParms();

在为每个动态数组声明变量之后,您可能会添加元素:

  // adding to an array of Java primitives 
  // is a one-step process
  myIntArrayVar.add(new Integer(5));

  // adding to an array of records or forms 
  // requires multiple steps; in this case, 
  // begin by allocating a new record object
  MyRec myLocalRec = (MyRec)myRecArrayVar.makeNewElement();
  
  // the steps to assign values are not shown 
  // in this example; but after you assign values, 
  // add the record to the array
  myRecArrayVar.add(myLocalRec);

  // next, run the program
  myProgram.execute();

  // when the program returns, you can determine 
  // the number of elements in the array
  int myIntArrayVarSize = myIntArrayVar.size();

  // get the first element of the integer array 
  // and cast it to an Integer object
  Integer firstIntElement = (Integer)myIntArrayVar.get(0);

  // get the second element of the record array
  // and cast it to a MyRec object
  MyRec secondRecElement = (MyRec)myRecArrayVar.get(1);

如该示例所建议的那样,EGL 提供了多个用于处理所声明的变量的方法。

动态数组类的方法 用途
add(int, Object) int 指定的位置插入对象并将当前及后续元素向右移。
add(Object) 将对象追加至动态数组末尾。
addAll(ArrayList) 将 ArrayList 追加至动态数组末尾。
get() 检索包含数组中的所有元素的 ArrayList 对象
get(int) 检索位于由 int 指定的位置中的元素
makeNewElement() 分配具有特定于数组的类型的新元素并检索该元素,而不将该元素添加到动态数组中。
maxSize() 检索一个整数,该整数指示了动态数组中的最大元素数目(但不是实际元素数目)
remove(int) 除去位于由 int 指定的位置中的元素
set(ArrayList) 使用指定的 ArrayList 来替换动态数组
set(int, Object) 使用指定的对象来替换位于由 int 指定的位置中的元素
size() 检索动态数组中的元素数目
在下列情况下例外(还有其它一些例外情况):
  • 如果在 getset 方法中指定无效的下标
  • 如果尝试添加(或设置)与数组中每个元素的类不兼容的类的元素
  • 如果在数组达到最大数量而无法支持追加的情况下尝试对动态数组添加元素;并且,如果 addAll 方法由于此原因而失败,则该方法不添加任何元素

Java 包装器类的命名约定

EGL 创建符合下列规则的名称:
  • 如果名称是全大写的,则将所有字母转换为小写。
  • 如果名称是关键字,则在它前面添加下划线
  • 如果名称包含连字符或下划线,则除去该字符并将下一个字母转换为大写字母
  • 如果名称包含美元符号($)、at 符号(@)或磅符(#),则将那些字符中的每一个替换为双下划线(__)并在名称前面添加下划线(_)。
  • 如果名称被用作类名,则将第一个字母转换为大写字母。
下列规则适用于动态数组包装器类:
  • 在大多数情况下,类名基于作为每个数组元素基础的部件声明(数据项、表单或记录)的名称。例如,如果记录部件名为 MyRec,并且数组声明是 recParms myRec[],则相关动态数组包装器类名为 MyRecArray
  • 如果数组基于没有相关部件声明的项声明,则动态数组类的名称基于数组名。例如,如果数组声明是 intParms int[],则相关动态数组包装器类名为 IntParmsArray

数据类型交叉引用

下表指示生成的程序中的 EGL 基本类型与生成的包装器中的 Java 数据类型之间的关系。

EGL 基本类型 按字符或数字所计的长度 按字节计的长度 小数位数 Java 数据类型 Java 的最大精度
CHAR 1-32767 2-32766 不适用 String 不适用
DBCHAR 1-16383 1-32767 不适用 String 不适用
MBCHAR 1-32767 1-32767 不适用 String 不适用
UNICODE 1-16383 2-32766 不适用 String 不适用
HEX 2-75534 1-32767 不适用 byte[] 不适用
BIN, SMALLINT 4 2 0 short 4
BIN, INT 9 4 0 int 9
BIN, BIGINT 18 8 0 long 18
BIN 4 2 >0 float 4
BIN 9 4 >0 double 15
BIN 18 8 >0 double 15
DECIMAL, PACF 1-3 1-2 0 short 4
DECIMAL, PACF 4-9 3-5 0 int 9
DECIMAL, PACF 10-18 6-10 0 long 18
DECIMAL, PACF 1-5 1-3 >0 float 6
DECIMAL, PACF 7-18 4-10 >0 double 15
NUM, NUMC 1-4 1-4 0 short 4
NUM, NUMC 5-9 5-9 0 int 9
NUM, NUMC 10-18 10-18 0 long 18
NUM, NUMC 1-6 1-6 >0 float 6
NUM, NUMC 7-18 7-18 >0 double 15

相关任务
生成 Java 包装器

使用条款 | 反馈
(C) Copyright IBM Corporation 2000, 2005. All Rights Reserved.