Author: norman
Date: Wed Dec 29 11:30:45 2010
New Revision: 1053614

URL: http://svn.apache.org/viewvc?rev=1053614&view=rev
Log:
Optimize getSize() calculation for MimeMessageWrapper. See JAMES-1159

Modified:
    james/server/trunk/core/src/main/java/org/apache/james/core/MailHeaders.java
    
james/server/trunk/core/src/main/java/org/apache/james/core/MimeMessageWrapper.java
    
james/server/trunk/core/src/test/java/org/apache/james/core/MimeMessageWrapperTest.java

Modified: 
james/server/trunk/core/src/main/java/org/apache/james/core/MailHeaders.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/core/src/main/java/org/apache/james/core/MailHeaders.java?rev=1053614&r1=1053613&r2=1053614&view=diff
==============================================================================
--- 
james/server/trunk/core/src/main/java/org/apache/james/core/MailHeaders.java 
(original)
+++ 
james/server/trunk/core/src/main/java/org/apache/james/core/MailHeaders.java 
Wed Dec 29 11:30:45 2010
@@ -25,9 +25,12 @@ import javax.mail.MessagingException;
 import javax.mail.internet.InternetHeaders;
 
 import java.io.ByteArrayOutputStream;
+import java.io.FilterInputStream;
+import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.io.Serializable;
+import java.util.Enumeration;
 
 import org.apache.mailet.base.RFC2822Headers;
 
@@ -39,7 +42,9 @@ import org.apache.mailet.base.RFC2822Hea
 public class MailHeaders extends InternetHeaders implements Serializable, 
