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 2007/10/28 16:39:51 UTC

svn commit: r589370 - in /james/server/trunk: core-library/src/main/java/org/apache/james/mailboxmanager/ core-library/src/main/java/org/apache/james/mailboxmanager/impl/ imap-mailbox-processor-function/src/main/java/org/apache/james/imapserver/process...

Author: rdonkin
Date: Sun Oct 28 08:39:51 2007
New Revision: 589370

URL: http://svn.apache.org/viewvc?rev=589370&view=rev
Log:
Add support for returning only header values in MessageResult.

Modified:
    james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/MessageResult.java
    james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/impl/MessageResultImpl.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/TorqueMailbox.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=589370&r1=589369&r2=589370&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 Oct 28 08:39:51 2007
@@ -20,8 +20,10 @@
 package org.apache.james.mailboxmanager;
 
 import java.util.Date;
+import java.util.List;
 
 import javax.mail.Flags;
+import javax.mail.MessagingException;
 import javax.mail.internet.MimeMessage;
 
 import org.apache.mailet.Mail;
@@ -89,6 +91,8 @@
 
     public static final int FLAGS = 0x80;
 
+    public static final int HEADERS = 0x100;
+    
     int getIncludedResults();
 
     boolean contains(int result);
@@ -130,5 +134,44 @@
     String getKey();
     
     int getSize();
-
+    
+    /**
+     * Gets headers for the message.
+     * @return <code>Headers</code>, 
+     * or null if {@link #HEADERS} was not fetched
+     */
+    Headers getHeaders();
+    
+    /**
+     * Details of the mail headers for this result.
+     */
+    public interface Headers {
+        /**
+         * Gets all header lines.
+         * @return <code>List</code> of <code>String</code> header lines,
+         * in their natural order
+         * @throws MessagingException
+         */
+        List getAllLines() throws MessagingException;
+        
+        /**
+         * Gets header lines whose header names matches (ignoring case)
+         * any of those given.
+         * @param names header names to be matched, not null
+         * @return <code>List</code> of <code>String</code> header lines,
+         * in their natural order
+         * @throws MessagingException
+         */
+        List getMatchingLines(String[] names) throws MessagingException;
+        
+        /**
+         * Gets header lines whose header name fails to match (ignoring case)
+         * all of the given names.
+         * @param names header names, not null
+         * @return <code>List</code> of <code>String</code> header lines,
+         * in their natural order
+         * @throws MessagingException
+         */
+        List getOtherLines(String[] names) throws MessagingException;
+    }
 }

Modified: james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/impl/MessageResultImpl.java
URL: http://svn.apache.org/viewvc/james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/impl/MessageResultImpl.java?rev=589370&r1=589369&r2=589370&view=diff
==============================================================================
--- james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/impl/MessageResultImpl.java (original)
+++ james/server/trunk/core-library/src/main/java/org/apache/james/mailboxmanager/impl/MessageResultImpl.java Sun Oct 28 08:39:51 2007
@@ -37,6 +37,7 @@
     private int size;
     private Date internalDate;
     private String key;
+    private Headers headers;
     
 
     public MessageResultImpl(long uid) {
@@ -184,4 +185,11 @@
         this.key=key;
     }
 
+    public Headers getHeaders() {
+        return headers;
+    }
+
+    public void setHeaders(Headers headers) {
+        this.headers = headers;
+    }
 }

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=589370&r1=589369&r2=589370&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 Oct 28 08:39:51 2007
@@ -23,7 +23,6 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Enumeration;
 import java.util.Iterator;
 import java.util.List;
 
@@ -99,9 +98,15 @@
         boolean omitExpunged = (!useUids);
 
         // TODO only fetch needed results
-        int resultToFetch = MessageResult.FLAGS | MessageResult.MIME_MESSAGE
+        int resultToFetch = MessageResult.FLAGS
                 | MessageResult.INTERNAL_DATE | MessageResult.MSN
                 | MessageResult.SIZE;
