📄 algorithm.java
字号:
/**
* idTable parameter contains e-mails threaded in threads with all levels
* This method creates just one level - there will be root messages and
* in next level there will be children (and their children and so on)
* of this root message
*
* @param idTable maps messageID to {@link MessageHeader}
*/
private ThreadedEmails createThreads( final Hashtable idTable ) {
removeEmptyMessages( idTable );
if (DEBUG) {
System.out.println("DEBUG Algorithm.createThreads(Hashtable) - start:");
//#ifdef MUJMAIL_DEVELOPMENT
//# dumpIDTable( idTable );
//#endif
}
final Enumeration messageIDs = idTable.keys();
String messageID;
MessageHeader actualMessageHeader;
Vector actualMessageHeaders;
int size;
MessageHeader parentMessageHeader;
Vector parentMessageHeaders;
final ThreadedEmails threadedEmails = new ThreadedEmails();
// for each message in idTable
// if it is root message (have no parentID) add it, if not skip
// it for now, that causes the problem
final Vector childMessages = new Vector();
while ( messageIDs.hasMoreElements() ) {
// get parent message
messageID = (String)messageIDs.nextElement();
actualMessageHeaders = (Vector)idTable.get( messageID );
size = actualMessageHeaders.size();
for (int i = 0; i < size; ++i) {
actualMessageHeader = (MessageHeader)actualMessageHeaders.elementAt( i );
parentMessageHeaders = (Vector)idTable.get( actualMessageHeader.getParentID() ); // getParentId should always return at least ""
if ( parentMessageHeaders != null ) {
parentMessageHeader = (MessageHeader)parentMessageHeaders.elementAt( 0 );
} else {
parentMessageHeader = null;
}
if ( parentMessageHeader == null ) { // have no parent
threadedEmails.addRoot( actualMessageHeader );
} else {
childMessages.addElement( actualMessageHeader.getThreadingMessageID() );
}
}
}
final int children = childMessages.size();
// MessageHeader rootMessage = null;
for ( int i = 0; i < children; ++i ) {
// get parent message
messageID = (String)childMessages.elementAt( i );
actualMessageHeaders = (Vector)idTable.get( messageID );
size = actualMessageHeaders.size();
for (int j = 0; j < size; ++j) {
actualMessageHeader = (MessageHeader)actualMessageHeaders.elementAt( j );
parentMessageHeaders = (Vector)idTable.get( actualMessageHeader.getParentID() ); // getParentId should always return at least ""
parentMessageHeader = (MessageHeader)parentMessageHeaders.elementAt( 0 );
threadedEmails.addMessage( parentMessageHeader, actualMessageHeader);
}
}
threadedEmails.removeUnnecessaryEmptyMessages();
return threadedEmails;
}
/**
* Method removes not needed empty messages from structure. Not needed are
* all empty messages.<br>
* Example:
* <pre>
* -- Msg1
* |--Empty (not needed message)
* | \-- Msg4
* \--Msg3
* -- Msg2
* </pre>
* Should be:
* <pre>
* -- Msg1
* |--Msg4
* \--Msg3
* -- Msg2
* </pre>
*
* @param idTable
*/
private void removeEmptyMessages( final Hashtable/*<String, MessageHeader>*/ idTable ) {
if (DEBUG) {
System.out.println("DEBUG Algorithm.removeEmptyMessages(Hashtable) - start:");
//#ifdef MUJMAIL_DEVELOPMENT
//# dumpIDTable(idTable);
//#endif
}
// first of all find messages that can be removed (have no non-empty child)
// find all empty messages
final Vector/*<String>*/ emptyMessages = new Vector();
Enumeration/*<String>*/ keys = idTable.keys();
MessageHeader messageHeader;
String key;
while ( keys.hasMoreElements() ) {
key = (String)keys.nextElement();
messageHeader = (MessageHeader)((Vector)idTable.get( key )).elementAt( 0 );
if ( messageHeader.isEmpty() ) {
emptyMessages.addElement( key ); // key is threading message ID
}
}
// remove messages that are referenced
// find number of references for each message
keys = idTable.keys();
final Hashtable/*<String(messageID), Integer>*/ referenceCounts = new Hashtable( emptyMessages.size() );
Object o;
String parentMessageID;
int count;
while ( keys.hasMoreElements() ) {
key = (String)keys.nextElement();
messageHeader = (MessageHeader)((Vector)idTable.get( key )).elementAt( 0 );
parentMessageID = messageHeader.getParentID();
if ( ! "".equals( parentMessageID ) /*&& !emptyMessages.contains( messageHeader.getThreadingMessageID() )*/ ) {
if ( ! messageHeader.isEmpty() ) { // if there is non-empty message that reference to message
emptyMessages.removeElement( parentMessageID ); // remove message from empty messages
} else {
o = referenceCounts.get( parentMessageID );
if ( o == null ) {
referenceCounts.put( parentMessageID, new Integer(1) );
} else {
count = ((Integer)o).intValue() + 1;
referenceCounts.put( parentMessageID, new Integer(count) );
}
}
}
}
if (DEBUG) System.out.println("DEBUG Algorithm.removeEmptyMessages(Hashtable) - empty messages (before removing referenced): " + emptyMessages );
// empty messages that are referenced more than 2 times are removed from empty messages
String messageID;
for ( int i = emptyMessages.size() - 1; i >= 0; --i ) {
messageID = (String)emptyMessages.elementAt(i);
o = referenceCounts.get( messageID );
if ( o != null ) { // leaves have no references
count = ((Integer)o).intValue();
if ( count > 1) {
emptyMessages.removeElementAt( i );
}
}
}
if (DEBUG) System.out.println("DEBUG Algorithm.removeEmptyMessages(Hashtable) - empty messages: " + emptyMessages );
// finally remove empty messages that can be removed
keys = idTable.keys();
Vector messageHeaders;
int size;
while ( keys.hasMoreElements() ) {
key = (String)keys.nextElement();
messageHeaders = (Vector)idTable.get( key );
size = messageHeaders.size();
for ( int i = 0; i < size; ++i ) {
messageHeader = (MessageHeader)messageHeaders.elementAt( i );
parentMessageID = messageHeader.getParentID();
while ( emptyMessages.contains( parentMessageID ) ) {
parentMessageID = ((MessageHeader)((Vector)idTable.get( parentMessageID )).elementAt( 0 ) ).getParentID();
}
messageHeader.setParentID( parentMessageID );
}
}
for ( int i = 0; i < emptyMessages.size(); ++i) {
idTable.remove( emptyMessages.elementAt( i ) );
}
if (DEBUG) {
System.out.println("DEBUG Algorithm.removeEmptyMessages(Hashtable) - end:");
//#ifdef MUJMAIL_DEVELOPMENT
//# dumpIDTable(idTable);
//#endif
}
}
//#ifdef MUJMAIL_DEVELOPMENT
//# public void dumpIDTable( final Hashtable/*<String, Vector<MessageHeader> >*/ idTable) {
//# if (!DEBUG) {
//# return;
//# } else {
//# System.out.println("DEBUG Algorithm.dumpIDTable()");
//# final Enumeration keys = idTable.keys();
//# String key;
//# MessageHeader messageHeader;
//# Vector/*MessageHeader*/ messageHeaderVector;
//# int messageHeaderVectorSize;
//# while ( keys.hasMoreElements() ) {
//# key = (String)keys.nextElement();
//# messageHeaderVector = (Vector)idTable.get( key );
//# messageHeaderVectorSize = messageHeaderVector.size();
//# for (int i = 0; i < messageHeaderVectorSize; ++i) {
//# messageHeader = (MessageHeader)messageHeaderVector.elementAt( i );
//# System.out.println(" key: " + key + "\n value: " + messageHeader.toString());
//# }
//# }
//# }
//# }
//#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -