The FlatRecordReader introduces only a few new attributes but has some new and overridden methods. It inherits several attributes and methods from its RecordReader and RecordHandler base classes (see Chapter 6).
Attributes:
Integer Fixed Record Length
Integer Record ID Field Offset
Integer Record ID Field Length
Methods:
Constructor
getFieldValue
getRecordType
parseRecord
readRecord
readRecordFixedLength
In the FlatRecordReader constructor method, we primarily retrieve values from the file description document that the reader needs for processing. The logic should look familiar by now.
Arguments: DOM Document File Description Document Call RecordReader base class constructor, passing File Description Document Record Format Element <- Get RecordFormat Element from File Description Document Child Element <- Get first childNode from Record Format Element, advancing over non-Element Nodes Fixed Record Length <- 0 IF Child Element NodeName = "Fixed" Fixed Record Length <- Call Child Element's getAttribute for "Length" ELSE Record Terminator <- Call Child Element's getAttribute for "RecordTerminator" Call setTerminator to set the Record Terminators ENDIF Tag Info Element <- Get "RecordTagInfo" Element from File Description Document Record ID Field Offset <- Call Tag Info's getAttribute for "Offset" Record ID Field Length <- Call Tag Info's getAttribute for "Length" |
This method gets the complete value of a record's field with a single call. It is declared and implemented only in the FlatRecordReader class and isn't used in any of the other classes derived from the RecordReader class. The reason for this is that the other legacy formats (CSV and EDI) parse input records on a character-by-character basis. They save a field's characters to a DataCell object as they parse the record. In contrast, with the flat file format we parse records on a field-by-field basis, extracting fields from the record buffer based on offsets and lengths. This method is called from the FlatRecordReader's parseRecord method to perform that extraction. In addition, this method is designed to be used for extracting the record identifier, and until we have it we don't know how to parse the full record and load the DataCell Array.
The method is also called from the FlatRecordReader's testPartnerBreak method and the FlatRecordReader's getRecordType method. We call it for these special cases and not as a general purpose method for extracting field values from the input record buffer since in Java and C++ that operation takes only a couple lines of code. In addition to extracting the value, getFieldValue trims trailing whitespace and returns an error if the field is empty.
Arguments: Integer Field Offset Integer Field Length Returns: Field value; throws exception or returns status IF Field Offset > Record Buffer Length Return error ENDIF IF Field Offset + Field Length > Record Buffer Length Field Length <- Record Buffer Length - Field Offset ENDIF Field Value <- Extract from Record Buffer according to Passed Field Offset and adjusted Field Length Field Value <- Trim trailing whitespace (<= ASCII space character) IF length of Field Value = 0 Return error ENDIF Return Field Value |
This method extracts the value of the Record ID field from the input record buffer, trimming trailing whitespace. In the current implementation the field value is returned in its raw form, interpreted as alphanumeric string data.
Arguments: None Returns: Record ID tag value; throws exception or returns status Record Tag Value <- call getFieldValue, passing Record ID Field Offset and Record ID Field Value Return Record Tag Value or status |
This method is not as interesting as the one in the CSVRecordReader because the grammar is not as complex. Essentially, we walk the FieldDescription Elements of the RecordDescription Element, extract the field contents according to their defined offsets and lengths, and create new DataCell objects.
Arguments: DOM Element Record Grammar Returns: Error status or throw exception Field Grammar NodeList <- call Record Grammar's getElementsByTagName for "FieldDescription" DO until end of Field Grammar Node List Field Grammar Element <- Next item in Field Grammar NodeList Field Number <- call Field Grammar Element's getAttribute on "FieldNumber" Field Offset <- call Field Grammar Element's getAttribute on "Offset" Field Length <- call Field Grammar Element's getAttribute on "Length" IF Field Offset + 1 > Record Buffer Length Return success // End of record ENDIF IF Field Offset + Field Length > Record Buffer Length Field Length <- Record Buffer Length - Field Offset ENDIF Field Length <- Record Buffer Length - Field Offset Field Value <- Extract from Record Buffer according to Field Offset and adjusted Field Length New Cell <- call RecordHandler's createDataCell method, passing Field Number and Field Grammar Element Call New Cell's putFieldValue method, passing Field Value ENDDO |
This convenience method provides a way to protect calling routines from the variations in how we physically process records for flat files. It performs either a fixed or variable length read, depending on the physical characteristics gleaned from the file description document.
Arguments: None Returns: Record Length or EOF IF Fixed Record Length > 0 Return call to readRecordFixedLength ENDIF Return call to base RecordReader's readRecordVariableLength |
This method calls the language-specific routines for reading a fixed length record from a flat file.
Arguments: DOM Element Record Grammar Returns: Error status or throw exception Clear Record Buffer Record Buffer <- Call language-specific routine to read a fixed number of bytes from the input record stream IF not EOF Return Fixed Record Length ENDIF Return EOF |