It would be nice to edit the commit comment to note the switch of Java
requirement.

Gary

---------- Forwarded message ----------
From: <sgoes...@apache.org>
Date: Mon, Feb 1, 2016 at 1:25 PM
Subject: svn commit: r1728011 - in /commons/proper/email/trunk: ./
src/changes/ src/main/java/org/apache/commons/mail/
src/main/java/org/apache/commons/mail/util/
src/test/java/org/apache/commons/mail/
src/test/java/org/apache/commons/mail/util/
To: comm...@commons.apache.org


Author: sgoeschl
Date: Mon Feb  1 21:25:23 2016
New Revision: 1728011

URL: http://svn.apache.org/viewvc?rev=1728011&view=rev
Log:
[EMAIL-160] Add Support for International Domain Names

Added:
    commons/proper/email/trunk/.gitignore

commons/proper/email/trunk/src/main/java/org/apache/commons/mail/util/IDNEmailAddressConverter.java

commons/proper/email/trunk/src/test/java/org/apache/commons/mail/util/IDNEmailAddressConverterTest.java
Modified:
    commons/proper/email/trunk/pom.xml
    commons/proper/email/trunk/src/changes/changes.xml

commons/proper/email/trunk/src/main/java/org/apache/commons/mail/Email.java

commons/proper/email/trunk/src/test/java/org/apache/commons/mail/EmailTest.java

Added: commons/proper/email/trunk/.gitignore
URL:
http://svn.apache.org/viewvc/commons/proper/email/trunk/.gitignore?rev=1728011&view=auto
==============================================================================
--- commons/proper/email/trunk/.gitignore (added)
+++ commons/proper/email/trunk/.gitignore Mon Feb  1 21:25:23 2016
@@ -0,0 +1,10 @@
+.DS_Store
+*.iml
+*.iws
+*.ipr
+target
+.swp
+.idea
+.classpath
+.project
+.settings

Modified: commons/proper/email/trunk/pom.xml
URL:
http://svn.apache.org/viewvc/commons/proper/email/trunk/pom.xml?rev=1728011&r1=1728010&r2=1728011&view=diff
==============================================================================
--- commons/proper/email/trunk/pom.xml (original)
+++ commons/proper/email/trunk/pom.xml Mon Feb  1 21:25:23 2016
@@ -292,8 +292,8 @@
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
-        <maven.compiler.source>1.5</maven.compiler.source>
-        <maven.compiler.target>1.5</maven.compiler.target>
+        <maven.compiler.source>1.6</maven.compiler.source>
+        <maven.compiler.target>1.6</maven.compiler.target>
         <commons.componentid>email</commons.componentid>
         <commons.jira.id>EMAIL</commons.jira.id>
         <commons.jira.pid>12310474</commons.jira.pid>

Modified: commons/proper/email/trunk/src/changes/changes.xml
URL:
http://svn.apache.org/viewvc/commons/proper/email/trunk/src/changes/changes.xml?rev=1728011&r1=1728010&r2=1728011&view=diff
==============================================================================
--- commons/proper/email/trunk/src/changes/changes.xml (original)
+++ commons/proper/email/trunk/src/changes/changes.xml Mon Feb  1 21:25:23
2016
@@ -22,7 +22,10 @@
   </properties>

   <body>
-    <release version="1.5" date="2015-MM-DD">
+    <release version="1.5" date="2016-MM-DD">
+      <action dev="sgoeschl" type="add" issue="EMAIL-160"
date="2016-02-01">
+        Add Support for International Domain Names.
+      </action>
       <action dev="ggregory" type="add" issue="EMAIL-154"
date="2015-07-26" due-to="Ken Geis, Balachandran Sivakumar">
         Add Email#getHeader(String) and Email#getHeaders() methods.
       </action>

