public String generateMappingCode(FieldMap fieldMap, VariableRef source, VariableRef destination, SourceCodeContext code) {
StringBuilder out = new StringBuilder();
MultiOccurrenceVariableRef s = MultiOccurrenceVariableRef.from(source);
MultiOccurrenceVariableRef d = MultiOccurrenceVariableRef.from(destination);
final Class<?> dc = destination.getOwner().rawType();
final Class<?> destinationElementClass = d.elementType().getRawType();
if (destinationElementClass == null) {
throw new MappingException("cannot determine runtime type of destination collection " + dc.getName() + "." + d.name());
}
// Start check if source property ! = null
out.append(s.ifNotNull() + " {\n");
/*
* TODO: migrate this to create a new destination variable first;
* fill it, and then assign it to the destination using the setter.
*/
MultiOccurrenceVariableRef newDest = new MultiOccurrenceVariableRef(d.type(), "new_" + d.name());
if (d.isAssignable()) {
out.append(statement(newDest.declare(d.newInstance(source.size()))));
} else {
out.append(statement(newDest.declare(""+d)));
out.append(statement("%s.clear()", newDest));
}
if (s.isArray()) {
if (s.elementType().isPrimitive()) {
out.append("\n");
out.append(statement("%s.addAll(asList(%s));", newDest, s));
} else {
out.append("\n");
out.append(statement("%s.addAll(mapperFacade.mapAsList(asList(%s), %s.class, mappingContext));", newDest, s, d.elementTypeName()));
}
} else {
append(out,
"\n",
format("%s.addAll(mapperFacade.mapAs%s(%s, %s, %s, mappingContext))", newDest, d.collectionType(), s,
code.usedType(s.elementType()), code.usedType(d.elementType())));
}
if (fieldMap.getInverse() != null) {
final MultiOccurrenceVariableRef inverse = new MultiOccurrenceVariableRef(fieldMap.getInverse(), "orikaCollectionItem");
if (fieldMap.getInverse().isCollection()) {
append(out,
format("for (java.util.Iterator orikaIterator = %s.iterator(); orikaIterator.hasNext();) { ", newDest),
format(" %s orikaCollectionItem = (%s) orikaIterator.next();", d.elementTypeName(), d.elementTypeName()),
format(" %s { %s; }", inverse.ifNull(), inverse.assignIfPossible(inverse.newCollection())),
format(" %s.add(%s)", inverse, d.owner()),
"}");
} else if (fieldMap.getInverse().isArray()) {
out.append(" // TODO support array");
} else {
append(out,
format("for (java.util.Iterator orikaIterator = %s.iterator(); orikaIterator.hasNext();) { ", newDest),
format(" %s orikaCollectionItem = (%s) orikaIterator.next();", d.elementTypeName(), d.elementTypeName()),
inverse.assign(d.owner()),
"}");
}
}
// End check if source property ! = null