Program: RXSAJAX
//*******************************************************************************************
// @Author: Aaron Bartell
// @Created: 2007-08-28
// @Desc:
// @Compile: CRTBNDRPG PGM(MYRXS/RPGAJAX) SRCFILE(MYRXS/QSOURCE) SRCMBR(RPGAJAX)
//*******************************************************************************************
H dftactgrp(*no) bnddir('RXSBND': 'SINBND')
/copy rxs,RXSCp
/copy sin,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;
// MYLIB was added here to show how to use a PF that is not
// in your default MYRXS library.
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('rxs_ajax.tpl': '::': '': '.:': ':.');
RXS_wrtSection('HTTP_HEAD');
RXS_wrtSection('env_beg');
select;
when gAction = 'CUST_NEXTNBR';
Cust_nextNbr(gCustErr: gCustNbr);
RXS_updVar('ERROR': gCustErr);
RXS_wrtSection('ERROR');
RXS_updVar('CUSTNBR': %char(gCustNbr));
RXS_wrtSection('CUSTNBR');
when gAction = 'CUST_SAVE';
Cust_save(gCustErr: CM);
when gAction = 'CUST_GETREC';
Cust_getRec(gCustErr: CM: gCustNbr);
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');
other;
RXS_updVar('ERROR': 'No action specified');
endsl;
RXS_updVar('ERROR': gCustErr);
RXS_wrtSection('ERROR');
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 PostAdr 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 = 'RXSAJAX.1';
gError.severity = 100;
gError.pgm = 'RXSAJAX.errHandler';
gError.text =
'Line:' + %char(pCurLine) +
' Column:' + %char(pCurCol) +
' ' + pErrStr;
/end-free
P E
Program: CUSTFN
//------------------------------------------------------------------------
// @Author: Aaron Bartell
// @Created: 2007-08-28
// @Desc: Modular customer RPG service program.
// @Compile: CRTRPGMOD
// MODULE(MYLIB/CUSTFN) SRCFILE(MYLIB/SIN) SRCMBR(CUSTFN)
//
// CRTSRVPGM
// SRVPGM(MYLIB/CUSTSV)
// MODULE(MYLIB/CUSTFN) SRCFILE(MYLIB/SIN)
//------------------------------------------------------------------------
h nomain
fCUSTMST uf a e k disk prefix('CM.')
d CM e ds qualified extname(CUSTMST)
/copy sin,CustCP
//------------------------------------------------------------------------
// @Author: Aaron Bartell
// @Created: 2007-08-28
// @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;
pError = 'Customer ' + %char(pNbr) + ' reserved for insertion.';
/end-free
p e
//------------------------------------------------------------------------
// @Author: Aaron Bartell
// @Created: 2007-08-28
// @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 ' + %char(pCustNbr) + ' Not Found';
else;
pCustRec = CM;
pError = 'Customer ' + %char(pCustNbr) + ' Found';
endif;
/end-free
p e
//------------------------------------------------------------------------
// @Author: Aaron Bartell
// @Created: 2007-08-28
// @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;
pError = 'Customer updated.';
else;
write CUSTMSTR;
pError = 'New customer record written.';
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: CUSTSV
strpgmexp
export symbol(Cust_nextNbr)
export symbol(Cust_getRec)
export symbol(Cust_save)
endpgmexp
Physical File: 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
IFS File: /www/myrxs/templates/rxs_ajax.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>