List of usage examples for org.apache.commons.net.nntp Threadable simplifiedSubject
public String simplifiedSubject();
From source file:org.ossmeter.metricprovider.trans.newsgroups.threads.Threader.java
/** * If any two members of the root set have the same subject, merge them. This is to attempt to accomodate messages without References: headers. *//* w w w . j a v a 2s .c o m*/ private void gatherSubjects() { int count = 0; for (ThreadContainer c = root.child; c != null; c = c.next) { count++; } // TODO verify this will avoid rehashing HashMap<String, ThreadContainer> subjectTable = new HashMap<String, ThreadContainer>((int) (count * 1.2), (float) 0.9); count = 0; for (ThreadContainer c = root.child; c != null; c = c.next) { Threadable threadable = c.threadable; // No threadable? If so, it is a dummy node in the root set. // Only root set members may be dummies, and they alway have at least 2 kids // Take the first kid as representative of the subject if (threadable == null) { threadable = c.child.threadable; } String subj = threadable.simplifiedSubject(); if (subj == null || subj.length() == 0) { continue; } ThreadContainer old = subjectTable.get(subj); // Add this container to the table iff: // - There exists no container with this subject // - or this is a dummy container and the old one is not - the dummy one is // more interesting as a root, so put it in the table instead // - The container in the table has a "Re:" version of this subject, and // this container has a non-"Re:" version of this subject. The non-"Re:" version // is the more interesting of the two. if (old == null || (c.threadable == null && old.threadable != null) || (old.threadable != null && old.threadable.subjectIsReply() && c.threadable != null && !c.threadable.subjectIsReply())) { subjectTable.put(subj, c); count++; } } // If the table is empty, we're done if (count == 0) { return; } // subjectTable is now populated with one entry for each subject which occurs in the // root set. Iterate over the root set, and gather together the difference. ThreadContainer prev, c, rest; for (prev = null, c = root.child, rest = c.next; c != null; prev = c, c = rest, rest = (rest == null ? null : rest.next)) { Threadable threadable = c.threadable; // is it a dummy node? if (threadable == null) { threadable = c.child.threadable; } String subj = threadable.simplifiedSubject(); // Dont thread together all subjectless messages if (subj == null || subj.length() == 0) { continue; } ThreadContainer old = subjectTable.get(subj); if (old == c) { // That's us continue; } // We have now found another container in the root set with the same subject // Remove the "second" message from the root set if (prev == null) { root.child = c.next; } else { prev.next = c.next; } c.next = null; if (old.threadable == null && c.threadable == null) { // both dummies - merge them ThreadContainer tail; for (tail = old.child; tail != null && tail.next != null; tail = tail.next) { // do nothing } if (tail != null) { // protect against possible NPE tail.next = c.child; } for (tail = c.child; tail != null; tail = tail.next) { tail.parent = old; } c.child = null; } else if (old.threadable == null || (c.threadable != null && c.threadable.subjectIsReply() && !old.threadable.subjectIsReply())) { // Else if old is empty, or c has "Re:" and old does not ==> make this message a child of old c.parent = old; c.next = old.child; old.child = c; } else { // else make the old and new messages be children of a new dummy container. // We create a new container object for old.msg and empty the old container ThreadContainer newc = new ThreadContainer(); newc.threadable = old.threadable; newc.child = old.child; for (ThreadContainer tail = newc.child; tail != null; tail = tail.next) { tail.parent = newc; } old.threadable = null; old.child = null; c.parent = old; newc.parent = old; // Old is now a dummy- give it 2 kids , c and newc old.child = c; c.next = newc; } // We've done a merge, so keep the same prev c = prev; } subjectTable.clear(); subjectTable = null; }