+        if (fetchMessage(fetch)) {
+            resultToFetch = resultToFetch | MessageResult.MIME_MESSAGE;
+        }
+        if (bodyElementRequiresHeaders(fetch.getBodyElements())) {
+            resultToFetch = resultToFetch | MessageResult.HEADERS;
+        }
         ImapMailboxSession mailbox = ImapSessionUtils.getMailbox(session);
         for (int i = 0; i < idSet.length; i++) {
             GeneralMessageSet messageSet = GeneralMessageSetImpl.range(idSet[i]
@@ -124,6 +129,55 @@
         result.addUnsolicitedResponses(unsolicitedResponses);
         return result;
     }
+    
+
+    private boolean fetchMessage(FetchData fetch) {
+        final boolean result;
+        if (fetch.isEnvelope() || fetch.isBody() || fetch.isBodyStructure()) {
+            result = true;
+        } else {
+            final Collection bodyElements = fetch.getBodyElements();
+            result = bodyElementRequiresMessage(bodyElements);
+        }
+        return result;
+    }
+
+    private boolean bodyElementRequiresMessage(final Collection bodyElements) {
+        boolean result = false;
+        if (bodyElements != null) {
+            for (final Iterator it=bodyElements.iterator();it.hasNext();) {
+                final BodyFetchElement element = (BodyFetchElement) it.next();
+                final String section = element.getParameters();
+                if ("TEXT".equalsIgnoreCase(section) || section.length() == 0) {
+                    result = true;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    private boolean bodyElementRequiresHeaders(final Collection bodyElements) {
+        boolean result = false;
+        if (bodyElements != null) {
+            for (final Iterator it=bodyElements.iterator();it.hasNext();) {
+                final BodyFetchElement element = (BodyFetchElement) it.next();
+                final String section = element.getParameters();
+                if ("HEADER".equalsIgnoreCase(section)) {
+                    result = true;
+                    break;
+                } else if ( section.startsWith( "HEADER.FIELDS.NOT " ) ) {
+                    result = true;
+                    break;
+                }
+                else if ( section.startsWith( "HEADER.FIELDS " ) ) {
+                    result = true;
+                    break;
+                }
+            }
+        }
+        return result;
+    }
 
     private String outputMessage(FetchData fetch, MessageResult result,
             ImapMailboxSession mailbox, boolean useUids)
@@ -160,33 +214,38 @@
 
             }
 
+            // TODO: RFC822.HEADER
+            
             // RFC822.SIZE response
             if (fetch.isSize()) {
                 response.append(" RFC822.SIZE ");
                 response.append(result.getSize());
             }
 
-            SimpleMessageAttributes attrs = new SimpleMessageAttributes(result
-                    .getMimeMessage(), getLogger());
-
-            // ENVELOPE response
-            if (fetch.isEnvelope()) {
-                response.append(" ENVELOPE ");
-                response.append(attrs.getEnvelope());
-            }
-
-            // BODY response
-            if (fetch.isBody()) {
-                response.append(" BODY ");
-                response.append(attrs.getBodyStructure(false));
-            }
-
-            // BODYSTRUCTURE response
-            if (fetch.isBodyStructure()) {
-                response.append(" BODYSTRUCTURE ");
-                response.append(attrs.getBodyStructure(true));
+            // Only create when needed
+            if (fetch.isEnvelope() || fetch.isBody() || fetch.isBodyStructure()) {
+                // TODO: replace SimpleMessageAttributes
+                final SimpleMessageAttributes attrs = new SimpleMessageAttributes(result
+                        .getMimeMessage(), getLogger());
+    
+                // ENVELOPE response
+                if (fetch.isEnvelope()) {
+                    response.append(" ENVELOPE ");
+                    response.append(attrs.getEnvelope());
+                }
+    
+                // BODY response
+                if (fetch.isBody()) {
+                    response.append(" BODY ");
+                    response.append(attrs.getBodyStructure(false));
+                }
+    
+                // BODYSTRUCTURE response
+                if (fetch.isBodyStructure()) {
+                    response.append(" BODYSTRUCTURE ");
+                    response.append(attrs.getBodyStructure(true));
+                }
             }
-
             // UID response
             if (fetch.isUid()) {
                 response.append(" UID ");
@@ -205,9 +264,8 @@
                 // Various mechanisms for returning message body.
                 String sectionSpecifier = fetchElement.getParameters();
 
-                MimeMessage mimeMessage = result.getMimeMessage();
                 try {
-                    handleBodyFetch(mimeMessage, sectionSpecifier, response);
+                    handleBodyFetch(result, sectionSpecifier, response);
                 } catch (MessagingException e) {
                     throw new MailboxException(e.getMessage(), e);
                 }
@@ -226,10 +284,12 @@
         }
     }
 
-    private void handleBodyFetch(MimeMessage mimeMessage,
+    private void handleBodyFetch(final MessageResult result,
             String sectionSpecifier, StringBuffer response)
             throws ProtocolException, MessagingException {
+        // TODO: section specifier should be fully parsed during parsing phase
         if (sectionSpecifier.length() == 0) {
+            final MimeMessage mimeMessage = result.getMimeMessage();
             // TODO - need to use an InputStream from the response here.
             ByteArrayOutputStream bout = new ByteArrayOutputStream();
             try {
@@ -240,24 +300,28 @@
             byte[] bytes = bout.toByteArray();
             addLiteral(bytes, response);
             // TODO JD maybe we've to add CRLF here
-
-        } else if (sectionSpecifier.equalsIgnoreCase("HEADER")) {
-            Enumeration e = mimeMessage.getAllHeaderLines();
-            addHeaders(e, response);
-        } else if (sectionSpecifier.startsWith("HEADER.FIELDS.NOT ")) {
-            String[] excludeNames = extractHeaderList(sectionSpecifier,
-                    "HEADER.FIELDS.NOT ".length());
-            Enumeration e = mimeMessage.getNonMatchingHeaderLines(excludeNames);
-            addHeaders(e, response);
-        } else if (sectionSpecifier.startsWith("HEADER.FIELDS ")) {
-            String[] includeNames = extractHeaderList(sectionSpecifier,
-                    "HEADER.FIELDS ".length());
-            Enumeration e = mimeMessage.getMatchingHeaderLines(includeNames);
-            addHeaders(e, response);
+        }
+        else if ( sectionSpecifier.equalsIgnoreCase( "HEADER" ) ) {
+            final MessageResult.Headers headers = result.getHeaders();
+            List lines = headers.getAllLines();
+            addHeaders( lines, response );
+        }
+        else if ( sectionSpecifier.startsWith( "HEADER.FIELDS.NOT " ) ) {
+            String[] excludeNames = extractHeaderList( sectionSpecifier, "HEADER.FIELDS.NOT ".length() );
+            final MessageResult.Headers headers = result.getHeaders();
+            List lines = headers.getOtherLines(excludeNames);
+            addHeaders( lines, response );
+        }
+        else if ( sectionSpecifier.startsWith( "HEADER.FIELDS " ) ) {
+            String[] includeNames = extractHeaderList( sectionSpecifier, "HEADER.FIELDS ".length() );
+            final MessageResult.Headers headers = result.getHeaders();
+            List lines = headers.getMatchingLines(includeNames);
+            addHeaders( lines, response );
         } else if (sectionSpecifier.equalsIgnoreCase("MIME")) {
             // TODO implement
             throw new ProtocolException("MIME not yet implemented.");
         } else if (sectionSpecifier.equalsIgnoreCase("TEXT")) {
+            final MimeMessage mimeMessage = result.getMimeMessage();
             // TODO - need to use an InputStream from the response here.
             // TODO - this is a hack. To get just the body content, I'm using a
             // null
@@ -338,22 +402,20 @@
         return (String[]) strings.toArray(new String[0]);
     }
 
-    private void addHeaders(Enumeration e, StringBuffer response) {
-        List lines = new ArrayList();
+    private void addHeaders( List headerLines, StringBuffer response )
+    {
         int count = 0;
-        while (e.hasMoreElements()) {
-            String line = (String) e.nextElement();
+        for (final Iterator it=headerLines.iterator();it.hasNext();) {
+            String line = (String) it.next();
             count += line.length() + 2;
-            lines.add(line);
         }
-        response.append('{');
-        response.append(count + 2);
-        response.append('}');
+        response.append( '{' );
+        response.append( count + 2 );
+        response.append( '}' );
         response.append("\r\n");
 
-        Iterator lit = lines.iterator();
-        while (lit.hasNext()) {
-            String line = (String) lit.next();
+        for (final Iterator it=headerLines.iterator();it.hasNext();) {
+            String line = (String) it.next();
             response.append(line);
             response.append("\r\n");
         }

Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java
URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java?rev=589370&r1=589369&r2=589370&view=diff
==============================================================================
--- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java (original)
+++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java Sun Oct 28 08:39:51 2007
@@ -22,6 +22,9 @@
 import java.io.ByteArrayOutputStream;
 import java.io.InputStream;
 import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Date;
 import java.util.Enumeration;
 import java.util.Iterator;
@@ -345,17 +348,81 @@
             messageResult.setKey(getUidToKeyConverter().toKey(messageRow.getUid()));
             result -= MessageResult.KEY;
         }
-        
+        if ((result & MessageResult.HEADERS) > 0) {
+            messageResult.setHeaders(createHeaders(messageRow));
+            result -= MessageResult.HEADERS;
+        }
         
         if (result != 0) {
-            throw new RuntimeException("Unsupportet result: " + result);
+            throw new RuntimeException("Unsupported result: " + result);
         }
         
         return messageResult;
     }
 
+    private MessageResult.Headers createHeaders(MessageRow messageRow) throws TorqueException {
+        final List headers=messageRow.getMessageHeaders();
+        Collections.sort(headers, new Comparator() {
 
+            public int compare(Object one, Object two) {
+                return ((MessageHeader) one).getLineNumber() - ((MessageHeader)two).getLineNumber();
+            }
+            
+        });
+        final MessageResult.Headers results = new HeaderRows(headers);
+        return results;
+    }
 
+    private static final class HeaderRows implements MessageResult.Headers {
+        private static final String[] EMPTY_STRING_ARRAY={};
+        private final List messageHeaders;
+        public HeaderRows(final List messageHeaders) {
+            this.messageHeaders = messageHeaders;
+        }
+        
+        public List getAllLines() throws MessagingException {
+            final ArrayList results = new ArrayList(messageHeaders.size());
+            int i = 0;
+            for (final Iterator it = messageHeaders.iterator();it.hasNext();i++) {
+                MessageHeader header = (MessageHeader) it.next();
+                final String line = toHeaderLine(header);
+                results.add(line);
+            }
+            return results;
+        }
+        
+        private String toHeaderLine(MessageHeader header) {
+            return header.getField() + ": " + header.getValue();
+        }
+        
+        public List getMatchingLines(String[] names) throws MessagingException {
+            final ArrayList results = new ArrayList(messageHeaders.size());
+            for (final Iterator it = messageHeaders.iterator();it.hasNext();) {
+                MessageHeader header = (MessageHeader) it.next();
+                for (int i=0;i<names.length;i++) {
+                    if (names[i].equalsIgnoreCase(header.getField())) {
+                        results.add(toHeaderLine(header));
+                    }
+                }
+            }
+            return results;
+        }
+        
+        public List getOtherLines(String[] names) throws MessagingException {
+            final ArrayList results = new ArrayList(messageHeaders.size());
+            for (final Iterator it = messageHeaders.iterator();it.hasNext();) {
+                MessageHeader header = (MessageHeader) it.next();
+                for (int i=0;i<names.length;i++) {
+                    if (!names[i].equalsIgnoreCase(header.getField())) {
+                        results.add(toHeaderLine(header));
+                    }
+                }
+            }
+            return results;
+        }
+        
+    }
+    
     public synchronized Flags getPermanentFlags() {
         Flags permanentFlags = new Flags();
         permanentFlags.add(Flags.Flag.ANSWERED);



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