You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ri...@apache.org on 2009/08/21 13:15:27 UTC

svn commit: r806497 - /geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java

Author: rickmcguire
Date: Fri Aug 21 11:15:27 2009
New Revision: 806497

URL: http://svn.apache.org/viewvc?rev=806497&view=rev
Log:
GERONIMO-4611 Exchange IMAP problem


Modified:
    geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java

Modified: geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java?rev=806497&r1=806496&r2=806497&view=diff
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/imap/connection/IMAPResponseTokenizer.java Fri Aug 21 11:15:27 2009
@@ -19,9 +19,9 @@
 
 import java.io.ByteArrayOutputStream;
 import java.io.UnsupportedEncodingException;
-import java.util.ArrayList; 
-import java.util.Date; 
-import java.util.List; 
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
 
 import javax.mail.Flags;
 import javax.mail.MessagingException;
@@ -29,7 +29,7 @@
 import javax.mail.internet.MailDateFormat;
 import javax.mail.internet.ParameterList;
 
-import org.apache.geronimo.javamail.util.ResponseFormatException; 
+import org.apache.geronimo.javamail.util.ResponseFormatException;
 
 /**
  * @version $Rev$ $Date$
@@ -52,11 +52,11 @@
     static {
         initializeDecodingTable();
     }
-    
+
     // a singleton formatter for header dates.
     protected static MailDateFormat dateParser = new MailDateFormat();
-    
-    
+
+
     public static class Token {
         // Constant values from J2SE 1.4 API Docs (Constant values)
         public static final int ATOM = -1;
@@ -65,18 +65,18 @@
         public static final int NUMERIC = -4;
         public static final int EOF = -5;
         public static final int NIL = -6;
-        // special single character markers     
-        public static final int CONTINUATION = '-';
+        // special single character markers
+        public static final int CONTINUATION = '+';
         public static final int UNTAGGED = '*';
-            
+
         /**
-         * The type indicator.  This will be either a specific type, represented by 
-         * a negative number, or the actual character value. 
+         * The type indicator.  This will be either a specific type, represented by
+         * a negative number, or the actual character value.
          */
         private int type;
         /**
-         * The String value associated with this token.  All tokens have a String value, 
-         * except for the EOF and NIL tokens. 
+         * The String value associated with this token.  All tokens have a String value,
+         * except for the EOF and NIL tokens.
          */
         private String value;
 
@@ -98,10 +98,10 @@
         }
 
         /**
-         * Return the token as an integer value.  If this can't convert, an exception is 
-         * thrown. 
-         * 
-         * @return The integer value of the token. 
+         * Return the token as an integer value.  If this can't convert, an exception is
+         * thrown.
+         *
+         * @return The integer value of the token.
          * @exception ResponseFormatException
          */
         public int getInteger() throws MessagingException {
@@ -116,10 +116,10 @@
         }
 
         /**
-         * Return the token as a long value.  If it can't convert, an exception is 
-         * thrown. 
-         * 
-         * @return The token as a long value. 
+         * Return the token as a long value.  If it can't convert, an exception is
+         * thrown.
+         *
+         * @return The token as a long value.
          * @exception ResponseFormatException
          */
         public long getLong() throws MessagingException {
@@ -131,24 +131,24 @@
             }
             throw new ResponseFormatException("Number value expected in response; fount: " + value);
         }
-        
+
         /**
-         * Handy debugging toString() method for token. 
-         * 
-         * @return The string value of the token. 
+         * Handy debugging toString() method for token.
+         *
+         * @return The string value of the token.
          */
         public String toString() {
             if (type == NIL) {
-                return "NIL"; 
+                return "NIL";
             }
             else if (type == EOF) {
                 return "EOF";
             }
-            
+
             if (value == null) {
-                return ""; 
+                return "";
             }
-            return value; 
+            return value;
         }
     }
 
@@ -156,14 +156,14 @@
     public static final Token NIL = new Token(Token.NIL, null);
 
     private static final String WHITE = " \t\n\r";
-    // The list of delimiter characters we process when    
-    // handling parsing of ATOMs.  
+    // The list of delimiter characters we process when
+    // handling parsing of ATOMs.
     private static final String atomDelimiters = "(){}%*\"\\" + WHITE;
