Example usage for org.apache.commons.net.nntp Threadable simplifiedSubject

List of usage examples for org.apache.commons.net.nntp Threadable simplifiedSubject

Introduction

In this page you can find the example usage for org.apache.commons.net.nntp Threadable simplifiedSubject.

Prototype

public String simplifiedSubject();

Source Link

Usage

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;

}