0

I was looking for a way to parse flat file that contains nested records. As an example I have file containig a line

NAME,SURNAME,ADRESSLINE1|ADDRESSLINE2|ADDRESLINE3,PHONE1|PHONE2

In the end i would hope it to map to POJO

class Record {
  String name;//NAME
  String surname;//SURNAME
  List<String> address;//three elements
  List<String> phone;//two elements
}

My hope is that one of Camel dataformats supports that. But i can't seem to find which one would?

  • I doubt there is dataformat for that. You are better off handling the parsing of that yourself. – Souciance Eqdam Rashti Feb 23 '18 at 15:39
  • 1) Is it in any way possible for you to change one of the delimiters to the other one before giving the data to BeanIO? For example change the pipe `|` into a comma `,` before processing the file with BeanIO? 2) Will there always be 3 ADDRESSLINE fields and 2 PHONE fields? Also, show us what you have already done as a mapping.xml file – nicoschl Feb 23 '18 at 16:04
  • @nicoschl very rarely I get to choose data format and this is more like a general question about "not so flat" flat file parsing using camel. – Arunas Junevicius Feb 27 '18 at 08:19
  • @SoucianceEqdamRashti I'd accept your comment as an answer, since I was looking for how to map file in an elegant way without scattering mapping logic. – Arunas Junevicius Feb 27 '18 at 08:19

2 Answers2

0

You can likely add a setter to your POJO for those multi-values that takes a String argument, and then internally split that into a list.

public void setAddress(String adr) {
  String[] parts = adr.split("|");
  ... // convert array to list and set it
}

Then you can use beanio etc to map the fields separated by comma.

Claus Ibsen
  • 56,060
  • 7
  • 50
  • 65
0

I guess that camel has got elegant decision for it

Firstly, define your POJO class as a CSV bindy

@CsvRecord(separator = ",", crlf = "UNIX") 
public class Person {
  @DataField(pos = 1)
  private String name;

  @DataField(pos = 2)
  private String surname;

  @DataField(pos = 3)
  private String addresses;

  @DataField(pos = 4)
  private String phones;

  public String getName() {
      return name;
  }

  public String getSurname() {
      return surname;
  }

  public List<String> getAddress() {
    return  Arrays.asList(addresses.split("\\|"));
  }

  public List<String> getPhones() {
    return Arrays.asList(phones.split("\\|"));
  }
}

then you can use it in unmarshalling like this one

<camelContext id="camel" trace="true" xmlns="http://camel.apache.org/schema/spring">

    <dataFormats>
        <bindy id="bindyDataformat" type="Csv" classType="test.Person"/>
    </dataFormats>

    <route>
        <from uri="file:src/data?noop=true"/>
        <unmarshal ref="bindyDataformat"/>
        <split>
            <simple>body</simple>
            <to uri="mock:queue.csv"/>
        </split>
    </route>

</camelContext>