Changeset 262

Show
Ignore:
Timestamp:
08/02/08 05:15:29 PM (4 months ago)
Author:
octorian
Message:

UID support for messages

Location:
trunk/LogicMail/src/org/logicprobe/LogicMail
Files:
6 modified

Legend:

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

    r259 r262  
    377377        FolderMessage[] folderMessages = new FolderMessage[response.length]; 
    378378        for(int i=0;i<response.length;i++) { 
    379             folderMessages[i] = new FolderMessage(response[i].envelope, response[i].index); 
     379            folderMessages[i] = new FolderMessage(response[i].envelope, response[i].index, response[i].uid); 
    380380            folderMessages[i].setSeen(response[i].flags.seen); 
    381381            folderMessages[i].setAnswered(response[i].flags.answered); 
     
    391391 
    392392    public Message getMessage(FolderMessage folderMessage) throws IOException, MailException { 
    393         ImapParser.MessageSection structure = getMessageStructure(folderMessage.getIndex()); 
     393        ImapParser.MessageSection structure = getMessageStructure(folderMessage.getUid()); 
    394394        MessagePart rootPart = 
    395             getMessagePart(folderMessage.getIndex(), 
     395            getMessagePart(folderMessage.getUid(), 
    396396                           structure, globalConfig.getImapMaxMsgSize()); 
    397397        Message msg = new Message(folderMessage.getEnvelope(), rootPart); 
     
    399399    } 
    400400 
    401     private MessagePart getMessagePart(int index, 
     401    private MessagePart getMessagePart(int uid, 
    402402                                       ImapParser.MessageSection structure, 
    403403                                       int maxSize) 
     
    411411            else { 
    412412                if(structure.size < maxSize) { 
    413                     data = getMessageBody(index, structure.address); 
     413                    data = getMessageBody(uid, structure.address); 
    414414                    maxSize -= structure.size; 
    415415                } 
     
    426426        if((part instanceof MultiPart)&&(structure.subsections != null)&&(structure.subsections.length > 0)) { 
    427427            for(int i=0;i<structure.subsections.length;i++) { 
    428                 MessagePart subPart = getMessagePart(index, structure.subsections[i], maxSize); 
     428                MessagePart subPart = getMessagePart(uid, structure.subsections[i], maxSize); 
    429429                if(subPart != null) { 
    430430                    ((MultiPart)part).addPart(subPart); 
     
    439439     * This tree is used to build the final message tree. 
    440440     */ 
    441     private ImapParser.MessageSection getMessageStructure(int msgIndex) throws IOException, MailException { 
     441    private ImapParser.MessageSection getMessageStructure(int uid) throws IOException, MailException { 
    442442        if(activeMailbox.equals("")) { 
    443443            throw new MailException("Mailbox not selected"); 
    444444        } 
    445445 
    446         return imapProtocol.executeFetchBodystructure(msgIndex); 
     446        return imapProtocol.executeFetchBodystructure(uid); 
    447447    } 
    448448 
     
    466466    } 
    467467 
    468     private String getMessageBody(int index, String address) throws IOException, MailException { 
     468    private String getMessageBody(int uid, String address) throws IOException, MailException { 
    469469        if(activeMailbox.equals("")) { 
    470470            throw new MailException("Mailbox not selected"); 
    471471        } 
    472472         
    473         return imapProtocol.executeFetchBody(index, address); 
     473        return imapProtocol.executeFetchBody(uid, address); 
    474474    } 
    475475     
    476476    public void deleteMessage(FolderMessage folderMessage) throws IOException, MailException { 
    477477        ImapProtocol.MessageFlags updatedFlags = 
    478             imapProtocol.executeStore(folderMessage.getIndex(), true, new String[] { "\\Deleted" }); 
     478            imapProtocol.executeStore(folderMessage.getUid(), true, new String[] { "\\Deleted" }); 
    479479        refreshMessageFlags(updatedFlags, folderMessage); 
    480480    } 
     
    483483    public void undeleteMessage(FolderMessage folderMessage) throws IOException, MailException { 
    484484        ImapProtocol.MessageFlags updatedFlags = 
    485             imapProtocol.executeStore(folderMessage.getIndex(), false, new String[] { "\\Deleted" }); 
     485            imapProtocol.executeStore(folderMessage.getUid(), false, new String[] { "\\Deleted" }); 
    486486        refreshMessageFlags(updatedFlags, folderMessage); 
    487487    } 
     
    495495    public void messageAnswered(FolderMessage folderMessage) throws IOException, MailException { 
    496496        ImapProtocol.MessageFlags updatedFlags = 
    497             imapProtocol.executeStore(folderMessage.getIndex(), true, new String[] { "\\Answered" }); 
     497            imapProtocol.executeStore(folderMessage.getUid(), true, new String[] { "\\Answered" }); 
    498498        refreshMessageFlags(updatedFlags, folderMessage); 
    499499    } 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapParser.java

    r198 r262  
    257257 
    258258        // Sanity checking 
    259         if(parsedText.size() < 2 || 
    260            !(parsedText.elementAt(1) instanceof Vector)) { 
     259        if(parsedText.size() < 4 || 
     260           !(parsedText.elementAt(3) instanceof Vector)) { 
    261261           EventLogger.logEvent( 
    262262               AppInfo.GUID, 
     
    266266        } 
    267267         
    268         Vector parsedStruct = (Vector)parsedText.elementAt(1); 
     268        Vector parsedStruct = (Vector)parsedText.elementAt(3); 
    269269        MessageSection msgStructure = parseMessageStructureHelper(null, 1, parsedStruct); 
    270270        fixMessageStructure(msgStructure); 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/imap/ImapProtocol.java

    r255 r262  
    454454    public static class FetchEnvelopeResponse { 
    455455        public int index; 
     456        public int uid; 
    456457        public MessageFlags flags; 
    457458        public MessageEnvelope envelope; 
     
    459460 
    460461    /** 
    461      * Execute the "FETCH (ENVELOPE)" command 
     462     * Execute the "FETCH (FLAGS UID ENVELOPE)" command 
    462463     * @param firstIndex Index of the first message 
    463464     * @param lastIndex Index of the last message 
     
    475476                                   Integer.toString(firstIndex) + ":" + 
    476477                                   Integer.toString(lastIndex) + 
    477                                    " (FLAGS ENVELOPE)"); 
     478                                   " (FLAGS UID ENVELOPE)"); 
    478479         
    479480        FetchEnvelopeResponse[] envResponses = new FetchEnvelopeResponse[(lastIndex - firstIndex)+1]; 
     
    526527                            envRespItem.flags = ImapParser.parseMessageFlags((Vector)parsedText.elementAt(j+1)); 
    527528                        } 
     529                        else if(((String)parsedText.elementAt(j)).equals("UID") && 
     530                                        parsedSize > j+1 && 
     531                                        parsedText.elementAt(j+1) instanceof String) { 
     532                                try { 
     533                                        envRespItem.uid = Integer.parseInt((String)parsedText.elementAt(j+1)); 
     534                                } catch (NumberFormatException e) { 
     535                                        envRespItem.uid = -1; 
     536                                } 
     537                        } 
    528538                        else if(((String)parsedText.elementAt(j)).equals("ENVELOPE") && 
    529539                                parsedSize > j+1 && 
     
    559569    /** 
    560570     * Execute the "FETCH (BODYSTRUCTURE)" command 
    561      * @param index Index of the message 
     571     * @param uid Unique ID of the message 
    562572     * @return Body structure tree 
    563573     */ 
    564     public ImapParser.MessageSection executeFetchBodystructure(int index) throws IOException, MailException { 
    565         if(EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
    566             EventLogger.logEvent( 
    567             AppInfo.GUID, 
    568             ("ImapProtocol.executeFetchBodyStructure("+index+")").getBytes(), 
    569             EventLogger.DEBUG_INFO); 
    570         } 
    571          
    572         String[] rawList = execute("FETCH", index + " (BODYSTRUCTURE)"); 
     574    public ImapParser.MessageSection executeFetchBodystructure(int uid) throws IOException, MailException { 
     575        if(EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
     576            EventLogger.logEvent( 
     577            AppInfo.GUID, 
     578            ("ImapProtocol.executeFetchBodyStructure("+uid+")").getBytes(), 
     579            EventLogger.DEBUG_INFO); 
     580        } 
     581         
     582        String[] rawList = execute("UID FETCH", uid + " (BODYSTRUCTURE)"); 
    573583 
    574584        // Pre-process the returned text to clean up mid-field line breaks 
     
    607617    /** 
    608618     * Execute the "FETCH (BODY)" command 
    609      * @param index Index of the message 
     619     * @param uid Unique ID of the message 
    610620     * @param address Address of the body section (i.e. "1", "1.2") 
    611621     * @return Body text as a string 
    612622     */ 
    613     public String executeFetchBody(int index, String address) throws IOException, MailException { 
    614         if(EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
    615             EventLogger.logEvent( 
    616             AppInfo.GUID, 
    617             ("ImapProtocol.executeFetchBody("+index+", \""+address+"\")").getBytes(), 
    618             EventLogger.DEBUG_INFO); 
    619         } 
    620  
    621         String[] rawList = execute("FETCH", index + " (BODY["+ address +"])"); 
     623    public String executeFetchBody(int uid, String address) throws IOException, MailException { 
     624        if(EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
     625            EventLogger.logEvent( 
     626            AppInfo.GUID, 
     627            ("ImapProtocol.executeFetchBody("+uid+", \""+address+"\")").getBytes(), 
     628            EventLogger.DEBUG_INFO); 
     629        } 
     630 
     631        String[] rawList = execute("UID FETCH", uid + " (BODY["+ address +"])"); 
    622632 
    623633        if(rawList.length <= 1) { 
     
    636646    /** 
    637647     * Execute the "STORE" command to update message flags. 
    638      * @param index The message index to modify. 
     648     * @param uid The message unique ID to modify. 
    639649     * @param addOrRemove True to add flags, false to remove them. 
    640650     * @param flags Array of flags to change.  (i.e. "\Seen", "\Answered") 
    641651     * @return Updated standard message flags, or null if there was a parse error. 
    642652     */ 
    643     public MessageFlags executeStore(int index, boolean addOrRemove, String[] flags) throws IOException, MailException { 
     653    public MessageFlags executeStore(int uid, boolean addOrRemove, String[] flags) throws IOException, MailException { 
    644654        if(EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
    645655            StringBuffer buf = new StringBuffer(); 
     
    654664            EventLogger.logEvent( 
    655665            AppInfo.GUID, 
    656             ("ImapProtocol.executeStore("+index+", "+(addOrRemove?"add":"remove")+", {"+buf.toString()+"})").getBytes(), 
     666            ("ImapProtocol.executeStore("+uid+", "+(addOrRemove?"add":"remove")+", {"+buf.toString()+"})").getBytes(), 
    657667            EventLogger.DEBUG_INFO); 
    658668        } 
    659669 
    660670        StringBuffer buf = new StringBuffer(); 
    661         buf.append(index); 
     671        buf.append(uid); 
    662672        buf.append(' '); 
    663673        buf.append(addOrRemove?'+':'-'); 
     
    670680        } 
    671681        buf.append(')'); 
    672         String[] rawList = execute("STORE", buf.toString()); 
     682        String[] rawList = execute("UID STORE", buf.toString()); 
    673683        if(rawList.length < 1) { 
    674684            throw new MailException("Unable to set message flags"); 
     
    676686         
    677687        try { 
    678             int p = rawList[0].indexOf(' '); 
    679             int q = rawList[0].indexOf(' ', p+1); 
    680             int fetchIndex = Integer.parseInt(rawList[0].substring(p+1, q)); 
    681             if(fetchIndex != index) { 
    682                 return null; 
     688            int p = rawList[0].indexOf("UID"); 
     689            int q = rawList[0].lastIndexOf(')'); 
     690            if(p != -1 && q != -1 && p < q) { 
     691                int fetchIndex = Integer.parseInt(rawList[0].substring(p+4, q)); 
     692                if(fetchIndex != uid) { 
     693                    return null; 
     694                } 
    683695            } 
    684696            p = rawList[0].indexOf("FLAGS ("); 
    685             q = rawList[0].indexOf("))"); 
     697            q = rawList[0].indexOf(") UID"); 
    686698            if(p == -1 || q == -1) { 
    687699                return null; 
     
    702714     * Execute the "APPEND" command to add a message to an existing mailbox. 
    703715     * @param mboxName Mailbox name. 
    704      * @param rawMessage The raw message text, in RFC2822-compliant format. 
     716     * @param rawMessage The raw message text, in RFC2822-complaint format. 
    705717     * @param flags Flags to store the message with. 
    706718     */ 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/pop/PopClient.java

    r259 r262  
    235235        int index = 0; 
    236236        String[] headerText; 
     237        String uid; 
    237238        MessageEnvelope env; 
    238239        for(int i=firstIndex; i<=lastIndex; i++) { 
    239240            headerText = popProtocol.executeTop(i, 0); 
     241            uid = popProtocol.executeUidl(i); 
    240242            env = PopParser.parseMessageEnvelope(headerText); 
    241             folderMessages[index++] = new FolderMessage(env, i); 
     243            folderMessages[index++] = new FolderMessage(env, i, uid.hashCode()); 
    242244        } 
    243245        return folderMessages; 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/mail/pop/PopProtocol.java

    r172 r262  
    130130        return executeFollow("TOP " + index + " " + lines); 
    131131    } 
    132  
     132     
     133    /** 
     134     * Execute the "UIDL" command 
     135     * @param index Message index 
     136     */ 
     137    public String executeUidl(int index) throws IOException, MailException { 
     138        if(EventLogger.getMinimumLevel() >= EventLogger.DEBUG_INFO) { 
     139            EventLogger.logEvent( 
     140            AppInfo.GUID, 
     141            ("PopProtocol.executeUidl("+index+")").getBytes(), 
     142            EventLogger.DEBUG_INFO); 
     143        } 
     144        String result = execute("UIDL " + index); 
     145        int p = result.lastIndexOf(' '); 
     146        if(p < result.length() - 2) { 
     147                return result.substring(p+1); 
     148        } 
     149        else { 
     150                return null; 
     151        } 
     152    } 
     153     
    133154    /** 
    134155     * Execute the "DELE" command. 
  • trunk/LogicMail/src/org/logicprobe/LogicMail/message/FolderMessage.java

    r253 r262  
    4040    private MessageEnvelope envelope; 
    4141    private int index; 
     42    private int uid; 
    4243    private MessageFlags messageFlags; 
    4344     
     
    4748     * @param index The index of the message within the folder 
    4849     */ 
    49     public FolderMessage(MessageEnvelope envelope, int index) { 
     50    public FolderMessage(MessageEnvelope envelope, int index, int uid) { 
    5051        this.envelope = envelope; 
    5152        this.index = index; 
     53        this.uid = uid; 
    5254        this.messageFlags = new MessageFlags(); 
    5355    } 
     
    6971    } 
    7072 
     73    /** 
     74     * Get the unique ID of this message 
     75     * @return unique ID 
     76     */ 
     77    public int getUid() { 
     78        return uid; 
     79    } 
     80     
    7181    /** 
    7282     * Gets the flags associated with this message.