in xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceUnmarshaller.java [45:86]
protected Object convert(final Object parent, final Class<?> type, final Converter converter) {
if (parentStack.size() > 0) { // handles circular references
final R parentReferenceKey = parentStack.peek();
if (parentReferenceKey != null) {
// see AbstractCircularReferenceTest.testWeirdCircularReference()
if (!values.containsKey(parentReferenceKey)) {
values.put(parentReferenceKey, parent);
}
}
}
final Object result;
final String attributeName = getMapper().aliasForSystemAttribute("reference");
final String reference = attributeName == null ? null : reader.getAttribute(attributeName);
final boolean isReferenceable = getMapper().isReferenceable(type);
if (reference != null) {
final Object cache = isReferenceable ? values.get(getReferenceKey(reference)) : null;
if (cache == null) {
final ConversionException ex = new ConversionException("Invalid reference");
ex.add("reference", reference);
ex.add("referenced-type", type.getName());
ex.add("referenceable", Boolean.toString(isReferenceable));
throw ex;
}
result = cache == NULL ? null : cache;
} else if (!isReferenceable) {
result = super.convert(parent, type, converter);
} else {
final R currentReferenceKey = getCurrentReferenceKey();
parentStack.push(currentReferenceKey);
Object localResult = null;
try {
localResult = super.convert(parent, type, converter);
} finally {
result = localResult;
if (currentReferenceKey != null) {
values.put(currentReferenceKey, result == null ? NULL : result);
}
parentStack.popSilently();
}
}
return result;
}