Author: sebb
Date: Sun Mar 27 14:53:48 2011
New Revision: 1085949
URL: http://svn.apache.org/viewvc?rev=1085949&view=rev
Log:
Move reply parsing to IMAPReply class
Distinguish between tagged and untagged replies when calling __getReply()
Modified:
commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java
commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java
Modified:
commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java
URL:
http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java?rev=1085949&r1=1085948&r2=1085949&view=diff
==============================================================================
---
commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java
(original)
+++
commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAP.java
Sun Mar 27 14:53:48 2011
@@ -26,7 +26,6 @@ import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
-import org.apache.commons.net.MalformedServerReplyException;
import org.apache.commons.net.ProtocolCommandListener;
import org.apache.commons.net.ProtocolCommandSupport;
import org.apache.commons.net.SocketClient;
@@ -95,6 +94,11 @@ public class IMAP extends SocketClient
private void __getReply() throws IOException
{
+ __getReply(true); // default to tagged response
+ }
+
+ private void __getReply(boolean wantTag) throws IOException
+ {
String line;
_replyLines.clear();
@@ -105,61 +109,18 @@ public class IMAP extends SocketClient
_replyLines.add(line);
- // Get extra lines if message continues.
- if (line.charAt(0) == IMAPReply.OK_INT_String.charAt(0)
- // can be untagged:
- && ! line.substring(2).startsWith(IMAPReply.OK_String))
- {
- do
- {
+ if (wantTag) {
+ while(IMAPReply.isUntagged(line)) {
line = _reader.readLine();
-
- if (line == null)
- throw new EOFException(
- "Connection closed without indication.");
-
+ if (line == null) {
+ throw new EOFException("Connection closed without
indication.");
+ }
_replyLines.add(line);
-
- // The length() check handles problems that could arise from
readLine()
- // returning too soon after encountering a naked CR or some
other
- // anomaly.
}
- while (line.charAt(0) == IMAPReply.OK_INT_String.charAt(0)
- // can be untagged:
- && ! line.substring(2).startsWith(IMAPReply.OK_String));
- }
-
- String _lastReplyLine = line;
- _lastReplyLine = _lastReplyLine.substring(_lastReplyLine.indexOf('
')+1).toUpperCase();
-
- // check the response code on the last line
- if (_lastReplyLine.startsWith(IMAPReply.OK_String))
- {
- _replyCode = IMAPReply.OK;
- }
- else if (_lastReplyLine.startsWith(IMAPReply.NO_String))
- {
- _replyCode = IMAPReply.NO;
- }
- else if (_lastReplyLine.startsWith(IMAPReply.BAD_String))
- {
- _replyCode = IMAPReply.BAD;
- }
- // response code not found - read the last line's type
- else if (line.startsWith(IMAPReply.OK_INT_String))
- {
- _replyCode = IMAPReply.OK_INT;
- }
- else if (line.startsWith(IMAPReply.CONT_String))
- {
- _replyCode = IMAPReply.CONT;
- }
- else
- {
- throw new
- MalformedServerReplyException(
- "Received invalid IMAP protocol response from server: '"
- + getReplyString() + "'.");
+ // check the response code on the last line
+ _replyCode = IMAPReply.getReplyCode(line);
+ } else {
+ _replyCode = IMAPReply.getUntaggedReplyCode(line);
}
if (_commandSupport_.getListenerCount() > 0)
@@ -184,7 +145,7 @@ public class IMAP extends SocketClient
if (tmo <= 0) { // none set currently
setSoTimeout(connectTimeout); // use connect timeout to ensure we
don't block forever
}
- __getReply();
+ __getReply(false); // untagged response
if (tmo <= 0) {
setSoTimeout(tmo); // restore the original value
}
Modified:
commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java
URL:
http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java?rev=1085949&r1=1085948&r2=1085949&view=diff
==============================================================================
---
commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java
(original)
+++
commons/proper/net/trunk/src/main/java/org/apache/commons/net/imap/IMAPReply.java
Sun Mar 27 14:53:48 2011
@@ -17,6 +17,12 @@
package org.apache.commons.net.imap;
+import java.io.IOException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.net.MalformedServerReplyException;
+
/**
* IMAPReply stores IMAP reply code constants.
*/
@@ -32,30 +38,100 @@ public final class IMAPReply
/** The reply code indicating command rejection. */
public static final int BAD = 2;
- /** The reply code indicating intermediate command processing stage. */
- public static final int OK_INT = 3;
-
- /** The reply code indicating a continuation mark. */
- public static final int CONT = 4;
-
- /** The reply String indicating success of an operation. */
- public static final String OK_String = "OK";
+ /** The IMAP reply String indicating success of an operation. */
+ private static final String IMAP_OK = "OK";
- /** The reply String indicating failure of an operation. */
- public static final String NO_String = "NO";
+ /** The IMAP reply String indicating failure of an operation. */
+ private static final String IMAP_NO = "NO";
- /** The reply String indicating command rejection. */
- public static final String BAD_String = "BAD";
+ /** The IMAP reply String indicating command rejection. */
+ private static final String IMAP_BAD = "BAD";
- /** The reply String indicating intermediate command processing stage. */
- public static final String OK_INT_String = "*";
+ // Start of line for untagged replies
+ private static final String IMAP_UNTAGGED_PREFIX = "* ";
- /** The reply String indicating a continuation mark. */
- public static final String CONT_String = "+";
+ // Start of line for continuation replies
+ private static final String IMAP_CONTINUATION_PREFIX = "+ ";
// Cannot be instantiated.
private IMAPReply()
{}
+
+ /**
+ * Checks if the reply line is untagged - e.g. "* OK ..."
+ * @param line to be checked
+ * @return {@code true} if the line is untagged
+ */
+ public static boolean isUntagged(String line) {
+ return line.startsWith(IMAP_UNTAGGED_PREFIX);
+ }
+
+ /**
+ * Checks if the reply line is a continuation, i.e. starts with "+ "
+ * @param line the line to be checked
+ * @return {@code true} if the line is untagged
+ */
+ public static boolean isContinuation(String line) {
+ return line.startsWith(IMAP_CONTINUATION_PREFIX);
+ }
+
+ private static final String TAGGED_RESPONSE = "^\\w+ (\\S+).*"; // TODO
perhaps be less strict on tag match?
+ // tag cannot contain: + ( ) { SP CTL % * " \ ]
+ private static final Pattern TAGGED_PATTERN =
Pattern.compile(TAGGED_RESPONSE);
+
+ /**
+ * Intepret the String reply code - OK, NO, BAD - in a tagged response as
a integer.
+ *
+ * @param line the tagged line to be checked
+ * @return {@link #OK} or {@link #NO} or {@link #BAD}
+ * @throws IOException if the input has an unexpected format
+ */
+ public static int getReplyCode(String line) throws IOException {
+ return getReplyCode(line, TAGGED_PATTERN);
+ }
+
+ private static final String UNTAGGED_RESPONSE = "^\\* (\\S+).*";
+ private static final Pattern UNTAGGED_PATTERN =
Pattern.compile(UNTAGGED_RESPONSE);
+
+ /**
+ * Intepret the String reply code - OK, NO, BAD - in an untagged response
as a integer.
+ *
+ * @param line the untagged line to be checked
+ * @return {@link #OK} or {@link #NO} or {@link #BAD}
+ * @throws IOException if the input has an unexpected format
+ */
+ public static int getUntaggedReplyCode(String line) throws IOException {
+ return getReplyCode(line, UNTAGGED_PATTERN);
+ }
+
+ // Helper method to process both tagged and untagged replies.
+ private static int getReplyCode(String line, Pattern pattern) throws
IOException{
+ Matcher m = pattern.matcher(line);
+ if (m.matches()) {
+ String code = m.group(1);
+ if (code.equals(IMAP_OK)) {
+ return OK;
+ }
+ if (code.equals(IMAP_BAD)) {
+ return BAD;
+ }
+ if (code.equals(IMAP_NO)) {
+ return NO;
+ }
+ }
+ throw new MalformedServerReplyException(
+ "Received unexpected IMAP protocol response from server: '" + line
+ "'.");
+ }
+
+ /**
+ * Checks whether the reply code indicates success or not
+ *
+ * @param replyCode the code to check
+ * @return {@code true} if the code equals {@link #OK}
+ */
+ public static boolean isSuccess(int replyCode) {
+ return replyCode == OK;
+ }
}
/* kate: indent-width 4; replace-tabs on; */