commits@javamail.java.net

[javamail~mercurial:224] New self-contained NTLM support, from the JDK (with permission).

From: <shannon_at_kenai.com>
Date: Sat, 19 Dec 2009 01:06:06 +0000

Project: javamail
Repository: mercurial
Revision: 224
Author: shannon
Date: 2009-12-19 00:44:07 UTC
Link:

Log Message:
------------
Support compiling tests with JDK 5, to allow tests to use JUnit 4.
Requires Maven 2.2.1, so use the maven-enforcer-plugin to verify that.
Add support for test suites that depend on System properties by loading them
in a separate ClassLoader.
Add ParameterList tests to test use of System properties.
Fix support for Properties objects with default Properties objects.
IMAP provider can lose track of message sequence numbers - bug 6910675
Convert more tests to JUnit 4.
Fix accidental dependency on JDK 1.5 API.
Add a "1.4" profile for compiling with the real JDK 1.4 compiler,
to make sure there are no accidental JDK 1.5 API depedencies.
Set project.build.sourceEncoding to iso-8859-1.
Fix maven-enforcer-plugin configuration to actually work.
Add IMAPStore.preLogin method for subclasses to override.
New self-contained NTLM support, from the JDK (with permission).


Revisions:
----------
213
214
215
216
217
218
219
220
221
222
223
224


Modified Paths:
---------------
pom.xml
mail/pom.xml
doc/release/CHANGES.txt
mail/src/main/java/com/sun/mail/util/PropUtil.java
mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
mail/src/main/java/com/sun/mail/imap/MessageCache.java
mail/src/test/java/com/sun/mail/imap/protocol/StratoImapBugfixTest.java
mail/src/test/java/com/sun/mail/pop3/POP3StoreTest.java
mail/src/main/java/com/sun/mail/pop3/POP3Store.java
mail/src/main/java/com/sun/mail/imap/IMAPStore.java
doc/release/NTLMNOTES.txt
mail/src/main/java/com/sun/mail/auth/Ntlm.java
mail/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java
mail/src/main/java/com/sun/mail/smtp/SMTPTransport.java


Added Paths:
------------
mail/src/test/java/com/sun/mail/test/ClassLoaderSuite.java
mail/src/test/java/javax/mail/internet/AppleFileNames.java
mail/src/test/java/javax/mail/internet/ParameterListTestSuite.java
mail/src/test/java/javax/mail/internet/ParameterListTests.java
mail/src/test/java/javax/mail/internet/WindowsFileNames.java
mail/src/test/java/com/sun/mail/util/PropUtilTest.java
mail/src/test/java/com/sun/mail/imap/MessageCacheTest.java
mail/src/main/java/com/sun/mail/auth/MD4.java


Diffs:
------
diff -r cba35f5daec5 -r 6aa43e64d86c pom.xml
--- a/pom.xml Sat Dec 12 01:31:12 2009 -0800
+++ b/pom.xml Tue Dec 15 10:16:09 2009 -0800
@@ -167,6 +167,24 @@
         <defaultGoal>install</defaultGoal>
         <plugins>
             <!--
+ Make sure we're using the correct version of maven,
+ required to allow us to build JavaMail with JDK 1.4
+ and build the tests with JDK 1.5. See the
+ maven-compiler-plugin configuration below.
+ -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-enforcer-plugin</artifactId>
+ <configuration>
+ <rules>
+ <requireMavenVersion>
+ <version>2.2.1</version>
+ </requireMavenVersion>
+ </rules>
+ </configuration>
+ </plugin>
+
+ <!--
                 This plugin is reponsible for packaging artifacts
                 as OSGi bundles. Please refer to
                 http://felix.apache.org/site/maven-bundle-plugin-bnd.html
@@ -232,12 +250,28 @@
                 </executions>
             </plugin>
 
+ <!--
+ Use the 1.4 compiler for JavaMail itself, but use the
+ 1.5 compiler for the test classes, so we can use JUnit 4.
+ -->
             <plugin>
                 <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.4</source>
- <target>1.4</target>
- </configuration>
+ <executions>
+ <execution>
+ <id>default-compile</id>
+ <configuration>
+ <source>1.4</source>
+ <target>1.4</target>
+ </configuration>
+ </execution>
+ <execution>
+ <id>default-testCompile</id>
+ <configuration>
+ <source>1.5</source>
+ <target>1.5</target>
+ </configuration>
+ </execution>
+ </executions>
             </plugin>
 
             <plugin>
@@ -405,13 +439,6 @@
             <artifactId>activation</artifactId>
             <version>${activation-api.version}</version>
         </dependency>
- <!-- following works around a bug that causes NullPointerException -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.3.1</version>
- <scope>test</scope>
- </dependency>
     </dependencies>
 
     <repositories>


diff -r 6aa43e64d86c -r 89e9f95069d9 mail/pom.xml
--- a/mail/pom.xml Tue Dec 15 10:16:09 2009 -0800
+++ b/mail/pom.xml Tue Dec 15 10:17:17 2009 -0800
@@ -98,6 +98,20 @@
                     <findbugsXmlWithMessages>true</findbugsXmlWithMessages>
                 </configuration>
             </plugin>
