commits@javamail.java.net

[javamail~mercurial:848] fix bugs related to expunge method - bug 8405

From: <shannon_at_java.net>
Date: Wed, 24 Aug 2016 20:46:06 +0000

Project: javamail
Repository: mercurial
Revision: 848
Author: shannon
Date: 2016-08-24 20:11:20 UTC
Link:

Log Message:
------------
Fix test to use getCanonicalHostName to match InternetAddress - bug 8403
fix bugs related to expunge method - bug 8405
don't add blank line between messages if not needed
properly handle loading new messages after expunge


Revisions:
----------
847
848


Modified Paths:
---------------
doc/release/CHANGES.txt
mail/src/test/java/javax/mail/internet/GetLocalAddressTest.java
mbox/pom.xml
mbox/src/main/java/com/sun/mail/mbox/MboxFolder.java
mbox/src/main/java/com/sun/mail/mbox/MboxMessage.java
mbox/src/main/java/com/sun/mail/mbox/MessageLoader.java
mbox/src/main/java/com/sun/mail/mbox/NewlineOutputStream.java
mbox/src/main/java/com/sun/mail/mbox/TempFile.java


Added Paths:
------------
mbox/src/test/java/com/sun/mail/mbox/MboxFolderExpungeTest.java


Diffs:
------
diff -r 5b6fe1659601 -r 1069ad8ea388 doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Fri Aug 19 14:04:32 2016 -0700
+++ b/doc/release/CHANGES.txt Tue Aug 23 12:20:07 2016 -0700
@@ -21,6 +21,7 @@
 
 K 8398 MailSessionDefinition should use the Repeatable annotation for Java EE 8
 K 8399 IdleManager fails on Android
+K 8403 Test fails: javax.mail.internet.GetLocalAddressTest
 
 
                   CHANGES IN THE 1.5.6 RELEASE

diff -r 5b6fe1659601 -r 1069ad8ea388 mail/src/test/java/javax/mail/internet/GetLocalAddressTest.java
--- a/mail/src/test/java/javax/mail/internet/GetLocalAddressTest.java Fri Aug 19 14:04:32 2016 -0700
+++ b/mail/src/test/java/javax/mail/internet/GetLocalAddressTest.java Tue Aug 23 12:20:07 2016 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010-2016 Oracle and/or its affiliates. All rights reserved.
  *
  * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common Development
