IBM Support

Programming Considerations About Usage of JSON Generate and Parse functionality on IBM i using EGL in Business Developer

White Papers


Abstract

Kushagra Goyal,
Senior Technical Specialist

This article guides you through the Programming Considerations About Usage of JSON Generate and Parse functionality on IBM using EGL in Business Developer.
IBM Business Developer offers various deployment architecture models for generated applications for its users based on their needs. This paper details the functionality of functions enhanced to support IBM i environment, their limitations and functioning for various requirement scenarios.

Content

Introduction

IBM Rational Business Developer aka RBD is an Eclipse-based IDE that helps developers in developing application using EGL that generates COBOL. As the new version (V9.7) of RBD is about to release and based on users input we enhanced the current JSON functions to also support IBM iSeries.

ILE COBOL currently does not support JSON processing. We have developed our own solution to support JSON processing on IBM i. This solution will provide both PARSE and GENERATE functionalities with certain caveats, which will be mentioned later in the document.

By this inclusion, the current RBD community (which uses EGL for their application development and maintenance on mainframes) will be able to use new version of RBD to develop/enhance applications including JSON functions as and when required on IBM i environment.

The existing EGL functions in scope of this document are:

  • servicelib.convertToJSON(EGLType)
  • servicelib.convertFromJSON(String, EGLType)
Objective
Below are a few reasons why this enhancement in the RBD environment is required.
  • Since the JSON processing is supported on IBM zOS, there is a definite need to extend support to IBM iSeries.
  • ILE COBOL on IBM iSeries does not provide support to JSON processing.
  • Customer’s demand to provide support to JSON on iSeries like it is provided for z/OS.
Thus, we planned to prepare our own JSON Parsing and JSON Generation mechanism in RBD that could run on IBM iSeries by using RBD.
Function Description
Under library ‘ServiceLib,’ the existing two functions are supported in RBD for IBM iSeries.  The two functions in EGL are:
  • Servicelib.convertToJSON() – a function that accepts an object of an EGL record as input and generates a JSON string as an output.
  • Servicelib.convertFromJSON() - a function that takes a valid JSON string and an object of an EGL record as input. After the parsing of JSON string, the provided object on an EGL record is populated as an output of this function.

Special Considerations
There are a couple of considerations with the current solution, which are listed as below:
  • All EGL datatypes are supported except Dictionary, NUM, and BIN.
  • Error handling while parsing JSON on IBM i will be limited to cover below error categories:
Seq No Error Message ID Message Description
1
GEN0350 Function convertFromJSON found an error in JSON string Generic error statement.
2 GEN0351 Syntax Error. Offset=<Displacement in input JSON String> expected=<Expected char/string> found=<Char/String found in the input JSON String> Issued when Syntax error is detected.
3 GEN0352 Non-nullable field <FFF> not found in the JSON string Field (defined as non-nullable) not present in the input JSON string.
4 GEN0353 Non-nullable field <FFF> found to be to null Value found to be NULL in input JSON string for a non-null field.
5 GEN0354 Value <NNN> would be truncated when copying to field <FFF> Target field capacity not adequate to store the received value.
6 GEN0355 Iconv conversion error. Character <SSS> cannot be converted to codepage <NNNN> Code page conversion error.

Below are the return codes which JSON Processor will provide to the JSON error handler:

  • 0 - No issues
  • 8 - non-recoverable error
  • The JSON string to be processed should not exceed 32767 bytes.
  • Null values to data types are supported at this time.
  • Arrays to these data types and Null value to an array element are supported.
Supported EGL Data Types/Formats
This solution is going to support below listed data types and their valid formats:
Data Type  Size (COBOL) Valid Data Format  Supported  Remarks 
INT   9 Digits (4 bytes)  Numeric 
Ex: 999999999 
 
 Array, Null  
SMALLINT   4 Digits (2 bytes) Numeric 
Ex:9999 
 
 Array, Null 
BIGINT   18 Digits (8 bytes)  Numeric 
Ex:999999999999999999 
 
 Array, Null  
 
 
CHAR   1 Byte (Max 32767)  Alphanumeric  
Ex: ”R”, “One1” 
 
 Array, Null 
