Author: rdonkin
Date: Mon May 18 10:53:01 2009
New Revision: 775895
URL: http://svn.apache.org/viewvc?rev=775895&view=rev
Log:
IMAP-91 Add configuration parameter to default encoder factory to enable a
workaround for broken clients. https://issues.apache.org/jira/browse/IMAP-91
Added:
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java
- copied, changed from r775865,
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderEnvelopeTest.java
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java?rev=775895&r1=775894&r2=775895&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/FetchResponseEncoder.java
Mon May 18 10:53:01 2009
@@ -40,8 +40,18 @@
public class FetchResponseEncoder extends AbstractChainedImapEncoder {
- public FetchResponseEncoder(final ImapEncoder next) {
+ /** Disables all optional BODYSTRUCTURE extensions */
+ private final boolean neverAddBodyStructureExtensions;
+
+ /**
+ * Constructs an encoder for FETCH messages.
+ * @param next not null
+ * @param neverAddBodyStructureExtensions true to activate a workaround
for broken clients who
+ * cannot parse BODYSTRUCTURE extensions, false to fully support RFC3501
+ */
+ public FetchResponseEncoder(final ImapEncoder next, final boolean
neverAddBodyStructureExtensions) {
super(next);
+ this.neverAddBodyStructureExtensions = neverAddBodyStructureExtensions;
}
public boolean isAcceptable(final ImapMessage message) {
@@ -104,12 +114,17 @@
final Structure structure, final boolean includeExtensions,
final String mediaType, final String subType, boolean isInnerPart,
ImapSession session)
throws IOException {
+ //
+ // Workaround for broken clients
+ // See IMAP-91
+ //
+ final boolean includeOptionalExtensions = includeExtensions &&
!neverAddBodyStructureExtensions;
if (isInnerPart) {
composer.skipNextSpace();
}
if (ImapConstants.MIME_TYPE_MULTIPART.equalsIgnoreCase(mediaType)) {
- encodeMultipart(composer, structure, subType, includeExtensions,
session);
+ encodeMultipart(composer, structure, subType,
includeOptionalExtensions, session);
} else {
if (ImapConstants.MIME_TYPE_MESSAGE.equalsIgnoreCase(mediaType)
@@ -117,9 +132,9 @@
.equalsIgnoreCase(subType)) {
encodeRfc822Message(composer, structure, mediaType, subType,
- includeExtensions, session);
+ includeOptionalExtensions, session);
} else {
- encodeBasic(composer, structure, includeExtensions, mediaType,
+ encodeBasic(composer, structure, includeOptionalExtensions,
mediaType,
subType, session);
}
}
Modified:
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java?rev=775895&r1=775894&r2=775895&view=diff
==============================================================================
---
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
(original)
+++
james/imap/trunk/message/src/main/java/org/apache/james/imap/encode/main/DefaultImapEncoderFactory.java
Mon May 18 10:53:01 2009
@@ -41,7 +41,14 @@
*/
public class DefaultImapEncoderFactory implements ImapEncoderFactory {
- public static final ImapEncoder createDefaultEncoder(final Localizer
localizer) {
+ /**
+ * Builds the default encoder
+ * @param localizer not null
+ * @param neverAddBodyStructureExtensions true to activate a workaround
for broken clients who
+ * cannot parse BODYSTRUCTURE extensions, false to fully support RFC3501
+ * @return not null
+ */
+ public static final ImapEncoder createDefaultEncoder(final Localizer
localizer, final boolean neverAddBodyStructureExtensions) {
final EndImapEncoder endImapEncoder = new EndImapEncoder();
final NamespaceResponseEncoder namespaceEncoder = new
NamespaceResponseEncoder(endImapEncoder);
final StatusResponseEncoder statusResponseEncoder = new
StatusResponseEncoder(
@@ -49,7 +56,7 @@
final RecentResponseEncoder recentResponseEncoder = new
RecentResponseEncoder(
statusResponseEncoder);
final FetchResponseEncoder fetchResponseEncoder = new
FetchResponseEncoder(
- recentResponseEncoder);
+ recentResponseEncoder, neverAddBodyStructureExtensions);
final ExpungeResponseEncoder expungeResponseEncoder = new
ExpungeResponseEncoder(
fetchResponseEncoder);
final ExistsResponseEncoder existsResponseEncoder = new
ExistsResponseEncoder(
@@ -70,18 +77,26 @@
}
private final Localizer localizer;
+ private final boolean neverAddBodyStructureExtensions;
public DefaultImapEncoderFactory() {
- this(new DefaultLocalizer());
+ this(new DefaultLocalizer(), false);
}
- public DefaultImapEncoderFactory(final Localizer localizer) {
+ /**
+ * Constructs the default factory for encoders
+ * @param localizer not null
+ * @param neverAddBodyStructureExtensions true to activate a workaround
for broken clients who
+ * cannot parse BODYSTRUCTURE extensions, false to fully support RFC3501
+ */
+ public DefaultImapEncoderFactory(final Localizer localizer, boolean
neverAddBodyStructureExtensions) {
super();
this.localizer = localizer;
+ this.neverAddBodyStructureExtensions = neverAddBodyStructureExtensions;
}
public ImapEncoder buildImapEncoder() {
- return createDefaultEncoder(localizer);
+ return createDefaultEncoder(localizer,
neverAddBodyStructureExtensions);
}
}
Modified:
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderEnvelopeTest.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderEnvelopeTest.java?rev=775895&r1=775894&r2=775895&view=diff
==============================================================================
---
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderEnvelopeTest.java
(original)
+++
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderEnvelopeTest.java
Mon May 18 10:53:01 2009
@@ -103,7 +103,7 @@
message = new FetchResponse(MSN, null, null, null, null, envelope,
null, null, null);
composer = mock(ImapResponseComposer.class);
mockNextEncoder = mock(ImapEncoder.class);
- encoder = new FetchResponseEncoder(mockNextEncoder);
+ encoder = new FetchResponseEncoder(mockNextEncoder, false);
stubCommand = ImapCommand.anyStateCommand("COMMAND");
flags = new Flags(Flags.Flag.DELETED);
}
Copied:
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java
(from r775865,
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java)
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java?p2=james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java&p1=james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java&r1=775865&r2=775895&rev=775895&view=diff
==============================================================================
---
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
(original)
+++
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderNoExtensionsTest.java
Mon May 18 10:53:01 2009
@@ -19,6 +19,11 @@
package org.apache.james.imap.encode;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import javax.mail.Flags;
import org.apache.james.imap.api.ImapCommand;
@@ -31,12 +36,13 @@
import org.jmock.Sequence;
import org.jmock.integration.junit3.MockObjectTestCase;
-public class FetchResponseEncoderTest extends MockObjectTestCase {
+public class FetchResponseEncoderNoExtensionsTest extends MockObjectTestCase {
Flags flags;
ImapResponseComposer composer;
+ FetchResponse.Structure stubStructure;
ImapEncoder mockNextEncoder;
@@ -48,9 +54,10 @@
super.setUp();
composer = mock(ImapResponseComposer.class);
mockNextEncoder = mock(ImapEncoder.class);
- encoder = new FetchResponseEncoder(mockNextEncoder);
+ encoder = new FetchResponseEncoder(mockNextEncoder, true);
stubCommand = ImapCommand.anyStateCommand("COMMAND");
flags = new Flags(Flags.Flag.DELETED);
+ stubStructure = mock(FetchResponse.Structure.class);
}
protected void tearDown() throws Exception {
@@ -104,4 +111,47 @@
}});
encoder.doEncode(message, composer, new FakeImapSession());
}
+
+ public void testShouldNotAddExtensionsWithEncodingBodyStructure() throws
Exception {
+ FetchResponse message = new FetchResponse(100, flags, new Long(72),
+ null, null, null, null, stubStructure, null);
+ final Map<String, String> parameters = new HashMap<String, String>();
+ parameters.put("CHARSET", "US-ASCII");
+ final List<String> parameterList= new ArrayList<String>();
+ parameterList.add("CHARSET");
+ parameterList.add("US-ASCII");
+
+ checking(new Expectations() {{
+ final long octets = 2279L;
+ final long lines = 48L;
+ allowing(stubStructure).getMediaType(); will(returnValue("TEXT"));
+ allowing(stubStructure).getSubType(); will(returnValue("HTML"));
+ allowing(stubStructure).getOctets();will(returnValue(octets));
+ allowing(stubStructure).getLines();will(returnValue(lines));
+ allowing(stubStructure).getParameters();
will(returnValue(parameterList));
+ allowing(stubStructure).getEncoding(); will(returnValue("7BIT"));
+ ignoring(stubStructure);
+
+ final Sequence sequence = sequence("composition");
+ oneOf(composer).openFetchResponse(with(equal(100L)));
inSequence(sequence);
+ oneOf(composer).flags(with(equal(flags))); inSequence(sequence);
+
oneOf(composer).message(with(equal("BODYSTRUCTURE")));inSequence(sequence);
+
oneOf(composer).openParen();will(returnValue(composer));inSequence(sequence);
+
oneOf(composer).quoteUpperCaseAscii("TEXT");will(returnValue(composer));inSequence(sequence);
+
oneOf(composer).quoteUpperCaseAscii("HTML");will(returnValue(composer));inSequence(sequence);
+
oneOf(composer).nillableQuotes(parameterList);will(returnValue(composer));inSequence(sequence);
+
oneOf(composer).nillableQuote("");will(returnValue(composer));inSequence(sequence);
+
oneOf(composer).nillableQuote("");will(returnValue(composer));inSequence(sequence);
+
oneOf(composer).quoteUpperCaseAscii("7BIT");will(returnValue(composer));inSequence(sequence);
+ oneOf(composer).message(octets);inSequence(sequence);
+ oneOf(composer).message(lines);inSequence(sequence);
+ oneOf(composer).closeParen();inSequence(sequence);
+ oneOf(composer).message(with(equal("UID"))); inSequence(sequence);
+ oneOf(composer).message(with(equal(72L))); inSequence(sequence);
+ oneOf(composer).closeFetchResponse(); inSequence(sequence);
+ ;
+ }});
+ final FakeImapSession fakeImapSession = new FakeImapSession();
+ encoder.doEncode(message, composer, fakeImapSession);
+ }
}
Modified:
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
URL:
http://svn.apache.org/viewvc/james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java?rev=775895&r1=775894&r2=775895&view=diff
==============================================================================
---
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
(original)
+++
james/imap/trunk/message/src/test/java/org/apache/james/imap/encode/FetchResponseEncoderTest.java
Mon May 18 10:53:01 2009
@@ -48,7 +48,7 @@
super.setUp();
composer = mock(ImapResponseComposer.class);
mockNextEncoder = mock(ImapEncoder.class);
- encoder = new FetchResponseEncoder(mockNextEncoder);
+ encoder = new FetchResponseEncoder(mockNextEncoder, false);
stubCommand = ImapCommand.anyStateCommand("COMMAND");
flags = new Flags(Flags.Flag.DELETED);
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]