@@ -59,7 +59,7 @@
     private static String localhost;
     static {
         try {
- localhost = InetAddress.getLocalHost().getHostName();
+ localhost = InetAddress.getLocalHost().getCanonicalHostName();
         } catch (UnknownHostException ex) {
             localhost = "localhost";
         }


diff -r 1069ad8ea388 -r c0c4fcd9a7a0 doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Tue Aug 23 12:20:07 2016 -0700
+++ b/doc/release/CHANGES.txt Wed Aug 24 13:11:20 2016 -0700
@@ -22,6 +22,7 @@
 K 8398 MailSessionDefinition should use the Repeatable annotation for Java EE 8
 K 8399 IdleManager fails on Android
 K 8403 Test fails: javax.mail.internet.GetLocalAddressTest
+K 8405 MboxFolder.expunge can corrupt mailbox file
 
 
                   CHANGES IN THE 1.5.6 RELEASE

diff -r 1069ad8ea388 -r c0c4fcd9a7a0 mbox/pom.xml
--- a/mbox/pom.xml Tue Aug 23 12:20:07 2016 -0700
+++ b/mbox/pom.xml Wed Aug 24 13:11:20 2016 -0700
@@ -3,7 +3,7 @@
 
     DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 
- Copyright (c) 1997-2015 Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 1997-2016 Oracle and/or its affiliates. All rights reserved.
 
     The contents of this file are subject to the terms of either the GNU
     General Public License Version 2 only ("GPL") or the Common Development
@@ -60,25 +60,27 @@
         <mail.packages.export>
             com.sun.mail.mbox; version=${mail.version}
         </mail.packages.export>
+ <findbugs.skip>
+ false
+ </findbugs.skip>
+ <findbugs.exclude>
+ ${project.basedir}/exclude.xml
+ </findbugs.exclude>
     </properties>
 
     <build>
         <plugins>
             <!--
- Configure FindBugs to run with "mvn findbugs:findbugs"
- and generate XML output that can be used by the Hudson
- FindBugs plugin.
+ Configure test plugin to find *TestSuite classes.
             -->
             <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
                 <configuration>
- <skip>false</skip>
- <threshold>${findbugs.threshold}</threshold>
- <excludeFilterFile>
- ${project.basedir}/exclude.xml
- </excludeFilterFile>
- <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
+ <includes>
+ <include>**/*Test.java</include>
+ <include>**/*TestSuite.java</include>
+ </includes>
                 </configuration>
             </plugin>
         </plugins>
@@ -89,23 +91,12 @@
             <groupId>com.sun.mail</groupId>
             <artifactId>javax.mail</artifactId>
         </dependency>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.12</version>
+ <scope>test</scope>
+ <optional>true</optional>
+ </dependency>
     </dependencies>
-
- <reporting>
- <plugins>
- <!--
- Configure FindBugs to run with "mvn site" and
- generate html output that can be viewed directly.
- -->
- <plugin>
- <groupId>org.codehaus.mojo</groupId>
- <artifactId>findbugs-maven-plugin</artifactId>
- <configuration>
- <skip>false</skip>
- <threshold>${findbugs.threshold}</threshold>
- <excludeFilterFile>exclude.xml</excludeFilterFile>
- </configuration>
- </plugin>
- </plugins>
- </reporting>
 </project>

diff -r 1069ad8ea388 -r c0c4fcd9a7a0 mbox/src/main/java/com/sun/mail/mbox/MboxFolder.java
--- a/mbox/src/main/java/com/sun/mail/mbox/MboxFolder.java Tue Aug 23 12:20:07 2016 -0700
+++ b/mbox/src/main/java/com/sun/mail/mbox/MboxFolder.java Wed Aug 24 13:11:20 2016 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2016 Oracle and/or its affiliates. All rights reserved.
  *
  * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common Development
@@ -82,7 +82,9 @@
      * is null; otherwise the MboxMessage object contains the metadata.
      */
     static final class MessageMetadata {
+ public long start; // offset in temp file of start of this message
         public long end; // offset in temp file of end of this message
+ public long dataend; // offset of end of message data, <= "end"
         public MboxMessage message; // the message itself
         public boolean recent; // message is recent?
         public boolean deleted; // message is marked deleted?
@@ -522,7 +524,6 @@
                 folder.touchlock();
                 wr++;
             }
- file_size = saved_file_size = folder.length();
             // If no messages in the mailbox, and we're closing,
             // maybe we should remove the mailbox.
             if (wr == 0 && closing) {
@@ -542,6 +543,7 @@
             // close the folder, flushing out the data
             try {
                 os.close();
+ file_size = saved_file_size = folder.length();
                 if (!keep) {
                     folder.delete();
                     file_size = 0;
@@ -611,12 +613,11 @@
                 NewlineOutputStream nos = new NewlineOutputStream(cos);
                 msg.writeTo(nos);
                 nos.flush();
- os = new NewlineOutputStream(os);
+ os = new NewlineOutputStream(os, true);
                 os = new ContentLengthUpdater(os, cos.getSize());
                 PrintStream pos = new PrintStream(os, false, "iso-8859-1");
                 pos.println(getUnixFrom(msg));
                 msg.writeTo(pos);
- pos.println(); // make sure there's a blank line at the end
                 pos.flush();
             }
         } catch (MessagingException me) {
@@ -712,13 +713,8 @@
 
     private InputStream getMessageStream(int msgno) {
         int index = messageIndexOf(msgno);
- long start;
- if (index == 0)
- start = 0;
- else
- start = ((MessageMetadata)messages.get(index - 1)).end;
- long end = ((MessageMetadata)messages.get(index)).end;
- return temp.newStream(start, end);
+ MessageMetadata md = (MessageMetadata)messages.get(index);
+ return temp.newStream(md.start, md.dataend);
     }
 
     public synchronized void appendMessages(Message[] msgs)

diff -r 1069ad8ea388 -r c0c4fcd9a7a0 mbox/src/main/java/com/sun/mail/mbox/MboxMessage.java
--- a/mbox/src/main/java/com/sun/mail/mbox/MboxMessage.java Tue Aug 23 12:20:07 2016 -0700
+++ b/mbox/src/main/java/com/sun/mail/mbox/MboxMessage.java Wed Aug 24 13:11:20 2016 -0700
@@ -482,12 +482,11 @@
                 // setContentSize((int)cos.getSize());
             }
 
- os = new NewlineOutputStream(os);
+ os = new NewlineOutputStream(os, true);
             PrintStream pos = new PrintStream(os, false, "iso-8859-1");
 
             pos.println(unix_from);
             super.writeTo(pos, null);
- pos.println(); // make sure there's a blank line at the end
             pos.flush();
         } catch (MessagingException e) {
             throw new IOException("unexpected exception " + e);

diff -r 1069ad8ea388 -r c0c4fcd9a7a0 mbox/src/main/java/com/sun/mail/mbox/MessageLoader.java
--- a/mbox/src/main/java/com/sun/mail/mbox/MessageLoader.java Tue Aug 23 12:20:07 2016 -0700
+++ b/mbox/src/main/java/com/sun/mail/mbox/MessageLoader.java Wed Aug 24 13:11:20 2016 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2016 Oracle and/or its affiliates. All rights reserved.
  *
  * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common Development
@@ -51,8 +51,9 @@
     private final TempFile temp;
     private FileInputStream fis = null;
     private AppendStream fos = null;
- private int pos, len;
- private long off;
+ private int pos, len; // position in and length of buffer
+ private long off; // current offset in temp file
+ private long prevend; // the end of the previous message in temp file
     private MboxFolder.MessageMetadata md;
     private byte[] buf = null;
     // the length of the longest header we'll need to look at
@@ -78,7 +79,7 @@
             fis = new FileInputStream(fd);
             if (fis.skip(offset) != offset)
                 throw new EOFException("Failed to skip to offset " + offset);
- this.off = offset;
+ this.off = prevend = temp.length();
             pos = len = 0;
             line = new char[LINELEN];
             buf = new byte[64 * 1024];
@@ -91,23 +92,27 @@
                     // didn't find a Content-Length, skip the body
                     start = skipBody();
                     if (start < 0) {
- md.end = -1;
+ md.end = md.dataend = -1;
                         msgs.add(md);
                         loaded++;
                         break;
                     }
+ md.dataend = start;
                 } else {
                     // skip over the body
                     skip(n);
+ md.dataend = off;
                     int b;
- start = off;
                     // skip any blank lines after the body
                     while ((b = get()) >= 0) {
                         if (b != '\n')
                             break;
                     }
+ start = off;
+ if (b >= 0)
+ start--; // back up one byte if not at EOF
                 }
- md.end = start;
+ md.end = prevend = start;
                 msgs.add(md);
                 loaded++;
             }
