You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by rd...@apache.org on 2008/03/22 09:53:39 UTC
svn commit: r639967 [1/2] - in /james/server/trunk:
experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/
experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/encode/writer/
imap-api/s...
Author: rdonkin
Date: Sat Mar 22 01:53:26 2008
New Revision: 639967
URL: http://svn.apache.org/viewvc?rev=639967&view=rev
Log:
Basic CHARSET implementation for SEARCH
Added:
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/MockLogger.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserCharsetTest.java
Modified:
james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/DefaultImapDecoderFactory.java
james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/encode/writer/ChannelImapResponseWriter.java
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/ImapConstants.java
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/display/HumanReadableTextKey.java
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponse.java
james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/AbstractTestForStatusResponseFactory.java
james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponseTest.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/ImapRequestLineReader.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/MessagingImapCommandParser.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/AppendCommandParser.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/Imap4Rev1CommandParserFactory.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/ListCommandParser.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseWriter.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/base/ImapResponseComposerImpl.java
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/StatusResponseEncoder.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/AbstractTestImapResponseComposer.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/ImapResponseTest.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/base/ByteImapResponseWriter.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/base/ImapResponseComposerImplTest.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/imap4rev1/StatusResponseEncoderTest.java
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/imap4rev1/legacy/MockImapResponseWriter.java
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/AppendProcessor.java
Modified: james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/DefaultImapDecoderFactory.java
URL: http://svn.apache.org/viewvc/james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/DefaultImapDecoderFactory.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/DefaultImapDecoderFactory.java (original)
+++ james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/DefaultImapDecoderFactory.java Sat Mar 22 01:53:26 2008
@@ -23,6 +23,7 @@
import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
import org.apache.james.imap.command.imap4rev1.StandardImap4Rev1CommandFactory;
import org.apache.james.imap.message.request.base.BaseImap4Rev1MessageFactory;
+import org.apache.james.imap.message.response.imap4rev1.status.UnpooledStatusResponseFactory;
import org.apache.james.imapserver.codec.decode.ImapCommandParserFactory;
import org.apache.james.imapserver.codec.decode.ImapDecoder;
import org.apache.james.imapserver.codec.decode.ImapDecoderFactory;
@@ -38,7 +39,7 @@
final Imap4Rev1MessageFactory messageFactory = new BaseImap4Rev1MessageFactory();
final Imap4Rev1CommandFactory commandFactory = new StandardImap4Rev1CommandFactory();
final ImapCommandParserFactory imapCommands = new Imap4Rev1CommandParserFactory(
- messageFactory, commandFactory);
+ messageFactory, commandFactory, new UnpooledStatusResponseFactory());
final ImapDecoder result = new DefaultImapDecoder(messageFactory,
imapCommands);
return result;
Modified: james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/encode/writer/ChannelImapResponseWriter.java
URL: http://svn.apache.org/viewvc/james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/encode/writer/ChannelImapResponseWriter.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/encode/writer/ChannelImapResponseWriter.java (original)
+++ james/server/trunk/experimental-seda-imap-function/src/main/java/org/apache/james/experimental/imapserver/encode/writer/ChannelImapResponseWriter.java Sat Mar 22 01:53:26 2008
@@ -168,13 +168,21 @@
}
public void closeParen() throws IOException {
- write(BYTES_CLOSING_PARENTHESIS);
+ closeBracket(BYTES_CLOSING_PARENTHESIS);
+ }
+
+ private void closeBracket(final byte[] bracket) throws IOException {
+ write(bracket);
clearSkipNextSpace();
}
public void openParen() throws IOException {
+ openBracket(BYTES_OPENING_PARENTHESIS);
+ }
+
+ private void openBracket(final byte[] bracket) throws IOException {
space();
- write(BYTES_OPENING_PARENTHESIS);
+ write(bracket);
skipNextSpace();
}
@@ -201,5 +209,13 @@
write(BYTES_CLOSE_BRACE);
write(BYTES_LINE_END);
literal.writeTo(out);
+ }
+
+ public void closeSquareBracket() throws IOException {
+ closeBracket(BYTES_CLOSE_SQUARE_BRACKET);
+ }
+
+ public void openSquareBracket() throws IOException {
+ openBracket(BYTES_OPEN_SQUARE_BRACKET);
}
}
Modified: james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/ImapConstants.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/ImapConstants.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/ImapConstants.java (original)
+++ james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/ImapConstants.java Sat Mar 22 01:53:26 2008
@@ -44,6 +44,8 @@
public static final byte BYTE_BACK_SLASH = 0x5C;
public static final byte BYTE_QUESTION = 0x3F;
public static final byte[] BYTES_DQUOTE = {BYTE_DQUOTE};
+ public static final byte BYTE_OPEN_SQUARE_BRACKET = 0x5B;
+ public static final byte[] BYTES_OPEN_SQUARE_BRACKET = {BYTE_OPEN_SQUARE_BRACKET};
public static final byte BYTE_CLOSE_SQUARE_BRACKET = 0x5D;
public static final byte[] BYTES_CLOSE_SQUARE_BRACKET = {BYTE_CLOSE_SQUARE_BRACKET};
public static final byte BYTE_OPEN_BRACE = 0x7B;
@@ -54,6 +56,9 @@
public static final char OPENING_PARENTHESIS = '(';
public static final char CLOSING_PARENTHESIS = ')';
+ public static final char OPENING_SQUARE_BRACKET = '[';
+ public static final char CLOSING_SQUARE_BRACKET = ']';
+
public static final char SP_CHAR = ' ';
public static final char DQUOTE ='\"';
Modified: james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/display/HumanReadableTextKey.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/display/HumanReadableTextKey.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/display/HumanReadableTextKey.java (original)
+++ james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/display/HumanReadableTextKey.java Sat Mar 22 01:53:26 2008
@@ -54,6 +54,10 @@
= new HumanReadableTextKey("org.apache.james.imap.UNSUPPORTED_CRITERIA",
"failed. One or more search criteria is unsupported.");
+ public static final HumanReadableTextKey BAD_CHARSET
+ = new HumanReadableTextKey("org.apache.james.imap.BAD_CHARSET",
+ "failed. Charset is unsupported.");
+
public static final HumanReadableTextKey MAILBOX_IS_READ_ONLY
= new HumanReadableTextKey("org.apache.james.imap.MAILBOX_IS_READ_ONLY",
"failed. Mailbox is read only.");
Modified: james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponse.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponse.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponse.java (original)
+++ james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponse.java Sat Mar 22 01:53:26 2008
@@ -19,6 +19,9 @@
package org.apache.james.api.imap.message.response.imap4rev1;
+import java.util.Collection;
+import java.util.Collections;
+
import org.apache.james.api.imap.ImapCommand;
import org.apache.james.api.imap.display.HumanReadableTextKey;
import org.apache.james.api.imap.message.response.ImapResponseMessage;
@@ -125,24 +128,102 @@
* Enumerates response codes.
*/
public static final class ResponseCode {
+
/** RFC2060 <code>ALERT</code> response code */
- public static final ResponseCode ALERT = new ResponseCode("[ALERT]");
- /** RFC2060 <code>NEWNAME</code> response code */
- public static final ResponseCode NEWNAME = new ResponseCode("[NEWNAME]");
+ private static final ResponseCode ALERT = new ResponseCode("ALERT");
/** RFC2060 <code>PARSE</code> response code */
- public static final ResponseCode PARSE = new ResponseCode("[PARSE]");
- /** RFC2060 <code>PERMANENTFLAGS</code> response code */
- public static final ResponseCode PERMANENTFLAGS = new ResponseCode("[PERMANENTFLAGS]");
+ private static final ResponseCode PARSE = new ResponseCode("PARSE");
/** RFC2060 <code>READ_ONLY</code> response code */
- public static final ResponseCode READ_ONLY = new ResponseCode("[READ-ONLY]");
+ private static final ResponseCode READ_ONLY = new ResponseCode("READ-ONLY");
/** RFC2060 <code>READ_WRITE</code> response code */
- public static final ResponseCode READ_WRITE = new ResponseCode("[READ-WRITE]");
+ private static final ResponseCode READ_WRITE = new ResponseCode("READ-WRITE");
/** RFC2060 <code>TRYCREATE</code> response code */
- public static final ResponseCode TRYCREATE = new ResponseCode("[TRYCREATE]");
- /** RFC2060 <code>UIDVALIDITY</code> response code */
- public static final ResponseCode UIDVALIDITY = new ResponseCode("[UIDVALIDITY]");
- /** RFC2060 <code>UNSEEN</code> response code */
- public static final ResponseCode UNSEEN = new ResponseCode("[UNSEEN]");
+ private static final ResponseCode TRYCREATE = new ResponseCode("TRYCREATE");
+
+ /**
+ * Creates a RFC2060 <code>ALERT</code> response code.
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode alert() {
+ return ALERT;
+ }
+
+ /**
+ * Creates a RFC2060 <code>BADCHARSET</code> response code.
+ * @param charsetNames <code>Collection<String></code> containing charset names
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode badCharset(Collection charsetNames) {
+ return new ResponseCode("BADCHARSET", charsetNames);
+ }
+
+ /**
+ * Creates a RFC2060 <code>PARSE</code> response code.
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode parse() {
+ return PARSE;
+ }
+
+ /**
+ * Creates a RFC2060 <code>PERMENANTFLAGS</code> response code.
+ * @param flagNames <code>Collection<String></code> containing flag names
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode permanentFlags(Collection flagNames) {
+ return new ResponseCode("PERMANENTFLAGS", flagNames);
+ }
+
+ /**
+ * Creates a RFC2060 <code>READ-ONLY</code> response code.
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode readOnly() {
+ return READ_ONLY;
+ }
+
+ /**
+ * Creates a RFC2060 <code>READ-WRITE</code> response code.
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode readWrite() {
+ return READ_WRITE;
+ }
+
+ /**
+ * Creates a RFC2060 <code>TRYCREATE</code> response code.
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode tryCreate() {
+ return TRYCREATE;
+ }
+
+ /**
+ * Creates a RFC2060 <code>UIDVALIDITY</code> response code.
+ * @param uid positive non-zero integer
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode uidValidity(int uid) {
+ return new ResponseCode("UIDVALIDITY", uid);
+ }
+
+ /**
+ * Creates a RFC2060 <code>UNSEEN</code> response code.
+ * @param numberUnseen positive non-zero integer
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode unseen(int numberUnseen) {
+ return new ResponseCode("UNSEEN", numberUnseen);
+ }
+
+ /**
+ * Creates a RFC2060 <code>UIDNEXT</code> response code.
+ * @param uid positive non-zero integer
+ * @return <code>ResponseCode</code>, not null
+ */
+ public static final ResponseCode uidNext(int uid) {
+ return new ResponseCode("UIDNEXT", uid);
+ }
/**
* Creates an extension response code.
@@ -151,32 +232,66 @@
* @return <code>ResponseCode</code>, not null
*/
public static ResponseCode createExtension(String name) {
- StringBuffer buffer = new StringBuffer();
- buffer.append('[');
+ StringBuffer buffer = new StringBuffer(name.length() + 2);
if (!name.startsWith("X")) {
buffer.append('X');
}
buffer.append(name);
- buffer.append(']');
final ResponseCode result = new ResponseCode(buffer.toString());
return result;
}
private final String code;
+ private final Collection parameters;
+ private final int number;
private ResponseCode(final String code) {
+ this(code, Collections.EMPTY_LIST, 0);
+ }
+
+ private ResponseCode(final String code, final int number) {
+ this(code, Collections.EMPTY_LIST, number);
+ }
+
+ private ResponseCode(final String code, final Collection parameters) {
+ this(code, parameters, 0);
+ }
+
+ private ResponseCode(final String code, final Collection parameters, final int number) {
super();
this.code = code;
+ this.parameters = parameters;
+ this.number = number;
}
public final String getCode() {
return code;
}
+
+ /**
+ * Gets number for this response.
+ * @return the number,
+ * or zero if no number has been set
+ */
+ public final int getNumber() {
+ return number;
+ }
+ /**
+ * Gets parameters for this code.
+ * @return the parameters <code>Collection</code>
+ * of <code>String</code> parameters, not null
+ */
+ public final Collection getParameters() {
+ return parameters;
+ }
+
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((code == null) ? 0 : code.hashCode());
+ result = PRIME * result + number;
+ result = PRIME * result + ((parameters == null) ? 0 : parameters.hashCode());
return result;
}
@@ -193,9 +308,16 @@
return false;
} else if (!code.equals(other.code))
return false;
+ if (number != other.number)
+ return false;
+ if (parameters == null) {
+ if (other.parameters != null)
+ return false;
+ } else if (!parameters.equals(other.parameters))
+ return false;
return true;
}
-
+
public String toString() {
return code;
}
Modified: james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/AbstractTestForStatusResponseFactory.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/AbstractTestForStatusResponseFactory.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/AbstractTestForStatusResponseFactory.java (original)
+++ james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/AbstractTestForStatusResponseFactory.java Sat Mar 22 01:53:26 2008
@@ -27,7 +27,7 @@
private static final String TAG = "ATAG";
private static final HumanReadableTextKey KEY = new HumanReadableTextKey("KEY", "TEXT");
- private static final StatusResponse.ResponseCode CODE = StatusResponse.ResponseCode.ALERT;
+ private static final StatusResponse.ResponseCode CODE = StatusResponse.ResponseCode.alert();
private ImapCommand command;
Modified: james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponseTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponseTest.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponseTest.java (original)
+++ james/server/trunk/imap-api/src/test/java/org/apache/james/api/imap/message/response/imap4rev1/StatusResponseTest.java Sat Mar 22 01:53:26 2008
@@ -30,7 +30,7 @@
}
public void testResponseCodeExtension() throws Exception {
- assertEquals("Preserve names beginning with X", "[XEXTENSION]", StatusResponse.ResponseCode.createExtension("XEXTENSION").getCode());
- assertEquals("Correct other names", "[XEXTENSION]", StatusResponse.ResponseCode.createExtension("EXTENSION").getCode());
+ assertEquals("Preserve names beginning with X", "XEXTENSION", StatusResponse.ResponseCode.createExtension("XEXTENSION").getCode());
+ assertEquals("Correct other names", "XEXTENSION", StatusResponse.ResponseCode.createExtension("EXTENSION").getCode());
}
}
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/request/base/BaseImap4Rev1MessageFactory.java Sat Mar 22 01:53:26 2008
@@ -160,7 +160,5 @@
public ImapMessage createCheckMessage(ImapCommand command, String tag) {
return new CheckRequest(command, tag);
- }
-
-
+ }
}
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/ImapRequestLineReader.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/ImapRequestLineReader.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/ImapRequestLineReader.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/ImapRequestLineReader.java Sat Mar 22 01:53:26 2008
@@ -146,6 +146,8 @@
/**
* Reads and consumes a number of characters from the underlying reader,
* filling the char array provided.
+ * TODO: remove unnecessary copying of bits; line reader should maintain an internal
+ * ByteBuffer;
* @param holder A char array which will be filled with chars read from the underlying reader.
* @throws ProtocolException If a char can't be read into each array element.
*/
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/MessagingImapCommandParser.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/MessagingImapCommandParser.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/MessagingImapCommandParser.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/MessagingImapCommandParser.java Sat Mar 22 01:53:26 2008
@@ -19,6 +19,7 @@
package org.apache.james.imapserver.codec.decode;
import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponseFactory;
public interface MessagingImapCommandParser {
@@ -26,4 +27,7 @@
public abstract void setMessageFactory(Imap4Rev1MessageFactory messageFactory);
+ public abstract StatusResponseFactory getStatusResponseFactory();
+
+ public abstract void setStatusResponseFactory(StatusResponseFactory statusResponseFactory) ;
}
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/AbstractImapCommandParser.java Sat Mar 22 01:53:26 2008
@@ -19,6 +19,12 @@
package org.apache.james.imapserver.codec.decode.base;
+import java.nio.ByteBuffer;
+import java.nio.charset.CharacterCodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.MalformedInputException;
+import java.nio.charset.UnmappableCharacterException;
import java.util.ArrayList;
import java.util.Date;
@@ -32,6 +38,7 @@
import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
import org.apache.james.api.imap.message.IdRange;
import org.apache.james.api.imap.message.request.DayMonthYear;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponseFactory;
import org.apache.james.imapserver.codec.decode.DecoderUtils;
import org.apache.james.imapserver.codec.decode.ImapCommandParser;
import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
@@ -45,8 +52,11 @@
*/
public abstract class AbstractImapCommandParser extends AbstractLogEnabled implements ImapCommandParser, MessagingImapCommandParser
{
+ private static final Charset US_ASCII = Charset.forName("US-ASCII");
+
private ImapCommand command;
private Imap4Rev1MessageFactory messageFactory;
+ private StatusResponseFactory statusResponseFactory;
public AbstractImapCommandParser() {
super();
@@ -74,6 +84,15 @@
this.messageFactory = messageFactory;
}
+ public final StatusResponseFactory getStatusResponseFactory() {
+ return statusResponseFactory;
+ }
+
+ public final void setStatusResponseFactory(
+ StatusResponseFactory statusResponseFactory) {
+ this.statusResponseFactory = statusResponseFactory;
+ }
+
/**
* Parses a request into a command message
* for later processing.
@@ -131,12 +150,20 @@
*/
public String astring(ImapRequestLineReader request) throws ProtocolException
{
+ return astring(request, null);
+ }
+
+ /**
+ * Reads an argument of type "astring" from the request.
+ */
+ public String astring(ImapRequestLineReader request, Charset charset) throws ProtocolException
+ {
char next = request.nextWordChar();
switch ( next ) {
case '"':
return consumeQuoted( request );
case '{':
- return consumeLiteral( request );
+ return consumeLiteral( request, charset );
default:
return atom( request );
}
@@ -152,7 +179,7 @@
case '"':
return consumeQuoted( request );
case '{':
- return consumeLiteral( request );
+ return consumeLiteral( request, null );
default:
String value = atom( request );
if ( "NIL".equals( value ) ) {
@@ -277,44 +304,66 @@
* "{" charCount "}" CRLF *CHAR8
* Note before calling, the request should be positioned so that nextChar
* is '{'. Leading whitespace is not skipped in this method.
+ * @param charset ,
+ * or null for <code>US-ASCII</code>
*/
- protected String consumeLiteral( ImapRequestLineReader request )
+ protected String consumeLiteral( final ImapRequestLineReader request, final Charset charset )
throws ProtocolException
{
- // The 1st character must be '{'
- consumeChar( request, '{' );
-
- StringBuffer digits = new StringBuffer();
- char next = request.nextChar();
- while ( next != '}' && next != '+' )
- {
- digits.append( next );
- request.consume();
- next = request.nextChar();
- }
-
- // If the number is *not* suffixed with a '+', we *are* using a synchronized literal,
- // and we need to send command continuation request before reading data.
- boolean synchronizedLiteral = true;
- // '+' indicates a non-synchronized literal (no command continuation request)
- if ( next == '+' ) {
- synchronizedLiteral = false;
- consumeChar(request, '+' );
- }
-
- // Consume the '}' and the newline
- consumeChar( request, '}' );
- consumeCRLF( request );
-
- if ( synchronizedLiteral ) {
- request.commandContinuationRequest();
+ if (charset == null) {
+ return consumeLiteral(request, US_ASCII);
+ } else {
+ // The 1st character must be '{'
+ consumeChar( request, '{' );
+
+ StringBuffer digits = new StringBuffer();
+ char next = request.nextChar();
+ while ( next != '}' && next != '+' )
+ {
+ digits.append( next );
+ request.consume();
+ next = request.nextChar();
+ }
+
+ // If the number is *not* suffixed with a '+', we *are* using a synchronized literal,
+ // and we need to send command continuation request before reading data.
+ boolean synchronizedLiteral = true;
+ // '+' indicates a non-synchronized literal (no command continuation request)
+ if ( next == '+' ) {
+ synchronizedLiteral = false;
+ consumeChar(request, '+' );
+ }
+
+ // Consume the '}' and the newline
+ consumeChar( request, '}' );
+ consumeCRLF( request );
+
+ if ( synchronizedLiteral ) {
+ request.commandContinuationRequest();
+ }
+
+ final int size = Integer.parseInt( digits.toString() );
+ final byte[] bytes = new byte[size];
+ request.read( bytes );
+ final ByteBuffer buffer = ByteBuffer.wrap(bytes);
+ try {
+
+ final String result = charset.newDecoder()
+ .onMalformedInput(CodingErrorAction.REPORT)
+ .onUnmappableCharacter(CodingErrorAction.REPORT)
+ .decode(buffer).toString();
+ return result;
+
+ } catch (IllegalStateException e) {
+ throw new ProtocolException ("Bad character encoding", e);
+ } catch (MalformedInputException e) {
+ throw new ProtocolException ("Bad character encoding", e);
+ } catch (UnmappableCharacterException e) {
+ throw new ProtocolException ("Bad character encoding", e);
+ } catch (CharacterCodingException e) {
+ throw new ProtocolException ("Bad character encoding", e);
+ }
}
-
- int size = Integer.parseInt( digits.toString() );
- byte[] buffer = new byte[size];
- request.read( buffer );
-
- return new String( buffer );
}
/**
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/AppendCommandParser.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/AppendCommandParser.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/AppendCommandParser.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/AppendCommandParser.java Sat Mar 22 01:53:26 2008
@@ -91,7 +91,7 @@
throws ProtocolException
{
request.nextWordChar();
- String mailString = consumeLiteral(request);
+ String mailString = consumeLiteral(request, null);
MimeMessage mm = null;
try {
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/Imap4Rev1CommandParserFactory.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/Imap4Rev1CommandParserFactory.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/Imap4Rev1CommandParserFactory.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/Imap4Rev1CommandParserFactory.java Sat Mar 22 01:53:26 2008
@@ -28,6 +28,7 @@
import org.apache.james.api.imap.ImapConstants;
import org.apache.james.api.imap.imap4rev1.Imap4Rev1CommandFactory;
import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponseFactory;
import org.apache.james.imapserver.codec.decode.DelegatingImapCommandParser;
import org.apache.james.imapserver.codec.decode.ImapCommandParser;
import org.apache.james.imapserver.codec.decode.ImapCommandParserFactory;
@@ -44,12 +45,15 @@
{
private Map _imapCommands;
private final Imap4Rev1MessageFactory messageFactory;
+ private final StatusResponseFactory statusResponseFactory;
private final Imap4Rev1CommandFactory commandFactory;
- public Imap4Rev1CommandParserFactory(final Imap4Rev1MessageFactory messageFactory, final Imap4Rev1CommandFactory commandFactory)
+ public Imap4Rev1CommandParserFactory(final Imap4Rev1MessageFactory messageFactory, final Imap4Rev1CommandFactory commandFactory,
+ final StatusResponseFactory statusResponseFactory)
{
this.messageFactory = messageFactory;
this.commandFactory = commandFactory;
+ this.statusResponseFactory = statusResponseFactory;
_imapCommands = new HashMap();
// Commands valid in any state
@@ -144,7 +148,9 @@
}
if (cmd instanceof MessagingImapCommandParser) {
- ((MessagingImapCommandParser) cmd).setMessageFactory(messageFactory);
+ final MessagingImapCommandParser messagingImapCommandParser = (MessagingImapCommandParser) cmd;
+ messagingImapCommandParser.setMessageFactory(messageFactory);
+ messagingImapCommandParser.setStatusResponseFactory(statusResponseFactory);
}
if (cmd instanceof InitialisableCommandFactory) {
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/ListCommandParser.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/ListCommandParser.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/ListCommandParser.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/ListCommandParser.java Sat Mar 22 01:53:26 2008
@@ -53,7 +53,7 @@
case '"':
return consumeQuoted( request );
case '{':
- return consumeLiteral( request );
+ return consumeLiteral( request, null );
default:
return consumeWord( request, new ListCharValidator() );
}
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParser.java Sat Mar 22 01:53:26 2008
@@ -18,21 +18,35 @@
****************************************************************/
package org.apache.james.imapserver.codec.decode.imap4rev1;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import org.apache.james.api.imap.ImapCommand;
import org.apache.james.api.imap.ImapMessage;
import org.apache.james.api.imap.ProtocolException;
+import org.apache.james.api.imap.display.HumanReadableTextKey;
import org.apache.james.api.imap.imap4rev1.Imap4Rev1CommandFactory;
import org.apache.james.api.imap.message.IdRange;
import org.apache.james.api.imap.message.request.DayMonthYear;
import org.apache.james.api.imap.message.request.SearchKey;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponse;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponseFactory;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponse.ResponseCode;
import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
import org.apache.james.imapserver.codec.decode.InitialisableCommandFactory;
class SearchCommandParser extends AbstractUidCommandParser implements InitialisableCommandFactory
{
+ /** Lazy loaded */
+ private Collection charsetNames;
+
public SearchCommandParser() {
}
@@ -47,36 +61,41 @@
/**
* Parses the request argument into a valid search term.
+ * @param request <code>ImapRequestLineReader</code>, not null
+ * @param charset <code>Charset</code> or null if there is no charset
+ * @param isFirstToken true when this is the first token read,
+ * false otherwise
*/
- public SearchKey searchKey( ImapRequestLineReader request ) throws ProtocolException {
+ public SearchKey searchKey( ImapRequestLineReader request, Charset charset, boolean isFirstToken )
+ throws ProtocolException, IllegalCharsetNameException, UnsupportedCharsetException {
final char next = request.nextChar();
if (next >= '0' && next <= '9' || next == '*') {
return sequenceSet(request);
} else if (next == '(') {
- return paren(request);
+ return paren(request, charset);
} else {
final int cap = consumeAndCap(request);
switch (cap) {
case 'A': return a(request);
- case 'B': return b(request);
- case 'C': return cc(request);
+ case 'B': return b(request, charset);
+ case 'C': return c(request, isFirstToken, charset);
case 'D': return d(request);
case 'E': throw new ProtocolException("Unknown search key");
- case 'F': return f(request);
+ case 'F': return f(request, charset);
case 'G': throw new ProtocolException("Unknown search key");
- case 'H': return header(request);
+ case 'H': return header(request, charset);
case 'I': throw new ProtocolException("Unknown search key");
case 'J': throw new ProtocolException("Unknown search key");
case 'K': return keyword(request);
case 'L': return larger(request);
case 'M': throw new ProtocolException("Unknown search key");
- case 'N': return n(request);
- case 'O': return o(request);
+ case 'N': return n(request, charset);
+ case 'O': return o(request, charset);
case 'P': throw new ProtocolException("Unknown search key");
case 'Q': throw new ProtocolException("Unknown search key");
case 'R': return recent(request);
- case 'S': return s(request);
- case 'T': return t(request);
+ case 'S': return s(request, charset);
+ case 'T': return t(request, charset);
case 'U': return u(request);
default:
throw new ProtocolException("Unknown search key");
@@ -84,21 +103,21 @@
}
}
- private SearchKey paren(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey paren(ImapRequestLineReader request, Charset charset) throws ProtocolException {
request.consume();
List keys = new ArrayList();
- addUntilParen(request, keys);
+ addUntilParen(request, keys, charset);
return SearchKey.buildAnd(keys);
}
- private void addUntilParen(ImapRequestLineReader request, List keys) throws ProtocolException {
+ private void addUntilParen(ImapRequestLineReader request, List keys, Charset charset) throws ProtocolException {
final char next = request.nextWordChar();
if (next == ')') {
request.consume();
} else {
- final SearchKey key = searchKey( request );
+ final SearchKey key = searchKey( request, null, false );
keys.add(key);
- addUntilParen(request, keys);
+ addUntilParen(request, keys, charset);
}
}
@@ -108,15 +127,44 @@
return cap;
}
- private SearchKey cc(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey cc(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final SearchKey result;
- nextIsC(request);
nextIsSpace(request);
- final String value = astring(request);
+ final String value = astring(request, charset);
result = SearchKey.buildCc(value);
return result;
}
+ private SearchKey c(ImapRequestLineReader request, final boolean isFirstToken, final Charset charset)
+ throws ProtocolException, IllegalCharsetNameException, UnsupportedCharsetException {
+ final int next = consumeAndCap(request);
+ switch (next) {
+ case 'C': return cc(request, charset);
+ case 'H': return charset(request, isFirstToken);
+ default:
+ throw new ProtocolException("Unknown search key");
+ }
+ }
+
+ private SearchKey charset(ImapRequestLineReader request, final boolean isFirstToken)
+ throws ProtocolException, IllegalCharsetNameException, UnsupportedCharsetException {
+ final SearchKey result;
+ nextIsA(request);
+ nextIsR(request);
+ nextIsS(request);
+ nextIsE(request);
+ nextIsT(request);
+ nextIsSpace(request);
+ if (!isFirstToken) {
+ throw new ProtocolException("Unknown search key");
+ }
+ final String value = astring(request);
+ final Charset charset = Charset.forName(value);
+ request.nextWordChar();
+ result = searchKey(request, charset, false);
+ return result;
+ }
+
private SearchKey u(ImapRequestLineReader request) throws ProtocolException {
final int next = consumeAndCap(request);
switch (next) {
@@ -150,23 +198,23 @@
}
}
- private SearchKey t(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey t(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final int next = consumeAndCap(request);
switch (next) {
- case 'E': return text(request);
- case 'O': return to(request);
+ case 'E': return text(request, charset);
+ case 'O': return to(request, charset);
default:
throw new ProtocolException("Unknown search key");
}
}
- private SearchKey s(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey s(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final int next = consumeAndCap(request);
switch (next) {
case 'E': return se(request);
case 'I': return since(request);
case 'M': return smaller(request);
- case 'U': return subject(request);
+ case 'U': return subject(request, charset);
default:
throw new ProtocolException("Unknown search key");
}
@@ -202,32 +250,32 @@
}
}
- private SearchKey o(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey o(ImapRequestLineReader request, Charset charset) throws ProtocolException {
final int next = consumeAndCap(request);
switch (next) {
case 'L': return old(request);
case 'N': return on(request);
- case 'R': return or(request);
+ case 'R': return or(request, charset);
default:
throw new ProtocolException("Unknown search key");
}
}
- private SearchKey n(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey n(ImapRequestLineReader request, Charset charset) throws ProtocolException {
final int next = consumeAndCap(request);
switch (next) {
case 'E': return _new(request);
- case 'O': return not(request);
+ case 'O': return not(request, charset);
default:
throw new ProtocolException("Unknown search key");
}
}
- private SearchKey f(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey f(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final int next = consumeAndCap(request);
switch (next) {
case 'L': return flagged(request);
- case 'R': return from(request);
+ case 'R': return from(request, charset);
default:
throw new ProtocolException("Unknown search key");
}
@@ -272,7 +320,7 @@
}
- private SearchKey header(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey header(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final SearchKey result;
nextIsE(request);
nextIsA(request);
@@ -280,9 +328,9 @@
nextIsE(request);
nextIsR(request);
nextIsSpace(request);
- final String field = astring(request);
+ final String field = astring(request, charset);
nextIsSpace(request);
- final String value = astring(request);
+ final String value = astring(request, charset);
result = SearchKey.buildHeader(field, value);
return result;
}
@@ -313,12 +361,12 @@
return result;
}
- private SearchKey from(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey from(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final SearchKey result;
nextIsO(request);
nextIsM(request);
nextIsSpace(request);
- final String value = astring(request);
+ final String value = astring(request, charset);
result = SearchKey.buildFrom(value);
return result;
}
@@ -395,21 +443,21 @@
return result;
}
- private SearchKey or(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey or(ImapRequestLineReader request, Charset charset) throws ProtocolException {
final SearchKey result;
nextIsSpace(request);
- final SearchKey firstKey = searchKey(request);
+ final SearchKey firstKey = searchKey(request, charset, false);
nextIsSpace(request);
- final SearchKey secondKey = searchKey(request);
+ final SearchKey secondKey = searchKey(request, charset, false);
result = SearchKey.buildOr(firstKey, secondKey);
return result;
}
- private SearchKey not(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey not(ImapRequestLineReader request, Charset charset) throws ProtocolException {
final SearchKey result;
nextIsT(request);
nextIsSpace(request);
- final SearchKey nextKey = searchKey(request);
+ final SearchKey nextKey = searchKey(request, charset, false);
result = SearchKey.buildNot(nextKey);
return result;
}
@@ -459,23 +507,23 @@
return result;
}
- private SearchKey b(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey b(ImapRequestLineReader request, Charset charset) throws ProtocolException {
final int next = consumeAndCap(request);
switch (next) {
- case 'C': return bcc(request);
+ case 'C': return bcc(request, charset);
case 'E': return before(request);
- case 'O': return body(request);
+ case 'O': return body(request, charset);
default:
throw new ProtocolException("Unknown search key");
}
}
- private SearchKey body(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey body(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final SearchKey result;
nextIsD(request);
nextIsY(request);
nextIsSpace(request);
- final String value = astring(request);
+ final String value = astring(request, charset);
result = SearchKey.buildBody(value);
return result;
}
@@ -545,21 +593,21 @@
return result;
}
- private SearchKey bcc(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey bcc(ImapRequestLineReader request, Charset charset) throws ProtocolException {
final SearchKey result;
nextIsC(request);
nextIsSpace(request);
- final String value = astring(request);
+ final String value = astring(request, charset);
result = SearchKey.buildBcc(value);
return result;
}
- private SearchKey text(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey text(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final SearchKey result;
nextIsX(request);
nextIsT(request);
nextIsSpace(request);
- final String value = astring(request);
+ final String value = astring(request, charset);
result = SearchKey.buildText(value);
return result;
}
@@ -579,15 +627,15 @@
return result;
}
- private SearchKey to(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey to(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final SearchKey result;
nextIsSpace(request);
- final String value = astring(request);
+ final String value = astring(request, charset);
result = SearchKey.buildTo(value);
return result;
}
- private SearchKey subject(ImapRequestLineReader request) throws ProtocolException {
+ private SearchKey subject(ImapRequestLineReader request, final Charset charset) throws ProtocolException {
final SearchKey result;
nextIsB(request);
nextIsJ(request);
@@ -595,7 +643,7 @@
nextIsC(request);
nextIsT(request);
nextIsSpace(request);
- final String value = astring(request);
+ final String value = astring(request, charset);
result = SearchKey.buildSubject(value);
return result;
}
@@ -719,16 +767,16 @@
}
}
- public SearchKey decode(ImapRequestLineReader request) throws ProtocolException {
+ public SearchKey decode(ImapRequestLineReader request) throws ProtocolException, IllegalCharsetNameException, UnsupportedCharsetException {
request.nextWordChar();
- final SearchKey firstKey = searchKey( request );
+ final SearchKey firstKey = searchKey( request, null, true );
final SearchKey result;
if (request.nextChar() == ' ') {
List keys = new ArrayList();
keys.add(firstKey);
while (request.nextChar() == ' ') {
request.nextWordChar();
- final SearchKey key = searchKey( request );
+ final SearchKey key = searchKey( request, null, false );
keys.add(key);
}
result = SearchKey.buildAnd(keys);
@@ -739,12 +787,38 @@
return result;
}
- protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, String tag, boolean useUids) throws ProtocolException {
- // Parse the search term from the request
- final SearchKey key = decode( request );
-
- final ImapMessage result = getMessageFactory().createSearchMessage(command, key, useUids, tag);
+ private ImapMessage unsupportedCharset(final String tag, final ImapCommand command) {
+ loadCharsetNames();
+ final StatusResponseFactory factory = getStatusResponseFactory();
+ final ResponseCode badCharset = StatusResponse.ResponseCode.badCharset(charsetNames);
+ final StatusResponse result = factory.taggedNo(tag, command, HumanReadableTextKey.BAD_CHARSET, badCharset);
return result;
}
+ private synchronized void loadCharsetNames() {
+ if (charsetNames == null) {
+ charsetNames = new HashSet();
+ for (final Iterator it = Charset.availableCharsets().values().iterator(); it.hasNext();) {
+ final Charset charset = (Charset) it.next();
+ final Set aliases = charset.aliases();
+ charsetNames.addAll(aliases);
+ }
+ }
+ }
+
+ protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, String tag, boolean useUids) throws ProtocolException {
+ try {
+ // Parse the search term from the request
+ final SearchKey key = decode( request );
+
+ final ImapMessage result = getMessageFactory().createSearchMessage(command, key, useUids, tag);
+ return result;
+ } catch (IllegalCharsetNameException e) {
+ getLogger().debug(e.getMessage());
+ return unsupportedCharset(tag, command);
+ } catch (UnsupportedCharsetException e) {
+ getLogger().debug(e.getMessage());
+ return unsupportedCharset(tag, command);
+ }
+ }
}
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseComposer.java Sat Mar 22 01:53:26 2008
@@ -20,6 +20,7 @@
package org.apache.james.imapserver.codec.encode;
import java.io.IOException;
+import java.util.Collection;
import java.util.List;
import javax.mail.Flags;
@@ -270,7 +271,7 @@
public abstract void tag(String tag) throws IOException;
public abstract void statusResponse(String tag, ImapCommand command,
- String type, String responseCode, String text) throws IOException;
+ String type, String responseCode, Collection parameters, long number, String text) throws IOException;
public abstract void statusResponse(Long messages, Long recent,
Long uidNext, Long uidValidity, Long unseen, String mailboxName) throws IOException;
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseWriter.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseWriter.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseWriter.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/ImapResponseWriter.java Sat Mar 22 01:53:26 2008
@@ -84,6 +84,19 @@
void closeParen() throws IOException;
/**
+ * Closes a square bracket - writes a <code>[</code>.
+ * @throws IOException
+ */
+ void openSquareBracket() throws IOException;
+
+ /**
+ * Closes a square bracket - writes a <code>]</code>.
+ * @throws IOException
+ */
+ void closeSquareBracket() throws IOException;
+
+
+ /**
* Ends a response.
*
*/
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/base/ImapResponseComposerImpl.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/base/ImapResponseComposerImpl.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/base/ImapResponseComposerImpl.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/base/ImapResponseComposerImpl.java Sat Mar 22 01:53:26 2008
@@ -20,6 +20,7 @@
package org.apache.james.imapserver.codec.encode.base;
import java.io.IOException;
+import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -343,9 +344,10 @@
/**
* @throws IOException
- * @see org.apache.james.imapserver.codec.encode.ImapResponseComposer#statusResponse(java.lang.String, org.apache.james.api.imap.ImapCommand, java.lang.String, java.lang.String, java.lang.String)
+ * @see org.apache.james.imapserver.codec.encode.ImapResponseComposer#statusResponse(java.lang.String, org.apache.james.api.imap.ImapCommand, java.lang.String, java.lang.String, Collection, long, java.lang.String)
*/
- public void statusResponse(String tag, ImapCommand command, String type, String responseCode, String text) throws IOException {
+ public void statusResponse(String tag, ImapCommand command, String type, String responseCode,
+ Collection parameters, long number, String text) throws IOException {
if (tag == null) {
untagged();
} else {
@@ -353,7 +355,20 @@
}
message(type);
if (responseCode != null) {
+ openSquareBracket();
message(responseCode);
+ if (parameters != null && ! parameters.isEmpty()) {
+ openParen();
+ for (Iterator it = parameters.iterator();it.hasNext();) {
+ final String parameter = (String) it.next();
+ message(parameter);
+ }
+ closeParen();
+ }
+ if (number > 0) {
+ message(number);
+ }
+ closeSquareBracket();
}
if (command != null) {
commandName(command);
@@ -546,5 +561,13 @@
public void skipNextSpace() throws IOException {
writer.skipNextSpace();
+ }
+
+ public void closeSquareBracket() throws IOException {
+ writer.closeSquareBracket();
+ }
+
+ public void openSquareBracket() throws IOException {
+ writer.openSquareBracket();
}
}
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/StatusResponseEncoder.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/StatusResponseEncoder.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/StatusResponseEncoder.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/StatusResponseEncoder.java Sat Mar 22 01:53:26 2008
@@ -20,10 +20,14 @@
package org.apache.james.imapserver.codec.encode.imap4rev1;
import java.io.IOException;
+import java.util.Collection;
+import org.apache.james.api.imap.ImapCommand;
import org.apache.james.api.imap.ImapMessage;
import org.apache.james.api.imap.display.HumanReadableTextKey;
import org.apache.james.api.imap.message.response.imap4rev1.StatusResponse;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponse.ResponseCode;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponse.Type;
import org.apache.james.imapserver.codec.encode.ImapEncoder;
import org.apache.james.imapserver.codec.encode.ImapResponseComposer;
import org.apache.james.imapserver.codec.encode.base.AbstractChainedImapEncoder;
@@ -37,9 +41,24 @@
protected void doEncode(ImapMessage acceptableMessage,
ImapResponseComposer composer) throws IOException {
StatusResponse response = (StatusResponse) acceptableMessage;
- composer.statusResponse(response.getTag(), response.getCommand(),
- asString(response.getServerResponseType()), asString(response.getResponseCode()),
- asString(response.getTextKey()));
+ final Type serverResponseType = response.getServerResponseType();
+ final String type = asString(serverResponseType);
+ final ResponseCode responseCode = response.getResponseCode();
+ final String code = asString(responseCode);
+ final String tag = response.getTag();
+ final ImapCommand command = response.getCommand();
+ final HumanReadableTextKey textKey = response.getTextKey();
+ final String text = asString(textKey);
+ final Collection parameters;
+ final int number;
+ if (responseCode == null) {
+ parameters = null;
+ number = 0;
+ } else {
+ parameters = responseCode.getParameters();
+ number = responseCode.getNumber();
+ }
+ composer.statusResponse(tag, command, type, code, parameters, number, text);
}
private String asString(HumanReadableTextKey text)
Added: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/MockLogger.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/MockLogger.java?rev=639967&view=auto
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/MockLogger.java (added)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/MockLogger.java Sat Mar 22 01:53:26 2008
@@ -0,0 +1,83 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+/**
+ *
+ */
+package org.apache.james.imapserver.codec.decode.imap4rev1;
+
+import org.apache.avalon.framework.logger.Logger;
+
+final class MockLogger implements Logger {
+ public void debug(String arg0) {
+ }
+
+ public void debug(String arg0, Throwable arg1) {
+ }
+
+ public void error(String arg0) {
+ }
+
+ public void error(String arg0, Throwable arg1) {
+ }
+
+ public void fatalError(String arg0) {
+ }
+
+ public void fatalError(String arg0, Throwable arg1) {
+ }
+
+ public Logger getChildLogger(String arg0) {
+ return null;
+ }
+
+ public void info(String arg0) {
+ }
+
+ public void info(String arg0, Throwable arg1) {
+ }
+
+ public boolean isDebugEnabled() {
+ return false;
+ }
+
+ public boolean isErrorEnabled() {
+ return false;
+ }
+
+ public boolean isFatalErrorEnabled() {
+ return false;
+ }
+
+ public boolean isInfoEnabled() {
+ return false;
+ }
+
+ public boolean isWarnEnabled() {
+ return false;
+ }
+
+ public void warn(String arg0) {
+
+ }
+
+ public void warn(String arg0, Throwable arg1) {
+
+ }
+}
\ No newline at end of file
Added: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserCharsetTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserCharsetTest.java?rev=639967&view=auto
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserCharsetTest.java (added)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserCharsetTest.java Sat Mar 22 01:53:26 2008
@@ -0,0 +1,168 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one *
+ * or more contributor license agreements. See the NOTICE file *
+ * distributed with this work for additional information *
+ * regarding copyright ownership. The ASF licenses this file *
+ * to you under the Apache License, Version 2.0 (the *
+ * "License"); you may not use this file except in compliance *
+ * with the License. You may obtain a copy of the License at *
+ * *
+ * http://www.apache.org/licenses/LICENSE-2.0 *
+ * *
+ * Unless required by applicable law or agreed to in writing, *
+ * software distributed under the License is distributed on an *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
+ * KIND, either express or implied. See the License for the *
+ * specific language governing permissions and limitations *
+ * under the License. *
+ ****************************************************************/
+
+package org.apache.james.imapserver.codec.decode.imap4rev1;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.nio.charset.Charset;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import org.apache.james.api.imap.ImapCommand;
+import org.apache.james.api.imap.ImapMessage;
+import org.apache.james.api.imap.display.HumanReadableTextKey;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1CommandFactory;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.request.SearchKey;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponse;
+import org.apache.james.api.imap.message.response.imap4rev1.StatusResponseFactory;
+import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+
+public class SearchCommandParserCharsetTest extends MockObjectTestCase {
+
+ private static final Charset UTF8 = Charset.forName("UTF-8");
+ private static final Charset ASCII = Charset.forName("US-ASCII");
+ private static final String TAG = "A1";
+ private static final String ASCII_SEARCH_TERM = "A Search Term";
+ private static final String NON_ASCII_SEARCH_TERM = "\u043A\u0430\u043A \u0414\u0435\u043B\u0430?";
+ private static final byte[] BYTES_NON_ASCII_SEARCH_TERM = NON_ASCII_SEARCH_TERM.getBytes(UTF8);
+ private static final byte[] BYTES_UTF8_NON_ASCII_SEARCH_TERM = add(" {16}\r\n".getBytes(ASCII), BYTES_NON_ASCII_SEARCH_TERM);
+ private static final byte[] CHARSET = "CHARSET UTF-8 ".getBytes(ASCII);
+
+ private static final byte[] add(byte[] one, byte[] two) {
+ byte[] results = new byte[one.length + two.length];
+ System.arraycopy(one, 0, results, 0, one.length);
+ System.arraycopy(two, 0, results, one.length, two.length);
+ return results;
+ }
+
+ SearchCommandParser parser;
+ Mock mockStatusResponseFactory;
+ Mock mockCommandFactory;
+ Mock mockMessageFactory;
+ Mock mockCommand;
+ Mock mockMessage;
+ ImapCommand command;
+ ImapMessage message;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parser = new SearchCommandParser();
+ mockCommandFactory = mock(Imap4Rev1CommandFactory.class);
+ mockCommandFactory.expects(once()).method("getSearch");
+ mockMessageFactory = mock(Imap4Rev1MessageFactory.class);
+ mockCommand = mock(ImapCommand.class);
+ command = (ImapCommand) mockCommand.proxy();
+ mockMessage = mock(ImapMessage.class);
+ mockStatusResponseFactory = mock(StatusResponseFactory.class);
+ message = (ImapMessage) mockMessage.proxy();
+ parser.init((Imap4Rev1CommandFactory) mockCommandFactory.proxy());
+ parser.setMessageFactory((Imap4Rev1MessageFactory) mockMessageFactory.proxy());
+ parser.setStatusResponseFactory((StatusResponseFactory) mockStatusResponseFactory.proxy());
+ parser.enableLogging(new MockLogger());
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testBadCharset() throws Exception {
+ Collection charsetNames = new HashSet();
+ for (final Iterator it = Charset.availableCharsets().values().iterator(); it.hasNext();) {
+ final Charset charset = (Charset) it.next();
+ final Set aliases = charset.aliases();
+ charsetNames.addAll(aliases);
+ }
+ mockStatusResponseFactory.expects(once()).method("taggedNo").with(eq(TAG), same(command), eq(HumanReadableTextKey.BAD_CHARSET), eq(StatusResponse.ResponseCode.badCharset(charsetNames)));
+ ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream("CHARSET BOGUS ".getBytes("US-ASCII")),
+ new ByteArrayOutputStream());
+ parser.decode(command, reader, TAG, false);
+ }
+
+ public void testBCCShouldConvertCharset() throws Exception {
+ SearchKey key = SearchKey.buildBcc(NON_ASCII_SEARCH_TERM);
+ checkUTF8Valid("BCC".getBytes("US-ASCII"), key);
+ }
+
+ public void testBODYShouldConvertCharset() throws Exception {
+ SearchKey key = SearchKey.buildBody(NON_ASCII_SEARCH_TERM);
+ checkUTF8Valid("BODY".getBytes("US-ASCII"), key);
+ }
+
+ public void testCCShouldConvertCharset() throws Exception {
+ SearchKey key = SearchKey.buildCc(NON_ASCII_SEARCH_TERM);
+ checkUTF8Valid("CC".getBytes("US-ASCII"), key);
+ }
+
+ public void testFROMShouldConvertCharset() throws Exception {
+ SearchKey key = SearchKey.buildFrom(NON_ASCII_SEARCH_TERM);
+ checkUTF8Valid("FROM".getBytes("US-ASCII"), key);
+ }
+
+ public void testHEADERShouldConvertCharset() throws Exception {
+ SearchKey key = SearchKey.buildHeader("whatever", NON_ASCII_SEARCH_TERM);
+ checkUTF8Valid("HEADER whatever".getBytes("US-ASCII"), key);
+ }
+
+ public void testSUBJECTShouldConvertCharset() throws Exception {
+ SearchKey key = SearchKey.buildSubject(NON_ASCII_SEARCH_TERM);
+ checkUTF8Valid("SUBJECT".getBytes("US-ASCII"), key);
+ }
+
+ public void testTEXTShouldConvertCharset() throws Exception {
+ SearchKey key = SearchKey.buildText(NON_ASCII_SEARCH_TERM);
+ checkUTF8Valid("TEXT".getBytes("US-ASCII"), key);
+ }
+
+ public void testTOShouldConvertCharset() throws Exception {
+ SearchKey key = SearchKey.buildTo(NON_ASCII_SEARCH_TERM);
+ checkUTF8Valid("TO".getBytes("US-ASCII"), key);
+ }
+
+ public void testASCIICharset() throws Exception {
+ SearchKey key = SearchKey.buildBcc(ASCII_SEARCH_TERM);
+ checkValid("CHARSET US-ASCII BCC \"" + ASCII_SEARCH_TERM + "\"", key, true, "US-ASCII");
+ }
+
+ public void testSimpleUTF8Charset() throws Exception {
+ SearchKey key = SearchKey.buildBcc(ASCII_SEARCH_TERM);
+ checkValid("CHARSET UTF-8 BCC \"" + ASCII_SEARCH_TERM + "\"", key, true, "US-ASCII");
+ }
+
+ private void checkUTF8Valid(byte[] term, final SearchKey key) throws Exception {
+ ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(add(add(CHARSET, term), BYTES_UTF8_NON_ASCII_SEARCH_TERM)),
+ new ByteArrayOutputStream());
+ final SearchKey searchKey = parser.searchKey(reader, null, true);
+ assertEquals(key, searchKey);
+ }
+
+ private void checkValid(String input, final SearchKey key, boolean isFirst, String charset) throws Exception {
+ ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes(charset)),
+ new ByteArrayOutputStream());
+
+ final SearchKey searchKey = parser.searchKey(reader, null, isFirst);
+ assertEquals(key, searchKey);
+ }
+
+}
Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserNotTest.java Sat Mar 22 01:53:26 2008
@@ -116,6 +116,6 @@
ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")),
new ByteArrayOutputStream());
- assertEquals(key, parser.searchKey(reader));
+ assertEquals(key, parser.searchKey(reader, null, false));
}
}
Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserOrTest.java Sat Mar 22 01:53:26 2008
@@ -175,7 +175,7 @@
ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")),
new ByteArrayOutputStream());
- assertEquals(key, parser.searchKey(reader));
+ assertEquals(key, parser.searchKey(reader, null, false));
}
public class Input {
Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeySequenceSetTest.java Sat Mar 22 01:53:26 2008
@@ -103,7 +103,7 @@
ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")),
new ByteArrayOutputStream());
- final SearchKey searchKey = parser.searchKey(reader);
+ final SearchKey searchKey = parser.searchKey(reader, null, false);
assertEquals(key, searchKey);
}
}
Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/SearchCommandParserSearchKeyTest.java Sat Mar 22 01:53:26 2008
@@ -369,7 +369,7 @@
ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")),
new ByteArrayOutputStream());
- assertEquals(key, parser.searchKey(reader));
+ assertEquals(key, parser.searchKey(reader, null, false));
}
public void testShouldParseDeleted() throws Exception {
@@ -691,7 +691,7 @@
new ByteArrayOutputStream());
try {
- parser.searchKey(reader);
+ parser.searchKey(reader, null, false);
fail("Expected protocol exception to be throw since input is invalid");
} catch (ProtocolException e) {
//expected
Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/AbstractTestImapResponseComposer.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/AbstractTestImapResponseComposer.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/AbstractTestImapResponseComposer.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/AbstractTestImapResponseComposer.java Sat Mar 22 01:53:26 2008
@@ -20,20 +20,27 @@
package org.apache.james.imapserver.codec.encode;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import javax.mail.Flags;
-import junit.framework.TestCase;
+import org.apache.james.api.imap.ImapCommand;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
-public abstract class AbstractTestImapResponseComposer extends TestCase {
+public abstract class AbstractTestImapResponseComposer extends MockObjectTestCase {
private static final long[] ONE_TWO_THREE = {1, 2, 3};
private static final long[] FIBS = {1, 1, 2, 3, 5, 8, 13, 21, 34, 65, 99};
private static final long[] EMPTY = {};
+ Mock mockCommand;
+
protected void setUp() throws Exception {
super.setUp();
+ mockCommand = mock(ImapCommand.class);
}
protected void tearDown() throws Exception {
@@ -110,6 +117,26 @@
checkFlagsEncode(" FLAGS (\\Answered \\Deleted \\Draft \\Flagged \\Seen)", flags);
}
+ public void testShouldEncodeUnparameterisedStatus() throws Exception {
+ checkStatusResponseEncode("A1 NO [ALERT] APPEND failed\r\n", "A1", command("APPEND"),
+ "NO", "ALERT", Collections.EMPTY_LIST, 0, "failed");
+ checkStatusResponseEncode("A1 BAD [TRYCREATE] SELECT whatever\r\n", "A1", command("SELECT"),
+ "BAD", "TRYCREATE", Collections.EMPTY_LIST, 0, "whatever");
+ }
+
+ public void testShouldEncodeListParameterStatus() throws Exception {
+ Collection parameters = new ArrayList();
+ parameters.add("ONE");
+ parameters.add("TWO");
+ parameters.add("THREE");
+ checkStatusResponseEncode("A1 NO [BADCHARSET (ONE TWO THREE)] APPEND failed\r\n", "A1", command("APPEND"),
+ "NO", "BADCHARSET", parameters, 0, "failed");
+ }
+
+ public void testShouldEncodeNumberParameterStatus() throws Exception {
+ checkStatusResponseEncode("A1 NO [UIDNEXT 10] APPEND failed\r\n", "A1", command("APPEND"),
+ "NO", "UIDNEXT", null, 10, "failed");
+ }
private void checkFlagsEncode(String expected, Flags flags) throws Exception {
StringBuffer buffer = new StringBuffer();
@@ -165,4 +192,23 @@
Long uidNext, Long uidValidity, Long unseen, String mailbox) throws Exception;
protected abstract void clear() throws Exception;
+
+ protected abstract byte[] encodeStatusResponse(String tag, ImapCommand command, String type,
+ String responseCode, Collection parameters, int number, String text) throws Exception;
+
+ private void checkStatusResponseEncode(String expected, String tag, ImapCommand command, String type,
+ String responseCode, Collection parameters, int number, String text) throws Exception {
+ StringBuffer buffer = new StringBuffer();
+ byte[] output = encodeStatusResponse(tag, command, type, responseCode, parameters, number, text);
+ for (int i=0;i<output.length;i++) {
+ buffer.append((char) output[i]);
+ }
+ assertEquals(expected, buffer.toString());
+ clear();
+ }
+
+ private ImapCommand command(String name) {
+ mockCommand.expects(once()).method("getName").will(returnValue(name));
+ return (ImapCommand) mockCommand.proxy();
+ }
}
Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/ImapResponseTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/ImapResponseTest.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/ImapResponseTest.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/ImapResponseTest.java Sat Mar 22 01:53:26 2008
@@ -94,9 +94,9 @@
assertEquals(new MockImapResponseWriter.UntaggedOperation(), writer.operations.get(0));
assertEquals(new MockImapResponseWriter.TextMessageOperation(ImapResponseComposerImpl.FLAGS),
writer.operations.get(1));
- assertEquals(new MockImapResponseWriter.ParenOperation(true),
+ assertEquals(new MockImapResponseWriter.BracketOperation(true, false),
writer.operations.get(2));
- assertEquals(new MockImapResponseWriter.ParenOperation(false),
+ assertEquals(new MockImapResponseWriter.BracketOperation(false, false),
writer.operations.get(3));
assertEquals(new MockImapResponseWriter.EndOperation(),
writer.operations.get(4));
Modified: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/base/ByteImapResponseWriter.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/base/ByteImapResponseWriter.java?rev=639967&r1=639966&r2=639967&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/base/ByteImapResponseWriter.java (original)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/base/ByteImapResponseWriter.java Sat Mar 22 01:53:26 2008
@@ -127,13 +127,21 @@
}
public void closeParen() {
- writer.print(CLOSING_PARENTHESIS);
+ closeBracket(CLOSING_PARENTHESIS);
+ }
+
+ private void closeBracket(final char bracket) {
+ writer.print(bracket);
clearSkipNextSpace();
}
public void openParen() {
+ openBracket(OPENING_PARENTHESIS);
+ }
+
+ private void openBracket(final char bracket) {
space();
- writer.print(OPENING_PARENTHESIS);
+ writer.print(bracket);
skipNextSpace();
}
@@ -165,5 +173,13 @@
WritableByteChannel channel = Channels.newChannel(out);
literal.writeTo(channel);
writer.flush();
+ }
+
+ public void closeSquareBracket() throws IOException {
+ closeBracket(CLOSING_SQUARE_BRACKET);
+ }
+
+ public void openSquareBracket() throws IOException {
+ openBracket(OPENING_SQUARE_BRACKET);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org