Using X9Ware SDK X9Factory
The X9Factory class is used to populate x9.37 records by record type and logical field name. The fields to be populated and their attributes are determine by the current “bind” specification. This process will construct fields within records in their appropriate order. More importantly, x9factory determines which fields withing a given record type must be populated subject to the current specification. This is important when certain fields might be present in one specification (eg, x9.100-187) and not in another (eg, x9.100-180).
The factory class can be invoked using either a “set” based API that was originally introduced with R3.06, along with a newer fluent API that was added with R5.05. These X9Factory changes are backward compatible, which means that application programs written with the “set” methods are still supported, while you transition to the newer “with” assignments.
Here is an example of using the original “set” API to construct an x9.37 type 01 file header record:
final String fileMode = generateXml.isProdMode() ? "P" : "T";
final String ucdIndicator = sdkBase.getRules().isSpecUcd() ? "1" : " ";
final X9SdkObject sdkObject = sdkIO.startNewCsvRecord(X9.FILE_HEADER, X9.RECORD_FORMAT_000);
final X9Factory x9factory = new X9Factory(sdkBase);
final String[] record = x9factory.allocate(sdkObject);
x9factory.set(record, x9recordFields.r01StandardLevel, getStandardLevel());
x9factory.set(record, x9recordFields.r01TestFileIndicator, fileMode);
x9factory.set(record, x9recordFields.r01ImmediateDestinationRouting, generateAttr.immediateDestRouting);
x9factory.set(record, x9recordFields.r01ImmediateOriginRouting, generateAttr.immediateOrigRouting);
x9factory.set(record, x9recordFields.r01FileCreationDate, generateAttr.createDate);
x9factory.set(record, x9recordFields.r01FileCreationTime, generateAttr.createTime, 4);
x9factory.set(record, x9recordFields.r01ResendIndicator, "N");
x9factory.set(record, x9recordFields.r01ImmediateDestinationName, generateAttr.immediateDestName);
x9factory.set(record, x9recordFields.r01ImmediateOrigName, generateAttr.immediateOrigName);
x9factory.set(record, x9recordFields.r01FileIdModifier, generateAttr.fileIdModifier);
x9factory.set(record, x9recordFields.r01CountryCode, generateAttr.countryCode);
x9factory.set(record, x9recordFields.r01UserField, generateAttr.fileHeaderUserField);
x9factory.set(record, x9recordFields.r01UcdIndicator, ucdIndicator);
sdkIO.writeFromArray(sdkObject, record);
Here is the same logic, using our new “with” based, fluent API:
final String fileMode = generateXml.isProdMode() ? "P" : "T";
final String ucdIndicator = sdkBase.getRules().isSpecUcd() ? "1" : " ";
final X9SdkObject sdkObject = sdkIO.startNewCsvRecord(X9.FILE_HEADER, X9.RECORD_FORMAT_000);
final X9Factory x9factory = new X9Factory(sdkBase, sdkObject)
.with(x9recordFields.r01StandardLevel, getStandardLevel())
.with(x9recordFields.r01TestFileIndicator, fileMode)
.with(x9recordFields.r01ImmediateDestinationRouting, generateAttr.immediateDestRouting)
.with(x9recordFields.r01ImmediateOriginRouting, generateAttr.immediateOrigRouting)
.with(x9recordFields.r01FileCreationDate, generateAttr.createDate)
.with(x9recordFields.r01FileCreationTime, generateAttr.createTime, 4)
.with(x9recordFields.r01ResendIndicator, "N")
.with(x9recordFields.r01ImmediateDestinationName, generateAttr.immediateDestName)
.with(x9recordFields.r01ImmediateOrigName, generateAttr.immediateOrigName)
.with(x9recordFields.r01FileIdModifier, generateAttr.fileIdModifier)
.with(x9recordFields.r01CountryCode, generateAttr.countryCode)
.with(x9recordFields.r01UserField, generateAttr.fileHeaderUserField)
.with(x9recordFields.r01UcdIndicator, ucdIndicator);
sdkIO.writeFromArray(sdkObject, x9factory.build());
Here is another example, this time creating a type 61/62 credit in a general way:
/*
* Allocate our sdkObject and the x9factory.
*/
final String recordUsageIndicator = is100180 ? "5" : "2";
final String recordFormat = assignCreditFormat(x9type);
final X9SdkObject sdkObject = sdkIO.startNewCsvRecord(x9type, recordFormat);
/*
* Assign record fields for this credit format.
*/
x9recordFields.updateFieldsForSpecificationLevel(x9rules, x9type, recordFormat);
/*
* Format the credit based on the specifically selected record type (61/62) and format using
* our generic credit support which allows us to populate all of our supported formats.
*/
final String[] record = new X9Factory(sdkBase, sdkObject)
.with(x9recordFields.t6xRecordUsageIndicator, recordUsageIndicator)
.with(x9recordFields.t6xAuxOnus, csvArray, X9GenerateCols937.AUX_ONUS)
.with(x9recordFields.t6xExternalProcessingCode, csvArray, X9GenerateCols937.EPC)
.with(x9recordFields.t6xPostingBankRouting, routingNumber)
.with(x9recordFields.t6xOnus, csvArray, X9GenerateCols937.ONUS)
.with(x9recordFields.t6xItemAmount, csvArray, X9GenerateCols937.AMOUNT)
.with(x9recordFields.t6xCreditSequenceNumber, currentItemSequenceNumber)
.with(x9recordFields.t6xDocumentationTypeIndicator, csvArray,
X9GenerateCols937.DOCUMENTATION_INDICATOR)
.with(x9recordFields.t6xTypeOfAccount, generateAttr.creditTypeOfAccount)
.with(x9recordFields.t6xSourceOfWork, generateAttr.creditSourceOfWork)
.with(x9recordFields.t6xWorkType, generateAttr.creditWorkType)
.with(x9recordFields.t6xDebitCreditIndicator,
generateAttr.creditDebitCreditIndicator)
.with(x9recordFields.t6xUserField, generateAttr.creditUserField)
.with(x9recordFields.t6xReserved, "").build();
/*
* Write the manufactured credit record from the csv array.
*/
sdkIO.writeFromArray(sdkObject, record);
We provide this alternative because the new Java fluent API approach, with its method chaining, can simplify code readability and usability, compared to more traditional setter methods. By allowing methods to be chained together, the fluent API enables developers to construct and configure objects in a more intuitive and concise manner. Instead of invoking multiple setters individually, this approach can result in code that is less verbose and easier to read. It allows you to streamline object creation in a single, continuous expression. We agree that using the fluent API approach fosters cleaner, more maintainable code and makes it easier to understand the sequence of operations applied to an object.
Please see X9BuildX9 for more examples on how to use the new fluent API.