-    // this set of tokens is a slighly expanded set used for 
-    // specific response parsing.  When dealing with Body 
-    // section names, there are sub pieces to the name delimited 
-    // by "[", "]", ".", "<", ">" and SPACE, so reading these using 
-    // a superset of the ATOM processing makes for easier parsing. 
+    // this set of tokens is a slighly expanded set used for
+    // specific response parsing.  When dealing with Body
+    // section names, there are sub pieces to the name delimited
+    // by "[", "]", ".", "<", ">" and SPACE, so reading these using
+    // a superset of the ATOM processing makes for easier parsing.
     private static final String tokenDelimiters = "<>[].(){}%*\"\\" + WHITE;
 
     // the response data read from the connection
@@ -188,8 +188,8 @@
 
         return new String(response, pos, response.length - pos);
     }
-    
-    
+
+
     public Token next() throws MessagingException {
         return next(false);
     }
@@ -234,11 +234,11 @@
                 break;
             }
         }
-        
-        // Numeric tokens we store as a different type.  
-        String value = new String(response, start, pos - start); 
+
+        // Numeric tokens we store as a different type.
+        String value = new String(response, start, pos - start);
         try {
-            int intValue = Integer.parseInt(value); 
+            int intValue = Integer.parseInt(value);
             return new Token(Token.NUMERIC, value);
         } catch (NumberFormatException e) {
         }
@@ -253,8 +253,8 @@
      * @exception ResponseFormatException
      */
     private Token readToken(boolean nilAllowed, boolean expandedDelimiters) throws MessagingException {
-        String delimiters = expandedDelimiters ? tokenDelimiters : atomDelimiters; 
-        
+        String delimiters = expandedDelimiters ? tokenDelimiters : atomDelimiters;
+
         if (pos >= response.length) {
             return EOF;
         } else {
@@ -455,7 +455,7 @@
         } catch (NumberFormatException e) {
             throw new ResponseFormatException("Invalid literal length " + substring(lengthStart, lengthEnd));
         }
-        
+
         // step over the length
         pos = lengthEnd + 3;
 
@@ -466,7 +466,7 @@
 
         byte[] value = subarray(pos, pos + count);
         pos += count;
-        
+
         return value;
     }
 
@@ -574,8 +574,8 @@
                 && WHITE.indexOf(response[pos]) != -1)
             ;
     }
