Changeset 529


Ignore:
Timestamp:
11/08/09 12:41:11 (2 years ago)
Author:
octorian
Message:

Initial implementation of basic offline message cache and folder sync.

Location:
trunk/LogicMail/src/org/logicprobe/LogicMail
Files:
1 added
19 edited

Legend:

Unmodified
Added
Removed
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/AbstractMailStore.java

    r496 r529  
    154154    /** 
    155155     * Requests the message listing from a particular folder. 
     156     * All message tokens must refer to messages that exist within the provided 
     157     * folder item, or the results may be unexpected. 
    156158     *  
    157159     * <p>Successful completion is indicated by a call to 
     
    159161     *  
    160162     * @param folder The folder to request a message listing for. 
    161      * @param indices The set of indices for the messages to get headers for. 
    162      */ 
    163     public abstract void requestFolderMessagesSet(FolderTreeItem folder, int[] indices); 
     163     * @param messageTokens The set of tokens for the messages to get headers for. 
     164     */ 
     165    public abstract void requestFolderMessagesSet(FolderTreeItem folder, MessageToken[] messageTokens); 
    164166     
    165167    /** 
    166168     * Requests the recent message listing from a particular folder. 
    167169     *  
    168      * <p>Successful completion is indicated by a call to 
     170     * <p> 
     171     * Successful completion is indicated by a call to 
    169172     * {@link FolderListener#folderMessagesAvailable(FolderMessagesEvent)}. 
     173     * If <tt>flagsOnly</tt> is set to <b>true</b>, then the envelope and 
     174     * structure fields of the returned <tt>FolderMessage</tt> objects 
     175     * will be set to <b>null</b>. 
     176     * </p> 
    170177     *  
    171178     * @param folder The folder to request a message listing for. 
    172      */ 
    173     public abstract void requestFolderMessagesRecent(FolderTreeItem folder); 
     179     * @param flagsOnly If true, only tokens and flags will be fetched 
     180     */ 
     181    public abstract void requestFolderMessagesRecent(FolderTreeItem folder, boolean flagsOnly); 
     182     
     183    /** 
     184     * Requests the recent message listing from a particular folder. 
     185     *  
     186     * <p>Successful completion is indicated by a call to 
     187     * {@link FolderListener#folderMessagesAvailable(FolderMessagesEvent)}. 
     188     *  
     189     * @param folder The folder to request a message listing for. 
     190     */ 
     191    public void requestFolderMessagesRecent(FolderTreeItem folder) { 
     192        requestFolderMessagesRecent(folder, false); 
     193    } 
    174194     
    175195    /** 
     
    404424     * @param folder The folder which has available messages 
    405425     * @param messages The messages that are now available 
    406      */ 
    407     protected void fireFolderMessagesAvailable(FolderTreeItem folder, FolderMessage[] messages) { 
     426     * @param flagsOnly True if the message data only includes flags 
     427     */ 
     428    protected void fireFolderMessagesAvailable(FolderTreeItem folder, FolderMessage[] messages, boolean flagsOnly) { 
    408429        Object[] listeners = listenerList.getListeners(FolderListener.class); 
    409430        FolderMessagesEvent e = null; 
    410431        for(int i=0; i<listeners.length; i++) { 
    411432            if(e == null) { 
    412                 e = new FolderMessagesEvent(this, folder, messages); 
     433                e = new FolderMessagesEvent(this, folder, messages, flagsOnly); 
    413434            } 
    414435            ((FolderListener)listeners[i]).folderMessagesAvailable(e); 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/FolderMessagesEvent.java

    r220 r529  
    3636public class FolderMessagesEvent extends FolderEvent { 
    3737        private FolderMessage[] messages; 
     38        private boolean flagsOnly; 
    3839         
    39         public FolderMessagesEvent(Object source, FolderTreeItem folder, FolderMessage[] messages) { 
     40        public FolderMessagesEvent(Object source, FolderTreeItem folder, FolderMessage[] messages, boolean flagsOnly) { 
    4041                super(source, folder); 
    4142                this.messages = messages; 
     43                this.flagsOnly = flagsOnly; 
    4244        } 
    4345 
     46        public FolderMessagesEvent(Object source, FolderTreeItem folder, FolderMessage[] messages) { 
     47                this(source, folder, messages, false); 
     48        } 
     49         
    4450        /** 
    4551         * Gets the folder messages that have been made available 
     
    5157                return messages; 
    5258        } 
     59         
     60        /** 
     61         * Checks if the newly available folder messages contain only 
     62         * flag information. 
     63         *  
     64         * @return true, if updated messages are flags only 
     65         */ 
     66        public boolean isFlagsOnly() { 
     67                return flagsOnly; 
     68        } 
    5369} 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/IncomingMailClient.java

    r496 r529  
    201201     
    202202    /** 
     203     * Get a list of the messages in the selected folder 
     204     * which match the provided tokens. 
     205     *  
     206     * @param messageTokens Tokens of the messages 
     207     * @param progressHandler the progress handler 
     208     * @return List of message envelopes 
     209     *  
     210     * @throws IOException on I/O errors 
     211     * @throws MailException on protocol errors 
     212     */ 
     213    FolderMessage[] getFolderMessages(MessageToken[] messageTokens, MailProgressHandler progressHandler) 
     214        throws IOException, MailException; 
     215     
     216    /** 
    203217     * Get a list of new messages in the selected folder. 
    204218     * <p> 
     
    211225     * </p> 
    212226     *  
    213      * @param progressHandler the progress handler 
     227     * @param flagsOnly If true, only tokens and flags will be fetched 
     228     * @param progressHandler the progress handler 
     229     *  
    214230     * @return List of message envelopes 
    215231     *  
     
    217233     * @throws MailException on protocol errors 
    218234     */ 
    219     FolderMessage[] getNewFolderMessages(MailProgressHandler progressHandler) throws IOException, MailException; 
     235    FolderMessage[] getNewFolderMessages(boolean flagsOnly, MailProgressHandler progressHandler) throws IOException, MailException; 
    220236     
    221237    /** 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/IncomingMailConnectionHandler.java

    r496 r529  
    3535import java.util.Vector; 
    3636 
    37 import net.rim.device.api.system.UnsupportedOperationException; 
    38  
    3937import org.logicprobe.LogicMail.LogicMailResource; 
    4038import org.logicprobe.LogicMail.message.FolderMessage; 
     
    105103                        handleRequestFolderMessagesSet( 
    106104                                        (FolderTreeItem)params[0], 
    107                                         (int[])params[1]); 
     105                                        (MessageToken[])params[1]); 
    108106                        break; 
    109107                case REQUEST_FOLDER_MESSAGES_RECENT: 
    110108                        handleRequestFolderMessagesRecent( 
    111                                         (FolderTreeItem)params[0]); 
     109                                        (FolderTreeItem)params[0], ((Boolean)params[1]).booleanValue()); 
    112110                        break; 
    113111                case REQUEST_MESSAGE: 
     
    238236        } 
    239237         
    240         private void handleRequestFolderMessagesSet(FolderTreeItem folder, int[] indices) throws IOException, MailException { 
    241                 throw new UnsupportedOperationException("Not yet implemented"); 
    242 //              checkActiveFolder(folder); 
    243 //               
    244 //              FolderMessage[] messages = incomingClient.getFolderMessages(firstIndex, lastIndex); 
    245 //               
    246 //              MailConnectionHandlerListener listener = getListener(); 
    247 //              if(messages != null && messages.length > 0 && listener != null) { 
    248 //                      listener.mailConnectionRequestComplete(REQUEST_FOLDER_MESSAGES_SET, new Object[] { folder, messages }); 
    249 //              } 
    250         } 
    251          
    252         private void handleRequestFolderMessagesRecent(FolderTreeItem folder) throws IOException, MailException { 
     238        private void handleRequestFolderMessagesSet(FolderTreeItem folder, MessageToken[] messageTokens) throws IOException, MailException { 
     239                String message = resources.getString(LogicMailResource.MAILCONNECTION_REQUEST_FOLDER_MESSAGES); 
     240                showStatus(message + "..."); 
     241                checkActiveFolder(folder); 
     242                 
     243                FolderMessage[] messages = incomingClient.getFolderMessages(messageTokens, getProgressHandler(message)); 
     244                 
     245                MailConnectionHandlerListener listener = getListener(); 
     246                if(messages != null && messages.length > 0 && listener != null) { 
     247                        listener.mailConnectionRequestComplete(REQUEST_FOLDER_MESSAGES_SET, new Object[] { folder, messages }); 
     248                } 
     249        } 
     250         
     251        private void handleRequestFolderMessagesRecent(FolderTreeItem folder, boolean flagsOnly) throws IOException, MailException { 
    253252                String message = resources.getString(LogicMailResource.MAILCONNECTION_REQUEST_FOLDER_MESSAGES); 
    254253                showStatus(message + "..."); 
    255254                checkActiveFolder(folder); 
    256255         
    257                 FolderMessage[] messages = incomingClient.getNewFolderMessages(getProgressHandler(message)); 
     256                FolderMessage[] messages = incomingClient.getNewFolderMessages(flagsOnly, getProgressHandler(message)); 
    258257                 
    259258                MailConnectionHandlerListener listener = getListener(); 
    260259                if(messages != null && messages.length > 0 && listener != null) { 
    261                         listener.mailConnectionRequestComplete(REQUEST_FOLDER_MESSAGES_RECENT, new Object[] { folder, messages }); 
     260                        listener.mailConnectionRequestComplete(REQUEST_FOLDER_MESSAGES_RECENT, new Object[] { folder, messages, new Boolean(flagsOnly) }); 
    262261                } 
    263262        } 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/LocalMailStore.java

    r496 r529  
    3939import javax.microedition.io.file.FileConnection; 
    4040 
     41import net.rim.device.api.system.UnsupportedOperationException; 
     42 
    4143import org.logicprobe.LogicMail.conf.MailSettings; 
    4244import org.logicprobe.LogicMail.message.FolderMessage; 
     
    138140 
    139141    public void requestFolderMessagesRange(FolderTreeItem folder, int firstIndex, int lastIndex) { 
    140         // TODO Auto-generated method stub 
    141     } 
    142  
    143     public void requestFolderMessagesSet(FolderTreeItem folder, int[] indices) { 
    144         // TODO Auto-generated method stub 
    145     } 
    146  
    147     public void requestFolderMessagesRecent(FolderTreeItem folder) { 
     142        throw new UnsupportedOperationException("Not yet implemented"); 
     143        } 
     144 
     145        public void requestFolderMessagesSet(FolderTreeItem folder, MessageToken[] messageTokens) { 
     146                throw new UnsupportedOperationException("Not yet implemented"); 
     147        } 
     148 
     149    public void requestFolderMessagesRecent(FolderTreeItem folder, boolean flagsOnly) { 
     150        // The flagsOnly parameter has no effect on local mail stores, 
     151        // and it is not likely to ever be called on them anyways. 
    148152        FolderTreeItem requestFolder = getMatchingFolderTreeItem(folder.getPath()); 
    149153         
     
    169173                 
    170174                if(folderMessages != null) { 
    171                         fireFolderMessagesAvailable(requestFolder, folderMessages); 
     175                        fireFolderMessagesAvailable(requestFolder, folderMessages, false); 
    172176                } 
    173177                } 
     
    224228     
    225229    public void requestMessageDelete(MessageToken messageToken, MessageFlags messageFlags) { 
    226         // TODO Auto-generated method stub 
     230        throw new UnsupportedOperationException("Not yet implemented"); 
    227231    } 
    228232 
    229233    public void requestMessageUndelete(MessageToken messageToken, MessageFlags messageFlags) { 
    230         // TODO Auto-generated method stub 
     234        throw new UnsupportedOperationException("Not yet implemented"); 
    231235    } 
    232236 
    233237    public void requestMessageAnswered(MessageToken messageToken, MessageFlags messageFlags) { 
    234         // TODO Auto-generated method stub 
     238        throw new UnsupportedOperationException("Not yet implemented"); 
    235239    } 
    236240 
     
    264268                 
    265269                if(folderMessage != null) { 
    266                         fireFolderMessagesAvailable(requestFolder, new FolderMessage[] { folderMessage }); 
     270                        fireFolderMessagesAvailable(requestFolder, new FolderMessage[] { folderMessage }, false); 
    267271                } 
    268272                } 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/LocalMessageToken.java

    r518 r529  
    9090     * @return Unique ID. 
    9191     */ 
    92     String getMessageUid() { 
     92    public String getMessageUid() { 
    9393        return this.messageUid; 
    9494    } 
     
    145145                return hashCode; 
    146146        } 
     147         
     148        /* (non-Javadoc) 
     149         * @see java.lang.Object#toString() 
     150         */ 
     151        public String toString() { 
     152                StringBuffer buf = new StringBuffer(); 
     153                buf.append("LocalMessageToken ["); 
     154                buf.append("uniqueId="); buf.append(uniqueId); 
     155                buf.append(", folderPath=\""); buf.append(folderPath); buf.append("\""); 
     156                buf.append(", messageUid=\""); buf.append(messageUid); buf.append("\""); 
     157                buf.append("]"); 
     158                return buf.toString(); 
     159        } 
    147160} 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/MessageToken.java

    r407 r529  
    4747public interface MessageToken extends Serializable { 
    4848        /** 
     49         * Gets the message UID, which is a protocol-specific way of uniquely 
     50         * identifying a message within its mailbox.  This is different from 
     51         * the {@link Serializable#getUniqueId()}, as it is a <tt>String</tt> 
     52         * identifier known to the mail protocol and does not have to be 
     53         * unique beyond the mailbox. 
     54         *  
     55         * @return the message UID 
     56         */ 
     57        String getMessageUid();  
     58         
     59        /** 
    4960         * Returns whether this token represents a message contained within 
    5061         * the specified mail folder. 
     
    5364         * @return True if contained, false otherwise 
    5465         */ 
    55         public abstract boolean containedWithin(FolderTreeItem folderTreeItem); 
     66        boolean containedWithin(FolderTreeItem folderTreeItem); 
    5667} 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/NetworkMailStore.java

    r496 r529  
    128128        } 
    129129 
    130         public void requestFolderMessagesSet(FolderTreeItem folder, int[] indices) { 
    131                 throw new UnsupportedOperationException("Not yet implemented"); 
    132         } 
    133          
    134         public void requestFolderMessagesRecent(FolderTreeItem folder) { 
     130        public void requestFolderMessagesSet(FolderTreeItem folder, MessageToken[] messageTokens) { 
     131                connectionHandler.addRequest( 
     132                                IncomingMailConnectionHandler.REQUEST_FOLDER_MESSAGES_SET, 
     133                                new Object[] { folder, messageTokens }); 
     134        } 
     135         
     136        public void requestFolderMessagesRecent(FolderTreeItem folder, boolean flagsOnly) { 
    135137                connectionHandler.addRequest( 
    136138                                IncomingMailConnectionHandler.REQUEST_FOLDER_MESSAGES_RECENT, 
    137                                 new Object[] { folder }); 
     139                                new Object[] { folder, new Boolean(flagsOnly) }); 
    138140        } 
    139141         
     
    192194                case IncomingMailConnectionHandler.REQUEST_FOLDER_MESSAGES_RANGE: 
    193195                case IncomingMailConnectionHandler.REQUEST_FOLDER_MESSAGES_SET: 
     196                        results = (Object[])result; 
     197                        fireFolderMessagesAvailable((FolderTreeItem)results[0], (FolderMessage[])results[1], false); 
     198                        break; 
    194199                case IncomingMailConnectionHandler.REQUEST_FOLDER_MESSAGES_RECENT: 
    195200                        results = (Object[])result; 
    196                         fireFolderMessagesAvailable((FolderTreeItem)results[0], (FolderMessage[])results[1]); 
     201                        fireFolderMessagesAvailable((FolderTreeItem)results[0], (FolderMessage[])results[1], ((Boolean)results[2]).booleanValue()); 
    197202                        break; 
    198203                case IncomingMailConnectionHandler.REQUEST_MESSAGE: 
     
    218223                case IncomingMailConnectionHandler.REQUEST_MESSAGE_APPEND: 
    219224                        results = (Object[])result; 
    220                         fireFolderMessagesAvailable((FolderTreeItem)results[0], (FolderMessage[])results[1]); 
     225                        fireFolderMessagesAvailable((FolderTreeItem)results[0], (FolderMessage[])results[1], false); 
    221226                        break; 
    222227                case IncomingMailConnectionHandler.REQUEST_MESSAGE_COPY: 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapClient.java

    r496 r529  
    585585     */ 
    586586    public FolderMessage[] getFolderMessages(int firstIndex, int lastIndex, MailProgressHandler progressHandler) throws IOException, MailException { 
     587        return getFolderMessages(firstIndex, lastIndex, false, progressHandler); 
     588    } 
     589     
     590    private FolderMessage[] getFolderMessages(int firstIndex, int lastIndex, boolean flagsOnly, MailProgressHandler progressHandler) throws IOException, MailException { 
    587591        // Sanity check 
    588592        if(activeMailbox == null) { 
     
    595599        } 
    596600         
    597         ImapProtocol.FetchEnvelopeResponse[] response = 
     601        FolderMessage[] result; 
     602        if(flagsOnly) { 
     603            ImapProtocol.FetchFlagsResponse[] flagsResponse = 
     604                imapProtocol.executeFetchFlags(firstIndex, lastIndex, progressHandler); 
     605                result = prepareFolderMessagesFlags(flagsResponse); 
     606        } 
     607        else { 
     608            ImapProtocol.FetchEnvelopeResponse[] envResponse = 
    598609                imapProtocol.executeFetchEnvelope(firstIndex, lastIndex, progressHandler); 
     610                result = prepareFolderMessagesEnvelope(envResponse); 
     611        } 
    599612         
    600         return prepareFolderMessages(response); 
    601     } 
    602  
    603     /* (non-Javadoc) 
    604      * @see org.logicprobe.LogicMail.mail.IncomingMailClient#getNewFolderMessages(org.logicprobe.LogicMail.mail.MailProgressHandler) 
    605      */ 
    606     public FolderMessage[] getNewFolderMessages(MailProgressHandler progressHandler) throws IOException, MailException { 
     613        return result; 
     614    } 
     615 
     616        /* (non-Javadoc) 
     617         * @see org.logicprobe.LogicMail.mail.IncomingMailClient#getFolderMessages(org.logicprobe.LogicMail.mail.MessageToken[], org.logicprobe.LogicMail.mail.MailProgressHandler) 
     618         */ 
     619        public FolderMessage[] getFolderMessages(MessageToken[] messageTokens, MailProgressHandler progressHandler) 
     620                        throws IOException, MailException { 
     621                // TODO Auto-generated method stub 
     622        // Sanity check 
     623        if(activeMailbox == null) { 
     624                throw new MailException("Mailbox not selected"); 
     625        } 
     626 
     627        int[] uids = new int[messageTokens.length]; 
     628        for(int i=0; i<messageTokens.length; i++) { 
     629                uids[i] = ((ImapMessageToken)messageTokens[i]).getImapMessageUid(); 
     630        } 
     631        ImapProtocol.FetchEnvelopeResponse[] envResponse = 
     632            imapProtocol.executeFetchEnvelopeUid(uids, progressHandler); 
     633         
     634                return prepareFolderMessagesEnvelope(envResponse); 
     635        } 
     636 
     637    /* (non-Javadoc) 
     638     * @see org.logicprobe.LogicMail.mail.IncomingMailClient#getNewFolderMessages(boolean, org.logicprobe.LogicMail.mail.MailProgressHandler) 
     639     */ 
     640    public FolderMessage[] getNewFolderMessages(boolean flagsOnly, MailProgressHandler progressHandler) throws IOException, MailException { 
    607641        // Sanity check 
    608642        if(activeMailbox == null) { 
     
    615649                        int msgCount = activeMailbox.getMsgCount(); 
    616650                int firstIndex = Math.max(1, msgCount - count); 
    617                 result = getFolderMessages(firstIndex, activeMailbox.getMsgCount(), progressHandler); 
     651                result = getFolderMessages(firstIndex, activeMailbox.getMsgCount(), flagsOnly, progressHandler); 
    618652                seenMailboxes.put(activeMailbox, new Object()); 
    619653        } 
    620654        else { 
    621655                int uidNext = ((ImapProtocol.SelectResponse)knownMailboxes.get(activeMailbox)).uidNext; 
    622                 ImapProtocol.FetchEnvelopeResponse[] response = 
    623                         imapProtocol.executeFetchEnvelopeUid(uidNext, progressHandler); 
    624                 result = prepareFolderMessages(response); 
     656                if(flagsOnly) { 
     657                        ImapProtocol.FetchFlagsResponse[] flagsResponse = 
     658                                imapProtocol.executeFetchFlagsUid(uidNext, progressHandler); 
     659                        result = prepareFolderMessagesFlags(flagsResponse); 
     660                } 
     661                else { 
     662                        ImapProtocol.FetchEnvelopeResponse[] envResponse = 
     663                                imapProtocol.executeFetchEnvelopeUid(uidNext, progressHandler); 
     664                        result = prepareFolderMessagesEnvelope(envResponse); 
     665                } 
    625666                 
    626667                if(result.length > 0) { 
     
    632673    } 
    633674 
    634     private FolderMessage[] prepareFolderMessages(ImapProtocol.FetchEnvelopeResponse[] response) { 
     675    private FolderMessage[] prepareFolderMessagesEnvelope(ImapProtocol.FetchEnvelopeResponse[] response) { 
    635676        FolderMessage[] folderMessages = new FolderMessage[response.length]; 
    636677        for(int i=0;i<response.length;i++) { 
     
    652693    } 
    653694     
     695    private FolderMessage[] prepareFolderMessagesFlags(ImapProtocol.FetchFlagsResponse[] response) { 
     696        FolderMessage[] folderMessages = new FolderMessage[response.length]; 
     697        for(int i=0;i<response.length;i++) { 
     698            folderMessages[i] = new FolderMessage( 
     699                        new ImapMessageToken(activeMailbox.getPath(), response[i].uid), 
     700                        null, 
     701                        response[i].index, 
     702                        response[i].uid); 
     703            folderMessages[i].setSeen(response[i].flags.seen); 
     704            folderMessages[i].setAnswered(response[i].flags.answered); 
     705            folderMessages[i].setDeleted(response[i].flags.deleted); 
     706            folderMessages[i].setRecent(response[i].flags.recent); 
     707            folderMessages[i].setFlagged(response[i].flags.flagged); 
     708            folderMessages[i].setDraft(response[i].flags.draft); 
     709            folderMessages[i].setJunk(response[i].flags.junk); 
     710        } 
     711        return folderMessages; 
     712    } 
     713     
    654714    /* (non-Javadoc) 
    655715     * @see org.logicprobe.LogicMail.mail.IncomingMailClient#getMessage(org.logicprobe.LogicMail.mail.MessageToken, org.logicprobe.LogicMail.mail.MailProgressHandler) 
     
    661721        } 
    662722         
    663         ImapParser.MessageSection structure = getMessageStructure(imapMessageToken.getMessageUid()); 
     723        ImapParser.MessageSection structure = getMessageStructure(imapMessageToken.getImapMessageUid()); 
    664724        Hashtable contentMap = new Hashtable(); 
    665725        MimeMessagePart rootPart = 
    666             getMessagePart(contentMap, imapMessageToken.getMessageUid(), 
     726            getMessagePart(contentMap, imapMessageToken.getImapMessageUid(), 
    667727                           structure, accountConfig.getMaxMessageSize(), 
    668728                           progressHandler); 
     
    693753 
    694754         
    695         String data = getMessageBody(imapMessageToken.getMessageUid(), partAddress, progressHandler); 
     755        String data = getMessageBody(imapMessageToken.getImapMessageUid(), partAddress, progressHandler); 
    696756        MimeMessageContent content; 
    697757        try { 
     
    835895         
    836896        ImapProtocol.MessageFlags updatedFlags = 
    837             imapProtocol.executeStore(imapMessageToken.getMessageUid(), true, new String[] { "\\Deleted" }); 
     897            imapProtocol.executeStore(imapMessageToken.getImapMessageUid(), true, new String[] { "\\Deleted" }); 
    838898        refreshMessageFlags(updatedFlags, messageFlags); 
    839899    } 
     
    850910         
    851911        ImapProtocol.MessageFlags updatedFlags = 
    852             imapProtocol.executeStore(imapMessageToken.getMessageUid(), false, new String[] { "\\Deleted" }); 
     912            imapProtocol.executeStore(imapMessageToken.getImapMessageUid(), false, new String[] { "\\Deleted" }); 
    853913        refreshMessageFlags(updatedFlags, messageFlags); 
    854914    } 
     
    867927         
    868928        ImapProtocol.MessageFlags updatedFlags = 
    869             imapProtocol.executeStore(imapMessageToken.getMessageUid(), true, new String[] { "\\Answered" }); 
     929            imapProtocol.executeStore(imapMessageToken.getImapMessageUid(), true, new String[] { "\\Answered" }); 
    870930        refreshMessageFlags(updatedFlags, messageFlags); 
    871931    } 
     
    907967        } 
    908968         
    909         imapProtocol.executeCopy(imapMessageToken.getMessageUid(), destinationFolder.getPath()); 
     969        imapProtocol.executeCopy(imapMessageToken.getImapMessageUid(), destinationFolder.getPath()); 
    910970    } 
    911971     
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapMessageToken.java

    r518 r529  
    9292     * @return IMAP unique ID. 
    9393     */ 
    94     int getMessageUid() { 
     94    int getImapMessageUid() { 
    9595        return this.messageUid; 
     96    } 
     97     
     98    /* (non-Javadoc) 
     99     * @see org.logicprobe.LogicMail.mail.MessageToken#getMessageUid() 
     100     */ 
     101    public String getMessageUid() { 
     102        return Integer.toHexString(messageUid).toLowerCase(); 
    96103    } 
    97104     
     
    147154                return hashCode; 
    148155        } 
     156         
     157        /* (non-Javadoc) 
     158         * @see java.lang.Object#toString() 
     159         */ 
     160        public String toString() { 
     161                StringBuffer buf = new StringBuffer(); 
     162                buf.append("ImapMessageToken ["); 
     163                buf.append("uniqueId="); buf.append(uniqueId); 
     164                buf.append(", folderPath=\""); buf.append(folderPath); buf.append("\""); 
     165                buf.append(", messageUid="); buf.append(messageUid); 
     166                buf.append("]"); 
     167                return buf.toString(); 
     168        } 
    149169} 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapProtocol.java

    r496 r529  
    442442 
    443443    /** 
     444     * Execute the "FETCH (FLAGS UID)" command 
     445     * @param firstIndex Index of the first message 
     446     * @param lastIndex Index of the last message 
     447     * @param progressHandler the progress handler 
     448     * @return Array of FetchFlagsResponse objects 
     449     */ 
     450    public FetchFlagsResponse[] executeFetchFlags( 
     451                int firstIndex, 
     452            int lastIndex, 
     453            MailProgressHandler progressHandler) throws IOException, MailException { 
     454        if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
     455            EventLogger.logEvent(AppInfo.GUID, 
     456                ("ImapProtocol.executeFetchFlags(" + firstIndex + ", " + 
     457                lastIndex + ")").getBytes(), EventLogger.DEBUG_INFO); 
     458        } 
     459         
     460        String[] rawList = execute("FETCH", 
     461                Integer.toString(firstIndex) + ":" + 
     462                Integer.toString(lastIndex) + " (FLAGS UID)", progressHandler); 
     463         
     464        return prepareFetchFlagsResponse(rawList, progressHandler); 
     465    } 
     466 
     467    /** 
     468     * Execute the "UID FETCH (FLAGS UID)" command 
     469     * @param uidNext Unique ID of the next message 
     470     * @param progressHandler the progress handler 
     471     * @return Array of FetchFlagsResponse objects 
     472     */ 
     473    public FetchFlagsResponse[] executeFetchFlagsUid( 
     474                int uidNext, 
     475            MailProgressHandler progressHandler) throws IOException, MailException { 
     476        if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
     477            EventLogger.logEvent(AppInfo.GUID, 
     478                ("ImapProtocol.executeFetchFlagsUid(" + uidNext + ")").getBytes(), 
     479                EventLogger.DEBUG_INFO); 
     480        } 
     481         
     482        String[] rawList = execute("UID FETCH", 
     483                Integer.toString(uidNext) + ":*" + " (FLAGS UID)", progressHandler); 
     484         
     485        return prepareFetchFlagsResponse(rawList, progressHandler); 
     486    } 
     487     
     488    private FetchFlagsResponse[] prepareFetchFlagsResponse( 
     489            String[] rawList, MailProgressHandler progressHandler) throws IOException, MailException { 
     490 
     491        if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, -1); } 
     492        // Preprocess the returned text to clean up mid-field line breaks 
     493        // This should all become unnecessary once execute() 
     494        // becomes more intelligent in how it handles replies 
     495        Vector rawList2 = prepareCleanFetchResponse(rawList); 
     496 
     497        Vector flagResponses = new Vector(); 
     498        int size = rawList2.size(); 
     499 
     500        if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, size); } 
     501        for (int i = 0; i < size; i++) { 
     502            try { 
     503                String rawText = (String) rawList2.elementAt(i); 
     504 
     505                Vector parsedText = null; 
     506 
     507                try { 
     508                    parsedText = StringParser.nestedParenStringLexer(rawText.substring( 
     509                                rawText.indexOf('('))); 
     510                } catch (Exception exp) { 
     511                    parsedText = null; 
     512                } 
     513 
     514                FetchFlagsResponse flagRespItem = new FetchFlagsResponse(); 
     515                flagRespItem.flags = null; 
     516 
     517                // Iterate through results, locating and parsing the 
     518                // FLAGS and ENVELOPE sections in an order-independent way. 
     519                int parsedSize = parsedText.size(); 
     520 
     521                for (int j = 0; j < parsedSize; j++) { 
     522                    if (parsedText.elementAt(j) instanceof String) { 
     523                        if (((String)parsedText.elementAt(j)).equals("FLAGS") 
     524                                        && (parsedSize > (j + 1)) 
     525                                        && parsedText.elementAt(j + 1) instanceof Vector) { 
     526                            flagRespItem.flags = ImapParser.parseMessageFlags((Vector) parsedText.elementAt(j + 1)); 
     527                        } 
     528                        else if (((String)parsedText.elementAt(j)).equals("UID") 
     529                                        && (parsedSize > (j + 1)) 
     530                                        && parsedText.elementAt(j + 1) instanceof String) { 
     531                            try { 
     532                                flagRespItem.uid = Integer.parseInt((String) parsedText.elementAt(j + 1)); 
     533                            } catch (NumberFormatException e) { 
     534                                flagRespItem.uid = -1; 
     535                            } 
     536                        } 
     537                    } 
     538                } 
     539 
     540                if (flagRespItem.flags == null) { 
     541                    flagRespItem.flags = new MessageFlags(); 
     542                } 
     543 
     544                // Find the message index in the reply 
     545                int midx = Integer.parseInt(rawText.substring(rawText.indexOf( 
     546                                ' '), rawText.indexOf("FETCH") - 1).trim()); 
     547 
     548                flagRespItem.index = midx; 
     549                flagResponses.addElement(flagRespItem); 
     550            } catch (Exception exp) { 
     551                System.err.println("Parse error: " + exp); 
     552            } 
     553            if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, i, size); } 
     554        } 
     555 
     556        FetchFlagsResponse[] result = new FetchFlagsResponse[flagResponses.size()]; 
     557        flagResponses.copyInto(result); 
     558        if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, size, size); } 
     559 
     560        return result; 
     561    } 
     562     
     563    /** 
    444564     * Execute the "FETCH (FLAGS UID ENVELOPE BODYSTRUCTURE)" command 
    445565     * @param firstIndex Index of the first message 
    446566     * @param lastIndex Index of the last message 
     567     * @param progressHandler the progress handler 
    447568     * @return Array of FetchEnvelopeResponse objects 
    448569     */ 
    449     public FetchEnvelopeResponse[] executeFetchEnvelope(int firstIndex, 
    450         int lastIndex, MailProgressHandler progressHandler) throws IOException, MailException { 
     570    public FetchEnvelopeResponse[] executeFetchEnvelope( 
     571                int firstIndex, 
     572                int lastIndex, 
     573                MailProgressHandler progressHandler) throws IOException, MailException { 
    451574        if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
    452575            EventLogger.logEvent(AppInfo.GUID, 
     
    465588     * Execute the "UID FETCH (FLAGS UID ENVELOPE BODYSTRUCTURE)" command 
    466589     * @param uidNext Unique ID of the next message 
     590     * @param progressHandler the progress handler 
    467591     * @return Array of FetchEnvelopeResponse objects 
    468592     */ 
     
    480604        return prepareFetchEnvelopeResponse(rawList, progressHandler); 
    481605    } 
     606     
     607    /** 
     608     * Execute the "UID FETCH (FLAGS UID ENVELOPE BODYSTRUCTURE)" command 
     609     * @param uids Set of unique IDs for the messages to fetch 
     610     * @param progressHandler the progress handler 
     611     * @return Array of FetchEnvelopeResponse objects 
     612     */ 
     613    public FetchEnvelopeResponse[] executeFetchEnvelopeUid(int[] uids, MailProgressHandler progressHandler) 
     614        throws IOException, MailException { 
     615        if(uids.length == 0) { return new FetchEnvelopeResponse[0]; } 
     616        StringBuffer buf = new StringBuffer(); 
     617        for(int i=0; i<uids.length - 1; i++) { 
     618                buf.append(uids[i]); 
     619                buf.append(','); 
     620        } 
     621        buf.append(uids[uids.length - 1]); 
     622        String uidList = buf.toString(); 
     623         
     624        if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
     625            EventLogger.logEvent(AppInfo.GUID, 
     626                ("ImapProtocol.executeFetchEnvelopeUid(" + uidList + ")").getBytes(), 
     627                EventLogger.DEBUG_INFO); 
     628        } 
     629 
     630        String[] rawList = execute("UID FETCH", 
     631                        uidList + " (FLAGS UID ENVELOPE BODYSTRUCTURE)", progressHandler); 
     632 
     633        return prepareFetchEnvelopeResponse(rawList, progressHandler); 
     634    } 
    482635 
    483636    private FetchEnvelopeResponse[] prepareFetchEnvelopeResponse( 
    484637        String[] rawList, MailProgressHandler progressHandler) throws IOException, MailException { 
     638 
     639        if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, -1); } 
    485640        // Preprocess the returned text to clean up mid-field line breaks 
    486641        // This should all become unnecessary once execute() 
    487642        // becomes more intelligent in how it handles replies 
    488         String line; 
    489         StringBuffer lineBuf = new StringBuffer(); 
    490         Vector rawList2 = new Vector(); 
    491  
    492         if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_PROCESSING, 0, -1); } 
    493         for (int i = 0; i < rawList.length; i++) { 
    494             line = rawList[i]; 
    495  
    496             if ((line.length() > 0) && lineBuf.toString().startsWith("* ") && 
    497                     line.startsWith("* ")) { 
    498                 rawList2.addElement(lineBuf.toString()); 
    499                 lineBuf = new StringBuffer(); 
    500             } 
    501  
    502             lineBuf.append(line); 
    503  
    504             if ((i == (rawList.length - 1)) && 
    505                     lineBuf.toString().startsWith("* ")) { 
    506                 rawList2.addElement(lineBuf.toString()); 
    507             } 
    508         } 
     643        Vector rawList2 = prepareCleanFetchResponse(rawList); 
    509644 
    510645        Vector envResponses = new Vector(); 
     
    594729        return result; 
    595730    } 
     731     
     732    private static Vector prepareCleanFetchResponse(String[] rawList) { 
     733        Vector cleanList = new Vector(); 
     734        String line; 
     735        StringBuffer lineBuf = new StringBuffer(); 
     736        for (int i = 0; i < rawList.length; i++) { 
     737            line = rawList[i]; 
     738 
     739            if ((line.length() > 0) && lineBuf.toString().startsWith("* ") && 
     740                    line.startsWith("* ")) { 
     741                cleanList.addElement(lineBuf.toString()); 
     742                lineBuf = new StringBuffer(); 
     743            } 
     744 
     745            lineBuf.append(line); 
     746 
     747            if ((i == (rawList.length - 1)) && 
     748                    lineBuf.toString().startsWith("* ")) { 
     749                cleanList.addElement(lineBuf.toString()); 
     750            } 
     751        } 
     752        return cleanList; 
     753    } 
    596754 
    597755    /** 
     
    11371295     * @param command IMAP command 
    11381296     * @param arguments Arguments for the command 
     1297     * @param progressHandler the progress handler 
    11391298     * @return List of returned strings 
    11401299     */ 
     
    13511510 
    13521511    /** 
    1353      * Container for a FETCH (ENVELOPE) response 
    1354      */ 
    1355     public static class FetchEnvelopeResponse { 
     1512     * Container for a FETCH (FLAGS) response 
     1513     */ 
     1514    public static class FetchFlagsResponse { 
    13561515        public int index; 
    13571516        public int uid; 
    13581517        public MessageFlags flags; 
     1518    } 
     1519     
     1520    /** 
     1521     * Container for a FETCH (ENVELOPE) response 
     1522     */ 
     1523    public static class FetchEnvelopeResponse extends FetchFlagsResponse { 
    13591524        public MessageEnvelope envelope; 
    13601525        public ImapParser.MessageSection structure; 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/pop/PopClient.java

    r496 r529  
    335335     */ 
    336336    public FolderMessage[] getFolderMessages(int firstIndex, int lastIndex, MailProgressHandler progressHandler) throws IOException, MailException { 
    337         FolderMessage[] folderMessages = new FolderMessage[(lastIndex - firstIndex)+1]; 
     337        return getFolderMessages(firstIndex, lastIndex, false, progressHandler); 
     338    } 
     339     
     340    private FolderMessage[] getFolderMessages(int firstIndex, int lastIndex, boolean flagsOnly, MailProgressHandler progressHandler) throws IOException, MailException { 
     341        int[] indices = new int[(lastIndex - firstIndex)+1]; 
     342        for(int i=firstIndex; i<=lastIndex; i++) { 
     343                indices[i] = i; 
     344        } 
     345         
     346        return getFolderMessagesImpl(indices, flagsOnly, progressHandler); 
     347    } 
     348 
     349        /* (non-Javadoc) 
     350         * @see org.logicprobe.LogicMail.mail.IncomingMailClient#getFolderMessages(org.logicprobe.LogicMail.mail.MessageToken[], org.logicprobe.LogicMail.mail.MailProgressHandler) 
     351         */ 
     352        public FolderMessage[] getFolderMessages(MessageToken[] messageTokens, MailProgressHandler progressHandler) 
     353                        throws IOException, MailException { 
     354                // Since POP servers typically lock the mailbox while a client is connected, 
     355                // and given the typical use case of this method, we will make the assumption 
     356                // that the message indices in the provided tokens exactly match the messages 
     357                // we want to retrieve headers for. 
     358                 
     359                int[] indices = new int[messageTokens.length]; 
     360                for(int i=0; i<messageTokens.length; i++) { 
     361                        indices[i] = ((PopMessageToken)messageTokens[i]).getMessageIndex(); 
     362                } 
     363                 
     364                return getFolderMessagesImpl(indices, false, progressHandler); 
     365        } 
     366 
     367    private FolderMessage[] getFolderMessagesImpl(int[] indices, boolean flagsOnly, MailProgressHandler progressHandler) 
     368                throws IOException, MailException { 
     369        FolderMessage[] folderMessages = new FolderMessage[indices.length]; 
    338370        int index = 0; 
    339371        String[] headerText; 
     
    342374        int preCount; 
    343375        int postCount = connection.getBytesReceived(); 
    344         for(int i=firstIndex; i<=lastIndex; i++) { 
     376        for(int i=0; i<indices.length; i++) { 
    345377                preCount = postCount; 
    346             headerText = popProtocol.executeTop(i, 0); 
    347             uid = popProtocol.executeUidl(i); 
    348             env = MailMessageParser.parseMessageEnvelope(headerText); 
     378            if(!flagsOnly) { 
     379                headerText = popProtocol.executeTop(indices[i], 0); 
     380                env = MailMessageParser.parseMessageEnvelope(headerText); 
     381                } 
     382            else { 
     383                env = null; 
     384            } 
     385            uid = popProtocol.executeUidl(indices[i]); 
    349386            folderMessages[index++] = new FolderMessage( 
    350                         new PopMessageToken(i, uid), 
    351                         env, i, uid.hashCode()); 
     387                        new PopMessageToken(indices[i], uid), 
     388                        env, indices[i], uid.hashCode()); 
    352389            postCount = connection.getBytesReceived(); 
    353390            if(progressHandler != null) { progressHandler.mailProgress(MailProgressHandler.TYPE_NETWORK, (postCount - preCount), -1); } 
     
    355392        return folderMessages; 
    356393    } 
    357  
    358     /* (non-Javadoc) 
    359      * @see org.logicprobe.LogicMail.mail.IncomingMailClient#getNewFolderMessages(org.logicprobe.LogicMail.mail.MailProgressHandler) 
    360      */ 
    361     public FolderMessage[] getNewFolderMessages(MailProgressHandler progressHandler) throws IOException, MailException { 
     394     
     395    /* (non-Javadoc) 
     396     * @see org.logicprobe.LogicMail.mail.IncomingMailClient#getNewFolderMessages(boolean, org.logicprobe.LogicMail.mail.MailProgressHandler) 
     397     */ 
     398    public FolderMessage[] getNewFolderMessages(boolean flagsOnly, MailProgressHandler progressHandler) throws IOException, MailException { 
    362399        int count = MailSettings.getInstance().getGlobalConfig().getRetMsgCount(); 
    363400                int msgCount = activeMailbox.getMsgCount(); 
    364401        int firstIndex = Math.max(1, msgCount - count); 
    365         return getFolderMessages(firstIndex, activeMailbox.getMsgCount(), progressHandler); 
     402        return getFolderMessages(firstIndex, activeMailbox.getMsgCount(), flagsOnly, progressHandler); 
    366403    } 
    367404 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/pop/PopMessageToken.java

    r518 r529  
    109109     * @return POP unique ID 
    110110     */ 
    111     String getMessageUid() { 
     111    public String getMessageUid() { 
    112112        return this.messageUid; 
    113113    } 
     
    160160                return hashCode; 
    161161        } 
     162         
     163        /* (non-Javadoc) 
     164         * @see java.lang.Object#toString() 
     165         */ 
     166        public String toString() { 
     167                StringBuffer buf = new StringBuffer(); 
     168                buf.append("PopMessageToken ["); 
     169                buf.append("uniqueId="); buf.append(uniqueId); 
     170                buf.append(", messageIndex="); buf.append(messageIndex); 
     171                buf.append(", messageUid=\""); buf.append(messageUid); buf.append("\""); 
     172                buf.append("]"); 
     173                return buf.toString(); 
     174        } 
    162175} 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/AccountNode.java

    r507 r529  
    572572 
    573573            MailboxNode mailboxNode = (MailboxNode) pathMailboxMap.get(e.getFolder().getPath()); 
    574  
    575             // Determine what MessageNodes need to be created, and add them. 
    576574            FolderMessage[] folderMessages = e.getMessages(); 
    577             Vector addedMessages = new Vector(); 
    578  
    579             for (int i = 0; i < folderMessages.length; i++) { 
    580                 addedMessages.addElement(new MessageNode(folderMessages[i])); 
    581             } 
    582  
    583             MessageNode[] addedMessagesArray = new MessageNode[addedMessages.size()]; 
    584             addedMessages.copyInto(addedMessagesArray); 
    585             mailboxNode.addMessages(addedMessagesArray); 
     575 
     576            if(e.isFlagsOnly()) { 
     577                // Only flags have been retrieved, so the existing messages need to 
     578                // be checked and additional actions requested accordingly. 
     579                //TODO: Implement flags-only logic 
     580                Vector messagesToFetch = null; 
     581                    for (int i = 0; i < folderMessages.length; i++) { 
     582                        MessageNode messageNode = 
     583                                mailboxNode.getMessageByToken(folderMessages[i].getMessageToken()); 
     584                        if(messageNode != null) { 
     585                                messageNode.setFlags(MessageNode.convertMessageFlags(folderMessages[i].getFlags())); 
     586                        } 
     587                        else { 
     588                                if(messagesToFetch == null) { messagesToFetch = new Vector(); } 
     589                                messagesToFetch.addElement(folderMessages[i].getMessageToken()); 
     590                                System.err.println("-->Need to fetch: " + folderMessages[i].getMessageToken()); 
     591                        } 
     592                    } 
     593                    if(messagesToFetch != null) { 
     594                        MessageToken[] fetchArray = new MessageToken[messagesToFetch.size()]; 
     595                        messagesToFetch.copyInto(fetchArray); 
     596                        mailStore.requestFolderMessagesSet(e.getFolder(), fetchArray); 
     597                    } 
     598            } 
     599            else { 
     600                    // Determine what MessageNodes need to be created, and add them. 
     601                    Vector addedMessages = new Vector(); 
     602         
     603                    for (int i = 0; i < folderMessages.length; i++) { 
     604                        addedMessages.addElement(new MessageNode(folderMessages[i])); 
     605                    } 
     606         
     607                    MessageNode[] addedMessagesArray = new MessageNode[addedMessages.size()]; 
     608                    addedMessages.copyInto(addedMessagesArray); 
     609                    mailboxNode.addMessages(addedMessagesArray); 
     610            } 
    586611        } 
    587612    } 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/MailboxNode.java

    r518 r529  
    3737import java.util.Vector; 
    3838 
     39import net.rim.device.api.system.EventLogger; 
    3940import net.rim.device.api.util.Comparator; 
    4041import net.rim.device.api.util.SimpleSortingVector; 
    4142 
     43import org.logicprobe.LogicMail.AppInfo; 
    4244import org.logicprobe.LogicMail.mail.FolderTreeItem; 
    4345import org.logicprobe.LogicMail.mail.MessageToken; 
     
    501503                        messageMap.put(message, message); 
    502504                        messageTokenMap.put(message.getMessageToken(), message); 
     505                        if(!message.isCached() && message.isCachable()) { 
     506                                try { 
     507                                        MailFileManager.getInstance().writeMessage(message); 
     508                                        message.setCached(true); 
     509                                } catch (IOException e) { 
     510                                        System.err.println("-->Unable to write message: " + e.getMessage()); 
     511                                        e.printStackTrace(); 
     512                                } catch (Throwable t) { 
     513                                        System.err.println("-->Unable to write message: " + t.getMessage()); 
     514                                        t.printStackTrace(); 
     515                                } 
     516                        } 
    503517                        return true; 
    504518                } 
     
    689703     */ 
    690704    public void refreshMessages() { 
    691         parentAccount.getMailStore().requestFolderMessagesRecent(this.folderTreeItem); 
     705        // Fetch messages stored in the cache 
     706        if(parentAccount.getAccountConfig() != null) { 
     707                //TODO: Make this thread-safe and prevent redundant calls 
     708                Thread fetchThread = new Thread() { 
     709                        public void run() { 
     710                                try { 
     711                                        MessageNode[] messages = 
     712                                                MailFileManager.getInstance().readMessageNodes(MailboxNode.this); 
     713                                        MailboxNode.this.addMessages(messages); 
     714                                } catch (IOException e) { 
     715                                        EventLogger.logEvent(AppInfo.GUID, 
     716                                        ("Unable to read messages from cache\r\n" 
     717                                                + e.getMessage()).getBytes(), 
     718                                        EventLogger.ERROR); 
     719                                } 
     720                                 
     721                        // Request flags and tokens for recent messages from the mail store 
     722                        parentAccount.getMailStore().requestFolderMessagesRecent(folderTreeItem, true); 
     723                        } 
     724                }; 
     725                fetchThread.start(); 
     726        } 
     727        else { 
     728                parentAccount.getMailStore().requestFolderMessagesRecent(this.folderTreeItem); 
     729        } 
    692730    } 
    693731     
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/MessageNode.java

    r517 r529  
    124124        /** Hash code used to verify uniqueness of message nodes */ 
    125125        private int hashCode = -1; 
     126        /** True if the message is up-to-date in the cache */ 
     127        private boolean cached; 
    126128        /** Bit-field set of message flags. */ 
    127129        private int flags; 
     
    247249        } 
    248250         
     251        /** 
     252         * Checks if the message is up-to-date in the cache. 
     253         *  
     254         * @return true, if the message is cached 
     255         */ 
     256        boolean isCached() { 
     257                return this.cached; 
     258        } 
     259         
     260        /** 
     261         * Checks if the message is capable of being cached. 
     262         *  
     263         * @return true, if the message is associated with a mailbox from a non-local account 
     264         */ 
     265        boolean isCachable() { 
     266                if(parent != null 
     267                                && parent.getParentAccount() != null 
     268                                && parent.getParentAccount().getAccountConfig() != null) { 
     269                        return true; 
     270                } 
     271                else { 
     272                        return false; 
     273                } 
     274        } 
     275         
     276        /** 
     277         * Sets whether the message is up-to-date in the cache. 
     278         *  
     279         * @param cached the new cached state 
     280         */ 
     281        void setCached(boolean cached) { 
     282                this.cached = cached; 
     283        } 
     284         
    249285        /* (non-Javadoc) 
    250286         * @see org.logicprobe.LogicMail.model.Node#accept(org.logicprobe.LogicMail.model.NodeVisitor) 
     
    287323         */ 
    288324        protected void setMessageToken(MessageToken messageToken) { 
     325                cached = false; 
    289326                this.messageToken = messageToken; 
    290327        } 
     
    305342         */ 
    306343        public void setFlags(int flags) { 
     344                cached = false; 
    307345                this.flags = flags; 
    308346        } 
     
    323361         */ 
    324362        public void setDate(Date date) { 
     363                cached = false; 
    325364                this.date = date; 
    326365        } 
     
    341380         */ 
    342381        public void setSubject(String subject) { 
     382                cached = false; 
    343383                this.subject = subject; 
    344384        } 
     
    359399         */ 
    360400        public void setFrom(Address[] from) { 
     401                cached = false; 
    361402                this.from = from; 
    362403        } 
     
    377418         */ 
    378419        public void setSender(Address[] sender) { 
     420                cached = false; 
    379421                this.sender = sender; 
    380422        } 
     
    395437         */ 
    396438        public void setReplyTo(Address[] replyTo) { 
     439                cached = false; 
    397440                this.replyTo = replyTo; 
    398441        } 
     
    413456         */ 
    414457        public void setTo(Address[] to) { 
     458                cached = false; 
    415459                this.to = to; 
    416460        } 
     
    431475         */ 
    432476        public void setCc(Address[] cc) { 
     477                cached = false; 
    433478                this.cc = cc; 
    434479        } 
     
    449494         */ 
    450495        public void setBcc(Address[] bcc) { 
     496                cached = false; 
    451497                this.bcc = bcc; 
    452498        } 
     
    467513         */ 
    468514        public void setInReplyTo(String inReplyTo) { 
     515                cached = false; 
    469516                this.inReplyTo = inReplyTo; 
    470517        } 
     
    485532         */ 
    486533        public void setMessageId(String messageId) { 
     534                cached = false; 
    487535                this.messageId = messageId; 
    488536        } 
     
    496544                boolean fireEvent; 
    497545                synchronized(messageContent) { 
     546                        cached = false; 
    498547                        this.messageStructure = messageStructure; 
    499548                        if(this.messageStructure != null) { 
     
    519568        void putMessageContent(MimeMessageContent mimeMessageContent) { 
    520569                synchronized(mimeMessageContent) { 
     570                        cached = false; 
    521571                        this.messageContent.put(mimeMessageContent.getMessagePart(), mimeMessageContent); 
    522572                } 
     
    535585        void putMessageContent(MimeMessageContent[] messageContent) { 
    536586                synchronized(messageContent) { 
     587                        cached = false; 
    537588                        for(int i=0; i<messageContent.length; i++) { 
    538589                                this.messageContent.put(messageContent[i].getMessagePart(), messageContent[i]); 
     
    9791030     */ 
    9801031        public boolean refreshMessage() { 
     1032                // TODO: Add code to refresh message from cache first 
    9811033                boolean result = false; 
    9821034                if(!refreshInProgress) { 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/MessageNodeReader.java

    r517 r529  
    3636import java.util.Hashtable; 
    3737 
     38import org.logicprobe.LogicMail.AppInfo; 
    3839import org.logicprobe.LogicMail.mail.MessageToken; 
    3940import org.logicprobe.LogicMail.message.MimeMessageContent; 
     
    4142import org.logicprobe.LogicMail.util.SerializationUtils; 
    4243 
     44import net.rim.device.api.system.EventLogger; 
    4345import net.rim.device.api.util.Arrays; 
    4446import net.rim.device.api.util.CRC32; 
    4547 
     48/** 
     49 * Reads in <tt>MessageNode</tt> objects from an input stream. 
     50 * <p> 
     51 * Allows for separate reading of header information and content, 
     52 * to facilitate partial loading of cached messages. 
     53 * The specific data format is described in detail within 
     54 * {@link MessageNodeWriter}. 
     55 * </p> 
     56 */ 
    4657public class MessageNodeReader { 
    4758        private DataInputStream input; 
     
    5465        }; 
    5566         
     67        /** 
     68         * Instantiates a new message node reader. 
     69         *  
     70         * @param input the input 
     71         */ 
    5672        public MessageNodeReader(DataInputStream input) { 
    5773                this.input = input; 
     
    124140        } 
    125141         
     142        /** 
     143         * Checks if more content is available for reading. 
     144         *  
     145         * @return true, if content is available 
     146         */ 
    126147        public boolean isContentAvailable() { 
    127148                if(!headerParsed) { throw new IllegalStateException(); } 
     
    129150        } 
    130151         
     152        /** 
     153         * Gets the next content section of the message. 
     154         *  
     155         * @return the next content section 
     156         *  
     157         * @throws IOException Signals that an I/O exception has occurred. 
     158         */ 
    131159        public MimeMessageContent getNextContent() throws IOException { 
    132160                if(!headerParsed || contentCount == 0) { throw new IllegalStateException(); } 
    133                 System.err.println("-->getNextContent(): contentCount=" + contentCount + ", available=" + input.available()); 
     161                if (EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
     162                        EventLogger.logEvent(AppInfo.GUID, 
     163                ("MessageNodeReader.getNextContent()\r\n" 
     164                        + "contentCount=" + contentCount 
     165                        + ", available=" + input.available()).getBytes(), 
     166                EventLogger.DEBUG_INFO); 
     167        } 
     168                 
    134169                contentCount--; 
    135170                 
     
    144179                 
    145180                if(storedChecksum != checksum) { 
    146                         System.err.println("-->Content checksum mismatch"); 
     181                        EventLogger.logEvent(AppInfo.GUID, 
     182                ("MessageNodeReader.getNextContent()\r\nContent checksum mismatch").getBytes(), 
     183                EventLogger.ERROR); 
    147184                        return null; 
    148185                } 
     
    153190                } 
    154191                else { 
    155                         System.err.println("-->Content deserialization error"); 
     192                        EventLogger.logEvent(AppInfo.GUID, 
     193                ("MessageNodeReader.getNextContent()\r\nContent deserialization error").getBytes(), 
     194                EventLogger.ERROR); 
    156195                        return null; 
    157196                } 
     
    161200                // Validate the header start text 
    162201                if(!Arrays.equals(fileHeader, 0, headerStart, 0, headerStart.length)) { 
    163                         System.err.println("-->Header start mismatch"); 
     202                        EventLogger.logEvent(AppInfo.GUID, 
     203                ("MessageNodeReader.validateHeader()\r\nHeader start mismatch").getBytes(), 
     204                EventLogger.ERROR); 
    164205                        return false; 
    165206                } 
     
    171212                int checksum = CRC32.update(CRC32.INITIAL_VALUE, headerCopy); 
    172213                if(headerChecksum != checksum) { 
    173                         System.err.println("-->Header checksum mismatch"); 
     214                        EventLogger.logEvent(AppInfo.GUID, 
     215                ("MessageNodeReader.validateHeader()\r\nHeader checksum mismatch").getBytes(), 
     216                EventLogger.ERROR); 
    174217                        return false; 
    175218                } 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/MessageNodeWriter.java

    r517 r529  
    9797        }; 
    9898         
     99        /** 
     100         * Instantiates a new message node writer. 
     101         *  
     102         * @param output the output stream 
     103         */ 
    99104        public MessageNodeWriter(DataOutputStream output) { 
    100105                this.output = output; 
    101106        } 
    102107         
     108        /** 
     109         * Write a complete message node to the output stream. 
     110         *  
     111         * @param messageNode the message node 
     112         *  
     113         * @throws IOException Signals that an I/O exception has occurred. 
     114         */ 
    103115        public void write(MessageNode messageNode) throws IOException { 
    104116                byte[] messageToken = generateMessageToken(messageNode); 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/model/OutboxMailboxNode.java

    r518 r529  
    223223                } 
    224224 
     225                public String getMessageUid() { 
     226                        return Integer.toHexString(messageId).toLowerCase(); 
     227                } 
     228                 
    225229                public long getUniqueId() { 
    226230                        // Empty because this special token is not intended to be serialized 
Note: See TracChangeset for help on using the changeset viewer.