⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 algorithm.java

📁 手机邮箱撒的方式方式方式的
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package mujmail.threading;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import mujmail.MessageHeader;
import mujmail.Settings;

/**
 * Class represents algorithm for creating mail threads.
 * 
 * Algorithm is based on description written by Jamie Zawinski at
 * <a href="http://www.jwz.org/doc/threading.html">
 *   http://www.jwz.org/doc/threading.html
 * </a>
 * 
 * @author Betlista
 */
public class Algorithm {

	/** Subject for empty root messages. */
    private static final String EMPTY_MESSAGE_SUBJECT = "root";

    /** Flag signals if we want to print debug prints. */
	public static final boolean DEBUG = false; // used in MailDB too

	/** Instance of the singleton class. */
    private static final Algorithm algorithm = new Algorithm();

    /** Method to enable accessing the {@link #Algorithm()} instance. */
    public static Algorithm getAlgorithm() {
        return algorithm;
    }

    /**
     * Algorithm that group messages to so called threads - group of messages
     * that belongs together, this messages create discussion.
     * 
     * Algorithm assumes that all MessageHeaders have set parent IDs.
     * 
     * This method just call {@link #processMessage(Hashtable, MessageHeader)}
     * for each message in messageHeaders.
     * 
     * @param messageHeaders to be sorted
     * @see #processMessage(Hashtable, MessageHeader)
     */
    public ThreadedEmails invoke(final Vector/*<MessageHeaders>*/ messageHeaders) {
          if (DEBUG) System.out.println("DEBUG Algorithm.invoke(" + messageHeaders.toString() + ")");
        if ( !Settings.threading ) {
        	final ThreadedEmails threadedEmails = new ThreadedEmails();
        	final int size = messageHeaders.size();
        	for ( int i = 0; i < size; ++i) {
        		threadedEmails.addRoot( (MessageHeader)messageHeaders.elementAt(i) );
        	}
        	return threadedEmails;
        }
        try {
              //checkContent( messageHeaders );
              // idTable represents mapping, it maps message (represented by
              // message ID) to Container
            final Hashtable idTable2 = new Hashtable( messageHeaders.size() ); // Hashtable<String /*messageID*/, Vector<MessageHeader> >
              // for each message
            MessageHeader message;
            final int size = messageHeaders.size();
            for ( int i = 0; i < size; ++i) {
                message = (MessageHeader)messageHeaders.elementAt( i );
                processMessage( idTable2, message );
            }
              if (DEBUG) System.out.println("===   Creating threads   ===");
              // when all messages are processed, we have parent message for each one
            ThreadedEmails structure = createThreads( idTable2 );

              if (DEBUG) {
            	  System.out.println("DEBUG Algorithm.invoke(Vector) - end" );
                  //#ifdef MUJMAIL_DEVELOPMENT
//#             	  structure.printToConsole();
            	  //#endif
              }
            return structure;
        } catch (Throwable t) {
            System.err.println("ERROR Algorithm.invoke(Vector) - unexpected exception");
            t.printStackTrace();
              if (DEBUG) System.out.println("DEBUG Algorithm.invoke(Vector) - end, returning null");
            return null;
        }
    }

