james-server-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nor...@apache.org
Subject svn commit: r1092700 - in /james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch: EmptyContent.java FetchResponseBuilder.java HeaderBodyElement.java MimeBodyElement.java
Date Fri, 15 Apr 2011 13:30:58 GMT
Author: norman
Date: Fri Apr 15 13:30:58 2011
New Revision: 1092700

URL: http://svn.apache.org/viewvc?rev=1092700&view=rev
Log:
FETCH *.MIME fields MUST NOT write a empty line terminated with a CRLF if no MIME Header was
found and FETCH *.HEADER MUST NOT write a empty line terminated with a CRLF if no body was
found. IMAP-297 and IMAP-298

Added:
    james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/EmptyContent.java
    james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/MimeBodyElement.java
Modified:
    james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
    james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/HeaderBodyElement.java

Added: james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/EmptyContent.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/EmptyContent.java?rev=1092700&view=auto
==============================================================================
--- james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/EmptyContent.java
(added)
+++ james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/EmptyContent.java
Fri Apr 15 13:30:58 2011
@@ -0,0 +1,46 @@
+/****************************************************************
+ * 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.processor.fetch;
+
+import java.io.IOException;
+import java.nio.channels.WritableByteChannel;
+
+import org.apache.james.mailbox.Content;
+
+/**
+ * Just an Empty {@link Content}
+ *
+ */
+public class EmptyContent implements Content{
+
+    /**
+     * Write nothing as this {@link Content} is empty
+     */
+    public void writeTo(WritableByteChannel channel) throws IOException {
+        // do nothing..
+    }
+
+    /**
+     * Return 0 as this {@link Content} is empty
+     */
+    public long size() {
+        return 0;
+    }
+
+}

Modified: james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java?rev=1092700&r1=1092699&r2=1092700&view=diff
==============================================================================
--- james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
(original)
+++ james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/FetchResponseBuilder.java
Fri Apr 15 13:30:58 2011
@@ -253,13 +253,16 @@ public final class FetchResponseBuilder 
 
     private FetchResponse.BodyElement text(final MessageResult messageResult, String name,
final int[] path, final boolean isBase) throws MailboxException {
         final FetchResponse.BodyElement result;
-        final Content body;
+        Content body;
         if (isBase) {
             body = messageResult.getBody();
         } else {
             MessageResult.MimePath mimePath = new MimePathImpl(path);
             body = messageResult.getBody(mimePath);
         }
+        if (body == null) {
+            body = new EmptyContent();
+        }
         result = new ContentBodyElement(name, body);
         return result;
     }
@@ -268,32 +271,39 @@ public final class FetchResponseBuilder 
         final FetchResponse.BodyElement result;
         final Iterator<MessageResult.Header> headers = getMimeHeaders(messageResult,
path, isBase);
         List<MessageResult.Header> lines = MessageResultUtils.getAll(headers);
-        result = new HeaderBodyElement(name, lines);
+        result = new MimeBodyElement(name, lines);
         return result;
     }
 
