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 2009/02/07 20:51:12 UTC

svn commit: r741946 - in /james/protocols/imap/trunk: jpa/src/main/java/org/apache/james/imap/jpa/ jpa/src/main/java/org/apache/james/imap/jpa/mail/model/ store/src/main/java/org/apache/james/imap/store/ store/src/main/java/org/apache/james/imap/store/...

Author: rdonkin
Date: Sat Feb  7 19:51:11 2009
New Revision: 741946

URL: http://svn.apache.org/viewvc?rev=741946&view=rev
Log:
Switch to store complete document plus start of body.

Modified:
    james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java
    james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMailboxMembership.java
    james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMessage.java
    james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/CountingInputStream.java
    james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/ResultUtils.java
    james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java
    james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/Document.java
    james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/PropertyBuilder.java
    james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageBuilder.java
    james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageRowUtilsTest.java
    james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMailboxMembership.java
    james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java

Modified: james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java (original)
+++ james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/JPAMailbox.java Sat Feb  7 19:51:11 2009
@@ -68,13 +68,14 @@
     }
     
     @Override
-    protected MailboxMembership createMessage(Date internalDate, final long uid, final int size, final byte[] body, final Flags flags, final List<Header> headers, PropertyBuilder propertyBuilder) {
+    protected MailboxMembership createMessage(Date internalDate, final long uid, final int size, int bodyStartOctet, final byte[] document, 
+            final Flags flags, final List<Header> headers, PropertyBuilder propertyBuilder) {
         final List<JPAHeader> jpaHeaders = new ArrayList<JPAHeader>(headers.size());
         for (Header header: headers) {
             jpaHeaders.add((JPAHeader) header);
         }
         final MailboxMembership message = new JPAMailboxMembership(mailboxId, uid, internalDate, 
-                size, flags, body, jpaHeaders, propertyBuilder);
+                size, flags, document, bodyStartOctet, jpaHeaders, propertyBuilder);
         return message;
     }
     

Modified: james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMailboxMembership.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMailboxMembership.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMailboxMembership.java (original)
+++ james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMailboxMembership.java Sat Feb  7 19:51:11 2009
@@ -145,13 +145,13 @@
     public JPAMailboxMembership() {}
 
     public JPAMailboxMembership(long mailboxId, long uid, Date internalDate, int size, Flags flags, 
-            byte[] body, final List<JPAHeader> headers, final PropertyBuilder propertyBuilder) {
+            byte[] content, int bodyStartOctet, final List<JPAHeader> headers, final PropertyBuilder propertyBuilder) {
         super();
         this.mailboxId = mailboxId;
         this.uid = uid;
         this.internalDate = internalDate;
         this.size = size;
-        this.message = new JPAMessage(body, headers, propertyBuilder);
+        this.message = new JPAMessage(content, bodyStartOctet, headers, propertyBuilder);
         setFlags(flags);
     }
 

Modified: james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMessage.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMessage.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMessage.java (original)
+++ james/protocols/imap/trunk/jpa/src/main/java/org/apache/james/imap/jpa/mail/model/JPAMessage.java Sat Feb  7 19:51:11 2009
@@ -36,6 +36,7 @@
 import org.apache.james.imap.store.mail.model.Header;
 import org.apache.james.imap.store.mail.model.Property;
 import org.apache.james.imap.store.mail.model.PropertyBuilder;