@@ -140,6 +145,7 @@
         int lpos = -1;
         int b;
         md = new MboxFolder.MessageMetadata();
+ md.start = prevend;
         md.recent = true;
         while ((b = get()) >= 0) {
             if (bol) {

diff -r 1069ad8ea388 -r c0c4fcd9a7a0 mbox/src/main/java/com/sun/mail/mbox/NewlineOutputStream.java
--- a/mbox/src/main/java/com/sun/mail/mbox/NewlineOutputStream.java Tue Aug 23 12:20:07 2016 -0700
+++ b/mbox/src/main/java/com/sun/mail/mbox/NewlineOutputStream.java Wed Aug 24 13:11:20 2016 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997-2016 Oracle and/or its affiliates. All rights reserved.
  *
  * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common Development
@@ -44,10 +44,13 @@
 
 /**
  * Convert the various newline conventions to the local platform's
- * newline convention.
+ * newline convention. Optionally, make sure the output ends with
+ * a blank line.
  */
 public class NewlineOutputStream extends FilterOutputStream {
     private int lastb = -1;
+ private int bol = 1; // number of times in a row we're at beginning of line
+ private final boolean endWithBlankLine;
     private static final byte[] newline;
 
     static {
@@ -64,17 +67,26 @@
     }
 
     public NewlineOutputStream(OutputStream os) {
+ this(os, false);
+ }
+
+ public NewlineOutputStream(OutputStream os, boolean endWithBlankLine) {
         super(os);
+ this.endWithBlankLine = endWithBlankLine;
     }
 
     public void write(int b) throws IOException {
         if (b == '\r') {
             out.write(newline);
+ bol++;
         } else if (b == '\n') {
- if (lastb != '\r')
+ if (lastb != '\r') {
                 out.write(newline);
+ bol++;
+ }
         } else {
             out.write(b);
+ bol = 0; // no longer at beginning of line
         }
         lastb = b;
     }
@@ -88,4 +100,19 @@
             write(b[off + i]);
         }
     }
+
+ public void flush() throws IOException {
+ if (endWithBlankLine) {
+ if (bol == 0) {
+ // not at bol, return to bol and add a blank line
+ out.write(newline);
+ out.write(newline);
+ } else if (bol == 1) {
+ // at bol, add a blank line
+ out.write(newline);
+ }
+ }
+ bol = 2;
+ out.flush();
+ }
 }

diff -r 1069ad8ea388 -r c0c4fcd9a7a0 mbox/src/main/java/com/sun/mail/mbox/TempFile.java
--- a/mbox/src/main/java/com/sun/mail/mbox/TempFile.java Tue Aug 23 12:20:07 2016 -0700
+++ b/mbox/src/main/java/com/sun/mail/mbox/TempFile.java Wed Aug 24 13:11:20 2016 -0700
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2010-2015 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010-2016 Oracle and/or its affiliates. All rights reserved.
  *
  * The contents of this file are subject to the terms of either the GNU
  * General Public License Version 2 only ("GPL") or the Common Development
@@ -81,6 +81,10 @@
         return sf.newStream(start, end);
     }
 
+ public long length() {
+ return file.length();
+ }
+
     /**
      * Close and remove this temp file.
      */

diff -r 1069ad8ea388 -r c0c4fcd9a7a0 mbox/src/test/java/com/sun/mail/mbox/MboxFolderExpungeTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbox/src/test/java/com/sun/mail/mbox/MboxFolderExpungeTest.java Wed Aug 24 13:11:20 2016 -0700
@@ -0,0 +1,386 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2009-2016 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License"). You
+ * may not use this file except in compliance with the License. You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license." If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above. However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package com.sun.mail.mbox;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Date;
+
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.Flags;
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+
+import org.junit.Test;
+import org.junit.BeforeClass;
+import org.junit.AfterClass;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * Test expunge of mbox folders.
+ */
+public final class MboxFolderExpungeTest {
+
+ @BeforeClass
+ public static void before() {
+ System.setProperty("mail.mbox.locktype", "none");
+ }
+
+ @AfterClass
+ public static void after() {
+ System.getProperties().remove("mail.mbox.locktype");
+ }
+
+ @Test
+ public void testRemoveFirst() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message m = f.getMessage(1);
+ m.setFlag(Flags.Flag.DELETED, true);
+ f.expunge();
+ m = f.getMessage(1);
+ assertEquals("2", ((String)m.getContent()).trim());
+ m.setFlag(Flags.Flag.DELETED, true);
+ m = f.getMessage(2);
+ assertEquals("3", ((String)m.getContent()).trim());
+ f.expunge();
+ m = f.getMessage(1);
+ assertEquals("3", ((String)m.getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testRemoveMiddle() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message m = f.getMessage(2);
+ m.setFlag(Flags.Flag.DELETED, true);
+ f.expunge();
+ m = f.getMessage(1);
+ assertEquals("1", ((String)m.getContent()).trim());
+ m = f.getMessage(2);
+ assertEquals("3", ((String)m.getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testRemoveLast() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message m = f.getMessage(3);
+ m.setFlag(Flags.Flag.DELETED, true);
+ f.expunge();
+ m = f.getMessage(1);
+ assertEquals("1", ((String)m.getContent()).trim());
+ m = f.getMessage(2);
+ assertEquals("2", ((String)m.getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testRemoveFirstClose() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message m = f.getMessage(1);
+ m.setFlag(Flags.Flag.DELETED, true);
+ f.close(true);
+ f.open(Folder.READ_WRITE);
+ m = f.getMessage(1);
+ assertEquals("2", ((String)m.getContent()).trim());
+ m.setFlag(Flags.Flag.DELETED, true);
+ m = f.getMessage(2);
+ assertEquals("3", ((String)m.getContent()).trim());
+ f.close(true);
+ f.open(Folder.READ_WRITE);
+ m = f.getMessage(1);
+ assertEquals("3", ((String)m.getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testRemoveMiddleClose() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message m = f.getMessage(2);
+ m.setFlag(Flags.Flag.DELETED, true);
+ f.close(true);
+ f.open(Folder.READ_WRITE);
+ m = f.getMessage(1);
+ assertEquals("1", ((String)m.getContent()).trim());
+ m = f.getMessage(2);
+ assertEquals("3", ((String)m.getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testRemoveLastClose() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message m = f.getMessage(3);
+ m.setFlag(Flags.Flag.DELETED, true);
+ f.close(true);
+ f.open(Folder.READ_WRITE);
+ m = f.getMessage(1);
+ assertEquals("1", ((String)m.getContent()).trim());
+ m = f.getMessage(2);
+ assertEquals("2", ((String)m.getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testRemoveFirstMessages() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message[] msgs = f.getMessages(1, 3);
+ msgs[0].setFlag(Flags.Flag.DELETED, true);
+ f.expunge();
+ assertEquals("2", ((String)msgs[1].getContent()).trim());
+ assertEquals("3", ((String)msgs[2].getContent()).trim());
+ msgs[1].setFlag(Flags.Flag.DELETED, true);
+ f.expunge();
+ assertEquals("3", ((String)msgs[2].getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testRemoveMiddleMessages() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message[] msgs = f.getMessages(1, 3);
+ msgs[1].setFlag(Flags.Flag.DELETED, true);
+ f.expunge();
+ assertEquals("1", ((String)msgs[0].getContent()).trim());
+ assertEquals("3", ((String)msgs[2].getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testRemoveLastMessages() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message[] msgs = f.getMessages(1, 3);
+ msgs[2].setFlag(Flags.Flag.DELETED, true);
+ f.expunge();
+ assertEquals("1", ((String)msgs[0].getContent()).trim());
+ assertEquals("2", ((String)msgs[1].getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testNewMessagesAfterExpunge() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message[] msgs = f.getMessages(1, 3);
+ msgs[0].setFlag(Flags.Flag.DELETED, true);
+ f.expunge();
+ f.appendMessages(new Message[] { createMessage(null, 4) });
+ assertEquals(3, f.getMessageCount());
+ Message m = f.getMessage(3);
+ assertEquals("4", ((String)m.getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ @Test
+ public void testNewMessagesAfterClose() throws Exception {
+ Folder f = createTestFolder();
+ try {
+ f.open(Folder.READ_WRITE);
+ Message[] msgs = f.getMessages(1, 3);
+ msgs[0].setFlag(Flags.Flag.DELETED, true);
+ f.close(true);
+ f.appendMessages(new Message[] { createMessage(null, 4) });
+ f.open(Folder.READ_WRITE);
+ assertEquals(3, f.getMessageCount());
+ Message m = f.getMessage(3);
+ assertEquals("4", ((String)m.getContent()).trim());
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ } finally {
+ f.close(false);
+ f.delete(false);
+ f.getStore().close();
+ }
+ }
+
+ /**
+ * Create a temp file to use as a test folder and populate it
+ * with 3 messages.
+ */
+ private Folder createTestFolder() {
+ Properties properties = new Properties();
+ Session session = Session.getInstance(properties);
+ //session.setDebug(true);
+
+ Folder folder = null;
+ try {
+ Store store = session.getStore("mbox");
+ File temp = File.createTempFile("mbox", ".mbx");
+ temp.deleteOnExit();
+ store.connect();
+ folder = store.getFolder(temp.getAbsolutePath());
+ folder.create(Folder.HOLDS_MESSAGES);
+ Message[] msgs = new Message[3];
+ for (int i = 0; i < 3; i++)
+ msgs[i] = createMessage(session, i + 1);
+ folder.appendMessages(msgs);
+ } catch (Exception ex) {
+ System.out.println(ex);
+ //ex.printStackTrace();
+ fail(ex.toString());
+ }
+ return folder;
+ }
+
+ /**
+ * Create a test message.
+ */
+ private Message createMessage(Session session, int msgno)
+ throws MessagingException {
+ MimeMessage msg = new MimeMessage(session);
+ msg.setFrom("test_at_example.com");
+ msg.setSentDate(new Date());
+ String subject = "test ";
+ // ensure each message is a different length
+ for (int i = 0; i < msgno; i++)
+ subject += "test ";
+ msg.setSubject(subject + msgno);
+ msg.setText(msgno + "\n");
+ msg.saveChanges();
+ return msg;
+ }
+}