BOOLEAN   1 Byte String values 
Ex: True, False, Yes, No 
 
 Array, Null 
STRING   Varies*  Alphanumeric and few formatting characters 
Ex: "No 123, ABCD Nagar, GHEF City, Pincode-123 456" 
 
 Array, Null  Formatting characters: ‘\t’, ‘\n’, ‘\cr’ 
DECIMAL   31 Digits  Decimal 
Ex:6.555555555555553333333333333333 
 
 Array, Null 
FLOAT  8 Bytes Decimal with Exponent
Ex :2.998e8;
 
Array, Null

This whitepaper has discussed the details of:

  • The objective behind this feature
  • The functions supporting this feature and the key components make it work as a unit.
  • Special consideration.
  • Supported EGL data types.
  • Working example to demonstrate usage of these functions on IBM i (see Annexure)

Annexure

This annexure is to share sample test cases that were executed successfully to show usage of the two JSON functions on IBM i system.

Sample Program 1:

package ijspkg;

// basic program

//

record BankCustomerRecord

    CustID smallInt;

    CustName NameDetails;

    CustAddress AddressLines[3];

    CustPhone1 string;

    CustPhone2 string;

    CustDOB char(12);

end

record NameDetails

    FirstName string;

    MiddleName string;

    LastName string;

end

record AddressLines

    address string;

end

program iJSON15 type BasicProgram{}

    // Use Declarations

    //use usePartReference;

   

    // Constant Declarations

    const constantName string = "literalString";

    // Variable Declarations

    variableName string;

    function main()

        obj1 BankCustomerRecord; //Object that will be populated by the user

        obj2 BankCustomerRecord; //This will get the data from JSON String

        jsonString string;

        //Initialize the variables

        obj1.CustID = 123;

        obj1.CustName.FirstName = "Aashish";

        obj1.CustName.MiddleName = null;

        obj1.CustName.LastName = "Kumar";

        obj1.CustAddress[1].address = "Flat A/123, New Avenue";

        obj1.CustAddress[2].address = "Motor City, Dubai";

        obj1.CustAddress[3].address = "UAE";

        obj1.CustPhone1 = "+971-123-456-789";

        obj1.CustDOB = "12-Jan-1975";

        //Generate the JSON string

        jsonString = servicelib.convertToJSON(obj1);

        syslib.writeStdout("-------------------------------------------");

        syslib.writeStdout("Generated JSON String: " + JsonString);

        syslib.writeStdout("-------------------------------------------");

        //Parse the JSON string

        servicelib.convertFromJSON(jsonString, obj2);

        syslib.writeStdout(" ");

        syslib.writeStdout(" ");

        syslib.writeStdout("-------------------------------------------");

        syslib.writeStdout("Object values after parsing of JSON String: ");

        syslib.writeStdout("-------------------------------------------");

        syslib.writeStdout("obj2.CustID                 : " + obj2.CustID);

        syslib.writeStdout("obj2.CustName.FirstName     : " +

                        obj2.CustName.FirstName);

        syslib.writeStdout("obj2.CustName.MiddleName    : " +

                        obj2.CustName.MiddleName);

        syslib.writeStdout("obj2.CustName.LastName      : " +

                        obj2.CustName.LastName);

        syslib.writeStdout("obj2.CustAddress[1].address : " +

                        obj2.CustAddress[1].address);

        syslib.writeStdout("obj2.CustAddress[2].address : " +

                        obj2.CustAddress[2].address);

        syslib.writeStdout("obj2.CustAddress[3].address : " +

                        obj2.CustAddress[3].address);

        syslib.writeStdout("obj2.CustPhone1             : " + obj2.CustPhone1);

        syslib.writeStdout("obj2.CustPhone2             : " + obj2.CustPhone2);

        syslib.writeStdout("obj2.CustDOB                : " + obj2.CustDOB);

    end

end

Output:

-------------------------------------------              

