ZipService Example

LANSA Integrator

ZipService Example

This example program will perform the following steps:

1.  Performs a series of calls necessary to load the ZipService.

2.  Creates a zip file called LIZIPIN.ZIP in directory /LIZIPOUT in the IFS.

3.  Zips the contents of directory /LIZIPIN into the zip file and closes the file.

4.  Opens the zip file again for reading.

5.  Retrieves a list of zip file entries into a multiple occurrence data structure.

6.  Unzips the first zip entry into the directory /LIZIPOUT.

7.  Closes the zip file, unloads the service and closes the connection to the JSM server.

Note:
  • To test this example meaningfully you need to create the two folders /LIZIPIN and /LIZIPOUT in the IFS and then add a small selection of files to the folder /LIZIPIN.  You can use any files – these are the files that will be zipped by the example program
  • The example program can only successfully retrieve the zip file entries if they number 999 or less, so do not add more files than this to the folder /LIZIPIN
  • For maximum compatibility, the example program can only cope with file paths up to 256 characters in length.  Do not add files and folders to /LIZIPIN such that any one file path will exceed this limit.  You can write your own programs to handle longer paths if necessary.

Refer to the comments and code in the example for more information.

There are three steps required to make this application work:

1.   Create the structure XML

The call to the GET ENTRY(*LIST) command of the ZipService passes a multiple occurrence data structure in which it will receive a list of up to 999 zip file entries.  For this to work, the LANSA Integrator service needs to know the characteristics of this structure.  This is accomplished by supplying an XML file that describes the structure.

For this example, the required XML is supplied below.  To install this XML you need to perform the following steps:

a.  Locate the structure folder in the JSM instance folder for your JSM server

b.  Create a file called ZipEntryList.xml

c.  Edit the file with a text editor and paste into it the xml supplied below

Note that the field names used in the structure XML do not need to match the variable names used in the RPG program (and they do not match in this example).  It is their order, types and length that are important.

<?xml version="1.0" encoding="UTF-8"?>

 

<rdml:structure xmlns:rdml="http://www.lansa.com/2000/XML/Function">

 

   <rdml:field name="ZIPENT" type="A" length="256" />

 

</rdml:structure>

2.    Register the structure XML with the JSM Server

The example program below refers to the structure XML supplied above with the symbolic name ZIP.ZipEntryList by specifying that name in the SERVICE_STRUCTURE keyword of the GET ENTRY(*LIST) command.

We need to give the JSM Server a link between that symbolic name and the actual name and location of the structure XML file created in step 1.  To do this you need to perform the following steps:

a.  Locate the system folder in the JSM instance folder for your JSM server.

b.  Edit the file structure.properties with a text editor and paste into it the entry supplied below (make sure the new entry is on a line by itself).

c.  Save your changes.

d.  Restart or refresh the JSM Server instance (refer to Java Service Manager Refresh).

     structure.ZIP.ZipEntryList=structure/ZipEntryList.xml 

3.   Create and run the ILE RPG example program

Recent installations of LANSA Integrator will already contain the source for the example program below.  If not, you can copy and paste the source into a source file member.

To create the program, you need to use the CRTRPGMOD and CRTPGM commands.  Make sure that you use the parameter values specified in the source member.

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

 * ZIP:     example in RPG ILE of using the LANSA Integrator         

 *          ZipService                                               

 *                                                                   

 * Note:    This is an example program containing only               

 *          rudimentary exception handling                           

 *                                                                   

 * To create this program you must execute the following commands,   

 * supplying the indicated parameter values and any others that are  

 * necessary in your installation:                                   

 *                                                                   

 *   CRTRPGMOD MODULE(<modlib>/ZIP)                                  

 *             SRCFILE(<srclib>/<srcfil>)                            

 *                                                                   

 *   CRTPGM    PGM(<pgmlib>/ZIP)                                     

 *             MODULE(<modlib>/ZIP)                                  

 *             BNDSRVPGM(<jsmpgmlib>/DCXS882X)                       

 *             ACTGRP(*CALLER)                                       

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

                                                                     

 * IFS folders used by this program                                  

 * - to try this program you need to create these folders in your IFS

 *   and add one or more files to the /LIZIPIN folder                

                                                                     

