2

One of the files I am parsing consist of two parts that I need to logically split into two different beans. I have found that the MultiBeanListProcessor is a great way to do this. I used test example 14 as source for my code.

Given the following configuration:

public class Sample {

    public static void main(String[] args) throws IOException {     
        CsvParserSettings parserSettings = new CsvParserSettings();
        parserSettings.getFormat().setDelimiter('|');
        MultiBeanListProcessor processor = new MultiBeanListProcessor(Person.class, Address.class);
        String[] headers = new String[7];
        headers[0] = "id";      
        headers[1] = "firstName";
        headers[2] = "lastName";
        headers[3] = "city";
        headers[4] = "streetName";
        headers[5] = "houseNo";
        headers[6] = "houseAdd";
        String[] selectedFields = new String[5];
        selectedFields[0] = "firstName";
        selectedFields[1] = "lastName";
        selectedFields[2] = "city";
        selectedFields[3] = "streetName";
        selectedFields[4] = "houseAdd";
        parserSettings.setHeaders(headers);
        parserSettings.selectFields(selectedFields);       
        parserSettings.setProcessor(processor);
        parserSettings.setColumnReorderingEnabled(false);       
        CsvParser parser = new CsvParser(parserSettings);
        parser.parse(new FileReader("src/main/resources/input.csv"));

        List<Person> persons = processor.getBeans(Person.class);
        List<Address> addresses = processor.getBeans(Address.class);

        for (Person person : persons) {
            System.out.println(person.getFirstName());
        }   

        for (Address address : addresses) {
            System.out.println(address.getCity());          
        }
    }
}

This really works very nice.

Unfortunately, the input file is to large to load in memory and I need to iterate instead of parse all at once. In a previously asked question an answer was given how to iterate over each bean. I however did not manage to apply this logic/code to this use case.

How do I iterate over each bean when using the MultiBeanListProcessor?

Community
  • 1
  • 1
Sander_M
  • 1,109
  • 2
  • 18
  • 36

1 Answers1

1

Currently the only option you have is to use the MultiBeanProcessor (instead of MultiBeanListProcessor), which is abstract and requires you to provide an implementation to method:

public void beanProcessed(Class<?> beanType, Object beanInstance, C context){
    // your code here
}

Every time a new instance of a bean is created, this method will be called and you can process the object instances as required. You can use the context object to get information about which record originated the object instance if needed. A very simple implementation could be:

private Person person;
private Address address;     

public void beanProcessed(Class<?> beanType, Object beanInstance, C context){
    if(beanType == Person.class){
         person = (Person) beanInstance;
    }
    if(beanType == Address.class){
         address = (Address) beanInstance;
    }
    if(person != null && address != null){
         //got all beans from a row, process them
         process(person, address);

         //clear up until you get the instances produced for the next record.
         person = null;
         address = null;
    }
}

Hope this helps

Jeronimo Backes
  • 6,141
  • 2
  • 25
  • 29
  • Thanks for the quick response.The process method used in your example doesn't seem to compile. Is the idea to write an implementation of process method myself? Last but not least, in my actual application I have two beans and they both implement an interface. I used the MultiBeanListProcessor to load in an aray of these classes represented as an interface. `MultiBeanListProcessor processor = new MultiBeanListProcessor(classArray);` `Class[] classArray` consists out of the Person and Adress beans but as an interface. Can I still use the beanProcessed method given this use case? – Sander_M Nov 07 '16 at 10:25
  • Figured it out, I was making some rookie cast mistakes. Its working now and I can apply my logic per line. – Sander_M Nov 07 '16 at 10:44