Modified:
commons/proper/email/trunk/src/main/java/org/apache/commons/mail/Email.java
URL:
http://svn.apache.org/viewvc/commons/proper/email/trunk/src/main/java/org/apache/commons/mail/Email.java?rev=1728011&r1=1728010&r2=1728011&view=diff
==============================================================================
---
commons/proper/email/trunk/src/main/java/org/apache/commons/mail/Email.java
(original)
+++
commons/proper/email/trunk/src/main/java/org/apache/commons/mail/Email.java
Mon Feb  1 21:25:23 2016
@@ -41,6 +41,8 @@ import javax.naming.Context;
 import javax.naming.InitialContext;
 import javax.naming.NamingException;

+import org.apache.commons.mail.util.IDNEmailAddressConverter;
+
 /**
  * The base class for all email messages.  This class sets the
  * sender's email &amp; name, receiver's email &amp; name, subject, and the
@@ -1913,7 +1915,7 @@ public abstract class Email

         try
         {
-            address = new InternetAddress(email);
+            address = new InternetAddress(new
IDNEmailAddressConverter().toASCII(email));

             // check name input
             if (EmailUtils.isNotEmpty(name))

Added:
commons/proper/email/trunk/src/main/java/org/apache/commons/mail/util/IDNEmailAddressConverter.java
URL:
http://svn.apache.org/viewvc/commons/proper/email/trunk/src/main/java/org/apache/commons/mail/util/IDNEmailAddressConverter.java?rev=1728011&view=auto
==============================================================================
---
commons/proper/email/trunk/src/main/java/org/apache/commons/mail/util/IDNEmailAddressConverter.java
(added)
+++
commons/proper/email/trunk/src/main/java/org/apache/commons/mail/util/IDNEmailAddressConverter.java
Mon Feb  1 21:25:23 2016
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.mail.util;
+
+import javax.mail.internet.InternetAddress;
+import java.net.IDN;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * Converts email addresses containing International Domain Names into an
ASCII
+ * representation suitable for sending an email.
+ *
+ * @see <a href="
https://docs.oracle.com/javase/tutorial/i18n/network/idn.html";>
https://docs.oracle.com/javase/tutorial/i18n/network/idn.html</a>
+ * @see <a href="https://en.wikipedia.org/wiki/Punycode";>
https://en.wikipedia.org/wiki/Punycode</a>
+ * @see <a href="https://tools.ietf.org/html/rfc5891";>
https://tools.ietf.org/html/rfc5891</a>
+ * @see <a href="https://en.wikipedia.org/wiki/Punycode";>
https://en.wikipedia.org/wiki/Punycode</a>
+ *
+ * @version $Id$
+ * @since 1.5
+ */
+public class IDNEmailAddressConverter {
+
+    /**
+     * Convert an email address to its ASCII representation using
"Punycode".
+     */
+    public String toASCII(final String email)
+    {
+        final int idx = findAtSymbolIndex(email);
+
+        if (idx < 0)
+        {
+            return email;
+        }
+
+        return getLocalPart(email, idx) + "@" +
IDN.toASCII(getDomainPart(email, idx));
+    }
+
+    /**
+     * Convert an "Punycode" email address to its Unicode representation.
+     */
+    public String toUnicode(final String email)
+    {
+        final int idx = findAtSymbolIndex(email);
+
+        if (idx < 0)
+        {
+            return email;
+        }
+
+        return getLocalPart(email, idx) + "@" +
IDN.toUnicode(getDomainPart(email, idx));
+    }
+
+    /**
+     * Convert the address part of an InternetAddress to its Unicode
representation.
+     */
+    public String toUnicode(final InternetAddress address)
+    {
+        return (address != null ? toUnicode(address.getAddress()) : null);
+    }
+
+    /**
+     * Convert the address part of a list of InternetAddress to its
Unicode representation.
+     */
+    public Collection<String> toUnicode(Collection<InternetAddress>
addresses)
+    {
+        if(addresses == null)
+        {
+            return null;
+        }
+
+        Collection<String> result = new ArrayList<String>();
+
+        for(InternetAddress address : addresses)
+        {
+            result.add(toUnicode(address));
+        }
+
+        return result;
+    }
+
+    private String getLocalPart(final String email, final int idx)
+    {
+
+        return email.substring(0, idx);
+    }
+
+    private String getDomainPart(final String email, final int idx)
+    {
+
+        return email.substring(idx + 1);
+    }
+
+    private int findAtSymbolIndex(final String value)
+    {
+        if (value == null)
+        {
+            return -1;
+        }
+
+        return value.indexOf('@');
+    }
+}

