Access to any of those host programs is by way of the JTOpen toolkit, which determines what program types are supported. For an overview of the toolkit, see the following web site: JTOpen (http://jt400.sourceforge.net/).
The main annotation is IBMiProgram. In most cases, that annotation references a resource binding in the EGL deployment descriptor. One runtime effect of referencing a resource binding is that you gain the performance benefits of using a connection from the AS400 connection pool.
When you include a using clause, the coded detail overrides any IBMiProgram annotation reference to the EGL deployment descriptor. If the using clause references a different deployment-descriptor entry, you still gain the performance benefits of using a pooled connection. However, the using clause might represent a connection that you define in your code; and in that case, you typically do not use a pooled connection, but rely on the AS400 connection object that is available in the JTOpen toolkit.
In general, a Rich UI application uses an asynchronous version of the call statement to get enterprise data from a service. In relation to an IBM i program, the application calls a proxy function that is defined in an EGL Service type.
The objects expected by the host are based on fixed-size types, whereas many EGL types are variably sized. You handle the difference by annotating the variably sized objects.
The annotations you specify are in the eglx.jtopen.annotations package, with annotation type names that of the form AS400xxxx. The annotation type names correspond to the JTOpen com.ibm.as400.access.AS400Datatype class names.
To determine which annotations to specify, refer to the table shown later, along with the Javadoc for the com.ibm.as400.access.AS400Datatype classes.
function GETRECA(CUST CUST[] inout,
EOF string inout,
COUNT decimal (2,0) inout)
{
@ExternalName{value="MyHostProc"}
@IBMiProgram {
programName = "GETREC",
libraryName = "/QSYS.LIB/VARLABXX.LIB/"
isServiceProgram=true,
parameterAnnotations = [
@AS400Array{elementCount = 10},
@AS400Text{length = 1},
null
],
resourceBindingURI = @Resource{uri = "binding:file:EGLDDFile#MyConnection"}
}
}
end
The ExternalName annotation is optional. It holds the name of the IBM i procedure and defaults to the name of the EGL proxy function.
You can specify both details on the programName field; in the current example, the field value would be "/QSYS.LIB/VARLABXX.LIB/GETREC". In any case, the EGL runtime code appends a file extension to the value of the programName field: .SRVPGM for service programs, .PGM for called programs.
The EGL runtime code uses the binding details to construct a JTOpen object of type AS400ConnectionPool.
A resource of type IBMiConnection contains a library field. Any value specified in that field replaces the library field in the IBMiProgram annotation
For general details on binding, see the following help topic: Resource bindings.
The data-conversion annotations cause the use of converters that are found in the following JTOpen package: com.ibm.as400.access. The EGL annotation name is the same as the Java class name.
If you do not set a value for the parameterAnnotations field, the defaults are used for every parameter.
Record Example
//Convert using the default AS400Bin4
f1 int;
//After the host program call, f2 is resized using the data returned in f3
f2 int[]{@AS400Array{elementCount = 10, returnCountVariable = "f3"}};
//A fixed text with a length 2 characters using the default encoding
f3 string{@AS400Text{length = 2}};
//Convert a number to a AS400DecFloat
f4 number?{@AS400DecimalFloat{length = 34}};
//Convert using the default AS400PackedDecimal
f5 decimal(10,2);
//Convert using the AS400ZonedDecimal
f6 decimal(10,4){@AS400ZonedDecimal{}};
end
If that Record type included a record, you would not specify an annotation for the included record, but might specify annotations for the fields in that record.
You write a call statement to invoke the EGL proxy function. A using clause, if present, refers to connection detail that is stored in the EGL deployment descriptor or is supplied in the call statement. If a using clause is not present in the call statement, the IBMiProgram annotation in the proxy function must reference a deployment descriptor entry.
Program TestSimpleProgram
//On IBM i, only service programs support a return
function MyHostProcedure(p1 string, p2 string)RETURNS(INT)
{
@IBMiProgram{
programName = "/QSYS.LIB/VARLABXX.LIB/GETREC",
resourceBindingURI = @Resource{uri = "binding:file:someConnection"},
isServiceProgram= true,
parameterAnnotations = [@AS400Text{length = 10}, @AS400Text{length = 10}]
}
}
end
end
cust Customer; result Int; myString String = "abc"; try call MyHostProcedure(myString, cust) returns (result); onexception(exception AnyException) //handle exception end
Here is an alternative call, which provides binding detail that overrides the binding detail, if any, that is specified in the IBMiProgram annotation:
cust Customer;
result int;
myString String = "abc";
conn IBMiConnection? = SysLib.getResource(uri="binding:file:someOtherConnection");
try
call MyHostProcedure(myString, cust)
using conn
returns (result);
onexception(exception AnyException)
//handle exception
end
cust Customer;
result int;
myString String = "abc";
try
call MyHostProcedure(myString, cust)
using SysLib.getResource(uri="binding:file:someOtherConnection")
as IBMiConnection
returns (result);
onexception(exception AnyException)
//handle exception
end
cust Customer;
result int;
myString String = "abc";
conn IBMiConnection? = getMyDefinedConnection();
try
call MyHostProcedure(myString, cust)
using conn
returns (result);
onexception(exception AnyException)
//handle exception
end
externalType JTOpenConnections type JavaObject private constructor(); static function getAS400ConnectionPool()returns(AS400ConnectionPool); end
For details on that function, see the JTOpen documentation for the AS400ConnectionPool object.
You can set a variety of fields in the EGL deployment descriptor entry. The type of each entry is AS400Connection, which is compatible with the IBMiConnection type that is used in the code examples.
This value overrides the default date format, which is com.ibm.as400.access.AS400Date.FORMAT_ISO. For an individual parameter or field that is being passed to the proxy, you can specify a ibmiFormat value on the AS400Date annotation, and that value overrides any other, with one exception: any ibmiSeparatorChar value on that annotation is used for the separator value.
This value overrides the date separator that is specified in the dateFormat value. For an individual parameter or field that is being passed to the proxy, you can specify a ibmiSeparatorChar value on the AS400Date annotation, and that value overrides any other.
This value overrides the default encoding, which is obtained from the CCSID value of the AS400 connection. For an individual parameter or field that is being passed to the proxy, you can specify an encoding value on the AS400Text annotation, and that value overrides any other.
This value overrides the default time format, which is com.ibm.as400.access.AS400Time.FORMAT_ISO. For an individual parameter or field that is being passed to the proxy, you can specify a ibmiFormat value on the AS400Time annotation, and that value overrides any other, with one exception: any ibmiSeparatorChar value on that annotation is used for the separator value.
This value overrides the date separator that is specified in the timeFormat value. For an individual parameter or field that is being passed to the proxy, you can specify a ibmiSeparatorChar value on the AS400Time annotation, and that value overrides any other.
This value overrides the default time zone, which is obtained from the timezone value of the AS400 connection. For an individual parameter or field that is being passed to the proxy, you can specify an ibmiTimezoneID value on the AS400Date, AS400Time, or AS400Timestamp annotation, and that value overrides any other.
| EGL type | EGL annotation | Annotation fields |
|---|---|---|
| bigint | AS400Bin8 (the default) or AS400UnsignedBin4. | |
| bytes (not yet supported) | AS400Array | For a non-parameterized bytes type:
|
| date | AS400Date |
|
| decimal | AS400PackedDecimal; AS400ZonedDecimal; or AS400DecFloat. | For a non-parameterized decimal type:
See the paragraph after this table. |
| float | AS400Float8 (the default). | |
| Handler types | No annotation. Conversion is controlled by the AS400Structure Java class. | |
| int | AS400Bin4 (the default) or AS400UnsignedBin2. | |
| List types | AS400Array (the default). You must specify the annotation if you need to use any of the annotation fields. None of those fields has a default value. For examples, see a later section. |
|
| Record types | No annotation. Conversion is controlled by the AS400Structure Java class. | |
| string | AS400Text (the default). | For a non-parameterized string type:
For any string type:
See the paragraph after this table. |
| smallfloat | AS400Float4 (the default). | |
| smallint | AS400Bin2 (the default), AS400Bin1, or AS400UnsignedBin1. | |
| time | AS400Time (the default). |
|
| timestamp | AS400Timestamp (the default). The conversion to an IBM i timestamp format is in accordance with the Java FORMAT_DEFAULT field in the following class: com.ibm.as400.access.AS400Timestamp. |
|
The following types can be parameterized: Bytes, Decimal, String, Timestamp.
f1 String[]
{@AS400Array{elementCount = 10,
elementTypeAS400Annotation = @AS400Text{length= 25},
returnCountVariable = f3}};
f2 Int[] = new Int[5]{@AS400Array{elementCount = 5}};
f3 Int;
function TEST(length1 String, f1 String[], f2 String[] ){
@IBMiProgram{
programName = "/QSYS.LIB/VARLABXX.LIB/GETREC",
parameterAnnotations = [
@AS400Text{length=2},
@AS400Array{elementCount = 10,
elementTypeAS400Annotation = @AS400Text{length= 25},
returnCountVariable = length1},
@AS400Array{
elementCount = 5,
elementTypeAS400Annotation = @AS400Text{length= 10}
}
}
]
}
Any value that is used to resize an array must be assignment compatible with an EGL int. An example is length1, which is of type String.