+
+ <!--
+ Configure test plugin to find *TestSuite classes.
+ -->
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <configuration>
+ <includes>
+ <include>**/*Test.java</include>
+ <include>**/*TestSuite.java</include>
+ </includes>
+ </configuration>
+ </plugin>
         </plugins>
     </build>
 
@@ -105,7 +119,7 @@
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
- <version>4.3.1</version>
+ <version>4.7</version>
             <scope>test</scope>
             <optional>true</optional>
         </dependency>

diff -r 6aa43e64d86c -r 89e9f95069d9 mail/src/test/java/com/sun/mail/test/ClassLoaderSuite.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/com/sun/mail/test/ClassLoaderSuite.java Tue Dec 15 10:17:17 2009 -0800
@@ -0,0 +1,199 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. 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.html
+ * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [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.test;
+
+import java.lang.annotation.*;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.net.URLClassLoader;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.junit.runners.Suite;
+import org.junit.runners.model.InitializationError;
+import org.junit.runners.model.RunnerBuilder;
+
+/**
+ * A special test suite that loads each of the test classes
+ * in a separate class loader, along with the class under test.
+ * This allows the tests to test methods whose behavior depends on
+ * the value of a System property that's read at class initialization
+ * time; each test can set a different value of the System property
+ * and the corresponding class under test will be loaded in a
+ * separate class loader. <p>
+ *
+ * To use this class, create a test suite class:
+ *
+ * <pre>
+ * @RunWith(ClassLoaderSuite.class)
+ * @SuiteClasses({ MyTest1.class, MyTest2.class })
+ * @TestClass(ClassToTest.class)
+ * public class MyTestSuite {
+ * }
+ * </pre>
+ *
+ * The MyTest1 and MyTest2 classes are written as normal JUnit
+ * test classes. Set the System property to test in the @BeforeClass
+ * method of these classes.
+ *
+ * @author Bill Shannon
+ */
+
+public class ClassLoaderSuite extends Suite {
+ /**
+ * An annotation to be used on the test suite class to indicate
+ * the class under test. The class is used to find the classpath
+ * to allow loading the class under test in a separate class loader.
+ * Note that other classes in the same classpath will also be loaded
+ * in the separate class loader, along with the test classes.
+ */
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.TYPE)
+ @Inherited
+ public @interface TestClass {
+ public Class<?> value();
+ }
+
+ /**
+ * A special class loader that loads classes from its own class path
+ * (specified via URLs) before delegating to the parent class loader.
+ * This is used to load the test classes in separate class loaders,
+ * even though those classes are also loaded in the parent class loader.
+ */
+ static class TestClassLoader extends URLClassLoader {
+ public TestClassLoader(URL[] urls, ClassLoader parent) {
+ super(urls, parent);
+ }
+
+ public Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ Class<?> c = null;
+ try {
+ c = findClass(name);
+ if (resolve)
+ resolveClass(c);
+ } catch (ClassNotFoundException cex) {
+ c = super.loadClass(name, resolve);
+ }
+ return c;
+ }
+ }
+
+ /**
+ * Constructor.
+ */
+ public ClassLoaderSuite(Class<?> klass, RunnerBuilder builder)
+ throws InitializationError {
+ super(builder, klass,
+ reloadClasses(getTestClass(klass), getSuiteClasses(klass)));
+ }
+
+ /**
+ * Get the value of the SuiteClasses annotation.
+ */
+ private static Class<?>[] getSuiteClasses(Class<?> klass)
+ throws InitializationError {
+ SuiteClasses annotation = klass.getAnnotation(SuiteClasses.class);
+ if (annotation == null)
+ throw new InitializationError("class '" + klass.getName() +
+ "' must have a SuiteClasses annotation");
+ return annotation.value();
+ }
+
+ /**
+ * Get the value of the TestClass annotation.
+ */
+ private static Class<?> getTestClass(Class<?> klass)
+ throws InitializationError {
+ TestClass annotation = klass.getAnnotation(TestClass.class);
+ if (annotation == null)
+ throw new InitializationError("class '" + klass.getName() +
+ "' must have a TestClass annotation");
+ return annotation.value();
+ }
+
+ /**
+ * Reload the classes in a separate class loader.
+ */
+ private static Class<?>[] reloadClasses(Class<?> testClass,
+ Class<?>[] suiteClasses) throws InitializationError {
+ URL[] urls = new URL[] {
+ classpathOf(testClass),
+ classpathOf(ClassLoaderSuite.class)
+ };
+ Class<?> sc = null;
+ try {
+ for (int i = 0; i < suiteClasses.length; i++) {
+ sc = suiteClasses[i];
+ ClassLoader cl = new TestClassLoader(urls,
+ ClassLoaderSuite.class.getClassLoader());
+ suiteClasses[i] = cl.loadClass(sc.getName());
+ }
+ return suiteClasses;
+ } catch (ClassNotFoundException cex) {
+ throw new InitializationError("could not reload class: " + sc);
+ }
+ }
+
+ /**
+ * Return the classpath entry used to load the named resource.
+ * XXX - Only handles file: and jar: URLs.
+ */
+ private static URL classpathOf(Class<?> c) {
+ String name = "/" + c.getName().replace('.', '/') + ".class";
+ try {
+ URL url = ClassLoaderSuite.class.getResource(name);
+ if (url.getProtocol().equals("file")) {
+ String file = url.getPath();
+ if (file.endsWith(name)) // has to be true?
+ file = file.substring(0, file.length() - name.length() + 1);
+//System.out.println("file URL " + url + " has CLASSPATH " + file);
+ return new URL("file", null, file);
+ } else if (url.getProtocol().equals("jar")) {
+ String file = url.getPath();
+ int i = file.lastIndexOf('!');
+ if (i >= 0)
+ file = file.substring(0, i);
+//System.out.println("jar URL " + url + " has CLASSPATH " + file);
+ return new URL(file);
+ } else
+ return url;
+ } catch (MalformedURLException mex) {
+ return null;
+ }
+ }
+}


