Author: rdonkin
Date: Sun Nov 25 11:38:01 2007
New Revision: 598041
URL: http://svn.apache.org/viewvc?rev=598041&view=rev
Log:
Eliminate intermediary string buffer for FETCH body elements.
Added:
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/Literal.java
Modified:
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/MessageResult.java
james/server/trunk/core-library/src/test/java/org/apache/james/mailboxmanager/MessageResultUtilsTest.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-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/FetchResponse.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/FetchResponseEncoder.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/imap4rev1/legacy/MockImapResponseWriter.java
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java
Modified:
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/MessageResult.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/MessageResult.java?rev=598041&r1=598040&r2=598041&view=diff
==============================================================================
---
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/MessageResult.java
(original)
+++
james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/MessageResult.java
Sun Nov 25 11:38:01 2007
@@ -19,6 +19,8 @@
package org.apache.james.mailboxmanager;
+import java.io.IOException;
+import java.nio.channels.WritableByteChannel;
import java.util.Date;
import java.util.Iterator;
@@ -191,13 +193,21 @@
* @param buffer <code>StringBuffer</code>, not null
* @throws MessagingException
*/
- public void writeTo(StringBuffer buffer) throws
MailboxManagerException;
+ public void writeTo(StringBuffer buffer);
+
+ /**
+ * Writes content to the given channel.
+ * @param channel <code>Channel</code> open, not null
+ * @throws MailboxManagerException
+ * @throws IOException when channel IO fails
+ */
+ public void writeTo(WritableByteChannel channel) throws IOException;
/**
* Size (in octets) of the content.
* @return number of octets to be written
* @throws MessagingException
*/
- public long size() throws MailboxManagerException;
+ public long size();
}
}
Modified:
james/server/trunk/core-library/src/test/java/org/apache/james/mailboxmanager/MessageResultUtilsTest.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/core-library/src/test/java/org/apache/james/mailboxmanager/MessageResultUtilsTest.java?rev=598041&r1=598040&r2=598041&view=diff
==============================================================================
---
james/server/trunk/core-library/src/test/java/org/apache/james/mailboxmanager/MessageResultUtilsTest.java
(original)
+++
james/server/trunk/core-library/src/test/java/org/apache/james/mailboxmanager/MessageResultUtilsTest.java
Sun Nov 25 11:38:01 2007
@@ -19,6 +19,8 @@
package org.apache.james.mailboxmanager;
+import java.io.IOException;
+import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.List;
@@ -43,11 +45,11 @@
value = "Value";
}
- public long size() throws MailboxManagerException {
+ public long size() {
return 0;
}
- public void writeTo(StringBuffer buffer) throws
MailboxManagerException {
+ public void writeTo(StringBuffer buffer) {
}
public String getName() {
@@ -56,6 +58,10 @@
public String getValue() {
return value;
+ }
+
+ public void writeTo(WritableByteChannel channel) throws IOException {
+
}
}
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=598041&r1=598040&r2=598041&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
Sun Nov 25 11:38:01 2007
@@ -26,6 +26,7 @@
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.james.api.imap.ImapConstants;
+import org.apache.james.imap.message.response.imap4rev1.Literal;
import org.apache.james.imapserver.codec.encode.ImapResponseWriter;
/**
@@ -191,5 +192,14 @@
} else {
write(BYTES_SPACE);
}
+ }
+
+ public void literal(Literal literal) throws IOException {
+ space();
+ write(BYTES_OPEN_BRACE);
+ writeASCII(Long.toString(literal.size()));
+ write(BYTES_CLOSE_BRACE);
+ write(BYTES_LINE_END);
+ literal.writeTo(out);
}
}
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=598041&r1=598040&r2=598041&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
Sun Nov 25 11:38:01 2007
@@ -46,6 +46,10 @@
public static final byte[] BYTES_DQUOTE = {BYTE_DQUOTE};
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;
+ public static final byte[] BYTES_OPEN_BRACE = {BYTE_OPEN_BRACE};
+ public static final byte BYTE_CLOSE_BRACE = 0x7D;
+ public static final byte[] BYTES_CLOSE_BRACE = {BYTE_CLOSE_BRACE};
public static final byte[] BYTES_LINE_END = {0x0D, 0x0A};
public static final char OPENING_PARENTHESIS = '(';
Modified:
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/FetchResponse.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/FetchResponse.java?rev=598041&r1=598040&r2=598041&view=diff
==============================================================================
---
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/FetchResponse.java
(original)
+++
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/FetchResponse.java
Sun Nov 25 11:38:01 2007
@@ -18,7 +18,10 @@
****************************************************************/
package org.apache.james.imap.message.response.imap4rev1;
+import java.io.IOException;
+import java.nio.channels.WritableByteChannel;
import java.util.Date;
+import java.util.List;
import javax.mail.Flags;
@@ -26,86 +29,112 @@
public final class FetchResponse implements ImapResponseMessage {
- private final int messageNumber;
- private final Flags flags;
- private final Long uid;
- private final Date internalDate;
- private final Integer size;
- private final StringBuffer misc;
- private final StringBuffer elements;
-
- public FetchResponse(final int messageNumber, final Flags flags, final
Long uid,
- final Date internalDate, final Integer size, StringBuffer
misc, StringBuffer elements) {
- super();
- this.messageNumber = messageNumber;
- this.flags = flags;
- this.uid = uid;
- this.internalDate = internalDate;
- this.size = size;
- this.misc = misc;
- this.elements = elements;
- }
-
- /**
- * Gets the number of the message whose details
- * have been fetched.
- * @return message number
- */
- public final int getMessageNumber() {
- return messageNumber;
- }
-
- /**
- * Gets the fetched flags.
- * @return [EMAIL PROTECTED] Flags} fetched,
- * or null if the <code>FETCH</code> did not include <code>FLAGS</code>
- */
- public Flags getFlags() {
- return flags;
- }
-
- /**
- * Gets the unique id for the fetched message.
- * @return message uid,
- * or null if the <code>FETCH</code> did not include <code>UID</code>
- */
- public Long getUid() {
- return uid;
- }
-
- /**
- * Gets the internal date for the fetched message.
- * @return the internalDate,
- * or null if the <code>FETCH</code> did not include
<code>INTERNALDATE</code>
+ private final int messageNumber;
+ private final Flags flags;
+ private final Long uid;
+ private final Date internalDate;
+ private final Integer size;
+ private final StringBuffer misc;
+ private final List elements;
+
+ public FetchResponse(final int messageNumber, final Flags flags, final
Long uid,
+ final Date internalDate, final Integer size, StringBuffer misc,
List elements) {
+ super();
+ this.messageNumber = messageNumber;
+ this.flags = flags;
+ this.uid = uid;
+ this.internalDate = internalDate;
+ this.size = size;
+ this.misc = misc;
+ this.elements = elements;
+ }
+
+ /**
+ * Gets the number of the message whose details
+ * have been fetched.
+ * @return message number
+ */
+ public final int getMessageNumber() {
+ return messageNumber;
+ }
+
+ /**
+ * Gets the fetched flags.
+ * @return [EMAIL PROTECTED] Flags} fetched,
+ * or null if the <code>FETCH</code> did not include <code>FLAGS</code>
+ */
+ public Flags getFlags() {
+ return flags;
+ }
+
+ /**
+ * Gets the unique id for the fetched message.
+ * @return message uid,
+ * or null if the <code>FETCH</code> did not include <code>UID</code>
+ */
+ public Long getUid() {
+ return uid;
+ }
+
+ /**
+ * Gets the internal date for the fetched message.
+ * @return the internalDate,
+ * or null if the <code>FETCH</code> did not include
<code>INTERNALDATE</code>
+ */
+ public final Date getInternalDate() {
+ return internalDate;
+ }
+
+ /**
+ * Gets the size for the fetched message.
+ * @return the size,
+ * or null if the <code>FETCH</code> did not include <code>SIZE</code>
+ */
+ public final Integer getSize() {
+ return size;
+ }
+
+ /**
+ * TODO: replace
+ * @return <code>List</code> of <code>BodyElement</code>'s,
+ * or null if the <code>FETCH</code> did not include body elements
+ */
+ public final List getElements() {
+ return elements;
+ }
+
+ /**
+ * TODO: replace
+ * @return the misc
+ */
+ public final StringBuffer getMisc() {
+ return misc;
+ }
+
+ /**
+ * BODY FETCH element content.
+ */
+ public interface BodyElement extends Literal {
+
+ /**
+ * The full name of the element fetched.
+ * As per <code>FETCH</code> command input.
+ * @return name, not null
+ */
+ public String getName();
+
+ /**
+ * Size of the literal content data.
+ * @return number of octets which [EMAIL PROTECTED]
#writeTo(WritableByteChannel)}
+ * will put onto the channel
+ */
+ public long size();
+
+ /**
+ * Writes the contents of this body element to the channel.
+ * @param channel <code>Channel</code>, not null
+ * @throws IOException
*/
- public final Date getInternalDate() {
- return internalDate;
- }
-
- /**
- * Gets the size for the fetched message.
- * @return the size,
- * or null if the <code>FETCH</code> did not include <code>SIZE</code>
- */
- public final Integer getSize() {
- return size;
- }
-
- /**
- * TODO: replace
- * @return the elements
- */
- public final StringBuffer getElements() {
- return elements;
- }
-
- /**
- * TODO: replace
- * @return the misc
- */
- public final StringBuffer getMisc() {
- return misc;
- }
-
-
+ public void writeTo(WritableByteChannel channel) throws IOException;
+ }
}
Added:
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/Literal.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/Literal.java?rev=598041&view=auto
==============================================================================
---
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/Literal.java
(added)
+++
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imap/message/response/imap4rev1/Literal.java
Sun Nov 25 11:38:01 2007
@@ -0,0 +1,39 @@
+/****************************************************************
+ * 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.imap.message.response.imap4rev1;
+
+import java.io.IOException;
+import java.nio.channels.WritableByteChannel;
+
+public interface Literal {
+ /**
+ * Size of the literal content data.
+ * @return number of octets which [EMAIL PROTECTED]
#writeTo(WritableByteChannel)}
+ * will put onto the channel
+ */
+ public long size();
+
+ /**
+ * Writes the contents of this body element to the channel.
+ * @param channel <code>Channel</code>, not null
+ * @throws IOException
+ */
+ public void writeTo(WritableByteChannel channel) throws IOException;
+}
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=598041&r1=598040&r2=598041&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
Sun Nov 25 11:38:01 2007
@@ -25,6 +25,7 @@
import javax.mail.Flags;
import org.apache.james.api.imap.ImapCommand;
+import org.apache.james.imap.message.response.imap4rev1.Literal;
public interface ImapResponseComposer {
@@ -227,5 +228,7 @@
String type, String responseCode, String text) throws IOException;
public void quote(String message) throws IOException;
+
+ public void literal(Literal literal) 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=598041&r1=598040&r2=598041&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
Sun Nov 25 11:38:01 2007
@@ -21,6 +21,8 @@
import java.io.IOException;
+import org.apache.james.imap.message.response.imap4rev1.Literal;
+
/**
* <p>Writes IMAP response.</p>
* <p>Factors out basic IMAP reponse writing operations
@@ -80,4 +82,12 @@
*
*/
void end() throws IOException;
+
+ /**
+ * Writes literal content
+ * @param literal <code>Literal</code> to be written,
+ * not null
+ * @throws IOException
+ */
+ void literal(Literal literal) throws IOException;
}
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=598041&r1=598040&r2=598041&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
Sun Nov 25 11:38:01 2007
@@ -30,6 +30,8 @@
import org.apache.james.api.imap.ImapCommand;
import org.apache.james.api.imap.ImapConstants;
import org.apache.james.api.imap.message.MessageFlags;
+import org.apache.james.imap.message.response.imap4rev1.Literal;
+import
org.apache.james.imap.message.response.imap4rev1.FetchResponse.BodyElement;
import org.apache.james.imapserver.codec.encode.ImapResponseComposer;
import org.apache.james.imapserver.codec.encode.ImapResponseWriter;
@@ -449,4 +451,9 @@
message(FETCH);
openParen();
}
+
+ public void literal(Literal literal) throws IOException {
+ writer.literal(literal);
+ }
+
}
Modified:
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java?rev=598041&r1=598040&r2=598041&view=diff
==============================================================================
---
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java
(original)
+++
james/server/trunk/imap-codec-library/src/main/java/org/apache/james/imapserver/codec/encode/imap4rev1/FetchResponseEncoder.java
Sun Nov 25 11:38:01 2007
@@ -21,6 +21,8 @@
import java.io.IOException;
import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
import javax.mail.Flags;
@@ -52,11 +54,21 @@
encodeSize(composer, fetchResponse);
encode(composer, fetchResponse.getMisc());
encodeUid(composer, fetchResponse);
- encode(composer, fetchResponse.getElements());
+ encodeBodyElements(composer, fetchResponse.getElements());
composer.closeFetchResponse();
}
}
+ private void encodeBodyElements(final ImapResponseComposer composer, final
List elements) throws IOException {
+ if (elements != null) {
+ for (final Iterator it = elements.iterator();it.hasNext();) {
+ FetchResponse.BodyElement element =
(FetchResponse.BodyElement) it.next();
+ composer.message(element.getName());
+ composer.literal(element);
+ }
+ }
+ }
+
private void encode(ImapResponseComposer composer, StringBuffer buffer)
throws IOException {
if (buffer != null && buffer.length() > 0) {
composer.message(buffer.substring(1));
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=598041&r1=598040&r2=598041&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
Sun Nov 25 11:38:01 2007
@@ -20,10 +20,14 @@
package org.apache.james.imapserver.codec.encode.base;
import java.io.ByteArrayOutputStream;
+import java.io.IOException;
import java.io.PrintWriter;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
import org.apache.avalon.framework.logger.AbstractLogEnabled;
import org.apache.james.api.imap.ImapConstants;
+import org.apache.james.imap.message.response.imap4rev1.Literal;
import org.apache.james.imapserver.codec.encode.ImapResponseWriter;
/**
@@ -153,5 +157,13 @@
} else {
writer.print(SP_CHAR);
}
+ }
+
+ public void literal(Literal literal) throws IOException {
+ space();
+ writer.flush();
+ WritableByteChannel channel = Channels.newChannel(out);
+ literal.writeTo(channel);
+ writer.flush();
}
}
Modified:
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/imap4rev1/legacy/MockImapResponseWriter.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/imap4rev1/legacy/MockImapResponseWriter.java?rev=598041&r1=598040&r2=598041&view=diff
==============================================================================
---
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/imap4rev1/legacy/MockImapResponseWriter.java
(original)
+++
james/server/trunk/imap-codec-library/src/test/java/org/apache/james/imapserver/codec/encode/imap4rev1/legacy/MockImapResponseWriter.java
Sun Nov 25 11:38:01 2007
@@ -19,9 +19,11 @@
package org.apache.james.imapserver.codec.encode.imap4rev1.legacy;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import org.apache.james.imap.message.response.imap4rev1.Literal;
import org.apache.james.imapserver.codec.encode.ImapResponseWriter;
public class MockImapResponseWriter implements ImapResponseWriter {
@@ -315,6 +317,41 @@
}
+
+ public void literal(Literal literal) throws IOException {
+ operations.add(new LiteralOperation(literal));
+ }
+ public static final class LiteralOperation {
+ public final Literal literal;
+ public LiteralOperation(Literal literal) {
+ this.literal = literal;
+ }
+
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = PRIME * result + ((literal == null) ? 0 :
literal.hashCode());
+ return result;
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final LiteralOperation other = (LiteralOperation) obj;
+ if (literal == null) {
+ if (other.literal != null)
+ return false;
+ } else if (!literal.equals(other.literal))
+ return false;
+ return true;
+ }
+
+
+ }
}
Modified:
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java?rev=598041&r1=598040&r2=598041&view=diff
==============================================================================
---
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java
(original)
+++
james/server/trunk/imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/processor/imap4rev1/FetchProcessor.java
Sun Nov 25 11:38:01 2007
@@ -19,6 +19,9 @@
package org.apache.james.imapserver.processor.imap4rev1;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
@@ -43,6 +46,7 @@
import org.apache.james.api.imap.process.ImapSession;
import org.apache.james.imap.message.request.imap4rev1.FetchRequest;
import org.apache.james.imap.message.response.imap4rev1.FetchResponse;
+import
org.apache.james.imap.message.response.imap4rev1.FetchResponse.BodyElement;
import org.apache.james.imapserver.processor.base.AbstractImapRequestProcessor;
import org.apache.james.imapserver.processor.base.AuthorizationException;
import org.apache.james.imapserver.processor.base.ImapSessionUtils;
@@ -53,6 +57,7 @@
import org.apache.james.mailboxmanager.MessageResult;
import org.apache.james.mailboxmanager.MessageResultUtils;
import org.apache.james.mailboxmanager.UnsupportedCriteriaException;
+import org.apache.james.mailboxmanager.MessageResult.Content;
import org.apache.james.mailboxmanager.impl.GeneralMessageSetImpl;
import org.apache.james.mailboxmanager.mailbox.ImapMailboxSession;
@@ -161,7 +166,7 @@
private Date internalDate;
private Integer size;
private StringBuffer misc;
- private StringBuffer elements;
+ private List elements;
public FetchResponseBuilder(final Logger logger) {
super();
@@ -264,21 +269,15 @@
// BODY part responses.
Collection elements = fetch.getBodyElements();
- this.elements = new StringBuffer();
+ this.elements = new ArrayList();
for (Iterator iterator = elements.iterator();
iterator.hasNext();) {
- BodyFetchElement fetchElement = (BodyFetchElement) iterator
- .next();
- this.elements.append(ImapConstants.SP);
- this.elements.append(fetchElement.getResponseName());
- this.elements.append(ImapConstants.SP);
-
- // Various mechanisms for returning message body.
- String sectionSpecifier = fetchElement.getParameters();
-
- try {
- handleBodyFetch(result, sectionSpecifier,
this.elements);
- } catch (MessagingException e) {
- throw new MailboxException(e.getMessage(), e);
+ BodyFetchElement fetchElement = (BodyFetchElement)
iterator.next();
+ final String sectionSpecifier =
fetchElement.getParameters();
+ final String responseName = fetchElement.getResponseName();
+ final FetchResponse.BodyElement element
+ = bodyFetch(result, sectionSpecifier, responseName);
+ if (element != null) {
+ this.elements.add(element);
}
}
return build();
@@ -302,36 +301,36 @@
reset(msn);
}
- private void handleBodyFetch(final MessageResult result,
- String sectionSpecifier, StringBuffer response)
- throws ProtocolException, MessagingException {
+ private FetchResponse.BodyElement bodyFetch(final MessageResult
messageResult,
+ String sectionSpecifier, String name) throws
MessagingException {
+ final FetchResponse.BodyElement result;
// TODO: section specifier should be fully parsed during parsing
phase
if (sectionSpecifier.length() == 0) {
- final MessageResult.Content fullMessage =
result.getFullMessage();
- addLiteralContent(fullMessage, response);
+ final MessageResult.Content fullMessage =
messageResult.getFullMessage();
+ result = new ContentBodyElement(name, fullMessage);
} else if (sectionSpecifier.equalsIgnoreCase("HEADER")) {
- final Iterator headers = result.iterateHeaders();
+ final Iterator headers = messageResult.iterateHeaders();
List lines = MessageResultUtils.getAll(headers);
- addHeaders(lines, response);
+ result = new HeaderBodyElement(name, lines);
} else if (sectionSpecifier.startsWith("HEADER.FIELDS.NOT ")) {
String[] excludeNames = extractHeaderList(sectionSpecifier,
"HEADER.FIELDS.NOT ".length());
- final Iterator headers = result.iterateHeaders();
+ final Iterator headers = messageResult.iterateHeaders();
List lines = MessageResultUtils.getNotMatching(excludeNames,
headers);
- addHeaders(lines, response);
+ result = new HeaderBodyElement(name, lines);
} else if (sectionSpecifier.startsWith("HEADER.FIELDS ")) {
String[] includeNames = extractHeaderList(sectionSpecifier,
"HEADER.FIELDS ".length());
- final Iterator headers = result.iterateHeaders();
+ final Iterator headers = messageResult.iterateHeaders();
List lines = MessageResultUtils.getMatching(includeNames,
headers);
- addHeaders(lines, response);
+ result = new HeaderBodyElement(name, lines);
} else if (sectionSpecifier.equalsIgnoreCase("MIME")) {
// TODO implement
- throw new ProtocolException("MIME not yet implemented.");
+ throw new MailboxManagerException("MIME not yet implemented.");
} else if (sectionSpecifier.equalsIgnoreCase("TEXT")) {
- final MessageResult.Content messageBody =
result.getMessageBody();
- addLiteralContent(messageBody, response);
+ final MessageResult.Content messageBody =
messageResult.getMessageBody();
+ result = new ContentBodyElement(name, messageBody);
} else {
// Should be a part specifier followed by a section specifier.
@@ -339,7 +338,7 @@
// If so, get the number, get the part, and call this
recursively.
int dotPos = sectionSpecifier.indexOf('.');
if (dotPos == -1) {
- throw new ProtocolException("Malformed fetch attribute: "
+ throw new MailboxManagerException("Malformed fetch
attribute: "
+ sectionSpecifier);
}
int partNumber = Integer.parseInt(sectionSpecifier.substring(0,
@@ -351,23 +350,13 @@
// with the new partSectionSpecifier.
// MimeMessage part;
// handleBodyFetch( part, partSectionSpecifier, response );
- throw new ProtocolException(
+ throw new MailboxManagerException(
"Mime parts not yet implemented for fetch.");
}
+ return result;
}
- private void addLiteralContent(final MessageResult.Content content,
- final StringBuffer response) throws MessagingException {
- response.append('{');
- final long length = content.size();
- response.append(length); // TODO JD addLiteral: why was it
- // bytes.length +1 here?
- response.append('}');
- response.append("\r\n");
- content.writeTo(response);
- }
-
// TODO should do this at parse time.
private String[] extractHeaderList(String headerList, int prefixLen) {
// Remove the trailing and leading ')('
@@ -391,26 +380,82 @@
return (String[]) strings.toArray(new String[0]);
}
+ }
+
+ private static final class HeaderBodyElement implements BodyElement {
+ private final String name;
+ private final List headers;
+ private final long size;
+
+ public HeaderBodyElement(final String name, final List headers) {
+ super();
+ this.name = name;
+ this.headers = headers;
+ size = calculateSize(headers);
+ }
- private void addHeaders(List headerLines, StringBuffer response)
- throws MessagingException {
+ public String getName() {
+ return name;
+ }
+
+ private long calculateSize(List headers) {
int count = 0;
- for (final Iterator it = headerLines.iterator(); it.hasNext();) {
+ for (final Iterator it = headers.iterator(); it.hasNext();) {
MessageResult.Header header = (MessageResult.Header) it.next();
count += header.size() + 2;
}
- response.append('{');
- response.append(count + 2);
- response.append('}');
- response.append("\r\n");
+ return count + 2;
+ }
+
+ public long size() {
+ return size;
+ }
- for (final Iterator it = headerLines.iterator(); it.hasNext();) {
+ public void writeTo(WritableByteChannel channel) throws IOException {
+ ByteBuffer endLine = ByteBuffer.wrap(ImapConstants.BYTES_LINE_END);
+ endLine.rewind();
+ for (final Iterator it = headers.iterator(); it.hasNext();) {
MessageResult.Header header = (MessageResult.Header) it.next();
- header.writeTo(response);
- response.append("\r\n");
+ header.writeTo(channel);
+ while (channel.write(endLine) > 0) {}
+ endLine.rewind();
}
- response.append("\r\n");
+ while (channel.write(endLine) > 0) {}
}
+
+ }
+
+ private static final class ContentBodyElement implements BodyElement {
+ private final String name;
+ private final MessageResult.Content content;
+
+ public ContentBodyElement(final String name, final Content content) {
+ super();
+ this.name = name;
+ this.content = content;
+ }
+
+ /**
+ * @see
org.apache.james.imap.message.response.imap4rev1.FetchResponse.BodyElement#getName()
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @see
org.apache.james.imap.message.response.imap4rev1.FetchResponse.BodyElement#size()
+ */
+ public long size() {
+ return content.size();
+ }
+
+ /**
+ * @see
org.apache.james.imap.message.response.imap4rev1.FetchResponse.BodyElement#writeTo(WritableByteChannel)
+ */
+ public void writeTo(WritableByteChannel channel) throws IOException {
+ content.writeTo(channel);
+ }
+
}
}
Modified:
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java
URL:
http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java?rev=598041&r1=598040&r2=598041&view=diff
==============================================================================
---
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java
(original)
+++
james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java
Sun Nov 25 11:38:01 2007
@@ -19,6 +19,10 @@
package org.apache.james.mailboxmanager.torque;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.WritableByteChannel;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -42,6 +46,10 @@
public class MessageRowUtils {
+ public static final byte[] BYTES_NEW_LINE = {0x0D, 0x0A};
+ public static final byte[] BYTES_HEADER_FIELD_VALUE_SEP = {0x3A, 0x20};
+ private static final Charset US_ASCII = Charset.forName("US-ASCII");
+
private static final class Header implements MessageResult.Header,
MessageResult.Content {
private final String name;
private final String value;
@@ -65,11 +73,11 @@
return value;
}
- public long size() throws MailboxManagerException {
+ public long size() {
return size;
}
- public void writeTo(StringBuffer buffer) throws
MailboxManagerException {
+ public void writeTo(StringBuffer buffer) {
// TODO: sort out encoding
for (int i=0; i<name.length();i++) {
buffer.append((char)(byte) name.charAt(i));
@@ -80,7 +88,19 @@
buffer.append((char)(byte) value.charAt(i));
}
}
+
+ public void writeTo(WritableByteChannel channel) throws
IOException {
+ writeAll(channel, US_ASCII.encode(name));
+ ByteBuffer buffer =
ByteBuffer.wrap(BYTES_HEADER_FIELD_VALUE_SEP);
+ writeAll(channel, buffer);
+ writeAll(channel, US_ASCII.encode(value));
+ }
+ private void writeAll(WritableByteChannel channel, ByteBuffer
buffer) throws IOException {
+ while (channel.write(buffer) > 0) {
+ // write more
+ }
+ }
}
private final static class ByteContent implements MessageResult.Content {
@@ -92,13 +112,20 @@
size = contents.length + MessageUtils.countUnnormalLines(contents);
}
- public long size() throws MailboxManagerException {
+ public long size() {
return size;
}
- public void writeTo(StringBuffer buffer) throws
MailboxManagerException {
+ public void writeTo(StringBuffer buffer) {
MessageUtils.normalisedWriteTo(contents, buffer);
}
+
+ public void writeTo(WritableByteChannel channel) throws IOException {
+ ByteBuffer buffer = ByteBuffer.wrap(contents);
+ while (channel.write(buffer) > 0) {
+ // write more
+ }
+ }
}
private final static class FullContent implements MessageResult.Content {
@@ -112,7 +139,7 @@
this.size = caculateSize();
}
- private long caculateSize() throws MailboxManagerException{
+ private long caculateSize() {
long result = contents.length +
MessageUtils.countUnnormalLines(contents);
result += 2;
for (final Iterator it=headers.iterator(); it.hasNext();) {
@@ -125,7 +152,7 @@
return result;
}
- public void writeTo(StringBuffer buffer) throws
MailboxManagerException {
+ public void writeTo(StringBuffer buffer) {
for (final Iterator it=headers.iterator(); it.hasNext();) {
final MessageResult.Header header = (MessageResult.Header)
it.next();
if (header != null) {
@@ -139,8 +166,30 @@
MessageUtils.normalisedWriteTo(contents, buffer);
}
- public long size() throws MailboxManagerException {
+ public long size() {
return size;
+ }
+
+ public void writeTo(WritableByteChannel channel) throws IOException {
+ ByteBuffer newLine = ByteBuffer.wrap(BYTES_NEW_LINE);
+ for (final Iterator it=headers.iterator(); it.hasNext();) {
+ final MessageResult.Header header = (MessageResult.Header)
it.next();
+ if (header != null) {
+ header.writeTo(channel);
+ }
+ newLine.rewind();
+ writeAll(channel, newLine);
+ }
+ newLine.rewind();
+ writeAll(channel, newLine);
+ final ByteBuffer wrap = ByteBuffer.wrap(contents);
+ writeAll(channel, wrap);
+ }
+
+ private void writeAll(WritableByteChannel channel, ByteBuffer buffer)
throws IOException {
+ while (channel.write(buffer) > 0) {
+ // write more
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]