-    private FetchResponse.BodyElement headers(final MessageResult messageResult, String name,
final int[] path, final boolean isBase) throws MailboxException {
-        final FetchResponse.BodyElement result;
+    private HeaderBodyElement headerBodyElement(final MessageResult messageResult, String
name, List<MessageResult.Header> lines, final int[] path, final boolean isBase) throws
MailboxException {
+        final HeaderBodyElement result = new HeaderBodyElement(name, lines);
+        // if the size is 2 we had found not header and just want to write the empty line
with CLRF terminated
+        // so check no if there is a content for it. If not we MUST NOT write the empty line
in any case
+        // as stated in rfc3501
+        if (result.size() == 2) {
+            if (content(messageResult, name, path, isBase).size() <= 0) {
+                result.noBody();
+            }
+        }
+        return result;
+    }
+    private FetchResponse.BodyElement headers(final MessageResult messageResult, String name,
final int[] path, final boolean isBase) throws MailboxException {        
         final Iterator<MessageResult.Header> headers = getHeaders(messageResult, path,
isBase);
         List<MessageResult.Header> lines = MessageResultUtils.getAll(headers);
-        result = new HeaderBodyElement(name, lines);
-        return result;
+        return headerBodyElement(messageResult, name, lines, path, isBase);
     }
 
     private FetchResponse.BodyElement fieldsNot(final MessageResult messageResult, String
name, final int[] path, Collection<String> names, final boolean isBase) throws MailboxException
{
-        final FetchResponse.BodyElement result;
         final Iterator<MessageResult.Header> headers = getHeaders(messageResult, path,
isBase);
         List<MessageResult.Header> lines = MessageResultUtils.getNotMatching(names,
headers);
-        result = new HeaderBodyElement(name, lines);
-        return result;
+        
+        return headerBodyElement(messageResult, name, lines, path, isBase);
     }
 
     private FetchResponse.BodyElement fields(final MessageResult messageResult, String name,
final int[] path, Collection<String> names, final boolean isBase) throws MailboxException
{
-        final FetchResponse.BodyElement result;
         final Iterator<MessageResult.Header> headers = getHeaders(messageResult, path,
isBase);
         List<MessageResult.Header> lines = MessageResultUtils.getMatching(names, headers);
-        result = new HeaderBodyElement(name, lines);
-        return result;
+        return headerBodyElement(messageResult, name, lines, path, isBase);
     }
 
     private Iterator<MessageResult.Header> getHeaders(final MessageResult messageResult,
final int[] path, final boolean isBase) throws MailboxException {
@@ -315,13 +325,16 @@ public final class FetchResponseBuilder 
 
     private FetchResponse.BodyElement content(final MessageResult messageResult, String name,
final int[] path, final boolean isBase) throws MailboxException {
         final FetchResponse.BodyElement result;
-        final Content full;
+        Content full;
         if (isBase) {
             full = messageResult.getFullContent();
         } else {
             MessageResult.MimePath mimePath = new MimePathImpl(path);
             full = messageResult.getMimeBody(mimePath);
         }
+        if (full == null) {
+            full = new EmptyContent();
+        }
         result = new ContentBodyElement(name, full);
         return result;
     }

Modified: james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/HeaderBodyElement.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/HeaderBodyElement.java?rev=1092700&r1=1092699&r2=1092700&view=diff
==============================================================================
--- james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/HeaderBodyElement.java
(original)
+++ james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/HeaderBodyElement.java
Fri Apr 15 13:30:58 2011
@@ -22,104 +22,41 @@
  */
 package org.apache.james.imap.processor.fetch;
 
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-import java.nio.channels.Channels;
-import java.nio.channels.WritableByteChannel;
-import java.util.Iterator;
 import java.util.List;
 
 import org.apache.james.imap.api.ImapConstants;
 import org.apache.james.imap.message.response.FetchResponse.BodyElement;
 import org.apache.james.mailbox.MessageResult;
 
-final class HeaderBodyElement implements BodyElement {
-    private final String name;
-
-    private final List<MessageResult.Header> headers;
-
-    private final long size;
+/**
+ * {@link BodyElement} which represent a HEADER element specified by for example (BODY[1.HEADER])
+ */
+public class HeaderBodyElement extends MimeBodyElement {
 
     public HeaderBodyElement(final String name, final List<MessageResult.Header> headers)
{
-        super();
-        this.name = name;
-        this.headers = headers;
-        this.size = calculateSize(headers);
+        super(name, headers);
     }
 
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.apache.james.imap.message.response.FetchResponse.BodyElement#getName
-     * ()
+    
+    /**
+     * Indicate that there is no text body in the message. In this case we don't need to
write a single CRLF in anycase if
+     * this Element does not contain a header.
      */
-    public String getName() {
-        return name;
+    public void noBody() {
+        if (headers.isEmpty()) {
+            size = 0;
+        }
     }
 
-    private long calculateSize(List<MessageResult.Header> headers) {
-        final int result;
+    @Override
+    protected long calculateSize(List<MessageResult.Header> headers) {
         if (headers.isEmpty()) {
             // even if the headers are empty we need to include the headers body
             // seperator
             // See IMAP-294
-            result = ImapConstants.LINE_END.length();
-        } else {
-            int count = 0;
-            for (final Iterator<MessageResult.Header> it = headers.iterator(); it.hasNext();)
{
-                MessageResult.Header header = it.next();
-                count += header.size() + ImapConstants.LINE_END.length();
-            }
-            result = count + ImapConstants.LINE_END.length();
-        }
-        return result;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.apache.james.imap.message.response.FetchResponse.BodyElement#size()
-     */
-    public long size() {
-        return size;
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see
-     * org.apache.james.imap.message.response.FetchResponse.BodyElement#writeTo
-     * (java.nio.channels.WritableByteChannel)
-     */
-    public void writeTo(WritableByteChannel channel) throws IOException {
-        ByteBuffer endLine = ByteBuffer.wrap(ImapConstants.LINE_END.getBytes());
-        endLine.rewind();
-        for (final Iterator<MessageResult.Header> it = headers.iterator(); it.hasNext();)
{
-            MessageResult.Header header = it.next();
-            header.writeTo(channel);
-            while (channel.write(endLine) > 0) { // NOPMD false positive
-            }
-            endLine.rewind();
+            return ImapConstants.LINE_END.length();
         }
-        while (channel.write(endLine) > 0) { // NOPMD false positive
-        }
-    }
-
-    /*
-     * (non-Javadoc)
-     * 
-     * @see org.apache.james.imap.message.response.FetchResponse.BodyElement#
-     * getInputStream()
-     */
-    public InputStream getInputStream() throws IOException {
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        writeTo(Channels.newChannel(out));
-        return new ByteArrayInputStream(out.toByteArray());
+        return super.calculateSize(headers);
     }
 
 }
\ No newline at end of file

Added: james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/MimeBodyElement.java
URL: http://svn.apache.org/viewvc/james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/MimeBodyElement.java?rev=1092700&view=auto
==============================================================================
--- james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/MimeBodyElement.java
(added)
+++ james/imap/trunk/processor/src/main/java/org/apache/james/imap/processor/fetch/MimeBodyElement.java
Fri Apr 15 13:30:58 2011
@@ -0,0 +1,130 @@
+/****************************************************************
+ * 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.processor.fetch;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.Channels;
+import java.nio.channels.WritableByteChannel;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.james.imap.api.ImapConstants;
+import org.apache.james.imap.message.response.FetchResponse.BodyElement;
+import org.apache.james.mailbox.MessageResult;
+
+
+/**
+ * {@link BodyElement} which represent a MIME element specified by for example (BODY[1.MIME])
+ *
+ */
+public class MimeBodyElement implements BodyElement {
+    private final String name;
+
+    protected final List<MessageResult.Header> headers;
+
+    protected long size;
+
+
+    public MimeBodyElement(final String name, final List<MessageResult.Header> headers)
{
+        super();
+        this.name = name;
+        this.headers = headers;
+        this.size = calculateSize(headers);
+        
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.james.imap.message.response.FetchResponse.BodyElement#getName
+     * ()
+     */
+    public String getName() {
+        return name;
+    }
+    
+
+    protected long calculateSize(List<MessageResult.Header> headers) {
+        final int result;
+        if (headers.isEmpty()) {
+           result = 0;
+        } else {
+            int count = 0;
+            for (final Iterator<MessageResult.Header> it = headers.iterator(); it.hasNext();)
{
+                MessageResult.Header header = it.next();
+                count += header.size() + ImapConstants.LINE_END.length();
+            }
+            result = count + ImapConstants.LINE_END.length();
+        }
+        return result;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.james.imap.message.response.FetchResponse.BodyElement#size()
+     */
+    public long size() {
+        return size;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.james.imap.message.response.FetchResponse.BodyElement#writeTo
+     * (java.nio.channels.WritableByteChannel)
+     */
+    public void writeTo(WritableByteChannel channel) throws IOException {
+        ByteBuffer endLine = ByteBuffer.wrap(ImapConstants.LINE_END.getBytes());
+        endLine.rewind();
+        for (final Iterator<MessageResult.Header> it = headers.iterator(); it.hasNext();)
{
+            MessageResult.Header header = it.next();
+            header.writeTo(channel);
+            while (channel.write(endLine) > 0) { // NOPMD false positive
+            }
+            endLine.rewind();
+        }
+       // no empty line with CRLF for MIME headers. See IMAP-297
+        if (size > 0) {
+            while (channel.write(endLine) > 0) { // NOPMD false positive
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see org.apache.james.imap.message.response.FetchResponse.BodyElement#
+     * getInputStream()
+     */
+    public InputStream getInputStream() throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        writeTo(Channels.newChannel(out));
+        return new ByteArrayInputStream(out.toByteArray());
+    }
+
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org


Mime
View raw message