d flrzipin        c                   const('/LIZIPIN')              

d flrzipout       c                   const('/LIZIPOUT')             

d zipfilepath     s            255a                                  

                                                                     

 * Declare variables for the JSM calls                               

                                                                     

d jsmsrv          s             50a   inz(*blanks)                   

d jsmsts          s             20a   inz(*blanks)                   

d jsmmsg          s            255a   inz(*blanks)                   

d jsmcmd          s            255a   inz(*blanks)                   

d bytelength      s             10i 0 inz(*zero)                     

                                                                     

 * Declare structure to send or receive zip file entries             

 * - the structure must contain the following fields as defined      

 *   by the GET command of the ZipService                            

 *   o Zip entry (path and/or file names)                                 

 * NB: This MUST match the structure xml provided to the JSM Server!      

                                                                          

d ziplist         ds                  occurs(zipocur)                     

d  zipentry                    256a                                       

                                                                          

d zipocur         c                   const(999)                          

d zipsize         c                   const(%size(ziplist))               

d zipcount        s              9p 0 inz(0)                              

                                                                          

 * Completion messages                                                    

                                                                          

d CompMsg10       c                   'JSMOPEN call completed.'           

d CompMsg20       c                   '  SERVICE_LOAD call completed.'    

d CompMsg30       c                   '  CREATE call completed.'          

d CompMsg40       c                   '  OPEN call completed.'            

d CompMsg50       c                   '  ADD call completed.'             

d CompMsg60       c                   '  GET ENTRY(*LIST) call completed.'

d CompMsg65       c                   '  GET ENTRY(*READ) call completed.'

d CompMsg70       c                   '  CLOSE call completed.'           

d CompMsg80       c                   '  SERVICE_UNLOAD call completed.'   

d CompMsg99       c                   'JSMCLOSE call completed.'           

                                                                           

 * Procedure prototypes                                                    

                                                                           

d CheckResult     pr                                                       

d  crjsts                             const like(jsmsts)                   

d  crjmsg                             const like(jsmmsg)                   

                                                                           

d SendMessage     pr                                                       

d  smText                      512a   VALUE                                

d  smType                       10a   VALUE                                

                                                                           

 * Prototypes for the JSM calls                                            

                                                                           

 /COPY QRPGLESRC,JSM_PROC.H                                                

                                                                           

 * Open a connection to the default JSM server                             

 * - because the server parameter is blank, details of the default         

 *   JSM server are obtained from the data area JSMCTLDTA on IBM i       

 *   or from the file jsmctldta.txt on other supported platforms)      

                                                                       

c                   callp     p_jsmopen(jsmsrv:jsmsts:jsmmsg)          

c                   callp     CheckResult(jsmsts:jsmmsg)               

c                   callp     SendMessage(CompMsg10:'*COMP')           

                                                                       

 * Load the ZipService                                                 

 * - this example explicitly turns tracing on, overriding the          

 *   settings in the manager.properties file                           

                                                                       

c                   eval      jsmcmd = 'SERVICE_LOAD'                  

c                             + ' SERVICE(ZIPSERVICE) TRACE(*YES)'     

c                   callp     p_jsmcmd(jsmcmd:jsmsts:jsmmsg)           

c                   callp     CheckResult(jsmsts:jsmmsg)               

c                   callp     SendMessage(CompMsg20:'*COMP')           

                                                                       

 * Create the zip file: /LIZIPOUT/LIZIPIN.ZIP                          

 * - we place it in the /LIZIPOUT folder                               

 * - we will zip the contents of /LIZIPIN into it                      

                                                                       

