Created On:  03 July 2012

Problem:

Customer has a fairly complex COBOL routine to perform business logic that they want to call from Java.  The COBOL routine uses parameter blocks which are defined as COBOL group item records. 

They have successfully created Micro Focus COBOL "Custom Record Interface" objects for these parameter blocks and have successfully called and passed this info into and out of the COBOL routine from Java.
 
Thus far, each "custom record" has only had to describe COBOL elementary group items. However, to complete the set of interfaces, they need to be able to handle COBOL record definitions that include an array (OCCURS).

The "custom record" documentation and other "calling COBOL from Java" documentation does not give examples or suggestions on how to handle these more complex COBOL record structures.

Does anyone have any examples or know of any more detailed documentation?

Resolution:

The customrecord interface has no internal functionality to automatically handle arrays that are defined within the COBOL record.  Its function is to format elementary items within a record and pass it to COBOL as a single java byte array.

If you wanted to add array functionality to the record then you would have to layout the array within java as if it were passing each item of the array as part of the byte array that is being passed into COBOL.

So if COBOL defined something like:

linkage Section.

01 customerDetails.
     03 customerName pic x(30).
     03 customerAddress pic x(30).
     03 customerRef pic 9(6).
     03 customerArray.
          05 customerProducts pic x(5) occurs 3 times.
procedure division using by reference customerDetails.

Java would define something like this (although you would probably change code to format your java array as a separate string to include)

public class RecordData implements DataType
{
    private String customerName, customerAddress, customerProd1, customerProd2, customerProd3;
    private int customerRef;
    private byte[] bytes;
    RecordData(String name, String address, int ref, String prod1, String prod2, String prod3)
    {
        customerName = name;
        customerAddress = address;
        customerRef = ref;
        customerProd1 = prod1;
        customerProd2 = prod2; 
        customerProd3 = prod3;
     }
    public void synchronizeData()
    {
      // This method is called from COBOL prior to return from a method.
      //
      // We use it here to update each field to contain the
      // data returned by COBOL in the updated byte array.
        customerName = new String(bytes, 0, 30);
        customerAddress = new String(bytes, 30, 30);
        customerRef = Integer.parseInt(new String(bytes, 60, 6));
        customerProd1 = new String(bytes, 66, 5);
        customerProd2 = new String(bytes, 71, 5);
        customerProd3 = new String(bytes, 76, 5);
    }
    public byte[] getBytes() 
   { 
    // This method is called from COBOL on entry to a method to obtain
    // the data to be moved into the COBOL data type.
    // To pass the information, a temporary string is created from the
    // fields in the class, to allow them to be passed to COBOL as a
    // byte array.
        int i;
        StringBuffer tmpCustomerName = new StringBuffer(customerName);
    // The COBOL program is expecting 30 character strings, so space fill.
        for (i = tmpCustomerName.length(); i < 30; i++)
            tmpCustomerName.append(" ");
        StringBuffer tmpCustomerAddress = new StringBuffer(customerAddress);
        for (i = tmpCustomerAddress.length(); i < 30; i++)
            tmpCustomerAddress.append(" ");
    // Format the reference number to match PIC 9(6)
        DecimalFormat pic9display = new DecimalFormat("000000");
        StringBuffer tmpCustomerRef = pic9display.format(customerRef, 
             new StringBuffer(""), new FieldPosition(0));
        StringBuffer tmpCustomerProd1 = new StringBuffer(customerProd1);
        for (i = tmpCustomerProd1.length(); i < 5; i++)
            tmpCustomerProd1.append(" "); 
        StringBuffer tmpCustomerProd2 = new StringBuffer(customerProd2);
        for (i = tmpCustomerProd2.length(); i < 5; i++)
            tmpCustomerProd2.append(" "); 
        StringBuffer tmpCustomerProd3 = new StringBuffer(customerProd3); 
        for (i = tmpCustomerProd3.length(); i < 5; i++)
            tmpCustomerProd3.append(" ");
        String tmpString = new String(tmpCustomerName.toString() +
            tmpCustomerAddress.toString() + tmpCustomerRef.toString() + tmpCustomerProd1.toString() +
                tmpCustomerProd2.toString() + tmpCustomerProd3.toString());
        bytes = tmpString.getBytes();
        return bytes;
    }
    public String getCustomerName()
    {   
        return this.customerName;
    }
    public String getCustomerAddress() 
    {
        return this.customerAddress;
    }
    public int getCustomerRef()
    {
       return this.customerRef;
    }
    public String getCustomerProd1()
    {
       return this.customerProd1; 
    }
    public String getCustomerProd2()
    {
       return this.customerProd2;
    }
    public String getCustomerProd3()
    {
       return this.customerProd3;  
    } 
    public void showRef()
   {
   // Method used to illustrate that the customerRef field was updated.
       System.out.println("Updated customerRef is : " + customerRef); 
   }
   public String toString()
   {
       return "Customer Name : "+this.customerName+"\n"+ "Customer Address : "+this.customerAddress+"\n"+
  "Customer Ref : "+this.customerRef+"\n"+ "Customer Prod1 : "+this.customerProd1+"\n"+ "Customer Prod2 : "+this.customerProd2+"\n"+
  "Customer Prod3 : "+this.customerProd3+"\n"; 
   }
}