in xstream/src/java/com/thoughtworks/xstream/core/AbstractReferenceMarshaller.java [48:126]
public void convert(final Object item, final Converter converter) {
if (getMapper().isImmutableValueType(item.getClass())) {
// strings, ints, dates, etc... don't bother using references.
converter.marshal(item, writer, this);
} else {
final Path currentPath = pathTracker.getPath();
final Id<R> existingReference = references.lookupId(item);
if (existingReference != null && existingReference.getPath() != currentPath) {
final String attributeName = getMapper().aliasForSystemAttribute("reference");
if (attributeName != null) {
writer.addAttribute(attributeName, createReference(currentPath, existingReference.getItem()));
}
} else {
final R newReferenceKey = existingReference == null
? createReferenceKey(currentPath, item)
: existingReference.getItem();
if (lastPath == null || !currentPath.isAncestor(lastPath)) {
fireValidReference(newReferenceKey);
lastPath = currentPath;
references.associateId(item, new Id<>(newReferenceKey, currentPath));
}
converter.marshal(item, writer, new ReferencingMarshallingContext<R>() {
@Override
public void put(final Object key, final Object value) {
AbstractReferenceMarshaller.this.put(key, value);
}
@Override
public Iterator<Object> keys() {
return AbstractReferenceMarshaller.this.keys();
}
@Override
public Object get(final Object key) {
return AbstractReferenceMarshaller.this.get(key);
}
@Override
public void convertAnother(final Object nextItem, final Converter converter) {
AbstractReferenceMarshaller.this.convertAnother(nextItem, converter);
}
@Override
public void convertAnother(final Object nextItem) {
AbstractReferenceMarshaller.this.convertAnother(nextItem);
}
@Override
public void replace(final Object original, final Object replacement) {
references.associateId(replacement, new Id<>(newReferenceKey, currentPath));
}
@Override
public R lookupReference(final Object item) {
final Id<R> id = references.lookupId(item);
return id.getItem();
}
/**
* @deprecated As of 1.4.2
*/
@Deprecated
@Override
public Path currentPath() {
return pathTracker.getPath();
}
@Override
public void registerImplicit(final Object item) {
if (implicitElements.containsId(item)) {
throw new ReferencedImplicitElementException(item, currentPath);
}
implicitElements.associateId(item, newReferenceKey);
}
});
}
}
}