* @param descriptor
* @param namespaceInfo
* @param referenceClass
*/
public CollectionReferenceMapping generateXMLCollectionReferenceMapping(Property property, Descriptor descriptor, NamespaceInfo namespaceInfo, JavaClass referenceClass) {
CollectionReferenceMapping mapping = new XMLCollectionReferenceMapping();
initializeXMLMapping((XMLMapping)mapping, property);
initializeXMLContainerMapping(mapping, property.getType().isArray());
mapping.setUsesSingleNode(property.isXmlList() || (property.isAttribute() && (property.getXmlPath() == null || !property.getXmlPath().contains("/"))));
String referenceClassName = referenceClass.getQualifiedName();
JavaClass collectionType = property.getType();
if (collectionType.isArray()){
JAXBArrayAttributeAccessor accessor = new JAXBArrayAttributeAccessor(mapping.getAttributeAccessor(), mapping.getContainerPolicy(), helper.getClassLoader());
JavaClass componentType = collectionType.getComponentType();
if(componentType.isArray()) {
Class adaptedClass = classToGeneratedClasses.get(componentType.getName());
referenceClassName = adaptedClass.getName();
accessor.setAdaptedClassName(referenceClassName);
JavaClass baseComponentType = getBaseComponentType(componentType);
if (baseComponentType.isPrimitive()){
Class primitiveClass = XMLConversionManager.getDefaultManager().convertClassNameToClass(baseComponentType.getRawName());
accessor.setComponentClass(primitiveClass);
} else {
accessor.setComponentClassName(baseComponentType.getQualifiedName());
}
} else {
accessor.setComponentClassName(componentType.getQualifiedName());
}
mapping.setAttributeAccessor(accessor);
}
collectionType = containerClassImpl(collectionType);
mapping.useCollectionClassName(collectionType.getRawName());
mapping.setReferenceClassName(referenceClassName);
// here we need to setup source/target key field associations
if (property.isSetXmlJoinNodes()) {
for (XmlJoinNode xmlJoinNode: property.getXmlJoinNodes().getXmlJoinNode()) {
validateJoinNode(descriptor.getJavaClassName(), property, xmlJoinNode.getReferencedXmlPath(), referenceClass);
mapping.addSourceToTargetKeyFieldAssociation(xmlJoinNode.getXmlPath(), xmlJoinNode.getReferencedXmlPath());
}
} else {
// here we need to setup source/target key field associations
TypeInfo referenceType = typeInfo.get(referenceClass.getQualifiedName());
String tgtXPath = null;
if (null != referenceType && referenceType.isIDSet()) {
Property prop = referenceType.getIDProperty();
tgtXPath = getXPathForField(prop, namespaceInfo, !prop.isAttribute(), false).getXPath();
}
// if the XPath is set (via xml-path) use it
Field srcXPath;
if (property.getXmlPath() != null) {
srcXPath = new XMLField(property.getXmlPath());
} else {
srcXPath = getXPathForField(property, namespaceInfo, true, false);
}
mapping.addSourceToTargetKeyFieldAssociation(srcXPath.getXPath(), tgtXPath);
}
if (property.getInverseReferencePropertyName() != null) {
mapping.getInverseReferenceMapping().setAttributeName(property.getInverseReferencePropertyName());
JavaClass backPointerPropertyType = null;
if (property.getInverseReferencePropertyGetMethodName() != null && property.getInverseReferencePropertySetMethodName() != null && !property.getInverseReferencePropertyGetMethodName().equals("") && !property.getInverseReferencePropertySetMethodName().equals("")) {
mapping.getInverseReferenceMapping().setGetMethodName(property.getInverseReferencePropertySetMethodName());
mapping.getInverseReferenceMapping().setSetMethodName(property.getInverseReferencePropertySetMethodName());
JavaMethod getMethod = referenceClass.getDeclaredMethod(mapping.getInverseReferenceMapping().getGetMethodName(), new JavaClass[]{});
if (getMethod != null) {
backPointerPropertyType = getMethod.getReturnType();
}
} else {
JavaField backpointerField = referenceClass.getDeclaredField(property.getInverseReferencePropertyName());
if (backpointerField != null) {
backPointerPropertyType = backpointerField.getResolvedType();
}
}
if (helper.isCollectionType(backPointerPropertyType)) {
mapping.getInverseReferenceMapping().setContainerPolicy(ContainerPolicy.buildDefaultPolicy());
}
}
return mapping;
}