+import org.apache.openjpa.jdbc.sql.FirebirdDictionary;
 
 @Entity(name="Message")
 public class JPAMessage implements Document {
@@ -43,11 +44,13 @@
     @Id@GeneratedValue private long id;
 
     /** The value for the body field. Lazy loaded */
-    @Basic(optional=false, fetch=FetchType.LAZY) @Lob private byte[] body;
+    @Basic(optional=false, fetch=FetchType.LAZY) @Lob private byte[] content;
     /** Headers for this message */
     @OneToMany(cascade = CascadeType.ALL, fetch=FetchType.LAZY) private List<JPAHeader> headers;
-    /** Number of octets in the body content */
-    @Basic(optional=false) private long bodyOctets;
+    /** The first body octet */
+    @Basic(optional=false) private int bodyStartOctet;
+    /** Number of octets in the full document content */
+    @Basic(optional=false) private long contentOctets;
     /** MIME media type */
     @Basic(optional=true) private String mediaType;
     /** MIME sub type */
@@ -63,10 +66,11 @@
     @Deprecated
     public JPAMessage() {}
 
-    public JPAMessage(byte[] body, final List<JPAHeader> headers, final PropertyBuilder propertyBuilder) {
+    public JPAMessage(byte[] content, final int bodyStartOctet, final List<JPAHeader> headers, final PropertyBuilder propertyBuilder) {
         super();
-        this.body = body;
-        bodyOctets = body.length;
+        this.content = content;
+        this.contentOctets = content.length;
+        this.bodyStartOctet = bodyStartOctet;
         this.headers = new ArrayList<JPAHeader>(headers);
         textualLineCount = propertyBuilder.getTextualLineCount();
         this.mediaType = propertyBuilder.getMediaType();
@@ -87,10 +91,12 @@
     }
     
     /**
-     * @see org.apache.james.imap.jpa.mail.model.Document#getBody()
+     * @see org.apache.james.imap.jpa.mail.model.Document#getBodyContent()
      */    
-    public ByteBuffer getBody() {
-        return ByteBuffer.wrap(body).asReadOnlyBuffer();
+    public ByteBuffer getBodyContent() {
+        final ByteBuffer contentBuffer = getFullContent();
+        contentBuffer.position(bodyStartOctet);
+        return contentBuffer.slice();
     }
 
     @Override
@@ -130,7 +136,7 @@
      * @return number of octets
      */
     public long getBodyOctets() {
-        return bodyOctets;
+        return contentOctets - bodyStartOctet;
     }
 
     /**
@@ -169,4 +175,12 @@
     public Long getTextualLineCount() {
         return textualLineCount;
     }
+
+    public ByteBuffer getFullContent() {
+        return ByteBuffer.wrap(content).asReadOnlyBuffer();
+    }
+
+    public long getFullContentOctets() {
+        return contentOctets;
+    }
 }

Modified: james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/CountingInputStream.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/CountingInputStream.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/CountingInputStream.java (original)
+++ james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/CountingInputStream.java Sat Feb  7 19:51:11 2009
@@ -55,4 +55,12 @@
     public final int getOctetCount() {
         return octetCount;
     }
+    
+    /**
+     * Reads - and discards - the rest of the stream
+     * @throws IOException
+     */
+    public void readAll() throws IOException {
+        while (read()>0);
+    }
 }
\ No newline at end of file

Modified: james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/ResultUtils.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/ResultUtils.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/ResultUtils.java (original)
+++ james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/ResultUtils.java Sat Feb  7 19:51:11 2009
@@ -73,17 +73,14 @@
     }
 
     public static Content createBodyContent(MailboxMembership membership) {
-        final ByteBuffer bytes = membership.getDocument().getBody();
+        final ByteBuffer bytes = membership.getDocument().getBodyContent();
         final ByteContent result = new ByteContent(bytes);
         return result;
     }
 
-    public static Content createFullContent(final MailboxMembership membership, List headers) {
-        if (headers == null) {
-            headers = createHeaders(membership);
-        }
-        final ByteBuffer bytes = membership.getDocument().getBody();
-        final FullContent results = new FullContent(bytes, headers);
+    public static Content createFullContent(final MailboxMembership membership) {
+        final ByteBuffer bytes = membership.getDocument().getFullContent();
+        final ByteContent results = new ByteContent(bytes);
         return results;
     }
 
@@ -134,8 +131,7 @@
 
     private static void addFullContent(final MailboxMembership messageRow, MessageResultImpl messageResult) 
             throws MailboxException {
-        final List headers = messageResult.getHeaders();
-        final Content content = createFullContent(messageRow, headers);
+        final Content content = createFullContent(messageRow);
         messageResult.setFullContent(content);
     }
 
@@ -219,7 +215,7 @@
             headersToString.append("\r\n");
         }
         headersToString.append("\r\n");
-        final ByteBuffer bodyContent = document.getBody();
+        final ByteBuffer bodyContent = document.getBodyContent();
         final MessageInputStream stream = new MessageInputStream(headersToString, bodyContent);
         return stream;
     }

Modified: james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java (original)
+++ james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/StoreMailbox.java Sat Feb  7 19:51:11 2009
@@ -20,7 +20,6 @@
 package org.apache.james.imap.store;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -115,6 +114,8 @@
 
                 final long uid = mailbox.getLastUid();
                 final int size = messageBytes.length;
+                final int bodyStartOctet = bodyStartOctet(messageBytes);
+                
                 final MimeTokenStream parser = MimeTokenStream.createMaximalDescriptorStream();
                 parser.setRecursionMode(MimeTokenStream.M_NO_RECURSE);
                 parser.parse(new ByteArrayInputStream(messageBytes));
@@ -172,31 +173,31 @@
                 } else {
                     propertyBuilder.setCharset(codeset);
                 }
