I'm trying to see if this is even possible with SuperCSV and Dozer, or if I should just revert to Map parsing. I have a POJO that has a member field of Map. Thankfully, during CSV parsing, I know what specific subclass of MyInterface should be built, and also the value of MyEnum will be static. But how would I set all this up in the column mappings? Thanks!
Currently, my cell processors have this structure, and I am using a CsvMapReader.
private static final CellProcessor[] CELL_PROCESSORS = new CellProcessor[] {
new NotNull(new Trim(new StrRegEx("^\\d{10,}$"))), // phone1
new Optional(new Trim(new StrRegEx("^\\d{10,}$"))), // phone2
new Optional(new Trim(new StrRegEx("^\\d{10,}$"))), // phone3
new Optional(new Trim()), // callVar1
new Optional(new Trim()), // callVar2
new Optional(new Trim()), // callVar3
new Optional(new Trim()), // callVar4
new Optional(new Trim()), // callVar5
new Optional(new Trim()), // callVar6
new Optional(new Trim()), // callVar7
new Optional(new Trim()), // callVar8
new Optional(new Trim()), // callVar9
new Optional(new Trim()), // callVar10
};
private Contact mapRowToContact(Map<String, Object> row) {
Contact contact = new Contact();
MyPhoneContactMethodData methodData = new MyPhoneContactMethodData();
List<Phone> phones = new ArrayList<>();
Phone phone = new Phone();
phone.setPhoneNumber((String)row.get("phone1"));
phones.add(phone);
phone = new Phone();
phone.setPhoneNumber((String)row.get("phone2"));
if (phone.getPhoneNumber() != null) {
phones.add(phone);
}
phone = new Phone();
phone.setPhoneNumber((String)row.get("phone3"));
if (phone.getPhoneNumber() != null) {
phones.add(phone);
}
methodData.setPhones(phones);
List<String> callVars = new ArrayList<>();
callVars.add((String)row.get("callVar1"));
callVars.add((String)row.get("callVar2"));
callVars.add((String)row.get("callVar3"));
callVars.add((String)row.get("callVar4"));
callVars.add((String)row.get("callVar5"));
callVars.add((String)row.get("callVar6"));
callVars.add((String)row.get("callVar7"));
callVars.add((String)row.get("callVar8"));
callVars.add((String)row.get("callVar9"));
callVars.add((String)row.get("callVar10"));
methodData.setEnterpriseCallVarData(callVars);
Map<ContactMethod, ContactMethodData> methodDataMap = new HashMap<>();
methodDataMap.put(ContactMethod.PHONE, methodData);
contact.setContactMethodData(methodDataMap);
return contact;
}
A Contact
has this structure, with many other unrelated fields:
public class Contact {
private Integer id;
private Map<ContactMethod, ContactMethodData> contactMethodData;
}
ContactMethod
is an enum, with values PHONE
and EMAIL
.
ContactMethodData
is an interface, of which the superclass of MyPhoneContactMethodData
implements.
Thanks for the code - much easier to understand now :)
You should be able to read each row of CSV as a MyPhoneContactMethodData
instance by using the following bean mapping. Just make sure you call configureBeanMapping()
with this before reading (as shown on the Super CSV website).
You will then have to manually create the Contact
and add the MyPhoneContactMethodData
to the contactMethodData
map, using with ContactMethod.PHONE
as the key (as done in the last 3 lines of your code).
final String[] beanMapping = new String[]{
"phones[0].phoneNumber",
"phones[1].phoneNumber",
"phones[2].phoneNumber",
"enterpriseCallVarData[0]",
"enterpriseCallVarData[1]",
"enterpriseCallVarData[2]",
"enterpriseCallVarData[3]",
"enterpriseCallVarData[4]",
"enterpriseCallVarData[5]",
"enterpriseCallVarData[6]",
"enterpriseCallVarData[7]",
"enterpriseCallVarData[8]",
"enterpriseCallVarData[9]"
};
beanReader.configureBeanMapping(MyPhoneContactMethodData.class, beanMapping);
MyPhoneContactMethodData methodData;
while( (methodData =
beanReader.read(MyPhoneContactMethodData.class, CELL_PROCESSORS)) != null ) {
// add to contact
}