diff -r 89e9f95069d9 -r c2d5ee7081c2 mail/src/test/java/javax/mail/internet/AppleFileNames.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/javax/mail/internet/AppleFileNames.java Tue Dec 15 10:17:34 2009 -0800
@@ -0,0 +1,65 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. 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.html
+ * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [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 javax.mail.internet;
+
+import org.junit.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test that the "mail.mime.applefilenames" System property
+ * causes the filename to be returned properly.
+ */
+public class AppleFileNames {
+
+ @BeforeClass
+ public static void before() {
+ System.out.println("AppleFileNames");
+ System.setProperty("mail.mime.applefilenames", "true");
+ }
+
+ @Test
+ public void testProp() throws Exception {
+ ParameterList pl = new ParameterList("; filename=a b.txt");
+ assertEquals(pl.get("filename"), "a b.txt");
+ }
+
+ @AfterClass
+ public static void after() {
+ // should be unnecessary
+ System.clearProperty("mail.mime.applefilenames");
+ }
+}

diff -r 89e9f95069d9 -r c2d5ee7081c2 mail/src/test/java/javax/mail/internet/ParameterListTestSuite.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/javax/mail/internet/ParameterListTestSuite.java Tue Dec 15 10:17:34 2009 -0800
@@ -0,0 +1,56 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. 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.html
+ * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [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 javax.mail.internet;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite.SuiteClasses;
+
+import com.sun.mail.test.ClassLoaderSuite;
+import com.sun.mail.test.ClassLoaderSuite.TestClass;
+
+/**
+ * Suite of ParameterList tests that need to be run in a separate class loader.
+ */
+_at_RunWith(ClassLoaderSuite.class)
+_at_TestClass(ParameterList.class)
+_at_SuiteClasses( {
+ ParameterListTests.class,
+ WindowsFileNames.class,
+ AppleFileNames.class
+})
+public class ParameterListTestSuite {
+}

diff -r 89e9f95069d9 -r c2d5ee7081c2 mail/src/test/java/javax/mail/internet/ParameterListTests.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/javax/mail/internet/ParameterListTests.java Tue Dec 15 10:17:34 2009 -0800
@@ -0,0 +1,63 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. 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.html
+ * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [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 javax.mail.internet;
+
+import org.junit.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * XXX - add more tests
+ */
+public class ParameterListTests {
+
+ @BeforeClass
+ public static void before() {
+ System.out.println("ParameterListTests");
+ System.clearProperty("mail.mime.windowsfilenames");
+ System.clearProperty("mail.mime.applefilenames");
+ }
+
+ /**
+ * Test that backslashes are properly removed.
+ */
+ @Test
+ public void testBackslash() throws Exception {
+ System.clearProperty("mail.mime.windowsfilenames");
+ ParameterList pl = new ParameterList("; filename=\"\\a\\b\\c.txt\"");
+ assertEquals(pl.get("filename"), "abc.txt");
+ }
+}

diff -r 89e9f95069d9 -r c2d5ee7081c2 mail/src/test/java/javax/mail/internet/WindowsFileNames.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/javax/mail/internet/WindowsFileNames.java Tue Dec 15 10:17:34 2009 -0800
@@ -0,0 +1,65 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. 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.html
+ * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [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 javax.mail.internet;
+
+import org.junit.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Test that the "mail.mime.windowsfilenames" System property
+ * causes the filename to be returned with backslashes preserved.
+ */
+public class WindowsFileNames {
+
+ @BeforeClass
+ public static void before() {
+ System.out.println("WindowsFileNames");
+ System.setProperty("mail.mime.windowsfilenames", "true");
+ }
+
+ @Test
+ public void testProp() throws Exception {
+ ParameterList pl = new ParameterList("; filename=\"\\a\\b\\c.txt\"");
+ assertEquals(pl.get("filename"), "\\a\\b\\c.txt");
+ }
+
+ @AfterClass
+ public static void after() {
+ // should be unnecessary
+ System.clearProperty("mail.mime.windowsfilenames");
+ }
+}


diff -r c2d5ee7081c2 -r 218515781a5f doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Tue Dec 15 10:17:34 2009 -0800
+++ b/doc/release/CHANGES.txt Tue Dec 15 10:17:47 2009 -0800
@@ -23,6 +23,7 @@
 <no id> add mail.mime.windowsfilenames System property to handle IE6 breakage
 <no id> properly disable TOP if POP3 CAPA response doesn't include it
 <no id> add mail.pop3.disablecapa property to disable use of the CAPA command
+<no id> fix support for Properties objects with default Properties objects
 
 
                   CHANGES IN THE 1.4.3 RELEASE

diff -r c2d5ee7081c2 -r 218515781a5f mail/src/main/java/com/sun/mail/util/PropUtil.java
--- a/mail/src/main/java/com/sun/mail/util/PropUtil.java Tue Dec 15 10:17:34 2009 -0800
+++ b/mail/src/main/java/com/sun/mail/util/PropUtil.java Tue Dec 15 10:17:47 2009 -0800
@@ -1,7 +1,7 @@
 /*
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  *
- * Copyright 1997-2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 1997-2009 Sun Microsystems, Inc. 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
@@ -55,7 +55,7 @@
      * Get an integer valued property.
      */
     public static int getIntProperty(Properties props, String name, int def) {
- return getInt(props.get(name), def);
+ return getInt(getProp(props, name), def);
     }
 
     /**
@@ -63,7 +63,7 @@
      */
     public static boolean getBooleanProperty(Properties props,
                                 String name, boolean def) {
- return getBoolean(props.get(name), def);
+ return getBoolean(getProp(props, name), def);
     }
 
     /**
@@ -71,7 +71,7 @@
      */
     public static int getIntSessionProperty(Session session,
                                 String name, int def) {
- return getInt(session.getProperties().get(name), def);
+ return getInt(getProp(session.getProperties(), name), def);
     }
 
     /**
@@ -79,7 +79,7 @@
      */
     public static boolean getBooleanSessionProperty(Session session,
                                 String name, boolean def) {
- return getBoolean(session.getProperties().get(name), def);
+ return getBoolean(getProp(session.getProperties(), name), def);
     }
 
     /**
@@ -87,7 +87,7 @@
      */
     public static boolean getBooleanSystemProperty(String name, boolean def) {
         try {
- return getBoolean(System.getProperties().get(name), def);
+ return getBoolean(getProp(System.getProperties(), name), def);
         } catch (SecurityException sex) {
             // fall through...
         }
@@ -110,6 +110,19 @@
     }
 
     /**
+ * Get the value of the specified property.
+ * If the "get" method returns null, use the getProperty method,
+ * which might cascade to a default Properties object.
+ */
+ private static Object getProp(Properties props, String name) {
+ Object val = props.get(name);
+ if (val != null)
+ return val;
+ else
+ return props.getProperty(name);
+ }
+
+ /**
      * Interpret the value object as an integer,
      * returning def if unable.
      */

diff -r c2d5ee7081c2 -r 218515781a5f mail/src/test/java/com/sun/mail/util/PropUtilTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/com/sun/mail/util/PropUtilTest.java Tue Dec 15 10:17:47 2009 -0800
@@ -0,0 +1,201 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. 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.html
+ * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [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.util;
+
+import java.util.Properties;
+import javax.mail.Session;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.Test;
+
+/**
+ * Test that the PropUtil methods return the correct values,
+ * especially when defaults and non-String values are considered.
+ */
+public class PropUtilTest {
+ @Test
+ public void testInt() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("test", "2");
+ Session sess = Session.getInstance(props, null);
+ assertEquals(PropUtil.getIntSessionProperty(sess, "test", 1), 2);
+ }
+
+ @Test
+ public void testIntDef() throws Exception {
+ Properties props = new Properties();
+ Session sess = Session.getInstance(props, null);
+ assertEquals(PropUtil.getIntSessionProperty(sess, "test", 1), 1);
+ }
+
+ @Test
+ public void testIntDefProp() throws Exception {
+ Properties defprops = new Properties();
+ defprops.setProperty("test", "2");
+ Properties props = new Properties(defprops);
+ Session sess = Session.getInstance(props, null);
+ assertEquals(PropUtil.getIntSessionProperty(sess, "test", 1), 2);
+ }
+
+ @Test
+ public void testInteger() throws Exception {
+ Properties props = new Properties();
+ props.put("test", 2);
+ Session sess = Session.getInstance(props, null);
+ assertEquals(PropUtil.getIntSessionProperty(sess, "test", 1), 2);
+ }
+
+ @Test
+ public void testBool() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("test", "true");
+ Session sess = Session.getInstance(props, null);
+ assertTrue(PropUtil.getBooleanSessionProperty(sess, "test", false));
+ }
+
+ @Test
+ public void testBoolDef() throws Exception {
+ Properties props = new Properties();
+ Session sess = Session.getInstance(props, null);
+ assertTrue(PropUtil.getBooleanSessionProperty(sess, "test", true));
+ }
+
+ @Test
+ public void testBoolDefProp() throws Exception {
+ Properties defprops = new Properties();
+ defprops.setProperty("test", "true");
+ Properties props = new Properties(defprops);
+ Session sess = Session.getInstance(props, null);
+ assertTrue(PropUtil.getBooleanSessionProperty(sess, "test", false));
+ }
+
+ @Test
+ public void testBoolean() throws Exception {
+ Properties props = new Properties();
+ props.put("test", true);
+ Session sess = Session.getInstance(props, null);
+ assertTrue(PropUtil.getBooleanSessionProperty(sess, "test", false));
+ }
+
+
+ // the Session variants...
+
+ @Test
+ public void testSessionInt() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("test", "2");
+ Session sess = Session.getInstance(props, null);
+ assertEquals(PropUtil.getIntSessionProperty(sess, "test", 1), 2);
+ }
+
+ @Test
+ public void testSessionIntDef() throws Exception {
+ Properties props = new Properties();
+ Session sess = Session.getInstance(props, null);
+ assertEquals(PropUtil.getIntSessionProperty(sess, "test", 1), 1);
+ }
+
+ @Test
+ public void testSessionIntDefProp() throws Exception {
+ Properties defprops = new Properties();
+ defprops.setProperty("test", "2");
+ Properties props = new Properties(defprops);
+ Session sess = Session.getInstance(props, null);
+ assertEquals(PropUtil.getIntSessionProperty(sess, "test", 1), 2);
+ }
+
+ @Test
+ public void testSessionInteger() throws Exception {
+ Properties props = new Properties();
+ props.put("test", 2);
+ Session sess = Session.getInstance(props, null);
+ assertEquals(PropUtil.getIntSessionProperty(sess, "test", 1), 2);
+ }
+
+ @Test
+ public void testSessionBool() throws Exception {
+ Properties props = new Properties();
+ props.setProperty("test", "true");
+ Session sess = Session.getInstance(props, null);
+ assertTrue(PropUtil.getBooleanSessionProperty(sess, "test", false));
+ }
+
+ @Test
+ public void testSessionBoolDef() throws Exception {
+ Properties props = new Properties();
+ Session sess = Session.getInstance(props, null);
+ assertTrue(PropUtil.getBooleanSessionProperty(sess, "test", true));
+ }
+
+ @Test
+ public void testSessionBoolDefProp() throws Exception {
+ Properties defprops = new Properties();
+ defprops.setProperty("test", "true");
+ Properties props = new Properties(defprops);
+ Session sess = Session.getInstance(props, null);
+ assertTrue(PropUtil.getBooleanSessionProperty(sess, "test", false));
+ }
+
+ @Test
+ public void testSessionBoolean() throws Exception {
+ Properties props = new Properties();
+ props.put("test", true);
+ Session sess = Session.getInstance(props, null);
+ assertTrue(PropUtil.getBooleanSessionProperty(sess, "test", false));
+ }
+
+
+ // the System variants...
+
+ @Test
+ public void testSystemBool() throws Exception {
+ System.setProperty("test", "true");
+ assertTrue(PropUtil.getBooleanSystemProperty("test", false));
+ }
+
+ @Test
+ public void testSystemBoolDef() throws Exception {
+ assertTrue(PropUtil.getBooleanSystemProperty("testnotset", true));
+ }
+
+ @Test
+ public void testSystemBoolean() throws Exception {
+ System.getProperties().put("testboolean", true);
+ assertTrue(PropUtil.getBooleanSystemProperty("testboolean", false));
+ }
+}


diff -r 218515781a5f -r 0bee233d00ea doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Tue Dec 15 10:17:47 2009 -0800
+++ b/doc/release/CHANGES.txt Tue Dec 15 10:20:20 2009 -0800
@@ -19,6 +19,7 @@
 The following bugs have been fixed in the 1.4.4 release.
 
 6905730 MimeMessage.parse() is very slow on malformed message content
+6910675 IMAP provider can lose track of message sequence numbers
 G 11069 update the mail.jar manifest to include DynamicImport-Package
 <no id> add mail.mime.windowsfilenames System property to handle IE6 breakage
 <no id> properly disable TOP if POP3 CAPA response doesn't include it

diff -r 218515781a5f -r 0bee233d00ea mail/src/main/java/com/sun/mail/imap/IMAPFolder.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Tue Dec 15 10:17:47 2009 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPFolder.java Tue Dec 15 10:20:20 2009 -0800
@@ -2367,7 +2367,7 @@
             Message[] msgs = new Message[count];
 
             // Add 'count' new IMAPMessage objects into the messageCache
- messageCache.addMessages(count);
+ messageCache.addMessages(count, realTotal + 1);
             int oldtotal = total; // used in loop below
             realTotal += count;
             total += count;

diff -r 218515781a5f -r 0bee233d00ea mail/src/main/java/com/sun/mail/imap/MessageCache.java
--- a/mail/src/main/java/com/sun/mail/imap/MessageCache.java Tue Dec 15 10:17:47 2009 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/MessageCache.java Tue Dec 15 10:20:20 2009 -0800
@@ -93,11 +93,13 @@
      */
     MessageCache(IMAPFolder folder, IMAPStore store, int size) {
         this.folder = folder;
- this.debug = store.getMessageCacheDebug();
- this.out = store.getSession().getDebugOut();
+ if (store != null) { // allow null store, for testing
+ this.debug = store.getMessageCacheDebug();
+ this.out = store.getSession().getDebugOut();
+ }
         if (debug)
             out.println("DEBUG IMAP MC: create cache of size " + size);
- ensureCapacity(size);
+ ensureCapacity(size, 1);
     }
 
     /**
@@ -350,19 +352,20 @@
 
     /**
      * Add count messages to the cache.
+ * newSeqNum is the sequence number of the first message added.
      */
- public void addMessages(int count) {
+ public void addMessages(int count, int newSeqNum) {
         if (debug)
             out.println("DEBUG IMAP MC: add " + count + " messages");
         // don't have to do anything other than making sure there's space
- ensureCapacity(size + count);
+ ensureCapacity(size + count, newSeqNum);
     }
 
     /*
      * Make sure the arrays are at least big enough to hold
      * "newsize" messages.
      */
- private void ensureCapacity(int newsize) {
+ private void ensureCapacity(int newsize, int newSeqNum) {
         if (messages == null)
             messages = new IMAPMessage[newsize + SLOP];
         else if (messages.length < newsize) {
@@ -374,7 +377,12 @@
             if (seqnums != null) {
                 int[] news = new int[newsize + SLOP];
                 System.arraycopy(seqnums, 0, news, 0, seqnums.length);
+ for (int i = seqnums.length; i < news.length; i++)
+ news[i] = newSeqNum++;
                 seqnums = news;
+ if (debug)
+ out.println("DEBUG IMAP MC: message " + newsize +
+ " has sequence number " + seqnums[newsize-1]);
             }
         } else if (newsize < size) { // shrinking?
             // this should never happen
@@ -395,8 +403,12 @@
     public int seqnumOf(int msgnum) {
         if (seqnums == null)
             return msgnum;
- else
+ else {
+ if (debug)
+ out.println("DEBUG IMAP MC: msgnum " + msgnum + " is seqnum " +
+ seqnums[msgnum-1]);
             return seqnums[msgnum-1];
+ }
     }
 
     /**

diff -r 218515781a5f -r 0bee233d00ea mail/src/test/java/com/sun/mail/imap/MessageCacheTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/test/java/com/sun/mail/imap/MessageCacheTest.java Tue Dec 15 10:20:20 2009 -0800
@@ -0,0 +1,68 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. 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.html
+ * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [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.imap;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+/**
+ * Test the IMAP MessageCache.
+ */
+public class MessageCacheTest {
+ /**
+ * Test that when a message is expunged and a new message is added,
+ * the new message has the expected sequence number.
+ */
+ @Test
+ public void testExpungeAdd() throws Exception {
+ // test a range of values to find boundary condition errors
+ for (int n = 1; n <= 100; n++) {
+ //System.out.println("MessageCache.testExpungeAdd: test " + n);
+ // start with one message
+ MessageCache mc = new MessageCache(null, null, 1);
+ // add the remaining messages (eat into SLOP)
+ mc.addMessages(n - 1, 2);
+ // now expunge a message to cause the seqnums array to be created
+ mc.expungeMessage(1);
+ // and add one more message
+ mc.addMessages(1, n);
+ //System.out.println(" new seqnum " + mc.seqnumOf(n + 1));
+ // does the new message have the expected sequence number?
+ assertEquals(mc.seqnumOf(n + 1), n);
+ }
+ }
+}


diff -r 0bee233d00ea -r e01d91e74a87 mail/src/test/java/com/sun/mail/imap/protocol/StratoImapBugfixTest.java
--- a/mail/src/test/java/com/sun/mail/imap/protocol/StratoImapBugfixTest.java Tue Dec 15 10:20:20 2009 -0800
+++ b/mail/src/test/java/com/sun/mail/imap/protocol/StratoImapBugfixTest.java Tue Dec 15 10:25:38 2009 -0800
@@ -39,17 +39,15 @@
 import com.sun.mail.iap.ParsingException;
 import com.sun.mail.iap.Response;
 import com.sun.mail.imap.protocol.Status;
-// XXX - need to work with JDK 1.4
-//import static org.junit.Assert.assertEquals;
-//import static org.junit.Assert.fail;
-import junit.framework.TestCase;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 import org.junit.Test;
 
 /**
  * @author tkrammer
  */
-public class StratoImapBugfixTest extends TestCase {
- //_at_Test
+public class StratoImapBugfixTest {
+ @Test
     public void testValidStatusResponseLeadingSpaces() throws Exception {
         final Response response =
                 new Response("STATUS \" Sent Items \" (UIDNEXT 1)");
@@ -59,7 +57,7 @@
         assertEquals(1, status.uidnext);
     }
 
- //_at_Test
+ @Test
     public void testValidStatusResponse() throws Exception {
         final Response response =
                 new Response("STATUS \"Sent Items\" (UIDNEXT 1)");
@@ -69,7 +67,7 @@
         assertEquals(1, status.uidnext);
     }
 
- //_at_Test
+ @Test
     public void testInvalidStatusResponse() throws Exception {
         Response response = new Response("STATUS Sent Items (UIDNEXT 1)");
         final Status status = new Status(response);
@@ -78,7 +76,7 @@
         assertEquals(1, status.uidnext);
     }
 
- //_at_Test
+ @Test
     public void testMissingBracket() throws Exception {
         final Response response =
                 new Response("STATUS \"Sent Items\" UIDNEXT 1)");

diff -r 0bee233d00ea -r e01d91e74a87 mail/src/test/java/com/sun/mail/pop3/POP3StoreTest.java
--- a/mail/src/test/java/com/sun/mail/pop3/POP3StoreTest.java Tue Dec 15 10:20:20 2009 -0800
+++ b/mail/src/test/java/com/sun/mail/pop3/POP3StoreTest.java Tue Dec 15 10:25:38 2009 -0800
@@ -43,22 +43,21 @@
 import javax.mail.Session;
 import javax.mail.Store;
 
-import junit.framework.Assert;
-import junit.framework.TestCase;
-
 import org.junit.Test;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
 
 /**
  * Test is connected.
  *
  * @author sbo
  */
-public final class POP3StoreTest extends TestCase {
+public final class POP3StoreTest {
     
     /**
      * Check is connected.
      */
- //_at_Test
+ @Test
     public void testIsConnected() {
         POP3Server server = null;
         try {
@@ -80,13 +79,13 @@
                 folder.open(Folder.READ_ONLY);
                 
                 // Check
- Assert.assertFalse(folder.isOpen());
+ assertFalse(folder.isOpen());
             } finally {
                 store.close();
             }
         } catch (final Exception e) {
             e.printStackTrace();
- Assert.fail(e.getMessage());
+ fail(e.getMessage());
         } finally {
             if (server != null) {
                 server.quit();
@@ -104,7 +103,7 @@
         /**
          * {_at_inheritDoc}
          */
- //_at_Override
+ @Override
         public void noop() throws IOException {
             this.println("-ERR");
         }


diff -r e01d91e74a87 -r e826f80c40a1 mail/src/main/java/com/sun/mail/pop3/POP3Store.java
--- a/mail/src/main/java/com/sun/mail/pop3/POP3Store.java Tue Dec 15 10:25:38 2009 -0800
+++ b/mail/src/main/java/com/sun/mail/pop3/POP3Store.java Tue Dec 15 19:34:28 2009 -0800
@@ -347,7 +347,7 @@
         if (c != null)
             return Collections.unmodifiableMap(c);
         else
- return Collections.emptyMap();
+ return Collections.EMPTY_MAP;
     }
 
     protected void finalize() throws Throwable {


diff -r e826f80c40a1 -r b4b56645c582 pom.xml
--- a/pom.xml Tue Dec 15 19:34:28 2009 -0800
+++ b/pom.xml Tue Dec 15 20:19:09 2009 -0800
@@ -99,6 +99,7 @@
         <mail.probeFile/>
         <!-- for the osgiversion-maven-plugin -->
         <hk2.plugin.version>0.4.11</hk2.plugin.version>
+ <javac.path>/opt/jdk1.4/bin/javac</javac.path>
     </properties>
 
     <developers>
@@ -153,6 +154,42 @@
         <profile>
             <id>deploy</id>
         </profile>
+
+ <!--
+ A special profile for compiling with the real JDK 1.4
+ compiler, to make sure there are no accidental dependencies
+ on JDK 1.5 APIs. Set the property javac.path to the path
+ to the JDK 1.4 compiler, e.g.,
+ "mvn -P1.4 -Djavac.path=/opt/jdk1.4/bin/javac".
+ -->
+ <profile>
+ <id>1.4</id>
+ <build>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>default-compile</id>
+ <configuration>
+ <fork>true</fork>
+ <executable>${javac.path}</executable>
+ <compilerVersion>1.4</compilerVersion>
+ <source>1.4</source>
+ <target>1.4</target>
+ <!-- this class depends on JDK 1.5 APIs -->
+ <excludes>
+ <exclude>
+ com/sun/mail/imap/protocol/IMAPSaslAuthenticator.java
+ </exclude>
+ </excludes>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
     </profiles>
 
     <distributionManagement>


diff -r b4b56645c582 -r 7edfa56e5c34 pom.xml
--- a/pom.xml Tue Dec 15 20:19:09 2009 -0800
+++ b/pom.xml Wed Dec 16 13:20:58 2009 -0800
@@ -100,6 +100,7 @@
         <!-- for the osgiversion-maven-plugin -->
         <hk2.plugin.version>0.4.11</hk2.plugin.version>
         <javac.path>/opt/jdk1.4/bin/javac</javac.path>
+ <project.build.sourceEncoding>iso-8859-1</project.build.sourceEncoding>
     </properties>
 
     <developers>


diff -r 7edfa56e5c34 -r 49b9482463bb pom.xml
--- a/pom.xml Wed Dec 16 13:20:58 2009 -0800
+++ b/pom.xml Thu Dec 17 23:06:21 2009 -0800
@@ -213,13 +213,21 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-enforcer-plugin</artifactId>
- <configuration>
- <rules>
- <requireMavenVersion>
- <version>2.2.1</version>
- </requireMavenVersion>
- </rules>
- </configuration>
+ <executions>
+ <execution>
+ <id>enforce-version</id>
+ <goals>
+ <goal>enforce</goal>
+ </goals>
+ <configuration>
+ <rules>
+ <requireMavenVersion>
+ <version>[2.2.1,)</version>
+ </requireMavenVersion>
+ </rules>
+ </configuration>
+ </execution>
+ </executions>
             </plugin>
 
             <!--


diff -r 49b9482463bb -r a8841b2918ad mail/src/main/java/com/sun/mail/imap/IMAPStore.java
--- a/mail/src/main/java/com/sun/mail/imap/IMAPStore.java Thu Dec 17 23:06:21 2009 -0800
+++ b/mail/src/main/java/com/sun/mail/imap/IMAPStore.java Fri Dec 18 16:43:29 2009 -0800
@@ -639,6 +639,9 @@
         if (p.isAuthenticated())
             return; // no need to login
 
+ // allow subclasses to issue commands before login
+ preLogin();
+
         /*
          * Put a special "marker" in the capabilities list so we can
          * detect if the server refreshed the capabilities in the OK
@@ -690,6 +693,19 @@
     }
 
     /**
+ * This method is called after the connection is made and
+ * TLS is started (if needed), but before any authentication
+ * is attempted. Subclasses can override this method to
+ * issue commands that are needed in the "not authenticated"
+ * state. Note that if the connection is pre-authenticated,
+ * this method won't be called. <p>
+ *
+ * The implementation of this method in this class does nothing.
+ */
+ protected void preLogin() throws ProtocolException {
+ }
+
+ /**
      * Set the user name that will be used for subsequent connections
      * after this Store is first connected (for example, when creating
      * a connection to open a Folder). This value is overridden


diff -r a8841b2918ad -r 4e897fce9cf2 doc/release/CHANGES.txt
--- a/doc/release/CHANGES.txt Fri Dec 18 16:43:29 2009 -0800
+++ b/doc/release/CHANGES.txt Fri Dec 18 16:44:07 2009 -0800
@@ -25,6 +25,7 @@
 <no id> properly disable TOP if POP3 CAPA response doesn't include it
 <no id> add mail.pop3.disablecapa property to disable use of the CAPA command
 <no id> fix support for Properties objects with default Properties objects
+<no id> integrate NTLM support, no longer needs jcifs.jar
 
 
                   CHANGES IN THE 1.4.3 RELEASE

diff -r a8841b2918ad -r 4e897fce9cf2 doc/release/NTLMNOTES.txt
--- a/doc/release/NTLMNOTES.txt Fri Dec 18 16:43:29 2009 -0800
+++ b/doc/release/NTLMNOTES.txt Fri Dec 18 16:44:07 2009 -0800
@@ -3,15 +3,10 @@
 
 Thanks to the efforts of Luis Serralheiro, JavaMail now suports the use
 of Microsoft's proprietary NTLM authentication mechanism. This support
-within JavaMail builds on the base NTLM support provided by the JCIFS
-project. To use this NTLM support in JavaMail, you'll also need to
-include the jcifs jar file in your CLASSPATH. You can download the
-latest jcifs jar file from the JCIFS site: http://jcifs.samba.org
-JCIFS is available under the LGPL license.
+within JavaMail is now derived from the NTLM support in the JDK and
+included directly in JavaMail, with no external dependencies.
 
-This release of JavaMail was tested with the 1.3.12 version of JCIFS
-and Microsoft Exchange 5.5 and 2007. Note that the 1.2.x versions of
-JCIFS won't work as the API has changed incompatibly.
+This release of JavaMail was tested with Microsoft Exchange 5.5 and 2007.
 
 The SMTP and IMAP providers support the use of NTLM authentication.
 The following properties can be used to configure the NTLM support:
@@ -20,7 +15,7 @@
         The NTLM authentication domain.
 
 mail.<protocol>.auth.ntlm.flags
- NTLM protocol-specific flags.
+ NTLM protocol-specific flags. (not currently used)
         See http://curl.haxx.se/rfc/ntlm.html#theNtlmFlags for details.
 
 

diff -r a8841b2918ad -r 4e897fce9cf2 mail/src/main/java/com/sun/mail/auth/MD4.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mail/src/main/java/com/sun/mail/auth/MD4.java Fri Dec 18 16:44:07 2009 -0800
@@ -0,0 +1,291 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2005-2009 Sun Microsystems, Inc. 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.html
+ * or glassfish/bootstrap/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 glassfish/bootstrap/legal/LICENSE.txt.
+ * Sun designates this particular file as subject to the "Classpath" exception
+ * as provided by Sun in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the License
+ * Header, with the fields enclosed by brackets [] replaced by your own
+ * identifying information: "Portions Copyrighted [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
+ *
[truncated due to length]