c                   eval      zipfilepath = flrzipout + flrzipin + '.ZIP'  

c                   eval      jsmcmd = 'CREATE'                            

c                                   + ' FILE(' + %trim(zipfilepath) + ')'  

c                   callp     p_jsmcmd(jsmcmd:jsmsts:jsmmsg)               

c                   callp     CheckResult(jsmsts:jsmmsg)                   

c                   callp     SendMessage(CompMsg30:'*COMP')               

                                                                           

 * Add the contents of the folder /LIZIPIN to the zip file                 

 * - by specifying BASE(*CURRENT) we request that path information stored  

 *   in the zip entries is only for descendant folders of /LIZIPIN         

                                                                           

c                   eval      jsmcmd = 'ADD'                               

c                             + ' PATH(' + flrzipin + ') BASE(*CURRENT)'   

c                   callp     p_jsmcmd(jsmcmd:jsmsts:jsmmsg)               

c                   callp     CheckResult(jsmsts:jsmmsg)                   

c                   callp     SendMessage(CompMsg50:'*COMP')               

                                                                           

 * Close the current archive                                               

                                                                           

c                   eval      jsmcmd = 'CLOSE'                             

c                   callp     p_jsmcmd(jsmcmd:jsmsts:jsmmsg)               

c                   callp     CheckResult(jsmsts:jsmmsg)                   

c                   callp     SendMessage(CompMsg70:'*COMP')               

                                                                           

 * Reopen the zip file: /LIZIPOUT/LIZIPIN.ZIP                              

 * - we will retrieve a list of its contents                               

 * - we will unzip the first file into /LIZIPOUT                           

                                                                           

c                   eval      jsmcmd = 'OPEN'                              

c                                   + ' FILE(' + %trim(zipfilepath) + ')'  

c                   callp     p_jsmcmd(jsmcmd:jsmsts:jsmmsg)               

c                   callp     CheckResult(jsmsts:jsmmsg)                   

c                   callp     SendMessage(CompMsg40:'*COMP')               

                                                                           

 * Load a list of zip entries from the current archive                     

 * - although this passes the multiple occurrence data structure           

 *   (ziplist) in which to receive the list, the data is not actually      

 *   received into the structure until the JSMBYTERECV call below          

 * - the structure is described to the ZipService by the                   

 *   structure XML identified by the SERVICE_STRUCTURE keyword - there     

 *   must be a matching entry in the structure.properties file and a       

 *   corresponding structure XML file, usually in the JSMInstance\Structure

 *   folder                                                                

                                                                           

 * NOTE: this call uses the JSMCMDX api in order to be able to send and/or 

 *       receive variable data (in this case the list)                     

                                                                           

c                   eval      jsmcmd = 'GET ENTRY(*LIST)'                  

c                             + ' SERVICE_STRUCTURE(ZIP.ZipEntryList)'     

c                             + ' OCCURS(' + %char(zipocur) + ')'          

c                             + ' SIZE('   + %char(zipsize) + ')'          

                                                                           

c                   eval      %occur(ziplist) = 1                          

c                   eval      bytelength = zipocur * zipsize               

                                                                           

c                   callp     p_jsmcmdx(jsmcmd:ziplist:bytelength:         

c                                       jsmsts:jsmmsg)                     

c                   callp     CheckResult(jsmsts:jsmmsg)                   

c                   callp     SendMessage(CompMsg60:'*COMP')               

                                                                           

 * Get the length of the received data structure                    

 * - only continue to attempt to receive it if the length is valid  

                                                                    

c                   callp     p_jsmbytelngth(bytelength)            

c                   if            (bytelength > 0)                  

c                             and (bytelength <= zipocur * zipsize) 

                                                                    

 * ... receive the zip entry list into                              

 *     our multiple occurrence data structure                       

 *     - don't forget to set the DS occurrence to 1 before the call 

                                                                    

