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 no...@apache.org on 2010/12/29 21:47:47 UTC

svn commit: r1053728 - in /james/server/trunk: core/src/main/java/org/apache/james/core/ core/src/test/java/org/apache/james/core/ mail-file/src/main/java/org/apache/james/mailrepository/file/ mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/

Author: norman
Date: Wed Dec 29 20:47:46 2010
New Revision: 1053728

URL: http://svn.apache.org/viewvc?rev=1053728&view=rev
Log:
Make sure we only read the body of the message into memory if only needed. See JAMES-1132

Modified:
    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
    james/server/trunk/mail-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java
    james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java
    james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/MessageInputStream.java

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=1053728&r1=1053727&r2=1053728&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 20:47:46 2010
@@ -217,7 +217,7 @@ public class MimeMessageWrapper
      * @throws MessagingException if an error is encountered while
      *                            loading the message
      */
-    protected synchronized void loadMessage() throws MessagingException {
+    public synchronized void loadMessage() throws MessagingException {
         if (messageParsed) {
             //Another thread has already loaded this message
             return;
@@ -289,19 +289,33 @@ public class MimeMessageWrapper
         writeTo(headerOs, bodyOs, new String[0]);
     }
 
-    public synchronized void writeTo(OutputStream headerOs, OutputStream bodyOs, String[] ignoreList) throws IOException, MessagingException {
+    public  void writeTo(OutputStream headerOs, OutputStream bodyOs, String[] ignoreList) throws IOException, MessagingException {
+        writeTo(headerOs, bodyOs, ignoreList, false);
+    }
+
+
+    public synchronized void writeTo(OutputStream headerOs, OutputStream bodyOs, String[] ignoreList, boolean preLoad) throws IOException, MessagingException {
         if (!saved)
             saveChanges();
 
-        if (source != null && !isModified()) {
+        
+        if (preLoad == false && source != null && !isBodyModified()) {
             //We do not want to instantiate the message... just read from source
             //  and write to this outputstream
 
             //First handle the headers
             InputStream in = source.getInputStream();
             try {
-                MailHeaders headers = new MailHeaders(in);
-                IOUtils.copy(new InternetHeadersInputStream(headers.getNonMatchingHeaderLines(ignoreList)), headerOs);
+                InternetHeaders myHeaders;
+                MailHeaders parsedHeaders = new MailHeaders(in);
+
+                // check if we should use the parsed headers or not
+                if (isHeaderModified() == false) {
+                    myHeaders = parsedHeaders;
+                } else {
+                    myHeaders = headers;
+                }
+                IOUtils.copy(new InternetHeadersInputStream(myHeaders.getNonMatchingHeaderLines(ignoreList)), headerOs);
                 IOUtils.copy(in, bodyOs);
             } finally {
                 IOUtils.closeQuietly(in);
@@ -312,10 +326,14 @@ public class MimeMessageWrapper
                 loadHeaders();
             }
             IOUtils.copy(new InternetHeadersInputStream(headers.getNonMatchingHeaderLines(ignoreList)), headerOs);
+            
+            if (preLoad && messageParsed == false) {
+                loadMessage();
+            }
+            System.out.println(getContent());
             MimeMessageUtil.writeMessageBodyTo(this, bodyOs);
         }
     }
-
     /**
      * This is the MimeMessage implementation - this should return ONLY the
      * body, not the entire message (should not count headers).  This size will never change on {@link #saveChanges()}
@@ -459,10 +477,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) {

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=1053728&r1=1053727&r2=1053728&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 20:47:46 2010
@@ -87,7 +87,7 @@ public class MimeMessageWrapperTest exte
             }
         }
 
-        protected synchronized void loadMessage() throws MessagingException {
+        public synchronized void loadMessage() throws MessagingException {
             if (messageLoadable) {
                 super.loadMessage();
             } else {

Modified: james/server/trunk/mail-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java
URL: http://svn.apache.org/viewvc/james/server/trunk/mail-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java?rev=1053728&r1=1053727&r2=1053728&view=diff
==============================================================================
--- james/server/trunk/mail-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java (original)
+++ james/server/trunk/mail-file/src/main/java/org/apache/james/mailrepository/file/FileMailRepository.java Wed Dec 29 20:47:46 2010
@@ -163,6 +163,7 @@ public class FileMailRepository
             keys.add(key);
         }
         boolean saveStream = true;
+        boolean update = true;
 
         MimeMessage message = mc.getMessage();
         // if the message is a Copy on Write proxy we check the wrapped message
@@ -189,18 +190,35 @@ public class FileMailRepository
                     .append(destination)
                     .append("/")
                     .append(mc.getName());
-            if (destinationBuffer.toString().equals(wrapper.getSourceId()) && !wrapper.isModified()) {
-                //We're trying to save to the same place, and it's not modified... we shouldn't save.
-                //More importantly, if we try to save, we will create a 0-byte file since we're
-                //retrying to retrieve from a file we'll be overwriting.
-                saveStream = false;
+            if (destinationBuffer.toString().equals(wrapper.getSourceId())) {
+                if (!wrapper.isModified()) {
+                    //We're trying to save to the same place, and it's not modified... we shouldn't save.
+                    //More importantly, if we try to save, we will create a 0-byte file since we're
+                    //retrying to retrieve from a file we'll be overwriting.
+                    saveStream = false;
+                }
+                
+                // its an update
+                update = true;
             }
         }
         if (saveStream) {
             OutputStream out = null;
             try {
-                out = streamRepository.put(key);
-                mc.getMessage().writeTo(out);
+                if (update && message instanceof MimeMessageWrapper) {
+                    // we need to force the loading of the message from the stream as we want to override the old message
+                    ((MimeMessageWrapper)message).loadMessage();
+                    out = streamRepository.put(key);
+
+                    ((MimeMessageWrapper)message).writeTo(out, out, null, true);;
+
+                } else {
+                    out = streamRepository.put(key);
+                    mc.getMessage().writeTo(out);
+
+                }
+
+
             } finally {
                 if (out != null) out.close();
             }

Modified: james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java
URL: http://svn.apache.org/viewvc/james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java?rev=1053728&r1=1053727&r2=1053728&view=diff
==============================================================================
--- james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java (original)
+++ james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/JDBCMailRepository.java Wed Dec 29 20:47:46 2010
@@ -447,6 +447,29 @@ public class JDBCMailRepository
             conn = datasource.getConnection();
             //Need to determine whether need to insert this record, or update it.
     
+            //Determine whether the message body has changed, and possibly avoid
+            //  updating the database.
+            boolean saveBody = false;
+            
+            MimeMessage messageBody = mc.getMessage();
+            // if the message is a CopyOnWrite proxy we check the modified wrapped object.
+            if (messageBody instanceof MimeMessageCopyOnWriteProxy) {
+                MimeMessageCopyOnWriteProxy messageCow = (MimeMessageCopyOnWriteProxy) messageBody;
+                messageBody = messageCow.getWrappedMessage();
+            }
+            if (messageBody instanceof MimeMessageWrapper) {
+                MimeMessageWrapper message = (MimeMessageWrapper)messageBody;
+                saveBody = message.isModified();
+                if (saveBody) {
+                    message.loadMessage();
+                }
+            } else {
+                saveBody = true;
+            }
+            MessageInputStream is = new MessageInputStream(mc,sr,inMemorySizeLimit, true);
+
+            
+
             //Begin a transaction
             conn.setAutoCommit(false);
     
@@ -466,6 +489,8 @@ public class JDBCMailRepository
             }
     
             if (exists) {
+                //MessageInputStream is = new MessageInputStream(mc,sr,inMemorySizeLimit, true);
+
                 //Update the existing record
                 PreparedStatement updateMessage = null;
     
@@ -545,27 +570,13 @@ public class JDBCMailRepository
                     }
                 }
     
-                //Determine whether the message body has changed, and possibly avoid
-                //  updating the database.
-                MimeMessage messageBody = mc.getMessage();
-                boolean saveBody = false;
-                // if the message is a CopyOnWrite proxy we check the modified wrapped object.
-                if (messageBody instanceof MimeMessageCopyOnWriteProxy) {
-                    MimeMessageCopyOnWriteProxy messageCow = (MimeMessageCopyOnWriteProxy) messageBody;
-                    messageBody = messageCow.getWrappedMessage();
-                }
-                if (messageBody instanceof MimeMessageWrapper) {
-                    MimeMessageWrapper message = (MimeMessageWrapper)messageBody;
-                    saveBody = message.isModified();
-                } else {
-                    saveBody = true;
-                }
+
                 
                 if (saveBody) {
+
                     PreparedStatement updateMessageBody = 
                         conn.prepareStatement(sqlQueries.getSqlString("updateMessageBodySQL", true));
                     try {
-                        MessageInputStream is = new MessageInputStream(mc,sr,inMemorySizeLimit);
                         updateMessageBody.setBinaryStream(1,is,(int) is.getSize());
                         updateMessageBody.setString(2, mc.getName());
                         updateMessageBody.setString(3, repositoryName);
@@ -606,7 +617,6 @@ public class JDBCMailRepository
                     insertMessage.setString(8, mc.getRemoteAddr());
                     insertMessage.setTimestamp(9, new java.sql.Timestamp(mc.getLastUpdated().getTime()));
     
-                    MessageInputStream is = new MessageInputStream(mc, sr, inMemorySizeLimit);
     
                     insertMessage.setBinaryStream(10, is, (int) is.getSize());
                     

Modified: james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/MessageInputStream.java
URL: http://svn.apache.org/viewvc/james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/MessageInputStream.java?rev=1053728&r1=1053727&r2=1053728&view=diff
==============================================================================
--- james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/MessageInputStream.java (original)
+++ james/server/trunk/mail-jdbc/src/main/java/org/apache/james/mailrepository/jdbc/MessageInputStream.java Wed Dec 29 20:47:46 2010
@@ -19,11 +19,14 @@
 
 package org.apache.james.mailrepository.jdbc;
 
+import org.apache.james.core.MimeMessageCopyOnWriteProxy;
 import org.apache.james.core.MimeMessageUtil;
+import org.apache.james.core.MimeMessageWrapper;
 import org.apache.james.repository.api.StreamRepository;
 import org.apache.mailet.Mail;
 
 import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -72,11 +75,13 @@ final class MessageInputStream extends I
      * @throws IOException get thrown if an IO error detected
      * @throws MessagingException get thrown if an error detected while reading informations of the mail 
      */
-    public MessageInputStream(Mail mc, StreamRepository srep, int sizeLimit) throws IOException, MessagingException {
+    public MessageInputStream(Mail mc, StreamRepository srep, int sizeLimit, final boolean update) throws IOException, MessagingException {
         super();
         caughtException = null;
         streamRep = srep;
         size = mc.getMessageSize();
+        
+        
         // we use the pipes only when streamRep is null and the message size is greater than 4096
         // Otherwise we should calculate the header size and not the message size when streamRep is not null (JAMES-475)
         if (streamRep == null && size > sizeLimit) {
@@ -88,7 +93,7 @@ final class MessageInputStream extends I
 
                 public void run() {
                     try {
-                        writeStream(mail,out);
+                        writeStream(mail,out, update);
                     } catch (IOException e) {
                         caughtException = e;
                     } catch (MessagingException e) {
@@ -105,7 +110,7 @@ final class MessageInputStream extends I
             wrapped = new PipedInputStream(headerOut);
         } else {
             ByteArrayOutputStream headerOut = new ByteArrayOutputStream();
-            writeStream(mc,headerOut);
+            writeStream(mc,headerOut, update);
             wrapped = new ByteArrayInputStream(headerOut.toByteArray());
             size = headerOut.size();
         }
@@ -131,7 +136,22 @@ final class MessageInputStream extends I
      * @throws IOException get thrown if an IO error detected
      * @throws MessagingException get thrown if an error detected while reading informations of the mail 
      */
-    private void writeStream(Mail mail, OutputStream out) throws IOException, MessagingException {
+    private void writeStream(Mail mail, OutputStream out, boolean update) throws IOException, MessagingException {
+        MimeMessage msg = mail.getMessage();
+
+        if (update) {
+        
+            if (msg instanceof MimeMessageCopyOnWriteProxy) {
+                msg = ((MimeMessageCopyOnWriteProxy)msg).getWrappedMessage();
+            }
+        
+            if (msg instanceof MimeMessageWrapper) {
+                MimeMessageWrapper wrapper = (MimeMessageWrapper) msg;
+                wrapper.loadMessage();
+                
+            }
+        }
+        
         OutputStream bodyOut = null;
         try {
             if (streamRep == null) {
@@ -143,8 +163,13 @@ final class MessageInputStream extends I
                 bodyOut = streamRep.put(mail.getName());
             }
         
-            //Write the message to the headerOut and bodyOut.  bodyOut goes straight to the file
-            MimeMessageUtil.writeTo(mail.getMessage(), out, bodyOut);
+            if (msg instanceof MimeMessageWrapper) {
+                ((MimeMessageWrapper)msg).writeTo(out, bodyOut, null, true);
+            } else {
+                //Write the message to the headerOut and bodyOut.  bodyOut goes straight to the file
+                MimeMessageUtil.writeTo(mail.getMessage(), out, bodyOut); 
+            }
+
             out.flush();
             bodyOut.flush();
         



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