• The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
Menu
  • The Four Hundred
  • Subscribe
  • Media Kit
  • Contributors
  • About Us
  • Contact
  • Rowing with Your OAR

    October 20, 2010 Jon Paris

    Note: The code referenced in this article is available for download here.

    In my first Open Access for RPG (OAR) tip, I discussed the basic mechanics of an OAR handler from a conceptual perspective. In this tip, I am going to walk you through the implementation of a simple handler that generates XML files derived from the definition of the file specifying the handler. As you will see, its capabilities are very limited but it will introduce the basic coding principals. You’ll need to understand some of the details from my first OAR tip to follow this one.

    Because it is the more flexible of the two operating modes of OAR, in this tip I am going to focus on Names/Values mode as it is the one that facilitates generic handlers.

    Modifying the “User” Program

    I started my handler with a very basic RPG program that read through a product file applying simple record selection logic. For selected records, it retrieves additional data from a second file and writes the result to a work file. The task I set myself was to modify this program to use an OAR handler to output the data instead as an XML file in the Integrated File System (IFS). The XML file will have this basic format:

    <filename>
      <recordname>
        <fieldName1>field 1 contents</fieldName1>
         ...
        <fieldNamen>field n contents</fieldNamen>
      </recordname>
    </filename>
    

    The first change required is to add the HANDLER keyword to the F-spec for the output file.

    Before:

    FXML_Out1  O    E             Disk
    

    After:

    FXML_Out1  O    E             Disk    Handler('ITJOAR_H1')
    

    I chose for this example to use a program as the handler (ITJOAR_H1), but could have used a subprocedure in which case the Handler keyword might have looked something like this:

    FXML_Out1  O    E             Disk    Handler('ITJOAR_H(XMLHandler1)')
    

    What else needs to be changed? Nothing. This is the only change that needs to be made–one of the many joys of the OAR approach. The only other thing that we might need to add in the future would be an additional parameter in which to pass (say) the name of the IFS output file to use. More on this later, but for now this simple addition is all we need.

    Writing the Handler

    Before we begin, download the code supplied with this article here to follow along with the references in this section.

    As I noted in the first tip, the handler receives its information from the RPG run time as a single parameter in the form of a Data Structure (DS). So one of the first things my handler needs to do is to /COPY the standard IBM definitions into the program (A), as seen in the code available in the download here.

    Once that is done I can reference the required template (QrnOpenAccess_T) in my procedure interface (B) by using the LIKEDS keyword. This is followed by the definition of the DS nvInput (C), which will hold the field name/value information. I will discuss this DS in more detail later when describing its use. Note that all of the IBM supplied structures use the TEMPLATE keyword (a 6.1 feature) and have the characters “_T” at the end of their names to identify them as templates.

    The definitions that begin at (D) are related to the IFS file that will be created. Both the file name and buffer area can simply be increased in size if they are too small for your needs. These are followed by the definitions of the two RPG status codes (E) I am using in this program.

    The actual handler logic begins at (F) with the SELECT operation that determines the actual I/O operation being requested. Because I named the input parameter info, the field that contains the requested operation code is info.rpgOperation. This is a numeric value and is tested against IBM supplied constants. Since the first request will (hopefully) be to open the file, let’s begin with that section which starts at (I).

    Opening the File

    I want to use the Names/Values option in this handler. That is requested by turning on the indicator useNamesValues. Once set this should not be changed while the file is open.

    The next task is to form the IFS file name from the RPG file name which I do at (J). The file is then opened.

    If the open fails, then I return an appropriate error number to the RPG run time by storing it in the parameter field rpgStatus (K). If the open is successful, I simply format the text for the XML root element name and write it to the file. That’s all there is to the open processing. The real action takes place on the write requests, the logic for which begins at (G).

    Handling Write Requests

    Before I can do anything I need to gain access to the Names/Values data that the RPG run time has supplied me. I do this by using the pointer supplied in the parameter data (namesValues) and use it to set the basing pointer for the structure nvInput that I defined at (C).

    Before processing the fields, I create text for the XML element that marks the beginning of the record and add it to the buffer. The actual element name is formed from the record name (info.recordName). Since the purpose of this handler is to format and output all the fields in the record, I then set up a FOR loop based on the number of fields received (nvInput.num) and proceed to loop though each one in turn.

    The data for the field will vary in length and so it is made available via a pointer (nvInput.field(i).value), which I use as the basing pointer for the field value (N). I have defined its length as 32,766 characters, the maximum supported for a DDS defined field. The actual length of the data is in the variable nvInput.field(i).valueLenBytes. This length is used in the %SUBST BIF (P) to ensure that only valid data is extracted. Note that the field values are always supplied to the handler in human-readable form, i.e., the way that you would see it on a screen or printer report.

    After processing all the fields, I just need to close the record element and send the length of the data back to the requestor. That’s really all there is to processing the write requests.

    What’s Left To Do?

    The process for handling the close request is really just the reverse of the open–you can see the code at (L) but hopefully it needs no explanation.

    The only other thing my logic has to handle is the possibility that a request other than open/write/close could be received. The RPG compiler would take care of any attempt to read from a file defined as output, but what if the programmer mistakenly specifies a “write only” handler (such as this one) for an input file? There is no way the compiler can catch that, and so I have to defend against it at run time. This is done at (M) by the OTHER clause of the SELECT. I simply set the appropriate status code and the RPG run time will take care of the rest.

    Summary

    This handler will work as-is, but is primarily intended as a teaching vehicle for the basics and as such has a number of limitations:

    • It cannot be used more than once in a program. In other words if you had a program with two output files and you wanted to use the handler to switch them both to being XML files, it would not work correctly.
    • It provides no control over the file and directory names. If the handler is to be truly universal it should allow the user program to supply those.
    • It is also limited to producing a very “flat” XML structure, which is not very realistic for anything except basic in-house use.
    • Simply setting an RPG status code will not cause any useful diagnostic information to be placed in the log file.

    The capabilities for handling the first two of these scenarios are built-in to the OAR design. The others are a simple matter of programming. Addressing these four items will be the topic of a future tip.

    Hopefully I have demonstrated here that writing OAR handlers can be a relatively painless task once the mechanics of the process are understood.

    What else can OAR handlers do for you?

    Jon Paris is one of the world’s most knowledgeable experts on programming on the System i platform. Paris cut his teeth on the System/38 way back when, and in 1987 he joined IBM’s Toronto software lab to work on the COBOL compilers for the System/38 and System/36. He also worked on the creation of the COBOL/400 compilers for the original AS/400s back in 1988, and was one of the key developers behind RPG IV and the CODE/400 development tool. In 1998, he left IBM to start his own education and training firm, a job he does to this day with his wife, Susan Gantner–also an expert in System i programming. Paris and Gantner, along with Paul Tuohy and Skip Marchesani, are co-founders of System i Developer, which hosts the new RPG & DB2 Summit conference. Send your questions or comments for Jon to Ted Holt via the IT Jungle Contact page.

    RELATED STORY

    Don’t Let Your RPG Just Drift, Grab an OAR!



                         Post this story to del.icio.us
                   Post this story to Digg
        Post this story to Slashdot

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Tags:

    Sponsored by
    Raz-Lee Security

    Start your Road to Zero Trust!

    Firewall Network security, controlling Exit Points, Open DB’s and SSH. Rule Wizards and graphical BI.

    Request Demo

    Share this:

    • Reddit
    • Facebook
    • LinkedIn
    • Twitter
    • Email

    Sponsored Links

    Help/Systems:  FREE Webinar: Manage your temporary storage and IFS. Oct. 21, 9 a.m. CST
    Vision Solutions:  Leaders Have Vision...And Vision Has Leaders! FREE White Papers!
    COMMON:  Join us at the 2011 IT Executive Conference, May 1-3, in Minneapolis, MN

    IT Jungle Store Top Book Picks

    BACK IN STOCK: Easy Steps to Internet Programming for System i: List Price, $49.95

    The iSeries Express Web Implementer's Guide: List Price, $49.95
    The iSeries Pocket Database Guide: List Price, $59
    The iSeries Pocket SQL Guide: List Price, $59
    The iSeries Pocket WebFacing Primer: List Price, $39
    Migrating to WebSphere Express for iSeries: List Price, $49
    Getting Started with WebSphere Express for iSeries: List Price, $49
    The All-Everything Operating System: List Price, $35
    The Best Joomla! Tutorial Ever!: List Price, $19.95

    Acxiom Touts Big Savings with New Digital Identifier Technology IBM i Competes with AIX/Oracle on Power 720s, Gets Beat on 750s

    Leave a Reply Cancel reply