Modified:
commons/proper/email/trunk/src/test/java/org/apache/commons/mail/EmailTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/email/trunk/src/test/java/org/apache/commons/mail/EmailTest.java?rev=1728011&r1=1728010&r2=1728011&view=diff
==============================================================================
---
commons/proper/email/trunk/src/test/java/org/apache/commons/mail/EmailTest.java
(original)
+++
commons/proper/email/trunk/src/test/java/org/apache/commons/mail/EmailTest.java
Mon Feb  1 21:25:23 2016
@@ -31,6 +31,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;

+import javax.mail.Message;
 import javax.mail.Session;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeMessage;
@@ -1266,4 +1267,25 @@ public class EmailTest extends AbstractE
         assertEquals(bounceAddress, email.getBounceAddress());
     }

+    @Test
+    public void testSupportForInternationalDomainNames() throws Exception
+    {
+        email.setHostName(strTestMailServer);
+        email.setSmtpPort(getMailServerPort());
+        email.setFrom("from@d\u00F6m\u00E4in.example");
+        email.addTo("to@d\u00F6m\u00E4in.example");
+        email.addCc("cc@d\u00F6m\u00E4in.example");
+        email.addBcc("bcc@d\u00F6m\u00E4in.example");
+        email.setSubject("test mail");
+        email.setSubject("testSupportForInternationalDomainNames");
+        email.setMsg("This is a test mail ... :-)");
+
+        email.buildMimeMessage();
+        final MimeMessage msg = email.getMimeMessage();
+
+        assertEquals("from@xn--dmin-moa0i.example",
msg.getFrom()[0].toString());
+        assertEquals("to@xn--dmin-moa0i.example", msg.getRecipients(
Message.RecipientType.TO)[0].toString());
+        assertEquals("cc@xn--dmin-moa0i.example", msg.getRecipients(
Message.RecipientType.CC)[0].toString());
+        assertEquals("bcc@xn--dmin-moa0i.example",
msg.getRecipients(Message.RecipientType.BCC)[0].toString());
+    }
 }