+                
                 final String boundary = descriptor.getBoundary();
                 if (boundary != null) {
                     propertyBuilder.setBoundary(boundary);
-                }
-                final CountingInputStream bodyStream = new CountingInputStream(parser.getInputStream());
-                final ByteArrayOutputStream out = StreamUtils.out(bodyStream);
-                long lines = bodyStream.getLineCount();
-                
-                next = parser.next();
-                if (next == MimeTokenStream.T_EPILOGUE)  {
-                    final CountingInputStream epilogueStream = new CountingInputStream(parser.getInputStream());
-                    StreamUtils.out(epilogueStream, out);
-                    lines+=epilogueStream.getLineCount();
                 }   
                 if ("text".equalsIgnoreCase(mediaType)) {
+                    final CountingInputStream bodyStream = new CountingInputStream(parser.getInputStream());
+                    bodyStream.readAll();
+                    long lines = bodyStream.getLineCount();
+                    
+                    next = parser.next();
+                    if (next == MimeTokenStream.T_EPILOGUE)  {
+                        final CountingInputStream epilogueStream = new CountingInputStream(parser.getInputStream());
+                        epilogueStream.readAll();
+                        lines+=epilogueStream.getLineCount();
+                    }
                     propertyBuilder.setTextualLineCount(lines);
                 }
-                final byte[] body = out.toByteArray();
                 
                 final Flags flags = new Flags();
                 if (isRecent) {
                     flags.add(Flags.Flag.RECENT);
                 }
                 
-                final MailboxMembership message = createMessage(internalDate, uid, size, body, flags, headers, propertyBuilder);
+                final MailboxMembership message = createMessage(internalDate, uid, size, bodyStartOctet, messageBytes, flags, headers, propertyBuilder);
                 final MessageMapper mapper = createMessageMapper();
 
                 mapper.begin();
@@ -213,8 +214,25 @@
         }
     }
 
