How Do I: Map Java Data Type Buffers to FML and VIEW

For type mapping to occur properly, you must edit the file to define a method that matches field names from complex Java data types to the FML/FML32 and VIEW/VIEW32 buffers. This means that the control matches parameter names and Java member names to fielded buffer field names. This field matching allows the control to build the correct request/response buffers that are expected. This field matching defines what data the control places in the buffer. The service defines or determines the buffer setup. In other words, the service type defines the communication model which determines request buffers and response buffers.

Communication Model
Service Type

Synchronous Request/Response (tpcall)

service

Request without Response (tpacall)

oneway

Queued (tpenqueue)

queue

The fields defined in the method in the control must match the fields defined in the field tables or VIEW class. For example, if the control defines a method of:

String anOp (String s1, Float f1, Short s2); 

At runtime when the anOp method is called, assuming a fielded buffer type is used, the control accesses the field tables for fields named "s1", "f1", and "s2". For the fields that are found, the control places the parameter with the same name into the buffer as that field.

For complex Java data types such as beans or Java classes with only data members, this field matching process is more complex. The control performs the same matching algorithm as previously described, but it is performed recursively on each of the complex Java data types. For example, classes as follows:

static public class Name {
	String		First;
	String		Last;
	Character		MI;
}

static public class Person {
	Name		CompleteName;
	Float		Age;
	Integer		Weight;
}

static public class People {
	Person[]		PEOPLE;
} 

and an operation signature as follows:

People addPerson(Person aPerson); 

In the previous example, the control at runtime looks for a field in the field table by the name of aPerson. If the control finds aPerson and it is an embedded type field such as FLD_FML32, the control creates the embedded buffer and begins filling the embedded buffer with the fields from the value passed as aPerson. Otherwise, because Person is a complex type, the control starts looking for fields matching the members of the complex type Person. Thus the control looks for a field named CompleteName. Again, if CompleteName matches an embedded buffer type, the control creates the embedded buffer and fills it. Next the control looks for a field in the field tables named First. If a match occurs, the control places the Java field aPerson.Name.First in the buffer with the field ID associated with the name First. Next it looks for a field named Last. The control performs a depth first traversal of the passed parameters and then looks for matching fields in the field table.

The control performs a similar process to pull the returned buffer apart. In the previous example, the control examines the return type of the method. As it is an array of a complex type, the control looks for occurrences of a field named PEOPLE, and if found, determines the number of occurrences and creates an array of Person of that size. If no field of name PEOPLE is found, it looks for occurrences of fields CompleteName, Age, and Weight. it then creates an array of Person large enough to hold the least number of occurrences of those fields found. Then the control starts populating the array by pulling fields out of the buffer that match the data member names of the Person and creating instances of Person.

Using JavaBean-style Data Accessors

A JavaBean is a Java class that hides its state behind methods that conform to certain naming standards. This Java class uses private data fields with public accessors. To determine the fields for a class, the control constructs a list of all public fields and then adds any additional fields found by examining the public methods of the class looking for methods of the following form:

public void setFIELD(type val);
public void setFIELD(type[] val);
public type getFIELD();
public type[] getFIELD();
 

In the previous code example,

The JavaBean naming conventions require that a field name begins with a lowercase character. By default, the Tuxedo Control will follow the JavaBean naming conventions. For example, a field called myField would have a getter named getMyField and a setter named setMyField. To convert an accessor name to a field name, the Tuxedo Control strips the get or set prefix and converts the first character of the resulting field name to lowercase, myField.

For some existing Tuxedo field tables that have field names that begin with an uppercase character, this naming convention conversion is a problem. To resolve this naming issue, use the accessor-name-conventions attribute in the @TuxedoControl.tuxedo annotation.

JavaBean Accessors allow you to control movement of data to and from the JavaBean. Using public data members, the control directly accesses the fields and the ability to control that movement of data is limited to the coercion capabilities of the control. An accessor allows user-provided methods to perform arbitrary checks or data modification before a field's data is retrieved or set. An example of where this may be helpful is in retrieving a string field from a buffer that was space padded as in a VIEW buffer generated by COBOL. A custom-written setter could trim the field before storing the string.

Data Type Mapping and Coercion

When the types of fields with the same name do not match exactly, coercion specifications determine the mapping behavior. You can specify the mapping-strictness attribute in the @TuxedoControl.tuxedo annotation using the Property view . Possible coercion values for mapping-strictness are:

The default is normal.

In the previous example from How Do I: Map Java Data Type Buffers to FML and VIEW, the field in the field table associated with Weight might be a String field. In this case, for mapping strictness of either loose or normal, the control converts the Integer data member of the Person instance to a String before trying to place the data in the buffer. That is a normal and reasonable coercion to perform, so the control performs that coercion when the mapping strictness is anything but strict. For a mapping strictness of normal, the control places an issue in the issue list to indicate that it had to coerce some data. With a mapping strictness of strict, the control raises an exception.