Added:
commons/proper/email/trunk/src/test/java/org/apache/commons/mail/util/IDNEmailAddressConverterTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/email/trunk/src/test/java/org/apache/commons/mail/util/IDNEmailAddressConverterTest.java?rev=1728011&view=auto
==============================================================================
---
commons/proper/email/trunk/src/test/java/org/apache/commons/mail/util/IDNEmailAddressConverterTest.java
(added)
+++
commons/proper/email/trunk/src/test/java/org/apache/commons/mail/util/IDNEmailAddressConverterTest.java
Mon Feb  1 21:25:23 2016
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.mail.util;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import javax.mail.internet.InternetAddress;
+
+import org.junit.Test;
+
+public class IDNEmailAddressConverterTest {
+
+    private static final String AUSTRIAN_IDN_EMAIL_ADDRESS = "noreply@d
\u00F6m\u00E4in.example";
+    private static final String CZECH_IDN_EMAIL_ADDRESS = "noreply@
\u010Desk\u00E1republika.icom.museum";
+    private static final String RUSSIAN_IDN_EMAIL_ADDRESS = "noreply@
\u0440\u043E\u0441\u0441\u0438\u044F.\u0438\u043A\u043E\u043C.museum";
+
+    private static final String GERMAN_IDN_EMAIL_NAME = "noreply@d
\u00F6m\u00E4in.example";
+
+    private static final String[] IDN_EMAIL_ADDRESSES = {
AUSTRIAN_IDN_EMAIL_ADDRESS, CZECH_IDN_EMAIL_ADDRESS,
RUSSIAN_IDN_EMAIL_ADDRESS };
+
+    private IDNEmailAddressConverter idnEmailConverter = new
IDNEmailAddressConverter();
+
+    @Test
+    public void testConvertInvalidEmailAddressToAscii()
+    {
+        assertEquals(null, idnEmailConverter.toASCII(null));
+        assertEquals("", idnEmailConverter.toASCII(""));
+        assertEquals("@", idnEmailConverter.toASCII("@"));
+        assertEquals("@@", idnEmailConverter.toASCII("@@"));
+        assertEquals("foo", idnEmailConverter.toASCII("foo"));
+        assertEquals("foo@", idnEmailConverter.toASCII("foo@"));
+        assertEquals("@badhost.com", idnEmailConverter.toASCII("@
badhost.com"));
+    }
+
+    @Test
+    public void testIDNEmailAddressToAsciiConversion()
+    {
+        assertEquals("noreply@xn--dmin-moa0i.example",
idnEmailConverter.toASCII(AUSTRIAN_IDN_EMAIL_ADDRESS));
+        assertEquals("nore...@xn--h1alffa9f.xn--h1aegh.museum",
idnEmailConverter.toASCII(RUSSIAN_IDN_EMAIL_ADDRESS));
+    }
+
+    @Test
+    public void testMultipleIDNEmailAddressToAsciiConversion()
+    {
+        assertEquals("noreply@xn--dmin-moa0i.example",
idnEmailConverter.toASCII(idnEmailConverter.toASCII(AUSTRIAN_IDN_EMAIL_ADDRESS)));
+    }
+
+    @Test
+    public void testInternetAddressToAsciiConversion() throws Exception
+    {
+        InternetAddress address = new
InternetAddress(idnEmailConverter.toASCII(AUSTRIAN_IDN_EMAIL_ADDRESS));
+        assertEquals(AUSTRIAN_IDN_EMAIL_ADDRESS,
idnEmailConverter.toUnicode(address));
+
+        InternetAddress addressWithPersonalName = new
InternetAddress(idnEmailConverter.toASCII(AUSTRIAN_IDN_EMAIL_ADDRESS),
GERMAN_IDN_EMAIL_NAME);
+        assertEquals(AUSTRIAN_IDN_EMAIL_ADDRESS,
idnEmailConverter.toUnicode(addressWithPersonalName));
+    }
+
+    @Test
+    public void testInternetAddressCollectionToAsciiConversion() throws
Exception
+    {
+        Collection<InternetAddress> addresses = new
ArrayList<InternetAddress>();
+        addresses.add(new
InternetAddress(idnEmailConverter.toASCII(AUSTRIAN_IDN_EMAIL_ADDRESS)));
+
+        Collection<String> emails = idnEmailConverter.toUnicode(addresses);
+
+        assertEquals(1, emails.size());
+        assertEquals(AUSTRIAN_IDN_EMAIL_ADDRESS, emails.iterator().next());
+    }
+
+    @Test
+    public void testRoundTripConversionOfIDNEmailAddress()
+    {
+        for(String email : IDN_EMAIL_ADDRESSES)
+        {
+            assertEquals(email,
idnEmailConverter.toUnicode(idnEmailConverter.toASCII(email)));
+        }
+    }
+
+    @Test
+    public void testNonIDNEmailAddressToAsciiConversion()
+    {
+        assertEquals("m...@home.com", idnEmailConverter.toASCII("m...@home.com
"));
+    }
+}





-- 
E-Mail: garydgreg...@gmail.com | ggreg...@apache.org
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Reply via email to