-    
-    
+
+
     /**
      * Ensure that the next token in the parsed response is a
      * '(' character.
@@ -623,7 +623,7 @@
         }
         return token.getValue();
     }
-    
+
 
     /**
      * Read an encoded string-valued token from the response.  A string
@@ -634,17 +634,17 @@
      * @exception ResponseFormatException
      */
     public String readEncodedString() throws MessagingException {
-        String value = readString(); 
-        return decode(value); 
+        String value = readString();
+        return decode(value);
     }
 
 
     /**
      * Decode a Base 64 encoded string value.
-     * 
+     *
      * @param original The original encoded string.
-     * 
-     * @return The decoded string. 
+     *
+     * @return The decoded string.
      * @exception MessagingException
      */
     public String decode(String original) throws MessagingException {
@@ -666,13 +666,13 @@
 
 
     /**
-     * Decode a section of an encoded string value. 
-     * 
+     * Decode a section of an encoded string value.
+     *
      * @param original The original source string.
      * @param index    The current working index.
      * @param result   The StringBuffer used for the decoded result.
-     * 
-     * @return The new index for the decoding operation. 
+     *
+     * @return The new index for the decoding operation.
      * @exception MessagingException
      */
     public static int decode(String original, int index, StringBuffer result) throws MessagingException {
@@ -798,9 +798,9 @@
      * @exception ResponseFormatException
      */
     public String readAtom() throws MessagingException {
-        return readAtom(false); 
+        return readAtom(false);
     }
-    
+
 
     /**
      * Read a string-valued token from the response, verifying this is an ATOM token.
@@ -828,7 +828,7 @@
      */
     public int readInteger() throws MessagingException {
         Token token = next();
-        return token.getInteger(); 
+        return token.getInteger();
     }
 
 
@@ -841,7 +841,7 @@
      */
     public int readLong() throws MessagingException {
         Token token = next();
-        return token.getInteger(); 
+        return token.getInteger();
     }
 
 
@@ -918,7 +918,7 @@
         String value = readStringOrNil();
         // this might be optional
         if (value == null) {
-            return null; 
+            return null;
         }
 
         try {
@@ -947,13 +947,13 @@
      * @exception ResponseFormatException
      */
     public InternetAddress readAddress() throws MessagingException {
-        // we recurse, expecting a null response back for sublists.  
+        // we recurse, expecting a null response back for sublists.
         if (peek().getType() != '(') {
-            return null; 
+            return null;
         }
-        
+
         // must start with a paren
-        checkLeftParen(); 
+        checkLeftParen();
 
         // personal information
         String personal = readStringOrNil();
@@ -1048,12 +1048,12 @@
         // we have a list, now parse it.
         while (notListEnd()) {
             // go read the next address.  If we had an address, add to the list.
-            // an address ITEM cannot be NIL inside the parens. 
+            // an address ITEM cannot be NIL inside the parens.
             InternetAddress address = readAddress();
             addresses.add(address);
         }
         // we need to skip over the peeked token.
-        checkRightParen(); 
+        checkRightParen();
         return (InternetAddress[])addresses.toArray(new InternetAddress[addresses.size()]);
     }
 
@@ -1099,7 +1099,7 @@
                     list.add(value);
                 }
             }
-            // step over the closing paren 
+            // step over the closing paren
             next();
 
             return list;
@@ -1123,20 +1123,20 @@
 
 
     /**
-     * Reads all remaining tokens and returns them as a list of strings. 
-     * NIL values are not supported. 
+     * Reads all remaining tokens and returns them as a list of strings.
+     * NIL values are not supported.
      *
      * @return A List containing all of the strings.
      * @exception ResponseFormatException
      */
     public List readStrings() throws MessagingException {
         List list = new ArrayList();
-        
+
         while (hasMore()) {
             String value = readString();
             list.add(value);
         }
-        return list; 
+        return list;
     }
 
 
@@ -1212,154 +1212,154 @@
     public byte[] readByteArray() throws MessagingException {
         return readData(true);
     }
-    
-    
+
+
     /**
-     * Determine what type of token encoding needs to be 
+     * Determine what type of token encoding needs to be
      * used for a string value.
-     * 
+     *
      * @param value  The string to test.
-     * 
-     * @return Either Token.ATOM, Token.QUOTEDSTRING, or 
+     *
+     * @return Either Token.ATOM, Token.QUOTEDSTRING, or
      *         Token.LITERAL, depending on the characters contained
      *         in the value.
      */
     static public int getEncoding(byte[] value) {
-        
-        // a null string always needs to be represented as a quoted literal. 
+
+        // a null string always needs to be represented as a quoted literal.
         if (value.length == 0) {
-            return Token.QUOTEDSTRING; 
+            return Token.QUOTEDSTRING;
         }
-        
+
         for (int i = 0; i < value.length; i++) {
-            int ch = value[i]; 
-            // make sure the sign extension is eliminated 
+            int ch = value[i];
+            // make sure the sign extension is eliminated
             ch = ch & 0xff;
-            // check first for any characters that would 
-            // disqualify a quoted string 
+            // check first for any characters that would
+            // disqualify a quoted string
             // NULL
             if (ch == 0x00) {
-                return Token.LITERAL; 
+                return Token.LITERAL;
             }
             // non-7bit ASCII
             if (ch > 0x7F) {
-                return Token.LITERAL; 
+                return Token.LITERAL;
             }
             // carriage return
             if (ch == '\r') {
-                return Token.LITERAL; 
+                return Token.LITERAL;
             }
-            // linefeed 
+            // linefeed
             if (ch == '\n') {
-                return Token.LITERAL; 
+                return Token.LITERAL;
             }
-            // now check for ATOM disqualifiers 
+            // now check for ATOM disqualifiers
             if (atomDelimiters.indexOf(ch) != -1) {
-                return Token.QUOTEDSTRING; 
+                return Token.QUOTEDSTRING;
             }
-            // CTL character.  We've already eliminated the high characters 
+            // CTL character.  We've already eliminated the high characters
             if (ch < 0x20) {
-                return Token.QUOTEDSTRING; 
+                return Token.QUOTEDSTRING;
             }
         }
-        // this can be an ATOM token 
+        // this can be an ATOM token
         return Token.ATOM;
     }
-    
-    
+
+
     /**
-     * Read a ContentType or ContentDisposition parameter 
+     * Read a ContentType or ContentDisposition parameter
      * list from an IMAP command response.
-     * 
-     * @return A ParameterList instance containing the parameters. 
+     *
+     * @return A ParameterList instance containing the parameters.
      * @exception MessagingException
      */
     public ParameterList readParameterList() throws MessagingException {
-        ParameterList params = new ParameterList(); 
-        
-        // read the tokens, taking NIL into account. 
-        Token token = next(true, false); 
-        
-        // just return an empty list if this is NIL 
+        ParameterList params = new ParameterList();
+
+        // read the tokens, taking NIL into account.
+        Token token = next(true, false);
+
+        // just return an empty list if this is NIL
         if (token.isType(token.NIL)) {
-            return params; 
+            return params;
         }
-        
-        // these are pairs of strings for each parameter value 
+
+        // these are pairs of strings for each parameter value
         while (notListEnd()) {
-            String name = readString(); 
-            String value = readString(); 
-            params.set(name, value); 
-        }
-        // we need to consume the list terminator 
-        checkRightParen(); 
-        return params; 
+            String name = readString();
+            String value = readString();
+            params.set(name, value);
+        }
+        // we need to consume the list terminator
+        checkRightParen();
+        return params;
     }