    /**
     * Checks if message ID is already in idTable.
     * <ul>
     * <li>if it's not we put the message header into ID table</li>
     * <li>when it is in idTable we check if the message header is empty (it
     *     was processed as reference in previous steps of algorithm) we
     *     simply mark it as not empty</li>
     *     <ul>
     *     <li>when the message is not empty that means we are processing same
     *         message again and that is error - exception is thrown</li>
     *     </ul>
     * </ul>
     * @param idTable
     * @param messageHeader
     * @exception IllegalStateException when message already processed wants to
     *            be processed again (or object in ID table is not instance
     *            of {@link MessageHeader message header})
     */
    private void processMessage(final Hashtable/*<String, MessageHeader>*/ idTable, final MessageHeader messageHeader) throws IllegalStateException {
          if (DEBUG) {
        	  System.out.println("DEBUG Algorithm.processMessage(..., " + messageHeader.toString() + ")");
              //#ifdef MUJMAIL_DEVELOPMENT
//#         	  dumpIDTable(idTable);
        	  //#endif
          }
        final String messageID = messageHeader.getThreadingMessageID();
          // 1. A.)
        Object o = idTable.get( messageID );
        Vector messageHeaders;
        if ( o == null ) {
              // message is not in idTable yet
        	messageHeaders = new Vector();
        	messageHeaders.addElement( messageHeader );
            idTable.put( messageID, messageHeaders );
        } else {
        	messageHeaders = (Vector)o;
            MessageHeader storedMessageHeader = (MessageHeader)messageHeaders.elementAt( 0 ); // get first element
            if ( storedMessageHeader.isEmpty() ) {
                  // container does not reference to any message
                  // this could happen when we processed message references
                  // and there was no container created for reference, so
                  // we created empty container
                //storedMessageHeader.setEmpty( false );
            	messageHeaders = new Vector();
            	messageHeaders.addElement( messageHeader );
                idTable.put( messageID, messageHeaders );
            } else {
            	messageHeaders.addElement( messageHeader );
            	// idTable3.put( messageID, messageHeader ); // not needed
            }
        }
        processMessageParentIDs(idTable, messageHeader);
    }

    /**
     * For each message loops over the list of message parents and adds the
     * parent (grandparent, ...) to ID table.
     * 
     * @param idTable
     * @param messageHeader
     * @throws IllegalStateException
     */
    private void processMessageParentIDs(final Hashtable idTable, final MessageHeader messageHeader) throws IllegalStateException {
          if (DEBUG) {
        	  System.out.println("DEBUG Algorithm.processMessageParentIDs(..., " + messageHeader.toString() + ")");
        	  //#ifdef MUJMAIL_DEVELOPMENT
//#         	  dumpIDTable(idTable);
        	  //#endif
          }
        //final Vector messageHeaders = (Vector)idTable.get( messageHeader.getThreadingMessageID() );
        final Vector parentIDs = messageHeader.getParentIDs(); // Vector<String>
        final int size = parentIDs.size();
          if (DEBUG) {
        	  System.out.println( "DEBUG Algorithm.processMessageParentIDs(..., ...) - size: " + size );
        	  System.out.println( "DEBUG Algorithm.processMessageParentIDs(..., ...) - parentIDs: " + parentIDs );
          }
        if (size == 0) return; // if there are no parent IDs we have nothing to do
        String previousParentID = null;
        String parentID = null;
        Vector parentIDVector;
        MessageHeader parentHeader = null;
        for ( int i = 0; i < size; ++i) {
              // parentID = message ID of parent message
            parentID = (String)parentIDs.elementAt( i );
            parentIDVector = (Vector)idTable.get( parentID );
            if ( parentIDVector == null ) {
            	parentHeader = null;
            } else {
            	parentHeader = (MessageHeader)parentIDVector.elementAt( 0 );
            }
            if ( parentHeader == null ) {
                  // if such message is not in idTable add it as a empty box
                parentHeader = new MessageHeader( messageHeader.getBox() );
                parentHeader.setThreadingMessageID( parentID );
                parentHeader.setSubject( EMPTY_MESSAGE_SUBJECT );
                parentHeader.setParentID( previousParentID );
                parentHeader.setEmpty( true );
                Vector vector = new Vector();
                vector.addElement( parentHeader );
                idTable.put(parentID, vector );
            }
//            parentHeader = messageHeader;
            previousParentID = parentID;
              //#ifdef MUJMAIL_DEVELOPMENT
//#               if (DEBUG) dumpIDTable(idTable);
              //#endif
        }
//      	final int parentIDVectorSize = messageHeaders.size();
          // for all messages in parent ID vector set parentID
//  		for ( int j = 0; j < parentIDVectorSize; ++j ) {
//  			((MessageHeader)messageHeaders.elementAt( j )).setParentID( parentID );
//  		}
//          break;
    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -