field.setNamespaceResolver(namespaceResolver);
while (stringTokenizer.hasMoreElements()) {
String nextToken = stringTokenizer.nextToken();
field.setXPath(xPath + nextToken);
field.initialize();
CoreMapping mapping = objectBuilder.getMappingForField(field);
if (null == mapping) {
// XPath might have indexes, while the mapping's XPath may not,
// so remove them and look again
XPathFragment xPathFragment = new XPathFragment(nextToken);
int fieldIndex = field.getXPathFragment().getIndexValue();
int fragmentIndex = xPathFragment.getIndexValue();
if (fieldIndex > 0 || fragmentIndex > 0) {
int index = fieldIndex - 1;
if (index < 0) {
index = fragmentIndex - 1;
}
String xPathNoIndexes = removeIndexesFromXPath(field.getXPath());
field.setXPath(xPathNoIndexes);
field.initialize();
mapping = objectBuilder.getMappingForField(field);
if (null == mapping) {
// Try adding /text()
field.setXPath(xPathNoIndexes + Constants.XPATH_SEPARATOR + Constants.TEXT);
field.initialize();
mapping = objectBuilder.getMappingForField(field);
}
if (null != mapping) {
if (field.getXPath().endsWith(Constants.TEXT) || !stringTokenizer.hasMoreElements()) {
// End of the line, we found a mapping so return it
queryResult.mapping = mapping;
queryResult.owner = object;
queryResult.index = index;
return queryResult;
} else {
// We need to keep looking -- get the mapping value,
// then recurse into getMappingForXPath with new root object
Object childObject = mapping.getAttributeValueFromObject(object);
if (mapping.isCollectionMapping()) {
Object collection = mapping.getAttributeValueFromObject(object);
if (null != collection && List.class.isAssignableFrom(collection.getClass())) {
List list = (List) collection;
if (index >= list.size()) {
// Index used in query is out of range, no matches
return null;
}
childObject = list.get(index);
}
}
if (null == childObject) {
childObject = mapping.getReferenceDescriptor().getObjectBuilder().buildNewInstance();
}
CoreObjectBuilder childObjectBuilder = mapping.getReferenceDescriptor().getObjectBuilder();
return getMappingForXPath(childObject, childObjectBuilder, stringTokenizer, namespaceResolver);
}
}
}
} else {
if (!stringTokenizer.hasMoreElements()) {
// End of the line, we found a mapping so return it
queryResult.mapping = mapping;
queryResult.owner = object;
return queryResult;
} else {
// We need to keep looking -- get the mapping value,
// then recurse into getMappingForXPath with new root object
Object childObject = mapping.getAttributeValueFromObject(object);
if (mapping.isCollectionMapping()) {
Object collection = mapping.getAttributeValueFromObject(object);
if (null != collection && List.class.isAssignableFrom(collection.getClass())) {
List list = (List) collection;
if (0 >= list.size()) {
return null;
}
childObject = list.get(0);
}
}
if (null == childObject) {
childObject = mapping.getReferenceDescriptor().getObjectBuilder().buildNewInstance();
}
CoreObjectBuilder childObjectBuilder = mapping.getReferenceDescriptor().getObjectBuilder();
return getMappingForXPath(childObject, childObjectBuilder, stringTokenizer, namespaceResolver);
}
}
xPath = xPath + nextToken + Constants.XPATH_SEPARATOR;
}