-    
-    
+
+
     /**
      * Test if we have more data in the response buffer.
-     * 
-     * @return true if there are more tokens to process.  false if 
+     *
+     * @return true if there are more tokens to process.  false if
      *         we've reached the end of the stream.
      */
     public boolean hasMore() throws MessagingException {
-        // we need to eat any white space that might be in the stream.  
+        // we need to eat any white space that might be in the stream.
         eatWhiteSpace();
-        return pos < response.length; 
+        return pos < response.length;
     }
-    
-    
+
+
     /**
      * Tests if we've reached the end of a parenthetical
      * list in our parsing stream.
-     * 
-     * @return true if the next token will be a ')'.  false if the 
+     *
+     * @return true if the next token will be a ')'.  false if the
      *         next token is anything else.
      * @exception MessagingException
      */
     public boolean notListEnd() throws MessagingException {
         return peek().getType() != ')';
     }
-    
+
     /**
-     * Read a list of Flag values from an IMAP response, 
-     * returning a Flags instance containing the appropriate 
-     * pieces. 
-     * 
-     * @return A Flags instance with the flag values. 
+     * Read a list of Flag values from an IMAP response,
+     * returning a Flags instance containing the appropriate
+     * pieces.
+     *
+     * @return A Flags instance with the flag values.
      * @exception MessagingException
      */
     public Flags readFlagList() throws MessagingException {
         Flags flags = new Flags();
-        
-        // this should be a list here 
-        checkLeftParen(); 
-        
-        // run through the flag list 
+
+        // this should be a list here
+        checkLeftParen();
+
+        // run through the flag list
         while (notListEnd()) {
-            // the flags are a bit of a pain.  The flag names include "\" in the name, which 
-            // is not a character allowed in an atom.  This requires a bit of customized parsing 
-            // to handle this. 
-            Token token = next(); 
-            // flags can be specified as just atom tokens, so allow this as a user flag. 
+            // the flags are a bit of a pain.  The flag names include "\" in the name, which
+            // is not a character allowed in an atom.  This requires a bit of customized parsing
+            // to handle this.
+            Token token = next();
+            // flags can be specified as just atom tokens, so allow this as a user flag.
             if (token.isType(token.ATOM)) {
-                // append the atom as a raw name 
-                flags.add(token.getValue()); 
+                // append the atom as a raw name
+                flags.add(token.getValue());
             }
-            // all of the system flags start with a '\' followed by 
-            // an atom.  They also can be extension flags.  IMAP has a special 
-            // case of "\*" that we need to check for. 
+            // all of the system flags start with a '\' followed by
+            // an atom.  They also can be extension flags.  IMAP has a special
+            // case of "\*" that we need to check for.
             else if (token.isType('\\')) {
-                token = next(); 
-                // the next token is the real bit we need to process. 
+                token = next();
+                // the next token is the real bit we need to process.
                 if (token.isType('*')) {
-                    // this indicates USER flags are allowed. 
-                    flags.add(Flags.Flag.USER); 
+                    // this indicates USER flags are allowed.
+                    flags.add(Flags.Flag.USER);
                 }
-                // if this is an atom name, handle as a system flag 
+                // if this is an atom name, handle as a system flag
                 else if (token.isType(Token.ATOM)) {
-                    String name = token.getValue(); 
+                    String name = token.getValue();
                     if (name.equalsIgnoreCase("Seen")) {
                         flags.add(Flags.Flag.SEEN);
                     }
@@ -1379,72 +1379,72 @@
                         flags.add(Flags.Flag.FLAGGED);
                     }
                     else {
-                        // this is a server defined flag....just add the name with the 
-                        // flag thingy prepended. 
-                        flags.add("\\" + name); 
+                        // this is a server defined flag....just add the name with the
+                        // flag thingy prepended.
+                        flags.add("\\" + name);
                     }
                 }
                 else {
-                    throw new MessagingException("Invalid Flag: " + token.getValue()); 
+                    throw new MessagingException("Invalid Flag: " + token.getValue());
                 }
             }
             else {
-                throw new MessagingException("Invalid Flag: " + token.getValue()); 
+                throw new MessagingException("Invalid Flag: " + token.getValue());
             }
         }