Cloneable {
 
     private static final long serialVersionUID = 238748126601L;
-
+    private boolean modified = false;
+    private long size = -1;
+    
        /**
      * No argument constructor
      *
@@ -63,6 +68,7 @@ public class MailHeaders extends Interne
         load(in);
     }
 
+
     /**
      * Write the headers to an output stream
      *
@@ -100,12 +106,13 @@ public class MailHeaders extends Interne
      *
      * @see javax.mail.internet.InternetHeaders#addHeader(java.lang.String, 
java.lang.String)
      */
-    public void addHeader(String arg0, String arg1) {
+    public synchronized void addHeader(String arg0, String arg1) {
         if (RFC2822Headers.RETURN_PATH.equalsIgnoreCase(arg0)) {
             headers.add(0, new InternetHeader(arg0, arg1));
         } else {
             super.addHeader(arg0, arg1);
         }
+        modified();
     }
 
     /**
@@ -115,13 +122,32 @@ public class MailHeaders extends Interne
      *
      * @see javax.mail.internet.InternetHeaders#setHeader(java.lang.String, 
java.lang.String)
      */
-    public void setHeader(String arg0, String arg1) {
+    public synchronized void setHeader(String arg0, String arg1) {
         if (RFC2822Headers.RETURN_PATH.equalsIgnoreCase(arg0)) {
             super.removeHeader(arg0);
         }
         super.setHeader(arg0, arg1);
+        
+        modified();
+    }
+
+    @Override
+    public synchronized void removeHeader(String name) {
+        super.removeHeader(name);
+        modified();
+    }
+
+    @Override
+    public synchronized void addHeaderLine(String line) {
+        super.addHeaderLine(line);
+        modified();
     }
 
+    private void modified() {
+        modified = true;
+        size = -1;
+    }
+    
     /**
      * Check if all REQUIRED headers fields as specified in RFC 822
      * are present.
@@ -131,4 +157,28 @@ public class MailHeaders extends Interne
     public boolean isValid() {
         return (isSet(RFC2822Headers.DATE) && isSet(RFC2822Headers.TO) && 
isSet(RFC2822Headers.FROM));
     }
+    
+    /**
+     * Return the size of the headers
+     * 
+     * @return size
+     */
+    @SuppressWarnings("unchecked")
+    public synchronized long getSize() {
+        System.out.println("modified=" + modified);
+
+        if (size == -1 || modified) {
+            long c = 0;
+            Enumeration<String> headerLines = getAllHeaderLines();
+            while (headerLines.hasMoreElements()) {
+                c += headerLines.nextElement().length();
+                // CRLF
+                c += 2;
+            }
+            size = c;
+            modified = false;
+        }
+        return size;
+
+    }
 }

Modified: 
james/server/trunk/core/src/main/java/org/apache/james/core/MimeMessageWrapper.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/core/src/main/java/org/apache/james/core/MimeMessageWrapper.java?rev=1053614&r1=1053613&r2=1053614&view=diff
==============================================================================
--- 
james/server/trunk/core/src/main/java/org/apache/james/core/MimeMessageWrapper.java
 (original)
+++ 
james/server/trunk/core/src/main/java/org/apache/james/core/MimeMessageWrapper.java
 Wed Dec 29 11:30:45 2010
@@ -84,6 +84,8 @@ public class MimeMessageWrapper
      */
     private InputStream sourceIn;
 
+    private long initialHeaderSize;
+
     private MimeMessageWrapper(Session session) throws MessagingException {
         super(session);
         this.headers = null;
@@ -197,6 +199,7 @@ public class MimeMessageWrapper
                 InputStream in = source.getInputStream();
                 try {
                     headers = createInternetHeaders(in);
+
                 } finally {
                     IOUtils.closeQuietly(in);
                 }
@@ -247,6 +250,24 @@ public class MimeMessageWrapper
     }
 
     /**
+     * Get whether the body of the message has been modified
+     * 
+     * @return bodyModified
+     */
+    public synchronized boolean isBodyModified() {
+        return bodyModified;
+    }
+    
+    /**
+     * Get whether the header of the message has been modified
+     * 
+     * @return headersModified
+     */
+    public synchronized boolean isHeaderModified() {
+        return headersModified;
+    }
+    
+    /**
      * Rewritten for optimization purposes
      */
     public synchronized void writeTo(OutputStream os) throws IOException, 
MessagingException {
@@ -299,14 +320,29 @@ public class MimeMessageWrapper
 
     /**
      * This is the MimeMessage implementation - this should return ONLY the
-     * body, not the entire message (should not count headers).  Will have
-     * to parse the message.
+     * body, not the entire message (should not count headers).  This size 
will never change on {...@link #saveChanges()}
      */
-    public int getSize() throws MessagingException {
-        if (!messageParsed) {
-            loadMessage();
+    public synchronized int getSize() throws MessagingException {
+        if (source != null) {
+            try {
+                long fullSize = source.getMessageSize();
+                if (headers == null) {
+                    loadHeaders();
+                }
+                // 2 == CRLF 
+                return (int) (fullSize - initialHeaderSize - 2);
+                
+            } catch (IOException e) {
+                throw new MessagingException("Unable to calculate message 
size");
+            } 
+        } else {
+            if (!messageParsed) {
+                loadMessage();
+            } 
+           
+            return super.getSize();
         }
-        return super.getSize();
+       
     }
 
     /**
@@ -425,9 +461,11 @@ public class MimeMessageWrapper
 
     private synchronized void checkModifyHeaders() throws MessagingException {
         // Disable only-header loading optimizations for JAMES-559
+       
         if (!messageParsed) {
             loadMessage();
         }
+   
         // End JAMES-559
         if (headers == null) {
             loadHeaders();
@@ -530,6 +568,8 @@ public class MimeMessageWrapper
         if (headers != null) {
             return headers;
         } else {
+            initialHeaderSize = newHeaders.getSize();
+
             return newHeaders;
         }
     }

Modified: 
james/server/trunk/core/src/test/java/org/apache/james/core/MimeMessageWrapperTest.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/core/src/test/java/org/apache/james/core/MimeMessageWrapperTest.java?rev=1053614&r1=1053613&r2=1053614&view=diff
==============================================================================
--- 
james/server/trunk/core/src/test/java/org/apache/james/core/MimeMessageWrapperTest.java
 (original)
+++ 
james/server/trunk/core/src/test/java/org/apache/james/core/MimeMessageWrapperTest.java
 Wed Dec 29 11:30:45 2010
@@ -294,4 +294,27 @@ public class MimeMessageWrapperTest exte
         reader.close();
         assertTrue(contentUpdated);
     }
+    
+    public void testSize() throws MessagingException {
+        assertEquals(body.length(), mw.getSize());
+    }
+    
+    
+    public void testSizeModifiedHeaders() throws MessagingException {
+        mw.addHeader("whatever", "test");
+        assertEquals(body.length(), mw.getSize());
+    }
+   
+    public void testSizeModifiedBodyWithoutSave() throws MessagingException {
+        String newBody = "This is the new body of the message";
+        mw.setText(newBody);
+        assertEquals(body.length(), mw.getSize());
+    }
+    
+    public void testSizeModifiedBodyWithSave() throws MessagingException {
+        String newBody = "This is the new body of the message";
+        mw.setText(newBody);
+        mw.saveChanges();
+        assertEquals(body.length(), mw.getSize());
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to