commits@javamail.java.net

[javamail~mercurial:592] Add more support for the IMAP CONDSTORE extension.

From: <shannon_at_java.net>
Date: Tue, 10 Sep 2013 22:33:19 +0000

Project: javamail
Repository: mercurial
Revision: 592
Author: shannon
Date: 2013-09-10 20:43:27 UTC
Link:

Log Message:
------------
Need to use UNAUTHENTICATE command to switch proxy user.
Add more support for the IMAP CONDSTORE extension.


Revisions:
----------
591
592


Modified Paths:
---------------
mail/src/main/java/com/sun/mail/imap/IMAPStore.java
mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
javadoc/pom.xml
mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
mail/src/main/java/com/sun/mail/imap/protocol/SearchSequence.java


Added Paths:
------------
mail/src/main/java/com/sun/mail/imap/ModifiedSinceTerm.java


Diffs:
------
diff -r cd8bd0e46fa8 -r 1c932f38eb34 mail/src/main/java/com/sun/mail/imap/IMAPStore.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPStore.java Wed Aug 28 17:04:20 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPStore.java Wed Sep 04 14:03:31 2013 -0700
@@ -697,7 +697,8 @@
     private void login(IMAPProtocol p, String u, String pw)
                 throws ProtocolException {
         // turn on TLS if it's been enabled or required and is supported
- if (enableStartTLS || requireStartTLS) {
+ // and we're not already using SSL
+ if ((enableStartTLS || requireStartTLS) && !p.isSSL()) {
             if (p.hasCapability("STARTTLS")) {
                 p.startTLS();
                 // if startTLS succeeds, refresh capabilities
@@ -907,7 +908,8 @@
 
                 // if proxyAuthUser has changed, switch to new user
                 if (proxyAuthUser != null &&
- !proxyAuthUser.equals(p.getProxyAuthUser())) {
+ !proxyAuthUser.equals(p.getProxyAuthUser()) &&
+ p.hasCapability("X-UNAUTHENTICATE")) {
                     try {
                         /*
                          * Swap in a special response handler that will handle
@@ -916,7 +918,8 @@
                          */
                         p.removeResponseHandler(this);
                         p.addResponseHandler(nonStoreResponseHandler);
- p.proxyauth(proxyAuthUser);
+ p.unauthenticate();
+ login(p, user, password);
                         p.removeResponseHandler(nonStoreResponseHandler);
                         p.addResponseHandler(this);
                     } catch (ProtocolException pex) {
@@ -1013,8 +1016,11 @@
 
                 // if proxyAuthUser has changed, switch to new user
                 if (proxyAuthUser != null &&
- !proxyAuthUser.equals(p.getProxyAuthUser()))
- p.proxyauth(proxyAuthUser);
+ !proxyAuthUser.equals(p.getProxyAuthUser()) &&
+ p.hasCapability("X-UNAUTHENTICATE")) {
+ p.unauthenticate();
+ login(p, user, password);
+ }
             }
  
             if (pool.storeConnectionInUse) {

diff -r cd8bd0e46fa8 -r 1c932f38eb34 mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java Wed Aug 28 17:04:20 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java Wed Sep 04 14:03:31 2013 -0700
@@ -807,6 +807,19 @@
     }
 
     /**
+ * UNAUTHENTICATE Command.
+ *
+ * @see "Netscape/iPlanet/SunONE Messaging Server extension"
+ * @since JavaMail 1.5.1
+ */
+ public void unauthenticate() throws ProtocolException {
+ if (!hasCapability("X-UNAUTHENTICATE"))
+ throw new BadCommandException("UNAUTHENTICATE not supported");
+ simpleCommand("UNAUTHENTICATE", null);
+ authenticated = false;
+ }
+
+ /**
      * ID Command, for Yahoo! Mail IMAP server.
      *
      * See <A HREF="http://en.wikipedia.org/wiki/Yahoo%21_Mail#Free_IMAP_and_SMTPs_access">


diff -r 1c932f38eb34 -r ed574b6f53ad javadoc/pom.xml
--- a/javadoc/pom.xml Wed Sep 04 14:03:31 2013 -0700
+++ b/javadoc/pom.xml Tue Sep 10 13:43:27 2013 -0700
@@ -94,6 +94,7 @@
                         com/sun/mail/imap/OlderTerm.java,
                         com/sun/mail/imap/YoungerTerm.java,
                         com/sun/mail/imap/MessageVanishedEvent.java,
+ com/sun/mail/imap/ModifiedSinceTerm.java,
                         com/sun/mail/pop3/POP3Store.java,
                         com/sun/mail/pop3/POP3SSLStore.java,
                         com/sun/mail/pop3/POP3Folder.java,

diff -r 1c932f38eb34 -r ed574b6f53ad mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Wed Sep 04 14:03:31 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Tue Sep 10 13:43:27 2013 -0700
@@ -2498,6 +2498,44 @@
     }
 
     /**
+ * Get the messages that have been changed since the given MODSEQ value.
+ * Also, prefetch the flags for the messages. <p>
+ *
+ * The server must support the CONDSTORE extension.
+ *
+ * @see "RFC 4551"
+ * @since JavaMail 1.5.1
+ */
+ public synchronized Message[] getMessagesByUIDChangedSince(
+ long start, long end, long modseq)
+ throws MessagingException {
+ checkOpened(); // insure that folder is open
+
+ Message[] msgs; // array of messages to be returned
+
+ try {
+ synchronized (messageCacheLock) {
+ IMAPProtocol p = getProtocol();
+ if (!p.hasCapability("CONDSTORE"))
+ throw new BadCommandException("CONDSTORE not supported");
+
+ // Issue FETCH for given range
+ int[] nums = p.uidfetchChangedSince(start, end, modseq);
+
+ msgs = new Message[nums.length];
+ for (int i = 0; i < nums.length; i++)
+ msgs[i] = getMessageBySeqNumber(nums[i]);
+ }
+ } catch(ConnectionException cex) {
+ throw new FolderClosedException(this, cex.getMessage());
+ } catch (ProtocolException pex) {
+ throw new MessagingException(pex.getMessage(), pex);
+ }
+
+ return msgs;
+ }
+
+ /**
      * Get the quotas for the quotaroot associated with this
      * folder. Note that many folders may have the same quotaroot.
      * Quotas are controlled on the basis of a quotaroot, not

diff -r 1c932f38eb34 -r ed574b6f53ad mail/src/main/java/com/sun/mail/imap/ModifiedSinceTerm.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/main/java/com/sun/mail/imap/ModifiedSinceTerm.java Tue Sep 10 13:43:27 2013 -0700
@@ -0,0 +1,115 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.mail.imap;
+
+import javax.mail.Message;
+import javax.mail.search.SearchTerm;
+
+/**
+ * Find messages that have been modified since a given MODSEQ value.
+ * Relies on the server implementing the CONDSTORE extension
+ * (<A HREF="http://www.ietf.org/rfc/rfc4551.txt">RFC 4551</A>).
+ *
+ * @since JavaMail 1.5.1
+ * @author Bill Shannon
+ */
+public final class ModifiedSinceTerm extends SearchTerm {
+
+ private long modseq;
+
+ //private static final long serialVersionUID = 3951078948727995682L;
+
+ /**
+ * Constructor.
+ *
+ * @param modseq modification sequence number
+ */
+ public ModifiedSinceTerm(long modseq) {
+ this.modseq = modseq;
+ }
+
+ /**
+ * Return the modseq.
+ *
+ * @return the modseq
+ */
+ public long getModSeq() {
+ return modseq;
+ }
+
+ /**
+ * The match method.
+ *
+ * @param msg the date comparator is applied to this Message's
+ * MODSEQ
+ * @return true if the comparison succeeds, otherwise false
+ */
+ public boolean match(Message msg) {
+ long m;
+
+ try {
+ if (msg instanceof IMAPMessage)
+ m = ((IMAPMessage)msg).getModSeq();
+ else
+ return false;
+ } catch (Exception e) {
+ return false;
+ }
+
+ return m >= modseq;
+ }
+
+ /**
+ * Equality comparison.
+ */
+ public boolean equals(Object obj) {
+ if (!(obj instanceof ModifiedSinceTerm))
+ return false;
+ return modseq == ((ModifiedSinceTerm)obj).modseq;
+ }
+
+ /**
+ * Compute a hashCode for this object.
+ */
+ public int hashCode() {
+ return (int)modseq + super.hashCode();
+ }
+}

diff -r 1c932f38eb34 -r ed574b6f53ad mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java Wed Sep 04 14:03:31 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java Tue Sep 10 13:43:27 2013 -0700
@@ -1664,6 +1664,42 @@
         return ua;
     }
 
+ /**
+ * Get the sequence numbers for messages changed since the given
+ * modseq and with UIDs ranging from start till end.
+ * Also, prefetch the flags for the returned messages.
+ *
+ * @see "RFC 4551"
+ * @since JavaMail 1.5.1
+ */
+ public int[] uidfetchChangedSince(long start, long end, long modseq)
+ throws ProtocolException {
+ String msgSequence = String.valueOf(start) + ":" +
+ (end == UIDFolder.LASTUID ? "*" :
+ String.valueOf(end));
+ Response[] r = command("UID FETCH " + msgSequence +
+ " (FLAGS) (CHANGEDSINCE " + String.valueOf(modseq) + ")", null);
+
+ List v = new ArrayList();
+ for (int i = 0, len = r.length; i < len; i++) {
+ if (r[i] == null || !(r[i] instanceof FetchResponse))
+ continue;
+
+ FetchResponse fr = (FetchResponse)r[i];
+ v.add(Integer.valueOf(fr.getNumber()));
+ }
+
+ notifyResponseHandlers(r);
+ handleResult(r[r.length-1]);
+
+ // Copy the list into 'matches'
+ int vsize = v.size();
+ int[] matches = new int[vsize];
+ for (int i = 0; i < vsize; i++)
+ matches[i] = ((Integer)v.get(i)).intValue();
+ return matches;
+ }
+
     public Response[] fetch(MessageSet[] msgsets, String what)
                         throws ProtocolException {
         return fetch(MessageSet.toString(msgsets), what, false);

diff -r 1c932f38eb34 -r ed574b6f53ad mail/src/main/java/com/sun/mail/imap/protocol/SearchSequence.java
--- a/mail/src/main/java/com/sun/mail/imap/protocol/SearchSequence.java Wed Sep 04 14:03:31 2013 -0700
+++ b/mail/src/main/java/com/sun/mail/imap/protocol/SearchSequence.java Tue Sep 10 13:43:27 2013 -0700
@@ -48,6 +48,7 @@
 import com.sun.mail.iap.*;
 import com.sun.mail.imap.OlderTerm;
 import com.sun.mail.imap.YoungerTerm;
+import com.sun.mail.imap.ModifiedSinceTerm;
 
 /**
  * This class traverses a search-tree and generates the
@@ -116,6 +117,8 @@
             return younger((YoungerTerm)term);
         else if (term instanceof MessageIDTerm) // MessageID
             return messageid((MessageIDTerm)term, charset);
+ else if (term instanceof ModifiedSinceTerm) // RFC 4551 MODSEQ
+ return modifiedSince((ModifiedSinceTerm)term);
         else
             throw new SearchException("Search too complex");
     }
@@ -478,4 +481,17 @@
         result.writeNumber(term.getInterval());
         return result;
     }
+
+ /**
+ * Generate argument for ModifiedSinceTerm.
+ *
+ * @since JavaMail 1.5.1
+ */
+ protected Argument modifiedSince(ModifiedSinceTerm term)
+ throws SearchException {
+ Argument result = new Argument();
+ result.writeAtom("MODSEQ");
+ result.writeNumber(term.getModSeq());
+ return result;
+ }
 }