Generated JSON String: {"CustID": 123,"CustName":{"FirstNa

me":"Aashish","MiddleName":"","LastName":"Kumar"},"CustAdd

ress":[{"address":"Flat A/123, New Avenue"},{"address":"Mo

tor City, Dubai"},{"address":"UAE"}],"CustPhone1":"+971-12

3-456-789","CustPhone2":"","CustDOB":"12-Jan-1975 "}     

-------------------------------------------        

-------------------------------------------      

Object values after parsing of JSON String:        

-------------------------------------------        

obj2.CustID                 : 123                  

obj2.CustName.FirstName     : Aashish              

obj2.CustName.MiddleName    :                      

obj2.CustName.LastName      : Kumar                

obj2.CustAddress[1].address : Flat A/123, New Avenue

obj2.CustAddress[2].address : Motor City, Dubai    

obj2.CustAddress[3].address : UAE                  

obj2.CustPhone1             : +971-123-456-789     

obj2.CustPhone2             :                      

obj2.CustDOB                : 12-Jan-1975          

Sample Program 2:

 

package ijspkg;

// basic program

//

record personRecord

    ID smallInt;

    Name NameDetails;

    Address AddressLines;

    Phone1 string;

    Phone2 string;

    DOB char(12);

end

record foodOrder

    orderNo smallInt;

    orderDate char(12);

    foodItem string;

    billAmount float;

    currency char(3);

end

record orderSummary

    customer personRecord;

    delPer personRecord;

    foodOrd foodOrder;

end

program iJSON16 type BasicProgram{}

    // Use Declarations

    //use usePartReference;

    // Constant Declarations

    const constantName string = "literalString";

    // Variable Declarations

    variableName string;

    function main()

        obj1 orderSummary; //Object that will be populated by the user

        obj2 orderSummary; //This will get the data from JSON String

        jsonString string;

        //Initialize the variables

        obj1.customer.ID = 123;

        obj1.customer.Name.FirstName = "Aashish";

        obj1.customer.Name.MiddleName = null;

        obj1.customer.Name.LastName = "Kumar";

        obj1.customer.Address.address = "Flat A/123, New Avenue, Motor City, Dubai, UAE";

        obj1.customer.Phone1 = "+971-123-456-789";

        obj1.customer.DOB = "12-Jan-1975";

        obj1.delPer.ID = 2001;

        obj1.delPer.Name.FirstName = "Lui";

        obj1.delPer.Name.MiddleName = "Yang";

        obj1.delPer.Name.LastName = "Su";

        obj1.delPer.Address.address = "Flat B/123, Old Stadium Road, Sharjah, UAE";

        obj1.delPer.Phone1 = "+971-777-456-789";

        obj1.delPer.DOB = "27-Jun-1985";

        obj1.foodOrd.orderDate = "28-Jan-2022";

        obj1.foodOrd.orderNo = 2802;

        obj1.foodOrd.foodItem = "Pizza";

        obj1.foodOrd.billAmount = 50;

        obj1.foodOrd.currency = "AED";

        //Generate the JSON string

        jsonString = servicelib.convertToJSON(obj1);

        syslib.writeStdout("-------------------------------------------");

        syslib.writeStdout("Generated JSON String: " + JsonString);

        syslib.writeStdout("-------------------------------------------");

        syslib.writeStdout(" ");

        syslib.writeStdout(" ");

        //Parse the JSON string

        servicelib.convertFromJSON(jsonString, obj2);

        syslib.writeStdout("-------------------------------------------");

        syslib.writeStdout("Object values after parsing of JSON String: ");

        syslib.writeStdout("-------------------------------------------");

        syslib.writeStdout("obj2.customer.ID               : " + "" +

                        obj2.customer.ID);

        syslib.writeStdout("obj2.customer.Name.FirstName   : " +

                        obj2.customer.Name.FirstName);

        syslib.writeStdout("obj2.customer.Name.MiddleName  : " +

                        obj2.customer.Name.MiddleName);

        syslib.writeStdout("obj2.customer.Name.LastName    : " +

                        obj2.customer.Name.LastName);

        syslib.writeStdout("obj2.customer.Address.address  : " +

                        obj2.customer.Address.address);

        syslib.writeStdout("obj2.customer.Phone1           : " +

                        obj2.customer.Phone1);

        syslib.writeStdout("obj2.customer.DOB              : " +

                        obj2.customer.DOB);

        syslib.writeStdout("obj2.delPer.ID                 : " +

                        obj2.delPer.ID);

        syslib.writeStdout("obj2.delPer.Name.FirstName     : " +

                        obj2.delPer.Name.FirstName);

        syslib.writeStdout("obj2.delPer.Name.MiddleName    : " +

                        obj2.delPer.Name.MiddleName);

        syslib.writeStdout("obj2.delPer.Name.LastName      : " +

                        obj2.delPer.Name.LastName);

        syslib.writeStdout("obj2.delPer.Address.address    : " +

                        obj2.delPer.Address.address);

        syslib.writeStdout("obj2.delPer.Phone1             : " +

                        obj2.delPer.Phone1);

        syslib.writeStdout("obj2.delPer.DOB                : " +

                        obj2.delPer.DOB);

        syslib.writeStdout("obj2.foodOrd.orderDate         : " +

                        obj2.foodOrd.orderDate);

        syslib.writeStdout("obj2.foodOrd.orderNo           : " +

                        obj2.foodOrd.orderNo);

        syslib.writeStdout("obj2.foodOrd.foodItem          : " +

                        obj2.foodOrd.foodItem);

        syslib.writeStdout("obj2.foodOrd.billAmount        : " +

                        obj2.foodOrd.billAmount);

        syslib.writeStdout("obj2.foodOrd.currency          : " +

                        obj2.foodOrd.currency);

end

end

Output:

 

-------------------------------------------              

Generated JSON String: {"customer":{"ID": 123,"Name":{"Fir

stName":"Aashish","MiddleName":"","LastName":"Kumar"},"Add

ress":{"address":"Flat A/123, New Avenue, Motor City, Duba

i, UAE"},"Phone1":"+971-123-456-789","Phone2":"","DOB":"12

-Jan-1975 "},"delPer":{"ID": 2001,"Name":{"FirstName":"Lui

","MiddleName":"Yang","LastName":"Su"},"Address":{"address

":"Flat B/123, Old Stadium Road, Sharjah, UAE"},"Phone1":"

+971-777-456-789","Phone2":"","DOB":"27-Jun-1985 "},"foodO

rd":{"orderNo": 2802,"orderDate":"28-Jan-2022 ","foodItem"

:"Pizza","billAmount": 5.00e+01,"currency":"AED"}}       

-------------------------------------------              

-------------------------------------------            

Object values after parsing of JSON String:              

-------------------------------------------              

obj2.customer.ID               : 123                     

obj2.customer.Name.FirstName   : Aashish                 

obj2.customer.Name.MiddleName  :                         

obj2.customer.Name.LastName    : Kumar                   

obj2.customer.Address.address  : Flat A/123, New Avenue, M

otor City, Dubai, UAE                                     

obj2.customer.Phone1           : +971-123-456-789        

obj2.customer.DOB              : 12-Jan-1975             

obj2.delPer.ID                 : 2001                    

obj2.delPer.Name.FirstName     : Lui                     

obj2.delPer.Name.MiddleName    : Yang                    

obj2.delPer.Name.LastName      : Su                      

obj2.delPer.Address.address    : Flat B/123, Old Stadium R

oad, Sharjah, UAE                                         

obj2.delPer.Phone1             : +971-777-456-789        

obj2.delPer.DOB                : 27-Jun-1985             

obj2.foodOrd.orderDate         : 28-Jan-2022             

obj2.foodOrd.orderNo           : 2802                    

obj2.foodOrd.foodItem          : Pizza                   

obj2.foodOrd.billAmount        : 50.0                    

obj2.foodOrd.currency          : AED                     

[{"Type":"MASTER","Line of Business":{"code":"LOB35","label":"Mainframe SW"},"Business Unit":{"code":"BU058","label":"IBM Infrastructure w\/TPS"},"Product":{"code":"SSMQ79","label":"Rational Business Developer"},"ARM Category":[{"code":"a8m0z0000000BB1AAM","label":"Rational Business Developer"}],"ARM Case Number":"","Platform":[{"code":"PF016","label":"Linux"},{"code":"PF033","label":"Windows"}],"Version":"9.7.0"}]

Document Information

Modified date:
16 June 2022

UID

ibm16559990