FileDocCategorySizeDatePackage
MessageTree.javaAPI DocExample2767Sun Sep 02 14:59:04 BST 2001com.oreilly.forum.domain

MessageTree.java

package com.oreilly.forum.domain;

import java.util.*;

/**
 * Arranges a collection of MessageSummary objects into a tree.
 */
public class MessageTree {
    private List topLevelMsgs = new ArrayList();

    // map ids to MessageSummary objects
    private Map idToMsgMap = new HashMap();

    // map reply-to ids to lists of MessageSummary objects
    private Map replyIDToMsgListMap = new HashMap();

    /**
     * Construct a new message tree from an iterator of MessageSummary
     * objects.
     */
    public MessageTree(Iterator messages) {
        while (messages.hasNext()) {
            // store each message in a map for fast retrieval by ID
            MessageSummary curMsg = (MessageSummary) messages.next();
            this.idToMsgMap.put(new Long(curMsg.getID()), curMsg);

            // build the inverted map that maps reply-to IDs to
            // lists of messages
            Long curReplyID = new Long(curMsg.getInReplyTo());
            List replyToList =
                    (List) this.replyIDToMsgListMap.get(curReplyID);
            if (replyToList == null) {
                replyToList = new ArrayList();
                this.replyIDToMsgListMap.put(curReplyID, replyToList);
            }
            replyToList.add(curMsg);
        }

        // build the list of top-level messages. A top-level message
        // fits one of the following two criteria:
        //  - its reply-to ID is -1
        //  - its reply-to ID was not found in the list of messages. This
        //    occurs when a message is a reply to a previous month's message
        Iterator iter = this.replyIDToMsgListMap.keySet().iterator();
        while (iter.hasNext()) {
            Long curReplyToID = (Long) iter.next();
            if (curReplyToID.longValue() == -1
                    || !this.idToMsgMap.containsKey(curReplyToID)) {
                List msgsToAdd =
                        (List) this.replyIDToMsgListMap.get(curReplyToID);
                this.topLevelMsgs.addAll(msgsToAdd);
            }
        }
        Collections.sort(this.topLevelMsgs);
    }

    public Iterator getTopLevelMessages() {
        return Collections.unmodifiableList(this.topLevelMsgs).iterator();
    }

    /**
     * @return an iterator of MessageSummary objects that are replies
     *         to the specified message.
     */
    public Iterator getReplies(MessageSummary msg) {
        List replies = (List) this.replyIDToMsgListMap.get(
                new Long(msg.getID()));
        if (replies != null) {
            Collections.sort(replies);
            return replies.iterator();
        } else {
            return Collections.EMPTY_LIST.iterator();
        }
    }
}