1. Skip to navigation
  2. Skip to content

That's Cool!  RPG-XML Suite Tips & Tricks for Developers

Offer XML To a Java Customer Maintenance App

The developers at Krengel Tech have been busy looking for new non-traditional ways for you to put RPG-XML Suite (RXS) to work. Considering the sole existence of RXS is to process incoming and outgoing XML, the possibilities for how you can benefit your business are endless!

 

In this installment of “Cool Things You Can Do With RPG-XML Suite” you will see how to offer non-verbose XML to a Java Customer Maintenance application running on the desktop.  Please note that SOAP was not used because that would have added unnecessary overhead.  By eliminating more complex XML we were able to use a very light weight parser/composer on the Java end which can be found here: http://nanoxml.cyberelf.be/.  Note that they also have a port for C#.NET if you are looking to accomplish the same thing from the Visual Studio environment.

The basic concept here is that we developed a Java desktop application that draws the UI and based on button clicks makes XML HTTP calls out to the System i5 and receives the response back for displaying to the user.  In this case RPG-XML Suite is used to facilitate a handful of validation and file I/O operations, but imagine if you could drive the entire desktop user interface completely from RPG without any need for Java knowledge on your staff to add/change GUI screens!?  Stay tuned as we have some more exciting things in store!

 

 

RXS Java GUI Frontend 

 

Download it now!

Note that you don't have to install the System i5 components if you don't want to.  By default the GUI application will connect to Krengel Tech's System i5 over the internet.

 

File: MYLIB/CUSTMST 

      **************************************************************************

      *  File: CUSTMST

      *  Use: Store customer information.

      **************************************************************************

     A                                      UNIQUE

     A          R CUSTMSTR

     A            CUSTNBR        5P 0       COLHDG('Cust Nbr')

     A            FNAM          15A         COLHDG('First Name')

     A            LNAM          15A         COLHDG('Last Name')

     A            CMPNY         20A         COLHDG('Company')

     A            ADR1          20A         COLHDG('Address 1')

     A            ADR2          20A         COLHDG('Address 2')

     A            CTY           15A         COLHDG('City')

     A            STT            2A         COLHDG('State')

     A            ZIPCD          5A         COLHDG('Zip Code')

     A            PHN           18A         COLHDG('Phone')

 

     A          K CUSTNBR

 

Module: CUSTFN 

      //------------------------------------------------------------------------

      // @Author: Aaron Bartell

      // @Created: 2007-06-08

      // @Desc: Modular customer RPG service program.

      // @Compile: ADDLIBLE MYLIB

      //           CRTRPGMOD

      //             MODULE(MYLIB/CUSTFN) SRCFILE(MYLIB/QSOURCE) SRCMBR(CUSTFN)

      //

      //           CRTSRVPGM

      //             SRVPGM(MYLIB/CUSTSV)

      //             MODULE(MYLIB/CUSTFN) SRCFILE(MYLIB/QSOURCE)

      //------------------------------------------------------------------------

     h nomain

 

     fCUSTMST   uf a e           k disk    prefix('CM.')

     d CM            e ds                  qualified extname(CUSTMST)

 

      /copy qsource,CustCP

 

 

      //------------------------------------------------------------------------

      // @Author: Aaron Bartell

      // @Created: 2007-06-08

      // @Desc: Get the next available customer number.

      //------------------------------------------------------------------------

     p Cust_nextNbr    b                   export

     d Cust_nextNbr    pi

     d  pError                             like(Cust_Error)

     d  pNbr                               like(CM.CUSTNBR)

      /free

 

         clear pError;

         setgt *hival CUSTMST;

         readp CUSTMST;

         pNbr = CM.CUSTNBR + 1;

         clear CUSTMSTR;

         CM.CUSTNBR = pNbr;

         write CUSTMSTR;

 

      /end-free

     p                 e

 

 

      //------------------------------------------------------------------------

      // @Author: Aaron Bartell

      // @Created: 2007-06-08

      // @Desc: Retrieve a customer record.

      //------------------------------------------------------------------------

     p Cust_getRec     b                   export

     d Cust_getRec     pi

     d  pError                             like(Cust_Error)

     d  pCustRec                           likeds(CM)

     d  pCustNbr                           like(CM.CUSTNBR)

      /free

 

         clear pError;

         clear pCustRec;

         chain(n) pCustNbr CUSTMST;

         if not %found;

           pError = 'Customer Not Found';

         else;

           pCustRec = CM;

         endif;

 

      /end-free

     p                 e

 

 

      //------------------------------------------------------------------------

      // @Author: Aaron Bartell

      // @Created: 2007-06-08

      // @Desc: Save a customer record

      //------------------------------------------------------------------------

     p Cust_save       b                   export

     d Cust_save       pi

     d  pError                             like(Cust_Error)

     d  pCustRec                           likeds(CM)

      /free

 

       monitor;

         clear pError;

         if ( pCustRec.CustNbr = 0

           or pCustRec.FNam = *blanks

           or pCustRec.LNam = *blanks

           or pCustRec.Cmpny = *blanks

           or pCustRec.Adr1 = *blanks

           or pCustRec.Cty = *blanks

           or pCustRec.Stt = *blanks

           or pCustRec.ZipCd = *zeros

           or pCustRec.Phn = *blanks );

            pError = 'Not all fields were set!';

           return;

         endif;

 

         chain pCustRec.CustNbr CUSTMST;

         CM = pCustRec;

         if %found(CUSTMST);

           update CUSTMSTR;

         else;

           write CUSTMSTR;

         endif;

       on-error;

         pError = 'Error occurred during save of customer!';

       endmon;

 

      /end-free

     p                 e

 

 