-    protected abstract MailboxMembership createMessage(Date internalDate, final long uid, final int size, final byte[] body, 
-            final Flags flags, final List<Header> headers, PropertyBuilder propertyBuilder);
+    private int bodyStartOctet(byte[] messageBytes) {
+        int bodyStartOctet = messageBytes.length;
+        for (int i=0;i<messageBytes.length-4;i++) {
+            if (messageBytes[i] == 0x0D) {
+                if (messageBytes[i+1] == 0x0A) {
+                    if (messageBytes[i+2] == 0x0D) {
+                        if (messageBytes[i+3] == 0x0A) {
+                            bodyStartOctet = i+4;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+        return bodyStartOctet;
+    }
+
+    protected abstract MailboxMembership createMessage(Date internalDate, final long uid, final int size, int bodyStartOctet, 
+            final byte[] document, final Flags flags, final List<Header> headers, PropertyBuilder propertyBuilder);
     
     protected abstract Header createHeader(int lineNumber, String name, String value);
 

Modified: james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/Document.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/Document.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/Document.java (original)
+++ james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/Document.java Sat Feb  7 19:51:11 2009
@@ -28,12 +28,19 @@
  */
 public interface Document {
 
+
+    /**
+     * Gets the full content (including headers) of the document.
+     * @return read only buffer, not null
+     */
+    public abstract ByteBuffer getFullContent();
+    
     /**
      * Gets the body content of the document.
      * Headers are excluded.
      * @return read only buffer, not null
      */
-    public abstract ByteBuffer getBody();
+    public abstract ByteBuffer getBodyContent();
 
     /**
      * Gets the top level MIME content media type.
@@ -57,6 +64,13 @@
     public abstract long getBodyOctets();
     
     /**
+     * The number of octets contained in the full content of this document.
+     * 
+     * @return number of octets
+     */
+    public abstract long getFullContentOctets();
+    
+    /**
      * Gets the number of CRLF in a textual document.
      * @return CRLF count when document is textual,
      * null otherwise

Modified: james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/PropertyBuilder.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/PropertyBuilder.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/PropertyBuilder.java (original)
+++ james/protocols/imap/trunk/store/src/main/java/org/apache/james/imap/store/mail/model/PropertyBuilder.java Sat Feb  7 19:51:11 2009
@@ -139,7 +139,7 @@
         textualLineCount = null;
         properties = new ArrayList<SimpleProperty>(INITIAL_CAPACITY);
     }
-    
+
     /**
      * Gets the number of CRLF in a textual document.
      * @return CRLF count when document is textual,

Modified: james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageBuilder.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageBuilder.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageBuilder.java (original)
+++ james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageBuilder.java Sat Feb  7 19:51:11 2009
@@ -38,7 +38,7 @@
     public final List<SimpleHeader> headers = new ArrayList<SimpleHeader>();
     public int lineNumber = 0;
     
-    public MailboxMembership build() {
+    public MailboxMembership build() throws Exception {
         MailboxMembership result = new SimpleMailboxMembership(mailboxId, uid, internalDate, size, flags, body, headers);
         return result;
     }

Modified: james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageRowUtilsTest.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageRowUtilsTest.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageRowUtilsTest.java (original)
+++ james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/MessageRowUtilsTest.java Sat Feb  7 19:51:11 2009
@@ -40,7 +40,7 @@
         assertTrue(ResultUtils.getUidComparator().compare(one, two) > 0);
     }
 
-    private MailboxMembership buildMessage(int uid) {
+    private MailboxMembership buildMessage(int uid) throws Exception {
         MessageBuilder builder = new MessageBuilder();
         builder.uid = uid;
         return builder.build();

Modified: james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMailboxMembership.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMailboxMembership.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMailboxMembership.java (original)
+++ james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMailboxMembership.java Sat Feb  7 19:51:11 2009
@@ -44,7 +44,7 @@
     public SimpleMessage message;
 
     public SimpleMailboxMembership(long mailboxId, long uid, Date internalDate, int size, 
-            Flags flags, byte[] body, final List<SimpleHeader> headers) {
+            Flags flags, byte[] body, final List<SimpleHeader> headers) throws Exception {
         super();
         this.mailboxId = mailboxId;
         this.uid = uid;

Modified: james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java
URL: http://svn.apache.org/viewvc/james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java?rev=741946&r1=741945&r2=741946&view=diff
==============================================================================
--- james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java (original)
+++ james/protocols/imap/trunk/store/src/test/java/org/apache/james/imap/store/SimpleMessage.java Sat Feb  7 19:51:11 2009
@@ -18,6 +18,9 @@
  ****************************************************************/
 package org.apache.james.imap.store;
 
+import java.io.ByteArrayOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
 import java.util.List;
@@ -28,19 +31,35 @@
 
 public class SimpleMessage implements Document {
     
+    public static final char[] NEW_LINE = { 0x0D, 0x0A };
+    
     public byte[] body;
+    public byte[] fullContent;
     public List<SimpleHeader> headers;
     public List<SimpleProperty> properties;
     public String subType = null;
     public String mediaType = null;
     public Long textualLineCount = null;
 
-    public SimpleMessage(byte[] body, final List<SimpleHeader> headers) {
+    public SimpleMessage(byte[] body, final List<SimpleHeader> headers) throws Exception {
         super();
         this.body = body;
         this.headers = new ArrayList<SimpleHeader>(headers);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        final Writer writer = new OutputStreamWriter(baos, "us-ascii");
+        for (SimpleHeader header:headers) {
+            writer.write(header.getField());
+            writer.write(": ");
+            writer.write(header.getValue());
+            writer.write(NEW_LINE);
+        }
+        writer.write(NEW_LINE);
+        writer.flush();
+        baos.write(body);
+        baos.flush();
+        fullContent = baos.toByteArray();
     }
-
+    
     /**
      * Constructs a copy of the given message.
      * All properties are cloned except mailbox and UID.
@@ -51,6 +70,7 @@
     public SimpleMessage(SimpleMessage original) {
         super();
         this.body = original.body;
+        this.fullContent = original.fullContent;
         final List<SimpleHeader> originalHeaders = original.headers;
         if (originalHeaders == null) {
             this.headers = new ArrayList<SimpleHeader>();
@@ -63,13 +83,21 @@
     }
 
     /**
-     * @see org.apache.james.imap.jpa.mail.model.Document#getBody()
+     * @see org.apache.james.imap.jpa.mail.model.Document#getBodyContent()
      */
-    public ByteBuffer getBody() {
+    public ByteBuffer getBodyContent() {
         return ByteBuffer.wrap(body).asReadOnlyBuffer();
     }
 
     /**
+     * Gets the full content (including headers) of the document.
+     * @return read only buffer, not null
+     */
+    public ByteBuffer getFullContent() {
+        return ByteBuffer.wrap(fullContent).asReadOnlyBuffer();
+    }
+    
+    /**
      * @see org.apache.james.imap.jpa.mail.model.Document#getHeaders()
      */
     public List<Header> getHeaders() {
@@ -95,4 +123,8 @@
     public Long getTextualLineCount() {
         return textualLineCount;
     }
+
+    public long getFullContentOctets() {
+        return fullContent.length;
+    }
 }



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