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

📄 threadedemails.java

📁 手机邮箱撒的方式方式方式的
💻 JAVA
📖 第 1 页 / 共 3 页
字号:

    /* *
     * Constant represents that message at this "position" is root message.
     * 
     * @see Enumerator#actualRootChild
     */
//    private static final int ROOT_MESSAGE = -1;

    /**
     * Class enables iterating over the structure.
     * There are two indexes:<ul>
     * <li>root index - index to the root messages vector</li>
     * <li>child index - index to the vector of children for root message</li>
     * </ul>
     * When child index is {@link ThreadedEmails#ROOT_MESSAGE}, that means that
     * the message to retrieve is the one from root message vector.
     * When root index is size of root messages vector, taht means that we are
     * at the end of all messages (there are no more elements).
     * 
     * @author Betlista
     */
    //#ifdef MUJMAIL_TEST_BACKWARD_ITERATING
//#     public
    //#else
       private
    //#endif
    class Enumerator implements Enumeration {

        /**
         * <p>
         * Index of next message, used for simple implementation
         * of {@link #hasMoreElements()} method.
         * </p>
         * <p>
         * When index value is for example 3 that means that next message will
         * be returned the 4th message in structure (index starts with 0).
         * </p>
         */
        private int index;

        /**
         * Reference to actual message.
         */
        private MessageHeader actual;

        /**
         * Idea of this enumeration is that it points to next element, this is
         * the invariant.
         */
        public Enumerator() {
            index = 0;
            actual = null;
        }

        /**
         * Returns <code>true</code> if there are more elements.
         * 
         * @return <code>true</code> if there are more elements in enumeration,
         *         <code>false</code> otherwise
         */
        public boolean hasMoreElements() {
            return index < size;
        }

        /**
         * Method is just synonym for {@link #hasMoreElements()} method.
         */
        //#ifdef MUJMAIL_TEST_BACKWARD_ITERATING
//#         public
        //#else
       private
        //#endif
        boolean hasNextElement() {
            return hasMoreElements();
        }

        /**
         * Returns next element in enumeration.
         * 
         * @return MessageHeader next message
         * @throws NoSuchElementException if there are no more elements.
         * @see #hasMoreElements()
         */
        public Object nextElement() throws NoSuchElementException {
            if ( !hasNextElement() ) {
                throw new NoSuchElementException();
            }
            MessageHeader messageHeader = null;
            
            if ( actual == null ) {
                messageHeader = (MessageHeader)rootMessages.elementAt( 0 );
            } else {
                boolean actualChanged = false;
                while ( messageHeader == null ) {
                    if ( !actualChanged ) {
                        messageHeader = getFirstChild();
                    }

                    if ( messageHeader == null ) {
                        messageHeader = getSibling(true);
                    }

                    if ( messageHeader == null ) {
                          // actual cannot be null here
                          // setting of
                        actual = (MessageHeader)parents.get( actual.getThreadingMessageID() );
                        actualChanged = true;
                        messageHeader = getSibling(true);
                    }
                }
            }

            actual = messageHeader;
            ++index;
            return messageHeader;
        }

        //#ifdef MUJMAIL_TEST_BACKWARD_ITERATING
//#         public
        //#else
       private
        //#endif
        boolean hasPreviousElement() {
              /* If index is 0 that means that next returned message will be
               * the 1st message, so there was no message returned yet and
               * that why it has no previous message. 
               * 
               * If index is 1 the actual message is the 1st one and it has
               * no previous message too.
               */
            return index > 1;
        }

        /**
         * Returns the previous message for actual one.
         *  
         * @return previous message for actual ones
         */
        //#ifdef MUJMAIL_TEST_BACKWARD_ITERATING
//#         public
        //#else
       private
        //#endif
        Object previousElement() {
            if ( !hasPreviousElement() ) {
                throw new NoSuchElementException();
            }
            MessageHeader messageHeader = null;

              /* First of all we need to retrieve the last child message
               * of the previous sibling tree.
               * Example:
               * --root
               *   |--1
               *   |  |--2
               *   |  \--3
               *   |     |--4
               *   |     \--5 <- previous
               *   \--6       <- actual
               * If actual message is 6, than previous message is 5
               * => previous sibling of 6 is 1 and last child is 5
               */
            MessageHeader parent = (MessageHeader)parents.get( actual.getThreadingMessageID() );
            if ( parent == null ) {
                MessageHeader sibling = getSibling( false );
                MessageHeader lastChild = getLastChild( sibling.getThreadingMessageID() );
                if ( lastChild == null ) {
                    messageHeader = sibling;
                } else {
                    messageHeader = lastChild;
                }
            } else {
                Vector childVector = (Vector)children.get( parent.getThreadingMessageID() );
                if ( childVector != null ) {
                    final int index = childVector.indexOf( actual );
                    if ( index > 0 ) {
                        MessageHeader previousSibling = (MessageHeader)childVector.elementAt( index - 1 );
                        MessageHeader lastChild = getLastChild( previousSibling.getThreadingMessageID() );
                        if ( lastChild == null ) {
                            messageHeader = previousSibling;
                        } else {
                            messageHeader = lastChild;
                        }
                    } else {
                        messageHeader = parent;
                    }
                }
            }

            actual = messageHeader;
            --index;
            return messageHeader;
        }

        /**
         * Method returns last child of the subtree with message identified
         * by rootThreadingID as root of this subtree.
         *  
         * @param rootThreadingID identification of the message that represents
         *        subtree root
         * @return last child of subtree or null if root message have no child.
         */
        private MessageHeader getLastChild( final String rootThreadingID ) {
            MessageHeader lastChild = null;

            Vector childVector = (Vector)children.get( rootThreadingID );
            if ( childVector != null ) {
                lastChild = (MessageHeader)childVector.elementAt( childVector.size() - 1 );
                MessageHeader newLastChild = getLastChild( lastChild.getThreadingMessageID() );
                if ( newLastChild != null ) {
                    lastChild = newLastChild;
                }
            }
            return lastChild;
        }

        /**
         * Returns first child for actual message.<br>
         * Example:
         * <pre>
         * -- Msg1
         *    |-- Msg3
         *    \-- Msg4
         * -- Msg2
         * </pre>
         * For Msg1 returns Msg3, for other message in this example returns null.
         * 
         * @return first child for actual message or null
         */
        private MessageHeader getFirstChild() {
            Object o = children.get( actual.getThreadingMessageID() );
            if ( o == null ) {
                return null;
            }
            Vector childVector = (Vector)o;
            return (MessageHeader)childVector.elementAt( 0 );
        }

        /**
         * Returns sibling for actual message.
         * Example:
         * <pre>
         * -- Msg1
         *    |-- Msg3
         *    \-- Msg4
         * -- Msg2
         * </pre>
         * For Msg1 returns Msg2, for Msg3 returns Msg4, for all other messages
         * returns null (have no sibling).
         * 
         * @param next specifies if we want next (<code>true</code>) sibling
         *        or the previous one (<code>false</code>)
         * @return sibling for actual message or null
         */
        private MessageHeader getSibling( final boolean next ) {
            final int shift = next?1:-1;
            final MessageHeader messageHeader;
              // get parent
            final String actualMessageID = actual.getThreadingMessageID();
            final int index;
            MessageHeader parentMessage = (MessageHeader)parents.get( actualMessageID );
            if ( parentMessage == null ) {
                  // have no parent, get next root message or first child (if some exist)
                index = rootMessages.indexOf( actual );
                  // how we know that there is such message?
                  //   it's simple: this method is called only from nextElement()
                  //   or previousElement() methods, so there was check if such
                  //   element exist
                messageHeader = (MessageHeader)rootMessages.elementAt( index + shift );
            } else {
                  // in this case we are not operating with root messages,
                  //   so there is no guarantee that sibling exists

                  // child vector cannot be null here, because actual message
                  //   is one of the children
                Vector childVector = (Vector)children.get( parentMessage.getThreadingMessageID() );
                index = childVector.indexOf( actual );
                if ( next && index == childVector.size() - 1 ) {
                      // when we want next message, but actual is last one
                      //   in child vector so there is no sibling
                    messageHeader = null;
                } else if ( !next && index == 0 ) {
                      // when we want previous message, but actual is first one
                      //   in child vector so there is no sibling
                    messageHeader = null;
                } else {
                    messageHeader = (MessageHeader)childVector.elementAt( index + shift );
                }
            }
            return messageHeader;
        }
    }
}

⌨️ 快捷键说明

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