-        
-        // step over this for good practice. 
-        checkRightParen(); 
-        
-        return flags; 
-    }
-    
-    
-    /**
-     * Read a list of Flag values from an IMAP response, 
-     * returning a Flags instance containing the appropriate 
-     * pieces. 
-     * 
-     * @return A Flags instance with the flag values. 
+
+        // step over this for good practice.
+        checkRightParen();
+
+        return flags;
+    }
+
+
+    /**
+     * Read a list of Flag values from an IMAP response,
+     * returning a Flags instance containing the appropriate
+     * pieces.
+     *
+     * @return A Flags instance with the flag values.
      * @exception MessagingException
      */
     public List readSystemNameList() throws MessagingException {
-        List flags = new ArrayList(); 
-        
-        // this should be a list here 
-        checkLeftParen(); 
-        
-        // run through the flag list 
+        List flags = new ArrayList();
+
+        // this should be a list here
+        checkLeftParen();
+
+        // run through the flag list
         while (notListEnd()) {
-            // the flags are a bit of a pain.  The flag names include "\" in the name, which 
-            // is not a character allowed in an atom.  This requires a bit of customized parsing 
-            // to handle this. 
-            Token token = next(); 
-            // all of the system flags start with a '\' followed by 
-            // an atom.  They also can be extension flags.  IMAP has a special 
-            // case of "\*" that we need to check for. 
+            // the flags are a bit of a pain.  The flag names include "\" in the name, which
+            // is not a character allowed in an atom.  This requires a bit of customized parsing
+            // to handle this.
+            Token token = next();
+            // all of the system flags start with a '\' followed by
+            // an atom.  They also can be extension flags.  IMAP has a special
+            // case of "\*" that we need to check for.
             if (token.isType('\\')) {
-                token = next(); 
-                // if this is an atom name, handle as a system flag 
+                token = next();
+                // if this is an atom name, handle as a system flag
                 if (token.isType(Token.ATOM)) {
-                    // add the token value to the list WITH the 
-                    // flag indicator included.  The attributes method returns 
-                    // these flag indicators, so we need to include it. 
-                    flags.add("\\" + token.getValue()); 
+                    // add the token value to the list WITH the
+                    // flag indicator included.  The attributes method returns
+                    // these flag indicators, so we need to include it.
+                    flags.add("\\" + token.getValue());
                 }
                 else {
-                    throw new MessagingException("Invalid Flag: " + token.getValue()); 
+                    throw new MessagingException("Invalid Flag: " + token.getValue());
                 }
             }
             else {
-                throw new MessagingException("Invalid Flag: " + token.getValue()); 
+                throw new MessagingException("Invalid Flag: " + token.getValue());
             }
         }
-        
-        // step over this for good practice. 
-        checkRightParen(); 
-        
-        return flags; 
+
+        // step over this for good practice.
+        checkRightParen();
+
+        return flags;
     }
 }