Volume 10, Number 32 -- October 20, 2010
THIS ISSUE SPONSORED BY:

SEQUEL Software
Profound Logic Software
inFORM Decisions

Table of Contents

  • Rowing with Your OAR
  • Leave My Stream Files Alone, Please
  • How Do I Record a PC5250 Macro?

Content archive

  • The Four Hundred
  • Four Hundred Stuff
  • Four Hundred Guru

Recent Posts

  • Public Preview For Watson Code Assistant for i Available Soon
  • COMMON Youth Movement Continues at POWERUp 2025
  • IBM Preserves Memory Investments Across Power10 And Power11
  • Eradani Uses AI For New EDI And API Service
  • Picking Apart IBM’s $150 Billion In US Manufacturing And R&D
  • FAX/400 And CICS For i Are Dead. What Will IBM Kill Next?
  • Fresche Overhauls X-Analysis With Web UI, AI Smarts
  • Is It Time To Add The Rust Programming Language To IBM i?
  • Is IBM Going To Raise Prices On Power10 Expert Care?
  • IBM i PTF Guide, Volume 27, Number 20

Subscribe

To get news from IT Jungle sent to your inbox every week, subscribe to our newsletter.

Pages

  • About Us
  • Contact
  • Contributors
  • Four Hundred Monitor
  • IBM i PTF Guide
  • Media Kit
  • Subscribe

Search

Copyright © 2025 IT Jungle