c                   callp     p_jsmbyterecv(ziplist)                

                                                                    

 * ... calculate the number of entries                              

                                                                    

c                   eval      zipcount = bytelength / zipsize       

                                                                    

 * ... unzip the first entry only into /LIZIPOUT                    

                                                                    

c                   eval      jsmcmd = 'GET ENTRY(*READ)'           

c                             + ' FILE(' + %trim(zipentry) + ')'

c                             + ' TO(' + flrzipout + ')'        

c                   callp     p_jsmcmd(jsmcmd:jsmsts:jsmmsg)    

c                   callp     CheckResult(jsmsts:jsmmsg)        

c                   callp     SendMessage(CompMsg65:'*COMP')    

                                                                

c                   endif                                       

                                                                

 * Close the current archive                                    

                                                                

c                   eval      jsmcmd = 'CLOSE'                  

c                   callp     p_jsmcmd(jsmcmd:jsmsts:jsmmsg)    

c                   callp     CheckResult(jsmsts:jsmmsg)        

c                   callp     SendMessage(CompMsg70:'*COMP')    

                                                                

 * Unload the ZipService                                        

                                                                

c                   eval      jsmcmd = 'SERVICE_UNLOAD'         

c                   callp     p_jsmcmd(jsmcmd:jsmsts:jsmmsg)    

c                   callp     CheckResult(jsmsts:jsmmsg)        

c                   callp     SendMessage(CompMsg80:'*COMP')   

                                                               

 * Close the connection to the JSM server and finish           

                                                               

c                   callp     p_jsmclose(jsmsts:jsmmsg)        

c                   callp     CheckResult(jsmsts:jsmmsg)       

c                   callp     SendMessage(CompMsg99:'*COMP')   

c                   eval      *inlr = *on                      

c                   return                                     

                                                               

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

 * Procedure to check the result of a Java Service Manager call

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

p CheckResult     b                                            

d CheckResult     pi                                           

d  crjsts                             const like(jsmsts)       

d  crjmsg                             const like(jsmmsg)       

d  crText         s            512a                            

d  crMsg1         c                   const('JSM Status : ')   

d  crMsg2         c                   const('JSM Message: ')   

d  crMsg3         c                   const('JSM Service error has +

d                                            occurred')             

c                   if        crjsts <> 'OK'                        

c                   eval      crText = crMsg1 + crjsts              

c                   callp     SendMessage(crText:'*DIAG')           

c                   eval      crText = crMsg2 + crjmsg              

c                   callp     SendMessage(crText:'*DIAG')           

c                   callp     SendMessage(crMsg3:'*ESCAPE')         

c                   endif                                           

p CheckResult     e                                                 

                                                                    

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

 * Procedure to send a program message                              

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

p SendMessage     b                                                 

                                                                    

d SendMessage     pi                                                

d smText                       512a   VALUE                         

d smMsgT                        10a   VALUE                         

                                                                    

d smMsgI          s              7a   inz('CPF9897')             

d smMsgF          s             20a   inz('QCPFMSG   *LIBL     ')

d smDtaL          s             10i 0 inz(%size(smText))         

d smStkE          s             10a   inz('*')                   

d smStkC          s             10i 0 inz(1)                     

d smMsgK          s              4a                              

d smErrC          s             10i 0 inz(0)                     

                                                                 

c                   if        smMsgT = '*ESCAPE'                 

c                   eval      smMsgI = 'CPF9898'                 

c                   endif                                        

                                                                 

c                   call      'QMHSNDPM'                         

c                   parm                    smMsgI               

c                   parm                    smMsgF               

c                   parm                    smText               

c                   parm                    smDtaL               

c                   parm                    smMsgT               

c                   parm                    smStkE               

c                   parm                    smStkC               

c                   parm                    smMsgK

c                   parm                    smErrC

                                                  

p                 e