commits@javamail.java.net

[javamail~mercurial:802] CollectorFormatter forward compatiblity with Formatter spec.

From: <shannon_at_java.net>
Date: Sat, 21 Nov 2015 00:01:32 +0000

Project: javamail
Repository: mercurial
Revision: 802
Author: shannon
Date: 2015-11-20 23:58:27 UTC
Link:

Log Message:
------------
Empty Gmail X-GM-LABELS list is misparsed - bug 7052
Remove need to use JDK 1.5 compiler, check API with Animal Sniffer Maven plugin.
Fix JAF to remove hard dependency on java.beans.Beans, which isn't on Android.
DurationFilter typos.
DurationFilterTest typos.

(From Jason)
Chain exception in MimePartDataSource.getInputStream.
Fix MailHandler to handle chained exceptions now thrown by getContent
due to previous MimePartDataSource fix.

(From Jason)
Workaround for bug in maven-compiler-plugin that breaks incremental compilation:
https://issues.apache.org/jira/browse/MCOMPILER-209
don't load envelope if we already have receivedDate - bug 7075
CollectorFormatter forward compatiblity with Formatter spec.
MailHandlerTest improve testIsMissingContent.

(From Jason)


Revisions:
----------
795
796
797
798
799
800
801
802


Modified Paths:
---------------
doc/release/CHANGES.txt
mail/src/main/java/com/sun/mail/iap/Response.java
mail/src/test/java/com/sun/mail/iap/ResponseTest.java
android/activation/src/main/java/javax/activation/CommandInfo.java
android/mail/pom.xml
android/pom.xml
mail/src/main/java/com/sun/mail/util/logging/DurationFilter.java
mail/src/test/java/com/sun/mail/util/logging/DurationFilterTest.java
mail/src/main/java/javax/mail/internet/MimePartDataSource.java
mail/src/main/java/com/sun/mail/util/logging/MailHandler.java
pom.xml
mail/src/main/java/com/sun/mail/imap/IMAPMessage.java
mail/src/main/java/com/sun/mail/util/logging/CollectorFormatter.java
mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java


Diffs:
------
diff -r 6e266e30cf4f -r cb70371f1cfc doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Thu Oct 29 13:42:26 2015 -0700
+++ b/doc/release/CHANGES.txt Fri Nov 06 16:03:10 2015 -0800
@@ -39,6 +39,7 @@
 K 7028 InternetAddress doesn't detect some illegal newlines
 K 7030 Status class doesn't decode mailbox name
 K 7035 add support for IMAP COMPRESS extension (RFC 4978)
+K 7052 Empty Gmail X-GM-LABELS list is misparsed
 
 
                   CHANGES IN THE 1.5.4 RELEASE

diff -r 6e266e30cf4f -r cb70371f1cfc mail/src/main/java/com/sun/mail/iap/Response.java
--- a/mail/src/main/java/com/sun/mail/iap/Response.java Thu Oct 29 13:42:26 2015 -0700
+++ b/mail/src/main/java/com/sun/mail/iap/Response.java Fri Nov 06 16:03:10 2015 -0800
@@ -288,15 +288,14 @@
         index++; // skip '('
 
         List<String> result = new ArrayList<String>();
- do {
- result.add(atom ? readAtomString() : readString());
- } while (buffer[index++] != ')');
+ skipSpaces();
+ if (peekByte() != ')') {
+ do {
+ result.add(atom ? readAtomString() : readString());
+ } while (buffer[index++] != ')');
+ }
 
- if (!result.isEmpty()) {
- return result.toArray(new String[result.size()]);
- } else {
- return null;
- }
+ return result.toArray(new String[result.size()]);
     }
 
     /**

diff -r 6e266e30cf4f -r cb70371f1cfc mail/src/test/java/com/sun/mail/iap/ResponseTest.java
--- a/mail/src/test/java/com/sun/mail/iap/ResponseTest.java Thu Oct 29 13:42:26 2015 -0700
+++ b/mail/src/test/java/com/sun/mail/iap/ResponseTest.java Fri Nov 06 16:03:10 2015 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013-2015 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
@@ -41,6 +41,7 @@
 package com.sun.mail.iap;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertArrayEquals;
 import org.junit.Test;
 
 /**
@@ -96,4 +97,23 @@
         Response r = new Response("* " + "atom] ");
         assertEquals("atom]", r.readAtomString());
     }
+
+ /**
+ * Test astring lists.
+ */
+ @Test
+ public void testAStringList() throws Exception {
+ Response r = new Response("* " + "(A B \"C\")");
+ assertArrayEquals(new String[] { "A", "B", "C" },
+ r.readAtomStringList());
+ }
+
+ /**
+ * Test empty astring lists.
+ */
+ @Test
+ public void testAStringListEmpty() throws Exception {
+ Response r = new Response("* " + "()");
+ assertArrayEquals(new String[0], r.readAtomStringList());
+ }
 }


