Class itemType = entry.getKey();
ElementMapping mapping = entry.getValue();
if (mapping.isNillable()) {
if (nilMapping != null && nilMapping != mapping) {
throw new BuildException("Property " + property + " mappings " + mapping.getXmlName() + " and " + nilMapping + " are both nillable. Only one mapping may of an property may be nilable");
}
nilMapping = mapping;
}
// add instance of check
JExpression isInstance = outerVar._instanceof(context.toJClass(itemType));
JBlock block = conditional.addCondition(isInstance);
// add space (' ') separator for XmlList
if (property.isXmlList()) {
// if (fooFirst) {
// writer.writeCharacters(" ");
// }
// fooFirst = false;
block._if(firstVar.not())._then().add(builder.getXSW().invoke("writeCharacters").arg(" "));
block.assign(firstVar, JExpr.FALSE);
}
// declare item variable
JVar itemVar;
if (toClass(property.getComponentType()) == itemType) {
itemVar = outerVar;
} else {
String itemName = builder.getWriteVariableManager().createId(itemType.getSimpleName());
itemVar = block.decl(context.toJClass(itemType), itemName, JExpr.cast(context.toJClass(itemType), outerVar));
}
writeElement(builder, block, mapping, itemVar, itemType, false, property.isXmlList());
}
// if item was null, write xsi:nil or report an error
JBlock nullBlock = conditional.addCondition(outerVar.eq(JExpr._null()));
if (nilMapping != null) {
// write start element
QName name = nilMapping.getXmlName();
nullBlock.add(builder.getWriteStartElement(name));
// write xsi:nil
nullBlock.add(builder.getXSW().invoke("writeXsiNil"));
// close element
nullBlock.add(builder.getXSW().invoke("writeEndElement"));
} else {
nullBlock.invoke(builder.getWriteContextVar(), "unexpectedNullValue").arg(builder.getWriteObject()).arg(property.getName());
}
// if not a recogonized type or null, report unknown type error
JInvocation unexpected = conditional._else().invoke(builder.getWriteContextVar(), "unexpectedElementType").arg(builder.getXSW()).arg(builder.getWriteObject()).arg(property.getName()).arg(outerVar);
for (Class expectedType : expectedTypes.keySet()) {
unexpected.arg(context.dotclass(expectedType));
}
}
break;
case ELEMENT_REF:
JBlock block = builder.getWriteMethod().body();
JVar itemVar = propertyVar;
if (property.isCollection()) {
JBlock collectionNotNull = block._if(propertyVar.ne(JExpr._null()))._then();
JType itemType;
if (!toClass(property.getComponentType()).isPrimitive()) {
itemType = context.getGenericType(property.getComponentType());
} else {
itemType = context.toJType((Class<?>) toClass(property.getComponentType()));
}
String itemName = builder.getWriteVariableManager().createId( property.getName() + "Item");
JForEach each = collectionNotNull.forEach(itemType, itemName, propertyVar);
JBlock newBody = each.body();
block = newBody;
itemVar = each.var();
}
// process value through adapter
itemVar = writeAdapterConversion(builder, block, property, itemVar);
if (property.isMixed()) {
// add instance of check
JExpression isInstance = itemVar._instanceof(context.toJClass(String.class));
JConditional conditional = block._if(isInstance);
// declare item variable
JVar stringVar;
if (toClass(property.getComponentType()) == String.class) {
stringVar = itemVar;
} else {
String itemName = builder.getWriteVariableManager().createId("string");
stringVar = conditional._then().decl(context.toJClass(String.class), itemName, JExpr.cast(context.toJClass(String.class), itemVar));
}
writeSimpleTypeElement(builder, stringVar, String.class, conditional._then());
block = conditional._else();
}
if (!property.isXmlAny()) {
block.invoke(builder.getWriteContextVar(), "unexpectedElementRef").arg(builder.getXSW()).arg(builder.getWriteObject()).arg(property.getName()).arg(itemVar);
} else {
block.invoke(builder.getWriteContextVar(), "writeXmlAny").arg(builder.getXSW()).arg(builder.getWriteObject()).arg(property.getName()).arg(itemVar);
}
break;
case VALUE:
block = builder.getWriteMethod().body();
itemVar = propertyVar;
firstVar = null;
if (property.isCollection()) {
JBlock collectionNotNull = block._if(propertyVar.ne(JExpr._null()))._then();
JType itemType;
if (!toClass(property.getComponentType()).isPrimitive()) {
itemType = context.getGenericType(property.getComponentType());
} else {
itemType = context.toJType((Class<?>) toClass(property.getComponentType()));
}
firstVar = collectionNotNull.decl(context.toJType(boolean.class), builder.getWriteVariableManager().createId(property.getName() + "First"), JExpr.TRUE);
String itemName = builder.getWriteVariableManager().createId( property.getName() + "Item");
JForEach each = collectionNotNull.forEach(itemType, itemName, propertyVar);
JBlock newBody = each.body();
block = newBody;
itemVar = each.var();
}
// add space (' ') separator for XmlList
if (property.isCollection()) {
// if (fooFirst) {
// writer.writeCharacters(" ");
// }
// fooFirst = false;
block._if(firstVar.not())._then().add(builder.getXSW().invoke("writeCharacters").arg(" "));
block.assign(firstVar, JExpr.FALSE);
}
// process value through adapter
propertyVar = writeAdapterConversion(builder, block, property, itemVar);
// write it
writeSimpleTypeElement(builder, propertyVar, toClass(property.getComponentType()), block);
break;
default:
throw new BuildException("Unknown XmlMapping type " + property.getXmlStyle());
}
}
}