First of all, your CSVReader
's "fields" attribute will be a hodge-podge of all fields contained inside the CSV file, irregardless of which POJO, list or type they map back to. Thus, some fields will be Person
properties, and some fields will be aliases that actually belong to the separate aliases
bean, which is of type java.util.ArrayList<String>
.
Your job is to tell Smooks how to map each field to the respective bean/list/component/type/etc, which means telling it what to do when it encounters each field.
Smooks does not support this sort of "dynamic" field binding, where you can have 0+ CSV fields map back to an ArrayList
, that itself will either be empty or populated. You must enumerate each field in the CSVReader
, which means having an ArrayList
of aliases that has a fixed size.
Ergo, you must decide on a maximum number of aliases that can be associated with each Person
, and account for them in the fields list:
<reader class="org.milyn.csv.CSVReader">
<param name="fields">lastName,fristName,age,gender,alias1,alias2,alias3</param>
<param name="separator">|</param>
<param name="strict">false</param>
</reader>
This means that each CSV record must have a credible value for your 3 aliases. I would recommend having an "ignore" value, such as "%%%IGNORE%%%
" so that your app logic can no to remove an list items that contain that value (after Smooks has finished performing the transformation that is).
You might also want to check out Smooks's built-in $ignore$
token, which might already do this or something like it.
The last piece before we can tie everything together in a complete code example is to simply accept the sad fact that Smooks either does not (or does not publicly document) any ability to use List<String>
in this kind of example. You must convert your POJO to use either to a List<StringBuffer>
or a List<StringBuilder>
for aliases, so that we may take advntage of a Smooks-JavaBean value
element attribute called setterMethod
.
Altogether now:
<jb:bean beanId="aliases" class="java.util.ArrayList" createOnElement="csv-set/csv-record">
<jb:wiring beanRefId="alias1"/>
<jb:wiring beanRefId="alias2"/>
<jb:wiring beanRefId="alias3"/>
</jb:bean>
<jb:bean beanId="alias1" class="java.util.StringBuffer" createOnElement="csv-set/csv-record/alias1">
<jb:value data="csv-set/csv-record/alias1" setterMethod="append" />
</jb:bean>
<jb:bean beanId="alias2" class="java.util.StringBuffer" createOnElement="csv-set/csv-record/alias2">
<jb:value data="csv-set/csv-record/alias2" setterMethod="append" />
</jb:bean>
<jb:bean beanId="alias3" class="java.util.StringBuffer" createOnElement="csv-set/csv-record/alias3">
<jb:value data="csv-set/csv-record/alias3" setterMethod="append" />
</jb:bean>
So every time we start parsing a new csv-record
, we create both a person
bean (as your initial code example shows perfectly) as well as an aliases
bean. Then, over the course of parsing this record, we will find Person
properties as well as alias1
through alias3
. The aliasN
fields get stored into the aliases
bean, meanwhile the other Person
field gets stored into the person
bean. Finally, Smooks knows to "wire" the person
and aliases
beans together to create a Java Person
object.