in src/main/java/org/apache/commons/net/nntp/Threader.java [39:131]
private void buildContainer(final Threadable threadable, final HashMap<String, NntpThreadContainer> idTable) {
String id = threadable.messageThreadId();
NntpThreadContainer container = idTable.get(id);
int bogusIdCount = 0;
// A NntpThreadContainer exists for this id already. This should be a forward reference, but may
// be a duplicate id, in which case we will need to generate a bogus placeholder id
if (container != null) {
if (container.threadable != null) { // oops! duplicate ids...
bogusIdCount++; // Avoid dead local store warning
id = "<Bogus-id:" + (bogusIdCount) + ">";
container = null;
} else {
// The container just contained a forward reference to this message, so let's
// fill in the threadable field of the container with this message
container.threadable = threadable;
}
}
// No container exists for that message Id. Create one and insert it into the hash table.
if (container == null) {
container = new NntpThreadContainer();
container.threadable = threadable;
idTable.put(id, container);
}
// Iterate through all the references and create ThreadContainers for any references that
// don't have them.
NntpThreadContainer parentRef = null;
{
final String[] references = threadable.messageThreadReferences();
for (final String refString : references) {
NntpThreadContainer ref = idTable.get(refString);
// if this id doesn't have a container, create one
if (ref == null) {
ref = new NntpThreadContainer();
idTable.put(refString, ref);
}
// Link references together in the order they appear in the References: header,
// IF they don't have a parent already &&
// IF it will not cause a circular reference
if ((parentRef != null) && (ref.parent == null) && (parentRef != ref) && !(ref.findChild(parentRef))) {
// Link ref into the parent's child list
ref.parent = parentRef;
ref.next = parentRef.child;
parentRef.child = ref;
}
parentRef = ref;
}
}
// parentRef is now set to the container of the last element in the references field. make that
// be the parent of this container, unless doing so causes a circular reference
if (parentRef != null && (parentRef == container || container.findChild(parentRef))) {
parentRef = null;
}
// if it has a parent already, it's because we saw this message in a References: field, and presumed
// a parent based on the other entries in that field. Now that we have the actual message, we can
// throw away the old parent and use this new one
if (container.parent != null) {
NntpThreadContainer rest, prev;
for (prev = null, rest = container.parent.child; rest != null; prev = rest, rest = rest.next) {
if (rest == container) {
break;
}
}
if (rest == null) {
throw new IllegalStateException("Didnt find " + container + " in parent " + container.parent);
}
// Unlink this container from the parent's child list
if (prev == null) {
container.parent.child = container.next;
} else {
prev.next = container.next;
}
container.next = null;
container.parent = null;
}
// If we have a parent, link container into the parents child list
if (parentRef != null) {
container.parent = parentRef;
container.next = parentRef.child;
parentRef.child = container;
}
}