Copy book: CUSTCP 

     D Cust_nextNbr    pr

     D  pError                             like(Cust_Error)

     D  pNbr                               like(CM.CUSTNBR)

 

     D Cust_getRec     pr

     D  pError                             like(Cust_Error)

     D  pCustRec                           likeds(CM)

     D  pCustNbr                           like(CM.CUSTNBR)

 

     D Cust_save       pr

     D  pError                             like(Cust_Error)

     D  pCustRec                           likeds(CM)

 

 

     D Cust_Error      s             50A

 

 

Binder Language (used to create *SRVPGM): 

  strpgmexp

    export symbol(Cust_nextNbr)

    export symbol(Cust_getRec)

    export symbol(Cust_save)

  endpgmexp

 

 

RPG-XML Suite web service program: 

      //*******************************************************************************************

      // @Author: Aaron Bartell

      // @Created: 2005-08-23

      // @Desc:

      // @Compile: CRTBNDRPG PGM(MYRXS/WSCUST) SRCFILE(MYLIB/QSOURCE) SRCMBR(WSCUST)

      //*******************************************************************************************

     H dftactgrp(*no) bnddir('RXSBND': 'SINBND')

 

      /copy rxs,RXSCp

      /copy qsource,CustCp

 

     D allHandler      pr

     D  pType                              value like(RXS_Type)

     D  pXPath                             value like(RXS_XPath)

     D  pData                              value like(RXS_XmlData)

     D  pDataLen                           value like(RXS_Length)

 

     D errHandler      pr

     D  pCurLine                     10i 0 value

     D  pCurCol                      10i 0 value

     D  pErrStr                    1024a   value varying

 

     D errRsp          pr

 

     D gAction         s             25a   varying

 

     D CM            e ds                  qualified extname(CUSTMST)

     D gError          ds                  likeds(RXS_Error) inz

     D gXml            s          65535a   varying

     D gCustErr        s                   like(Cust_Error)

     D gCustNbr        s                   like(CM.CUSTNBR)

      /free

 

       monitor;

         clear gError;

         clear gAction;

 

         if RXS_libLEExists('MYLIB') <= 0;

           RXS_addLibLE('MYLIB');

         endif;

 

         gXml = RXS_readStdIn();

 

         RXS_allElemContentHandler(%paddr(allHandler));

         RXS_addHandler('/ENV@ACTION': %paddr(allHandler));

         RXS_parse(gXml: RXS_VAR: %paddr(errHandler));

 

         if gError.code <> *blanks;

           RXS_stdOutError('error': gError: *on);

           *inlr = *on;

           return;

         endif;

 

         exsr compose;

 

       on-error;

         RXS_stdOutError('error': RXS_catchError(): *on);

       endmon;

 

       *inlr = *on;

 

 

 

       //--------------------------------------------------------------------------------------------

       // @Author: Aaron Bartell

       // @Created: 2005-08-03

       // @Desc: Using the template engine compose the response and send it to standard out (i.e.

       //        RXS_STDOUT).

       //--------------------------------------------------------------------------------------------

       begsr compose;

 

       // Compose xml

       RXS_initTplEng(RXS_STDOUT: *omit: *omit: *omit: *omit: *off);

       RXS_loadTpl('wscust.tpl': '::': '': '.:': ':.');

       RXS_wrtSection('HTTP_HEAD');

 

       RXS_wrtSection('env_beg');

       select;

       when gAction = 'CUST_NEXTNBR';

         Cust_nextNbr(gCustErr: gCustNbr);

         if gCustErr <> *blanks;

           RXS_updVar('ERROR': gCustErr);

           RXS_wrtSection('ERROR');

         else;

           RXS_updVar('CUSTNBR': %char(gCustNbr));

           RXS_wrtSection('CUSTNBR');

         endif;

       when gAction = 'CUST_SAVE';

         Cust_save(gCustErr: CM);

         if gCustErr <> *blanks;

           RXS_updVar('ERROR': gCustErr);

           RXS_wrtSection('ERROR');

         endif;

       when gAction = 'CUST_GETREC';

         Cust_getRec(gCustErr: CM: gCustNbr);

         if gCustErr <> *blanks;

           RXS_updVar('ERROR': gCustErr);

           RXS_wrtSection('ERROR');

         else;

           RXS_updVar('CUSTNBR': %char(CM.CUSTNBR));

           RXS_updVar('FNAM': CM.FNAM);

           RXS_updVar('LNAM': CM.LNAM);

           RXS_updVar('CMPNY': CM.CMPNY);

           RXS_updVar('ADR1': CM.ADR1);

           RXS_updVar('ADR2': CM.ADR2);

           RXS_updVar('CTY': CM.CTY);

           RXS_updVar('STT': CM.STT);

           RXS_updVar('ZIPCD': CM.ZIPCD);

           RXS_updVar('PHN': CM.PHN);

           RXS_wrtSection('CUSTMST');

         endif;

       other;

         RXS_updVar('ERROR': 'No action specified');

       endsl;

 

       RXS_wrtSection('env_end': *on);

 

       endsr;

 

      /end-free

      //--------------------------------------------------------------------------------------------

      // @Author: Aaron Bartell

      // @Created: 2005-08-03

      // @Desc: This local sub procedure will be called for each element content and attribute event

      //        that occurs during the parsing of the env document. Based on the event this sub

      //        procedure is being notified of it will place the value in the appropriate global

      //        variable.

      //--------------------------------------------------------------------------------------------

     P allHandler      b

     D allHandler      pi

     D  pType                              value like(RXS_Type)

     D  pXPath                             value like(RXS_XPath)

     D  pData                              value like(RXS_XmlData)

     D  pDataLen                           value like(RXS_Length)

      /free

 

       select;

 

       when pXPath = '/ENV@ACTION';

         gAction = pData;

 

       when pXPath = '/ENV/CUSTMST/CUSTNBR/';

         CM.CUSTNBR = RXS_charToNbr(pData: 0);

       when pXPath = '/ENV/CUSTMST/FNAM/';

         CM.FNAM = pData;

       when pXPath = '/ENV/CUSTMST/LNAM/';

         CM.LNAM = pData;

       when pXPath = '/ENV/CUSTMST/CMPNY/';

         CM.CMPNY = pData;

       when pXPath = '/ENV/CUSTMST/ADR1/';

         CM.ADR1 = pData;

       when pXPath = '/ENV/CUSTMST/ADR2/';

         CM.ADR2 = pData;

       when pXPath = '/ENV/CUSTMST/CTY/';

         CM.CTY = pData;

       when pXPath = '/ENV/CUSTMST/STT/';

         CM.STT = pData;

       when pXPath = '/ENV/CUSTMST/ZIPCD/';

         CM.ZIPCD = pData;

       when pXPath = '/ENV/CUSTMST/PHN/';

         CM.PHN = pData;

       when pXPath = '/ENV/CUSTNBR/';

         gCustNbr = RXS_charToNbr(pData: 0);

 

       endsl;

 

      /end-free

     P                 e

 

 

      //--------------------------------------------------------------------------------------------

      // @Author: Aaron Bartell

      // @Created: 2005-08-03

      // @Desc: If an error occurs this local sub procedure will be called by the parser.

      //--------------------------------------------------------------------------------------------

     P errHandler      B

     D errHandler      PI

     D  pCurLine                     10i 0 value

     D  pCurCol                      10i 0 value

     D  pErrStr                    1024a   value varying

      /free

 

       gError.code = 'RXS3.1';

       gError.severity = 100;

       gError.pgm = 'RXS3.errHandler';

       gError.text =

         'Line:' + %char(pCurLine) +

         ' Column:' + %char(pCurCol) +

         ' ' + pErrStr;

 

      /end-free

     P                 E

 

 

 

 

 

 

RPG-XML Suite template file: /www/myrxs/templates/wscust.tpl 

::HTTP_HEAD 

Content-type: text/xml 

 

::env_beg 

<env>

 

::CUSTMST 

<CUSTMST>

  <CUSTNBR>.:CUSTNBR:.</CUSTNBR>

  <FNAM>.:FNAM:.</FNAM>

  <LNAM>.:LNAM:.</LNAM>

  <CMPNY>.:CMPNY:.</CMPNY>

  <ADR1>.:ADR1:.</ADR1>

  <ADR2>.:ADR2:.</ADR2>

  <CTY>.:CTY:.</CTY>

  <STT>.:STT:.</STT>

  <ZIPCD>.:ZIPCD:.</ZIPCD>

  <PHN>.:PHN:.</PHN>

</CUSTMST>

 

::CUSTNBR 

<CUSTNBR>.:CUSTNBR:.</CUSTNBR>

 

::ERROR 

<ERROR>.:ERROR:.</ERROR>

 

::env_end 

</env>

 





Employment

View Current
Employment Opportunities.

Go

Our Partners

Get an overview of how to leverage a partnership with us.

Go

FAQs

See the questions everyone else is asking.

Read

Glossary of Terms

Get a better handle
on all the acronymns.

Read