📄 threadedemails.java
字号:
return messageHeader;
}
/**
* Removes all messages from structure.
*/
public void removeAllMessages() {
children.clear();
parents.clear();
rootMessages.removeAllElements();
size = 0;
}
/**
* <p>Removes message at the i-th position.</p>
* <p>
* Note: This structure is not designed to add/remove messages one by one.
* This method is a little bit more difficult than just removing message
* from {@link Vector}. Message have to be removed first and than
* messages in structure have to be resorted (new threads created).
* </p>
*/
public void removeMessageAt(final int index) {
if (DEBUG) { System.out.println("DEBUG ThreadedEmails.removeMessageAt(int index="+ index + ")"); }
final Enumeration messages = getEnumeration();
final Vector remainingMessages = new Vector();
MessageHeader messageHeader;
int i = 0;
while ( messages.hasMoreElements() ) {
messageHeader = (MessageHeader)messages.nextElement();
if ( i != index ) {
remainingMessages.addElement( messageHeader );
} else {
if (DEBUG) { System.out.println("DEBUG ThreadedEmails.removeMessageAt removing MH=" + messageHeader); }
}
++i;
}
createNewStructure(remainingMessages);
}
/**
* <p>Removes message equal to passed message.</p>
* <p>
* Note: This structure is not designed to add/remove messages one by one.
* This method is a little bit more difficult than just removing message
* from {@link Vector}. Message have to be removed first and than
* messages in structure have to be resorted (new threads created).
* </p>
*/
public void removeMessage(final MessageHeader messageToRemove) {
if (DEBUG) System.out.println("DEBUG ThreadedEmails.removeMessage(MessageHeader=" + messageToRemove + ")");
final Enumeration messages = getEnumeration();
final Vector remainingMessages = new Vector();
MessageHeader messageHeader;
while ( messages.hasMoreElements() ) {
messageHeader = (MessageHeader)messages.nextElement();
if ( messageToRemove.equals( messageHeader ) ) {
continue;
}
remainingMessages.addElement(messageHeader);
}
createNewStructure(remainingMessages);
if (DEBUG) System.out.println("removeMessage(MessageHeader) - end");
}
/**
* Method recreates structure from passed messages.
*
* @param messages messages to build this structure from
*/
private void createNewStructure(final Vector messages) {
ThreadedEmails newStructure = Algorithm.getAlgorithm().invoke( messages );
this.rootMessages = newStructure.rootMessages;
this.children = newStructure.children;
this.parents = newStructure.parents;
this.size = newStructure.size;
}
/**
* <p>Adds message to structure.</p>
*
* <p>
* Note: This structure is not designed to add/remove messages one by one.
* This method is a little bit more difficult than just adding message
* to {@link Vector}. Message have to be added first and than
* messages in structure have to be resorted (new threads created).
* </p>
*/
public void addMessage(final MessageHeader newMessageHeader) {
if ( newMessageHeader.getThreadingMessageID() == null ) {
throw new IllegalArgumentException( "message have to have threading ID set" );
}
final Enumeration messages = getEnumeration();
final Vector newMessages = new Vector();
MessageHeader messageHeader;
while ( messages.hasMoreElements() ) {
messageHeader = (MessageHeader)messages.nextElement();
newMessages.addElement( messageHeader );
}
newMessages.addElement( newMessageHeader );
createNewStructure( newMessages );
}
public void sort(Comparator comparator) {
if (DEBUG) {
//#ifdef MUJMAIL_DEVELOPMENT
//# printToConsole();
//#endif
System.out.println("comparator: " + comparator);
System.out.println("sorting rootMessages...");
}
Functions.sort(rootMessages, comparator);
MessageHeader messageHeader;
//Vector/*<MessageHeader>*/ childMessages;
for ( int i = 0; i < rootMessages.size(); ++i ) {
messageHeader = (MessageHeader)rootMessages.elementAt( i );
sortChildren( (Vector)children.get( messageHeader.getThreadingMessageID() ), comparator );
}
}
private void sortChildren( Vector v, Comparator c ) {
if ( v == null ) {
return;
}
Functions.sort(v, c);
for ( int i = 0; i < v.size(); ++i ) {
sortChildren( (Vector)children.get( v.elementAt(i) ), c);
}
}
public boolean isRootMessage(final MessageHeader messageHeader) {
return rootMessages.contains( messageHeader );
}
/**
* Returns level of the message in message tree.
*
* @param messageThreadingID threading message ID for which find the level
* @return level n which the message is stored in tree
*/
public int getLevel(final String messageThreadingID ) {
int level = 0;
String childMessageThreadingID = messageThreadingID;
MessageHeader parentMessage = (MessageHeader)parents.get( childMessageThreadingID );
while ( parentMessage != null ) {
// if there is parent increment level
++level;
// find grant parent - parent of previous parent message
parentMessage = (MessageHeader)parents.get( parentMessage.getThreadingMessageID() );
}
return level;
}
public boolean hasChildren(final MessageHeader messageHeader) {
if ( !isRootMessage(messageHeader) ) {
return false;
}
Object o = children.get( messageHeader.getThreadingMessageID() );
if (o instanceof Vector) {
Vector v = (Vector)o;
return !v.isEmpty();
} else {
if (DEBUG) { System.out.println( "DEBUG ThreadedEmails.hasChildren(MessageHeader) " + o.getClass() ); } // TODO: remove
}
return false;
}
/**
* Returns number of empty root messages.
* In ThreadedEmails structure only root messages can be empty. This method
* iterate over these headers and return number of the empy ones.
*
* @return number of empty root messages
*/
public int getEmptyRootsNumber() {
int result = 0;
final int rootMessagesCount = rootMessages.size();
for ( int i = 0; i < rootMessagesCount; ++i) {
if ( ((MessageHeader)rootMessages.elementAt( i )).isEmpty() ) {
++result;
}
}
return result;
}
/**
* When empty message have child which is empty, it moves children
* of this child to the empty parent message.<br>
* Example:
* <pre>
* --1 (empty)
* \--10 (empty)
* |--A (not empty)
* \--B (not empty)
* </pre>
* Result should be:
* <pre>
* --1
* |--A
* \--B
* </pre>
* At the end it removes all empty root messages without no children.
*/
public void removeUnnecessaryEmptyMessages() {
if ( DEBUG ) {
System.out.println( "DEBUG ThreadedEmails.removeUnnecessaryEmptyMessages()" );
//#ifdef MUJMAIL_DEVELOPMENT
//# printToConsole();
//#endif
}
final int rootsCount = rootMessages.size();
MessageHeader messageHeader;
Vector childVector;
for (int i = 0; i < rootsCount; ++i ) {
messageHeader = (MessageHeader)rootMessages.elementAt( i );
childVector = (Vector)children.get( messageHeader.getThreadingMessageID() );
removeEmptyMessages( childVector );
}
for ( int i = rootsCount - 1; i >= 0; --i ) {
messageHeader = (MessageHeader)rootMessages.elementAt( i );
if ( messageHeader.isEmpty() ) {
childVector = (Vector)children.get( messageHeader.getThreadingMessageID() );
if ( childVector == null || childVector.size() == 0 ) {
rootMessages.removeElementAt( i );
--size;
}
if ( childVector != null && childVector.size() == 1 ) {
children.remove( messageHeader.getThreadingMessageID() );
rootMessages.removeElementAt( i );
MessageHeader child = (MessageHeader)childVector.elementAt( 0 );
child.setParentID(null);
parents.remove( child.getThreadingMessageID() );
rootMessages.addElement( child );
--size;
}
}
}
}
private void removeEmptyMessages(final Vector messages) {
if ( messages == null ) {
return;
}
final int vectorSize = messages.size();
MessageHeader messageHeader;
MessageHeader messageParent;
Vector childVector;
for ( int i = vectorSize - 1; i >= 0; --i ) {
messageHeader = (MessageHeader)messages.elementAt( i );
messageParent = (MessageHeader)parents.get( messageHeader.getThreadingMessageID() );
childVector = (Vector)children.get( messageHeader.getThreadingMessageID() );
removeEmptyMessages( childVector );
if ( messageHeader.isEmpty() ) {
final int childCount = (childVector == null)?0:childVector.size();
MessageHeader child;
for ( int j = childCount - 1; j >= 0; --j ) {
child = (MessageHeader)childVector.elementAt(j); // child vector cannot be null here because size is greater than zero
childVector.removeElement( child );
child.setParentID( messageHeader.getParentID() );
parents.put( child.getThreadingMessageID(), messageParent );
messages.addElement( child );
}
children.remove( messageHeader.getThreadingMessageID() );
parents.remove( messageHeader.getThreadingMessageID() );
messages.removeElementAt( i );
--size;
}
}
}
//#ifdef MUJMAIL_DEVELOPMENT
//# public void printToConsole() {
//# if (!DEBUG) return;
//# System.out.println("ThreadedEmails.printConsole()");
//# System.out.println("size: " + size );
//# System.out.println("=== alternative ===");
//# Enumeration enumeration = this.getEnumeration();
//# while ( enumeration.hasMoreElements() ) {
//# MessageHeader mh = (MessageHeader)enumeration.nextElement();
//# System.out.println( "msg: " + mh.toString() );
//# }
//# }
//#endif
/* *******************
* inner class *
*********************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -