bean-iofixed-length-file

BeanIO how to skip/filter @Group in fixedLength


I'm trying to read a fixedlength file. I want to extract list of Document, but filtered only with RecordHeader (RH) with field value "BB". So skip Document with recordHeader equals:

RH20210607AA   

This is an example of my class Document

@Group
public class Document{

    @Record(order = 1, minOccurs=1, maxOccurs=1)
    private RH recordHeader;
    @Record(order = 2, minOccurs=1, maxOccurs = -1, type=RD.class, collection = List.class)
    private List<RD> recordDetails;
}

This is an example of my class RH

@Record
public class RH{

    @Field(ordinal = 0, required = true, length = 2, align = Align.LEFT, rid = true, literal = "RH")
    private String recordType;

    @Field(ordinal = 1, required = true, length=8, format = "yyyyMMdd")
    private LocalDate documentDate;

    @Field(ordinal = 2, required = true, length = 2, padding = ' ', align = Align.LEFT)
    private String documentCode;
}

This is an example of fixedLength file:

fake
Unknown record
Unknown record
RH20210607AA    
RDitem1
RDitem2
Unknown record
RH20210607BB    
RDitem2
RDitem3
Unknown record
Unknown record
Unknown record
RH20210607BB    
RDitem1
RDitem4
RDitem5

Thanks for help


Solution

  • You can use more than one field on your RH class to identify the records you want. You can do this:

    @Record
    public class RH {
    
      @Field(ordinal = 0, required = true, length = 2, align = Align.LEFT, rid = true, literal = "RH")
      private String recordType;
    
      @Field(ordinal = 1, required = true, length = 8, format = "yyyyMMdd")
      private Date documentDate;
    
      @Field(ordinal = 2, required = true, length = 2, padding = ' ', align = Align.LEFT, rid = true, literal = "BB")
      private String documentCode;
    
    }
    

    Note the extra attributes on the @Field annotation for the documentCode field --> rid = true, literal = "BB"

    You can use a regular expression in place of the literal = "BB" if you need to include more RH records or use it as an exclusion filter.

    You are probably already doing it, you also need to configure the StreamFactory to ignore unidentifiable records:

    final StreamBuilder builder = new StreamBuilder("streamName")
        .readOnly()
        .format("fixedlength")
        .parser(new FixedLengthParserBuilder())
        .ignoreUnidentifiedRecords()             // <-- important
        .addGroup(...)
        .addRecord(RD.class));
    factory.define(builder);