diff -r cb70371f1cfc -r 8e1aee7a6e09 android/activation/src/main/java/javax/activation/CommandInfo.java
--- a/android/activation/src/main/java/javax/activation/CommandInfo.java Fri Nov 06 16:03:10 2015 -0800
+++ b/android/activation/src/main/java/javax/activation/CommandInfo.java Tue Nov 10 15:41:33 2015 -0800
@@ -129,7 +129,30 @@
         Object new_bean = null;
 
         // try to instantiate the bean
- new_bean = java.beans.Beans.instantiate(loader, className);
+ Class<?> beans = null;
+ try {
+ beans = Class.forName("java.beans.Beans", true, loader);
+ } catch (Exception ex) { }
+
+ try {
+ if (beans != null) {
+ // invoke via reflection:
+ // new_bean = java.beans.Beans.instantiate(loader, className);
+ java.lang.reflect.Method m = beans.getMethod("instantiate",
+ ClassLoader.class, String.class);
+ new_bean = m.invoke(null, loader, className);
+ } else {
+ new_bean = Class.forName(className, true, loader).newInstance();
+ }
+ } catch (java.lang.reflect.InvocationTargetException ex) {
+ // ignore it
+ } catch (InstantiationException ex) {
+ // ignore it
+ } catch (NoSuchMethodException ex) {
+ // ignore it
+ } catch (IllegalAccessException ex) {
+ // ignore it
+ }
 
         // if we got one and it is a CommandObject
         if (new_bean != null) {

diff -r cb70371f1cfc -r 8e1aee7a6e09 android/mail/pom.xml
--- a/android/mail/pom.xml Fri Nov 06 16:03:10 2015 -0800
+++ b/android/mail/pom.xml Tue Nov 10 15:41:33 2015 -0800
@@ -81,7 +81,6 @@
             com.sun.mail.util.logging; version=${mail.osgiversion},
             com.sun.mail.handlers; version=${mail.osgiversion}
         </mail.packages.export>
- <javac.path>/opt/jdk1.5/bin/javac</javac.path>
     </properties>
 
     <build>
@@ -156,35 +155,6 @@
                     </archive>
                 </configuration>
             </plugin>
-
- <!--
- We need to build this one file in an environment that
- doesn't include javax.activation.*. The simplest way
- to do that is to use a real 1.5 compiler.
- (JAF was added to the JDK in 1.6.)
- -->
- <plugin>
- <artifactId>maven-compiler-plugin</artifactId>
- <executions>
- <execution>
- <id>default-compile</id>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- <fork>true</fork>
- <executable>${javac.path}</executable>
- <compilerVersion>1.5</compilerVersion>
- </configuration>
- </execution>
- <execution>
- <id>default-testCompile</id>
- <configuration>
- <source>1.5</source>
- <target>1.5</target>
- </configuration>
- </execution>
- </executions>
- </plugin>
         </plugins>
     </build>
 

diff -r cb70371f1cfc -r 8e1aee7a6e09 android/pom.xml
--- a/android/pom.xml Fri Nov 06 16:03:10 2015 -0800
+++ b/android/pom.xml Tue Nov 10 15:41:33 2015 -0800
@@ -61,4 +61,45 @@
         <module>mail</module>
     </modules>
 
+ <properties>
+ <!--
+ The minimum required Android API version.
+ This corresponds to Android Gingerbread.
+ https://en.wikipedia.org/wiki/Android_version_history
+ Older versions may also work but this seems old enough.
+ See the Maven repository for exact versions available:
+ https://repo1.maven.org/maven2/net/sf/androidscents/signature/
+ This only checks API signatures; it doesn't imply that it
+ works correctly in a runtime of that version.
+ -->
+ <android.api.level>9</android.api.level>
+ <android.version>2.3.1_r2</android.version>
+ </properties>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codehaus.mojo</groupId>
+ <artifactId>animal-sniffer-maven-plugin</artifactId>
+ <version>1.14</version>
+ <executions>
+ <execution>
+ <id>check-sig</id>
+ <phase>package</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <signature>
+ <groupId>net.sf.androidscents.signature</groupId>
+ <artifactId>android-api-level-${android.api.level}</artifactId>
+ <version>${android.version}</version>
+ </signature>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+
 </project>


diff -r 8e1aee7a6e09 -r 897e82dbda80 mail/src/main/java/com/sun/mail/util/logging/DurationFilter.java
--- a/mail/src/main/java/com/sun/mail/util/logging/DurationFilter.java Tue Nov 10 15:41:33 2015 -0800
+++ b/mail/src/main/java/com/sun/mail/util/logging/DurationFilter.java Wed Nov 11 14:49:10 2015 -0800
@@ -64,7 +64,7 @@
  * <li>{_at_literal <filter-name>}.duration the number of milliseconds to suppress
  * log records from being published. This is also used as duration to determine
  * the log record rate. A numeric long integer or a multiplication expression
- * can be used as the value. If the {_at_code java.time} package is avaliable then
+ * can be used as the value. If the {_at_code java.time} package is available then
  * an ISO-8601 duration format of {_at_code PnDTnHnMn.nS} can be used as the value.
  * The suffixes of "D", "H", "M" and "S" are for days, hours, minutes and
  * seconds. The suffixes must occur in order. The seconds can be specified with
@@ -109,7 +109,7 @@
     /**
      * The most recent record time seen for the current duration.
      */
- private long peek;
+ private long peak;
     /**
      * The start time for the current duration.
      */
@@ -166,12 +166,12 @@
         final long s;
         synchronized (other) {
             c = other.count;
- p = other.peek;
+ p = other.peak;
             s = other.start;
         }
 
         synchronized (this) {
- if (c != this.count || p != this.peek || s != this.start) {
+ if (c != this.count || p != this.peak || s != this.start) {
                 return false;
             }
         }
@@ -224,7 +224,7 @@
             if (c != records || (millis - s) >= duration) {
                 return true;
             }
- } else {
+ } else { //Subtraction is used to deal with numeric overflow.
             if ((millis - s) >= 0L || c == 0L) {
                 return true;
             }
@@ -257,7 +257,7 @@
     protected DurationFilter clone() throws CloneNotSupportedException {
         final DurationFilter clone = (DurationFilter) super.clone();
         clone.count = 0L; //Reset the filter state.
- clone.peek = 0L;
+ clone.peak = 0L;
         clone.start = 0L;
         return clone;
     }
@@ -269,10 +269,11 @@
      * @return true if accepted false otherwise.
      */
     private synchronized boolean accept(final long millis) {
+ //Subtraction is used to deal with numeric overflow of millis.
         boolean allow;
         if (count > 0L) { //If not saturated.
- if ((millis - peek) > 0L) {
- peek = millis; //Record the new peek.
+ if ((millis - peak) > 0L) {
+ peak = millis; //Record the new peak.
             }
 
             //Under the rate if the count has not been reached.
@@ -280,13 +281,13 @@
                 ++count;
                 allow = true;
             } else {
- if ((peek - start) >= duration) {
+ if ((peak - start) >= duration) {
                     count = 1L; //Start a new duration.
- start = peek;
+ start = peak;
                     allow = true;
                 } else {
                     count = -1L; //Saturate for the duration.
- start = peek + duration;
+ start = peak + duration;
                     allow = false;
                 }
             }
@@ -296,7 +297,7 @@
             if ((millis - start) >= 0L || count == 0L) {
                 count = 1L;
                 start = millis;
- peek = millis;
+ peak = millis;
                 allow = true;
             } else {
                 allow = false; //Remain in a saturated state.
@@ -319,6 +320,7 @@
         final String p = getClass().getName();
         String value = fromLogManager(p.concat(suffix));
         if (value != null && value.length() != 0) {
+ value = value.trim();
             if (isTimeEntry(suffix, value)) {
                 try {
                     result = LogManagerProperties.parseDurationToMillis(value);
@@ -370,8 +372,7 @@
      * @throws NullPointerException if the given value is null.
      * @throws NumberFormatException if the expression is invalid.
      */
- private static String[] tokenizeLongs(String value) {
- value = value.trim();
+ private static String[] tokenizeLongs(final String value) {
         String[] e;
         final int i = value.indexOf('*');
         if (i > -1 && (e = value.split("\\s*\\*\\s*")).length != 0) {

diff -r 8e1aee7a6e09 -r 897e82dbda80 mail/src/test/java/com/sun/mail/util/logging/DurationFilterTest.java
--- a/mail/src/test/java/com/sun/mail/util/logging/DurationFilterTest.java Tue Nov 10 15:41:33 2015 -0800
+++ b/mail/src/test/java/com/sun/mail/util/logging/DurationFilterTest.java Wed Nov 11 14:49:10 2015 -0800
@@ -260,7 +260,7 @@
 
         //Still saturated.
         millis += duration;
- final long peek = millis;
+ final long peak = millis;
         for (int i = 0; i < records; i++) {
             r = new LogRecord(lvl, Long.toString(millis));
             r.setMillis(millis);
@@ -268,7 +268,7 @@
         }
 
         //Cool down and allow.
- millis = peek + duration;
+ millis = peak + duration;
         for (int i = 0; i < records; i++) {
             r = new LogRecord(lvl, Long.toString(millis));
             r.setMillis(millis);
@@ -702,7 +702,7 @@
             Class.forName("java.time.Duration");
             return true;
         } catch (final ClassNotFoundException notSupported) {
- } catch (final NoClassDefFoundError notSupported) {
+ } catch (final LinkageError notSupported) {
         }
         return false;
     }


diff -r 897e82dbda80 -r 3dd941235ec2 mail/src/main/java/javax/mail/internet/MimePartDataSource.java
--- a/mail/src/main/java/javax/mail/internet/MimePartDataSource.java Wed Nov 11 14:49:10 2015 -0800
+++ b/mail/src/main/java/javax/mail/internet/MimePartDataSource.java Thu Nov 12 13:58:01 2015 -0800
@@ -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-2015 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
@@ -112,7 +112,9 @@
             throw new FolderClosedIOException(fex.getFolder(),
                                                 fex.getMessage());
         } catch (MessagingException mex) {
- throw new IOException(mex.getMessage());
+ IOException ioex = new IOException(mex.getMessage());
+ ioex.initCause(mex);
+ throw ioex;
         }
     }
 


diff -r 3dd941235ec2 -r 5bc1ffc60735 mail/src/main/java/com/sun/mail/util/logging/MailHandler.java
--- a/mail/src/main/java/com/sun/mail/util/logging/MailHandler.java Thu Nov 12 13:58:01 2015 -0800
+++ b/mail/src/main/java/com/sun/mail/util/logging/MailHandler.java Wed Nov 18 15:25:47 2015 -0800
@@ -1580,21 +1580,19 @@
         return null; //text/plain
     }
 
- /**
- * Determines if the given throwable is a no content exception.
- * Package-private for unit testing.
+ /**
+ * Determines if the given throwable is a no content exception. It is
+ * assumed Transport.sendMessage will call Message.writeTo so we need to
+ * ignore any exceptions that could be layered on top of that call chain to
+ * infer that sendMessage is failing because of writeTo. Package-private
+ * for unit testing.
      * @param msg the message without content.
- * @param t the throwable to test.
+ * @param t the throwable chain to test.
      * @return true if the throwable is a missing content exception.
      * @throws NullPointerException if any of the arguments are null.
      * @since JavaMail 1.4.5
      */
     final boolean isMissingContent(Message msg, Throwable t) {
- for (Throwable cause = t.getCause(); cause != null;) {
- t = cause;
- cause = cause.getCause();
- }
-
         final Object ccl = getAndSetContextClassLoader(MAILHANDLER_LOADER);
         try {
             msg.writeTo(new ByteArrayOutputStream(MIN_HEADER_SIZE));
@@ -1602,8 +1600,13 @@
             throw RE; //Avoid catch all.
         } catch (final Exception noContent) {
             final String txt = noContent.getMessage();
- if (!isEmpty(txt) && noContent.getClass() == t.getClass()) {
- return txt.equals(t.getMessage());
+ if (!isEmpty(txt)) {
+ for (; t != null; t = t.getCause()) {
+ if (noContent.getClass() == t.getClass()
+ && txt.equals(t.getMessage())) {
+ return true;
+ }
+ }
             }
         } finally {
             getAndSetContextClassLoader(ccl);


diff -r 5bc1ffc60735 -r 80ebfce8a147 pom.xml
--- a/pom.xml Wed Nov 18 15:25:47 2015 -0800
+++ b/pom.xml Wed Nov 18 15:34:54 2015 -0800
@@ -424,6 +424,12 @@
                         <configuration>
                             <source>1.5</source>
                             <target>1.5</target>
+ <!--
+ XXX - workaround for bug in maven compiler
+ plugin versions 3.0 - 3.3 (at least):
+ https://issues.apache.org/jira/browse/MCOMPILER-209
+ -->
+ <useIncrementalCompilation>false</useIncrementalCompilation>
                         </configuration>
                     </execution>
                     <execution>


diff -r 80ebfce8a147 -r 44bfb0bbc6e7 doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Wed Nov 18 15:34:54 2015 -0800
+++ b/doc/release/CHANGES.txt Fri Nov 20 15:54:52 2015 -0800
@@ -40,6 +40,8 @@
 K 7030 Status class doesn't decode mailbox name
 K 7035 add support for IMAP COMPRESS extension (RFC 4978)
 K 7052 Empty Gmail X-GM-LABELS list is misparsed
+K 7075 IMAPMessage.getReceivedDate should check if receivedDate is present
+ before loading envelope
 
 
                   CHANGES IN THE 1.5.4 RELEASE

diff -r 80ebfce8a147 -r 44bfb0bbc6e7 mail/src/main/java/com/sun/mail/imap/IMAPMessage.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPMessage.java Wed Nov 18 15:34:54 2015 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPMessage.java Fri Nov 20 15:54:52 2015 -0800
@@ -466,12 +466,12 @@
     }
 
     /**
- * Get the recieved date (INTERNALDATE)
+ * Get the received date (INTERNALDATE).
      */
     public Date getReceivedDate() throws MessagingException {
         checkExpunged();
- // XXX - have to go to the server for this
- loadEnvelope();
+ if (receivedDate == null)
+ loadEnvelope(); // have to go to the server for this
         if (receivedDate == null)
             return null;
         else


diff -r 44bfb0bbc6e7 -r 462b6507d18a mail/src/main/java/com/sun/mail/util/logging/CollectorFormatter.java
--- a/mail/src/main/java/com/sun/mail/util/logging/CollectorFormatter.java Fri Nov 20 15:54:52 2015 -0800
+++ b/mail/src/main/java/com/sun/mail/util/logging/CollectorFormatter.java Fri Nov 20 15:58:27 2015 -0800
@@ -324,6 +324,7 @@
      */
     @Override
     public String getTail(final Handler h) {
+ super.getTail(h); //Be forward compatible with super.getHead.
         return formatRecord(h, true);
     }
 
@@ -468,7 +469,7 @@
          * These arguments are described in the getTail documentation.
          */
         return mf.format(new Object[]{finish(head), finish(msg), finish(tail),
- c, (c - 1), t, (c - t), msl, msh, (msh - msl), INIT_TIME, now,
+ c, (c - 1L), t, (c - t), msl, msh, (msh - msl), INIT_TIME, now,
             (now - INIT_TIME), g});
     }
 

diff -r 44bfb0bbc6e7 -r 462b6507d18a mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java
--- a/mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java Fri Nov 20 15:54:52 2015 -0800
+++ b/mail/src/test/java/com/sun/mail/util/logging/MailHandlerTest.java Fri Nov 20 15:58:27 2015 -0800
@@ -5167,6 +5167,10 @@
             assertNotNull(expect.getMessage());
             assertTrue(expect.getMessage().length() != 0);
             assertTrue(target.isMissingContent(msg, expect));
+ assertTrue(target.isMissingContent(msg, new Exception(expect)));
+ assertTrue(target.isMissingContent(msg, new MessagingException("", expect)));
+ assertFalse(target.isMissingContent(msg, new Exception()));
+ assertFalse(target.isMissingContent(msg, new RuntimeException()));
         }
     }