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/26 22:34:58 UTC
svn commit: r641587 - in /james/server/trunk:
imap-api/src/main/java/org/apache/james/api/imap/message/
imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/base/
imap-codec-library/src/main/java/org/apache/james/imapserver/codec/d...
Author: rdonkin
Date: Wed Mar 26 14:34:56 2008
New Revision: 641587
URL: http://svn.apache.org/viewvc?rev=641587&view=rev
Log:
Parse partial FETCH
Added:
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParserPartialFetchTest.java
Modified:
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/BodyFetchElement.java
james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/FetchData.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/FetchCommandParser.java
Modified: james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/BodyFetchElement.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/BodyFetchElement.java?rev=641587&r1=641586&r2=641587&view=diff
==============================================================================
--- james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/BodyFetchElement.java (original)
+++ james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/BodyFetchElement.java Wed Mar 26 14:34:56 2008
@@ -18,6 +18,7 @@
****************************************************************/
package org.apache.james.api.imap.message;
+import java.util.Arrays;
import java.util.Collection;
import org.apache.james.api.imap.ImapConstants;
@@ -32,9 +33,9 @@
public static final int HEADER_NOT_FIELDS = 4;
public static final int CONTENT = 5;
- private static final BodyFetchElement rfc822 = new BodyFetchElement(ImapConstants.FETCH_RFC822, CONTENT, null, null);
- private static final BodyFetchElement rfc822Header = new BodyFetchElement(ImapConstants.FETCH_RFC822_HEADER, HEADER, null, null);
- private static final BodyFetchElement rfc822Text = new BodyFetchElement(ImapConstants.FETCH_RFC822_TEXT, TEXT, null, null);
+ private static final BodyFetchElement rfc822 = new BodyFetchElement(ImapConstants.FETCH_RFC822, CONTENT, null, null, null, null);
+ private static final BodyFetchElement rfc822Header = new BodyFetchElement(ImapConstants.FETCH_RFC822_HEADER, HEADER, null, null, null, null);
+ private static final BodyFetchElement rfc822Text = new BodyFetchElement(ImapConstants.FETCH_RFC822_TEXT, TEXT, null, null, null, null);
public static final BodyFetchElement createRFC822() {
return rfc822;
@@ -48,19 +49,22 @@
return rfc822Text;
}
-
+ private final Long firstOctet;
+ private final Long numberOfOctets;
private final String name;
private final int sectionType;
private final int[] path;
private final Collection fieldNames;
public BodyFetchElement( final String name, final int sectionType,
- final int[] path, final Collection fieldNames)
+ final int[] path, final Collection fieldNames, Long firstOctet, Long numberOfOctets)
{
this.name = name;
this.sectionType = sectionType;
this.fieldNames = fieldNames;
this.path = path;
+ this.firstOctet = firstOctet;
+ this.numberOfOctets = numberOfOctets;
}
public String getResponseName() {
@@ -94,4 +98,71 @@
public final int getSectionType() {
return sectionType;
}
+
+ /**
+ * Gets the first octet for a partial fetch.
+ * @return the firstOctet when this is a partial fetch
+ * or null
+ */
+ public final Long getFirstOctet() {
+ return firstOctet;
+ }
+
+ /**
+ * For a partial fetch, gets the number of octets to be returned.
+ * @return the lastOctet,
+ * or null
+ */
+ public final Long getNumberOfOctets() {
+ return numberOfOctets;
+ }
+
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((fieldNames == null) ? 0 : fieldNames.hashCode());
+ result = PRIME * result + ((firstOctet == null) ? 0 : firstOctet.hashCode());
+ result = PRIME * result + ((name == null) ? 0 : name.hashCode());
+ result = PRIME * result + ((numberOfOctets == null) ? 0 : numberOfOctets.hashCode());
+ result = PRIME * result + ((path == null) ? 0 : path.length);
+ result = PRIME * result + sectionType;
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final BodyFetchElement other = (BodyFetchElement) obj;
+ if (fieldNames == null) {
+ if (other.fieldNames != null)
+ return false;
+ } else if (!fieldNames.equals(other.fieldNames))
+ return false;
+ if (firstOctet == null) {
+ if (other.firstOctet != null)
+ return false;
+ } else if (!firstOctet.equals(other.firstOctet))
+ return false;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ if (numberOfOctets == null) {
+ if (other.numberOfOctets != null)
+ return false;
+ } else if (!numberOfOctets.equals(other.numberOfOctets))
+ return false;
+ if (!Arrays.equals(path, other.path))
+ return false;
+ if (sectionType != other.sectionType)
+ return false;
+ return true;
+ }
+
+
}
Modified: james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/FetchData.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/FetchData.java?rev=641587&r1=641586&r2=641587&view=diff
==============================================================================
--- james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/FetchData.java (original)
+++ james/server/trunk/imap-api/src/main/java/org/apache/james/api/imap/message/FetchData.java Wed Mar 26 14:34:56 2008
@@ -108,4 +108,51 @@
}
bodyElements.add(element);
}
+
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + (body ? 1231 : 1237);
+ result = PRIME * result + ((bodyElements == null) ? 0 : bodyElements.hashCode());
+ result = PRIME * result + (bodyStructure ? 1231 : 1237);
+ result = PRIME * result + (envelope ? 1231 : 1237);
+ result = PRIME * result + (flags ? 1231 : 1237);
+ result = PRIME * result + (internalDate ? 1231 : 1237);
+ result = PRIME * result + (setSeen ? 1231 : 1237);
+ result = PRIME * result + (size ? 1231 : 1237);
+ result = PRIME * result + (uid ? 1231 : 1237);
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final FetchData other = (FetchData) obj;
+ if (body != other.body)
+ return false;
+ if (bodyElements == null) {
+ if (other.bodyElements != null)
+ return false;
+ } else if (!bodyElements.equals(other.bodyElements))
+ return false;
+ if (bodyStructure != other.bodyStructure)
+ return false;
+ if (envelope != other.envelope)
+ return false;
+ if (flags != other.flags)
+ return false;
+ if (internalDate != other.internalDate)
+ return false;
+ if (setSeen != other.setSeen)
+ return false;
+ if (size != other.size)
+ return false;
+ if (uid != other.uid)
+ return false;
+ return true;
+ }
}
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=641587&r1=641586&r2=641587&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 Wed Mar 26 14:34:56 2008
@@ -472,10 +472,42 @@
*/
public long number( ImapRequestLineReader request ) throws ProtocolException
{
- String digits = consumeWord( request, new DigitCharValidator() );
- return Long.parseLong( digits );
+ return readDigits(request, 0, 0, true);
}
-
+
+ private long readDigits( final ImapRequestLineReader request, int add, final long total, final boolean first ) throws ProtocolException
+ {
+ final char next;
+ if (first) {
+ next = request.nextWordChar();
+ } else {
+ request.consume();
+ next = request.nextChar();
+ }
+ final long currentTotal = (10 * total) + add;
+ switch (next) {
+ case '0': return readDigits(request, 0, currentTotal, false);
+ case '1': return readDigits(request, 1, currentTotal, false);
+ case '2': return readDigits(request, 2, currentTotal, false);
+ case '3': return readDigits(request, 3, currentTotal, false);
+ case '4': return readDigits(request, 4, currentTotal, false);
+ case '5': return readDigits(request, 5, currentTotal, false);
+ case '6': return readDigits(request, 6, currentTotal, false);
+ case '7': return readDigits(request, 7, currentTotal, false);
+ case '8': return readDigits(request, 8, currentTotal, false);
+ case '9': return readDigits(request, 9, currentTotal, false);
+ case '.':
+ case ' ':
+ case '>':
+ case '\r':
+ case '\n':
+ case '\t':
+ return currentTotal;
+ default:
+ throw new ProtocolException("Expected a digit but was " + next);
+ }
+ }
+
/**
* Reads an argument of type "nznumber" (a non-zero number)
* (NOTE this isn't strictly as per the spec, since the spec disallows
@@ -612,15 +644,6 @@
chr == '{' ||
chr == ' ' ||
chr == Character.CONTROL );
- }
- }
-
- public static class DigitCharValidator implements CharacterValidator
- {
- public boolean isValid( char chr )
- {
- return ( ( chr >= '0' && chr <= '9' ) ||
- chr == '*' );
}
}
Modified: james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParser.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParser.java?rev=641587&r1=641586&r2=641587&view=diff
==============================================================================
--- james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParser.java (original)
+++ james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParser.java Wed Mar 26 14:34:56 2008
@@ -45,9 +45,9 @@
final ImapCommand command = factory.getFetch();
setCommand(command);
}
-
+
public FetchData fetchRequest( ImapRequestLineReader request )
- throws ProtocolException
+ throws ProtocolException
{
FetchData fetch = new FetchData();
@@ -63,81 +63,90 @@
consumeChar(request, ')');
} else {
addNextElement( request, fetch );
-
+
}
return fetch;
}
- private void addNextElement( ImapRequestLineReader command, FetchData fetch)
- throws ProtocolException
- {
- /*char next = nextCharInLine( command );
- StringBuffer element = new StringBuffer();
- while ( next != ' ' && next != '[' && next != ')' && next!='\n' && next!='\r' ) {
- element.append(next);
- command.consume();
- next = nextCharInLine( command );
- }*/
-
-
- //String name = element.toString();
- String name = readWord(command, " [)\r\n");
- char next = command.nextChar();
- // Simple elements with no '[]' parameters.
- //if ( next == ' ' || next == ')' || next == '\n' || next == '\r') {
- if (next != '[') {
- if ( "FAST".equalsIgnoreCase( name ) ) {
- fetch.setFlags(true);
- fetch.setInternalDate(true);
- fetch.setSize(true);
- } else if ("FULL".equalsIgnoreCase(name)) {
- fetch.setFlags(true);
- fetch.setInternalDate(true);
- fetch.setSize(true);
- fetch.setEnvelope(true);
- fetch.setBody(true);
- } else if ("ALL".equalsIgnoreCase(name)) {
- fetch.setFlags(true);
- fetch.setInternalDate(true);
- fetch.setSize(true);
- fetch.setEnvelope(true);
- } else if ("FLAGS".equalsIgnoreCase(name)) {
- fetch.setFlags(true);
- } else if ("RFC822.SIZE".equalsIgnoreCase(name)) {
- fetch.setSize(true);
- } else if ("ENVELOPE".equalsIgnoreCase(name)) {
- fetch.setEnvelope(true);
- } else if ("INTERNALDATE".equalsIgnoreCase(name)) {
- fetch.setInternalDate(true);
- } else if ("BODY".equalsIgnoreCase(name)) {
- fetch.setBody(true);
- } else if ("BODYSTRUCTURE".equalsIgnoreCase(name)) {
- fetch.setBodyStructure(true);
- } else if ("UID".equalsIgnoreCase(name)) {
- fetch.setUid(true);
- } else if ("RFC822".equalsIgnoreCase(name)) {
- fetch.add(BodyFetchElement.createRFC822(), false);
- } else if ("RFC822.HEADER".equalsIgnoreCase(name)) {
- fetch.add(BodyFetchElement.createRFC822Header(), true);
- } else if ("RFC822.TEXT".equalsIgnoreCase(name)) {
- fetch.add(BodyFetchElement.createRFC822Text(), false);
- } else {
- throw new ProtocolException( "Invalid fetch attribute: " + name );
- }
+ private void addNextElement( ImapRequestLineReader reader, FetchData fetch)
+ throws ProtocolException
+ {
+ //String name = element.toString();
+ String name = readWord(reader, " [)\r\n");
+ char next = reader.nextChar();
+ // Simple elements with no '[]' parameters.
+ if (next != '[') {
+ if ( "FAST".equalsIgnoreCase( name ) ) {
+ fetch.setFlags(true);
+ fetch.setInternalDate(true);
+ fetch.setSize(true);
+ } else if ("FULL".equalsIgnoreCase(name)) {
+ fetch.setFlags(true);
+ fetch.setInternalDate(true);
+ fetch.setSize(true);
+ fetch.setEnvelope(true);
+ fetch.setBody(true);
+ } else if ("ALL".equalsIgnoreCase(name)) {
+ fetch.setFlags(true);
+ fetch.setInternalDate(true);
+ fetch.setSize(true);
+ fetch.setEnvelope(true);
+ } else if ("FLAGS".equalsIgnoreCase(name)) {
+ fetch.setFlags(true);
+ } else if ("RFC822.SIZE".equalsIgnoreCase(name)) {
+ fetch.setSize(true);
+ } else if ("ENVELOPE".equalsIgnoreCase(name)) {
+ fetch.setEnvelope(true);
+ } else if ("INTERNALDATE".equalsIgnoreCase(name)) {
+ fetch.setInternalDate(true);
+ } else if ("BODY".equalsIgnoreCase(name)) {
+ fetch.setBody(true);
+ } else if ("BODYSTRUCTURE".equalsIgnoreCase(name)) {
+ fetch.setBodyStructure(true);
+ } else if ("UID".equalsIgnoreCase(name)) {
+ fetch.setUid(true);
+ } else if ("RFC822".equalsIgnoreCase(name)) {
+ fetch.add(BodyFetchElement.createRFC822(), false);
+ } else if ("RFC822.HEADER".equalsIgnoreCase(name)) {
+ fetch.add(BodyFetchElement.createRFC822Header(), true);
+ } else if ("RFC822.TEXT".equalsIgnoreCase(name)) {
+ fetch.add(BodyFetchElement.createRFC822Text(), false);
+ } else {
+ throw new ProtocolException( "Invalid fetch attribute: " + name );
}
- else {
- consumeChar( command, '[' );
+ }
+ else {
+ consumeChar( reader, '[' );
+
+ String parameter = readWord(reader, "]");
- String parameter = readWord(command, "]");
+ consumeChar( reader, ']');
- consumeChar( command, ']');
-
- final BodyFetchElement bodyFetchElement = createBodyElement(parameter);
- final boolean isPeek = isPeek(name);
- fetch.add(bodyFetchElement, isPeek);
+ final Long firstOctet;
+ final Long numberOfOctets;
+ if(reader.nextChar() == '<') {
+ consumeChar(reader, '<');
+ firstOctet = new Long(number(reader));
+ if (reader.nextChar() == '.') {
+ consumeChar(reader, '.');
+ numberOfOctets = new Long(nzNumber(reader));
+ } else {
+ numberOfOctets = null;
+ }
+ consumeChar(reader, '>');
+ } else {
+ firstOctet = null;
+ numberOfOctets = null;
}
+
+
+ final BodyFetchElement bodyFetchElement
+ = createBodyElement(parameter, firstOctet, numberOfOctets);
+ final boolean isPeek = isPeek(name);
+ fetch.add(bodyFetchElement, isPeek);
}
+ }
private boolean isPeek(String name) throws ProtocolException {
final boolean isPeek;
@@ -151,16 +160,15 @@
return isPeek;
}
- private BodyFetchElement createBodyElement(String parameter) throws ProtocolException {
+ private BodyFetchElement createBodyElement(String parameter, Long firstOctet, Long numberOfOctets) throws ProtocolException {
final String responseName = "BODY[" + parameter + "]";
FetchPartPathDecoder decoder = new FetchPartPathDecoder();
decoder.decode(parameter);
final int sectionType = getSectionType(decoder);
-
+
final List names = decoder.getNames();
final int[] path = decoder.getPath();
- final BodyFetchElement bodyFetchElement
- = new BodyFetchElement(responseName, sectionType, path, names);
+ final BodyFetchElement bodyFetchElement = new BodyFetchElement(responseName, sectionType, path, names, firstOctet, numberOfOctets);
return bodyFetchElement;
}
@@ -202,19 +210,9 @@
}
return buf.toString();
}
-
- private char nextCharInLine( ImapRequestLineReader request )
- throws ProtocolException
- {
- char next = request.nextChar();
- if ( next == '\r' || next == '\n' ) {
- throw new ProtocolException( "Unexpected end of line." );
- }
- return next;
- }
private char nextNonSpaceChar( ImapRequestLineReader request )
- throws ProtocolException
+ throws ProtocolException
{
char next = request.nextChar();
while ( next == ' ' ) {
@@ -224,11 +222,12 @@
return next;
}
- protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request, String tag, boolean useUids) throws ProtocolException {
+ protected ImapMessage decode(ImapCommand command, ImapRequestLineReader request,
+ String tag, boolean useUids) throws ProtocolException {
IdRange[] idSet = parseIdRange( request );
FetchData fetch = fetchRequest( request );
endLine( request );
-
+
final Imap4Rev1MessageFactory factory = getMessageFactory();
final ImapMessage result = factory.createFetchMessage(command, useUids, idSet, fetch, tag);
return result;
Added: james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParserPartialFetchTest.java
URL: http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParserPartialFetchTest.java?rev=641587&view=auto
==============================================================================
--- james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParserPartialFetchTest.java (added)
+++ james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/decode/imap4rev1/FetchCommandParserPartialFetchTest.java Wed Mar 26 14:34:56 2008
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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 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.imap4rev1.Imap4Rev1CommandFactory;
+import org.apache.james.api.imap.imap4rev1.Imap4Rev1MessageFactory;
+import org.apache.james.api.imap.message.BodyFetchElement;
+import org.apache.james.api.imap.message.FetchData;
+import org.apache.james.api.imap.message.IdRange;
+import org.apache.james.imapserver.codec.decode.ImapRequestLineReader;
+import org.jmock.Mock;
+import org.jmock.MockObjectTestCase;
+import org.jmock.core.Constraint;
+
+public class FetchCommandParserPartialFetchTest extends MockObjectTestCase {
+
+ FetchCommandParser parser;
+ Mock mockCommandFactory;
+ Mock mockMessageFactory;
+ Mock mockCommand;
+ Mock mockMessage;
+ ImapCommand command;
+ ImapMessage message;
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ parser = new FetchCommandParser();
+ mockCommandFactory = mock(Imap4Rev1CommandFactory.class);
+ mockCommandFactory.expects(once()).method("getFetch");
+ mockMessageFactory = mock(Imap4Rev1MessageFactory.class);
+ mockCommand = mock(ImapCommand.class);
+ command = (ImapCommand) mockCommand.proxy();
+ mockMessage = mock(ImapMessage.class);
+ message = (ImapMessage) mockMessage.proxy();
+ parser.init((Imap4Rev1CommandFactory) mockCommandFactory.proxy());
+ parser.setMessageFactory((Imap4Rev1MessageFactory) mockMessageFactory.proxy());
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void testShouldParseZeroAndLength() throws Exception {
+ IdRange[] ranges = {new IdRange(1)};
+ FetchData data = new FetchData();
+ data.add(new BodyFetchElement("BODY[]", BodyFetchElement.CONTENT, null, null,
+ new Long(0), new Long(100)), false);
+ check("1 (BODY[]<0.100>)\r\n", ranges, false, data, "A01");
+ }
+
+ public void testShouldParseNonZeroAndLength() throws Exception {
+ IdRange[] ranges = {new IdRange(1)};
+ FetchData data = new FetchData();
+ data.add(new BodyFetchElement("BODY[]", BodyFetchElement.CONTENT, null, null,
+ new Long(20), new Long(12342348)), false);
+ check("1 (BODY[]<20.12342348>)\r\n", ranges, false, data, "A01");
+ }
+
+ public void testShouldNotParseZeroLength() throws Exception {
+ try {
+ ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream("1 (BODY[]<20.0>)\r\n".getBytes("US-ASCII")),
+ new ByteArrayOutputStream());
+ parser.decode(command, reader, "A01", false);
+ fail("Number of octets must be non-zero");
+ } catch (ProtocolException e) {
+ // expected
+ }
+ }
+
+
+ private void check(String input, final IdRange[] idSet, final boolean useUids, FetchData data, String tag) throws Exception {
+ ImapRequestLineReader reader = new ImapRequestLineReader(new ByteArrayInputStream(input.getBytes("US-ASCII")),
+ new ByteArrayOutputStream());
+ Constraint[] constraints = {eq(command), eq(useUids), eq(idSet), eq(data), same(tag)};
+ mockMessageFactory.expects(once()).method("createFetchMessage").with(constraints).will(returnValue(message));
+ parser.decode(command, reader, tag, useUids);
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org