EDIRecordWriter Class (Extends RecordWriter)

Overview

Our analysis showed us that there were sufficient commonalities among the possible RecordReader classes for EDI to XML conversions (one derived class for each specific EDI syntax) to create a base EDIRecordReader class and put the common functionality into it. We have the same situation with the RecordWriter derived classes used to process EDI formats as the target of our conversions. So, in this class we develop some common functions for converting from XML to generic EDI segments, maintaining control information that will be used by the derived classes. Again, we build in preliminary support for the repetition separator and the release character, even though they aren't implemented in version 004010 of X12.

Attributes:

  • DOM Document EDI Control

  • Character Element Separator

  • Character Component Separator

  • Character Repetition Separator

  • Character Release Character

  • Integer Segment Count

Methods:

  • Constructor

  • parseRecord

  • writeRecord

  • writeEDIControl

The writeEDIControl method writes the updated EDI Control document to the EDIControl.xml file in BBHOME. It is fairly simple and very dependent on the DOM API implementation, so I won't discuss it further below.

Methods

Constructor

When we read EDI we parse the input to determine the delimiters. However, when we write it we must derive the delimiters from a data store. The primary purpose of this method is to get the delimiters from the file description document. In addition, the constructor method loads the EDIControl.xml file for sequence number generation.

Logic for the EDIRecordWriter Constructor Method
Arguments:
  DOM Document File Description Document
  Output Stream

Call RecordWriter base class constructor, passing File
    Description Document and Output Stream
Delimiters Element <- Call File Description Document's
    getElementsByTagName for "Delimiters"

Segment Terminator Element <- call Delimiters
    getElementsByTagName
        for "SegmentTerminator"
Delimiter Value = call Segment Terminator's getAttribute for
    "value"
Record Terminator1 <- Call setDelimiter, passing Delimiter Value

Element Separator Element <- call Delimiters
    getElementsByTagName
        for "SegmentTerminator"
Delimiter Value = call Element Separator Element's getAttribute
    for "value"
Element Separator <- Call setDelimiter, passing Delimiter Value

Component Separator Element <- call Delimiters
    getElementsByTagName
        for "ComponentSeparator"
Delimiter Value = call Component Separator Element's
    getAttribute
        for "value"
Component Separator <- Call setDelimiter, passing Delimiter Value

Repetition Separator Element <- call Delimiters getElementsByTagName
    for "RepetitionSeparator"
IF Repetition Separator Element is not null
  Delimiter Value = call Repetition Separator Element's getAttribute
      for "value"
  Repetition Separator <- Call setDelimiter, passing Delimiter Value
ENDIF

Release Character Element <- call Delimiters getElementsByTagName
    for "ReleaseCharacter"
IF Release Character Element is not null
  Delimiter Value = call Release Character Element's getAttribute
      for "value"
 Release Character <- Call setDelimiter, passing Delimiter Value
ENDIF

BBHomePath <- from system property or environment variable for
    BBHome
EDIControlPath <- BBHomePath + "EDIControl.xml"
Call implementation dependent methods to load EDIControl Document

parseRecord

This method is very similar to the parseRecord method of the RecordReader base class, although again we add some functionality that is solely needed for processing the EDI representations of composite data structures. Rather than confuse the base class method I have created a more specialized method for the derived class. For Babel Blaster 1.0 this might be moved to the base class if design review and testing verify that it will work fine for other legacy formats.

Logic for the EDIRecordWriter parseRecord Method
Arguments:
  DOM Element Record
  DOM Element Record Grammar

Returns:
  Void

Field Grammar <- Get first Grammar child Element from Record
    Grammar Element, skipping over non-Element nodes
Grammar Field Name <- call Field Grammar's getAttribute
    on "ElementName"
DO for all Field Elements that are children of Record Element
  // Test for a composite data structure
  Composite <- False
  childNode <- get Field Element's firstChild
  DO until childNode is null or Composite is true
    IF childNode nodeType = ELEMENT
      Composite <- true
    ELSE
      childNode <- childNode's nextSibling
    ENDIF
  ENDDO
  IF Composite is false
    Element Text <- call getElement Text on Field Element
    IF Element Text is empty
      Proceed to next field
    ENDIF
  ENDIF
  Field Name <- Field Element's tagName attribute
  DO UNTIL Field Name == Grammar Field Name or Grammar Element
        is null
    Get next sibling Field Grammar Element, skipping over
        non-Element Nodes
    Grammar Field Name <- Field Element's tagName attribute
  ENDDO
  IF Grammar Element is null
    Return error
  ENDIF
  IF Composite is true
    Call base class parseRecord, passing Field Element and
        Grammar Element
  ELSE
    Field Number <- Call Field Grammar's getAttribute
        on "FieldNumber"
    New Cell <- call createDataCell, passing Field Number
        and Grammar
    New Cell <- call New Cell's putField, passing Element Text
  ENDIF
ENDDO

Note that we don't need a special method to parse the XML representation of a composite data element. We can use the base class's parseRecord method because the structure of a composite data element's XML representation and grammar are the same as records in our other legacy formats.

writeRecord

Since we can identify a grammar that applies to the segments of most EDI syntaxes, we can develop this common method to write such segments. The overall logic flow is very similar to that of the CSVRecordWriter since both deal with delimited record formats. As with that method we walk the DataCell Array. For this method we must keep track of a few more pieces of information so that we write the correct delimiters. The Element Position counter keeps track of data element position within the output segment. The Component Position counter keeps track of component data element position within a composite data structure. The Previous Element Position indicates whether or not we have a repeating data element.

Logic for the EDIRecordWriter writeRecord Method
Arguments:
  DOM Element Segment Grammar

Returns:
  Error status or throws exception

Initialize Output Record Buffer to null
Segment Tag <- Call Segment Grammar's getAttribute for "TagValue"
Output Buffer <- Segment Tag
Set Buffer Length to Tag length
Element Position <- 0
Previous Element Position <- 0
Component Position <- 1
DO for Index from 0 through Highest Cell
  // Test for new element
  Cell Position = Get Cell's Field Number
  // Reset to start new composite if needed
  IF Element Position != Cell Position
    Component Position <- 1
  ENDIF
  // Write preceding data element separators
  DO while Element Position < Cell Position
    Append Element Separator to Record Buffer
    Increment Element Position
  ENDDO
  // Write preceding repetition separator
  // NOTE - An additional test is needed here to write repeating
  //     composite data structures correctly
  IF Element Position = Previous Element Position
    Append Repetition Separator to Record Buffer
  ENDIF
  Previous Element Position = Element Position
  // Write preceding component data element separators
  Cell SubPosition = Get Cell's SubField Number
  DO while Component Position < Cell SubPosition
    Append Component Separator to Record Buffer
    Increment Component Position
  ENDDO
  Call fromXML to convert Cell contents from XML data type
  Call prepareOutput to format Cell contents for EDI output
  Cell Contents <- Call getField to retrieve Cell Buffer
      contents
  Clear Array entry
  Append Cell Contents to Record Buffer
ENDDO
Highest Cell <- -1
Append base RecordHandler's Record Terminator1 to Record Buffer
Call language's write routines to do physical write of
    Record Buffer
Increment Segment Count
Return success

Again, this version of the method doesn't fully support composite data structures when used as repeating data elements. A Babel Blaster 1.0 requirement is to widen support beyond the demands of X12 version 004010.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset