diff --git a/org.springframework.context.support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java b/org.springframework.context.support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java
index b4984c693de..4184b2f3b41 100644
--- a/org.springframework.context.support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java
+++ b/org.springframework.context.support/src/main/java/org/springframework/mail/javamail/MimeMessageHelper.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2010 the original author or authors.
+ * Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,6 +35,7 @@ import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
+import javax.mail.internet.MimeUtility;
import org.springframework.core.io.InputStreamSource;
import org.springframework.core.io.Resource;
@@ -241,7 +242,7 @@ public class MimeMessageHelper {
* @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int, String)
*/
public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart, String encoding)
- throws MessagingException {
+ throws MessagingException {
this(mimeMessage, (multipart ? MULTIPART_MODE_MIXED_RELATED : MULTIPART_MODE_NO), encoding);
}
@@ -283,7 +284,7 @@ public class MimeMessageHelper {
* @see #MULTIPART_MODE_MIXED_RELATED
*/
public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode, String encoding)
- throws MessagingException {
+ throws MessagingException {
this.mimeMessage = mimeMessage;
createMimeMultiparts(mimeMessage, multipartMode);
@@ -355,7 +356,7 @@ public class MimeMessageHelper {
/**
* Set the given MimeMultipart objects for use by this MimeMessageHelper.
* @param root the root MimeMultipart object, which attachments will be added to;
- * or null to indicate no multipart at all
+ * or {@code null} to indicate no multipart at all
* @param main the main MimeMultipart object, which text(s) and inline elements
* will be added to (can be the same as the root multipart object, or an element
* nested underneath the root multipart element)
@@ -380,8 +381,8 @@ public class MimeMessageHelper {
private void checkMultipart() throws IllegalStateException {
if (!isMultipart()) {
throw new IllegalStateException("Not in multipart mode - " +
- "create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag " +
- "if you need to set alternative texts or add inline elements or attachments.");
+ "create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag " +
+ "if you need to set alternative texts or add inline elements or attachments.");
}
}
@@ -420,7 +421,7 @@ public class MimeMessageHelper {
* Determine the default encoding for the given MimeMessage.
* @param mimeMessage the passed-in MimeMessage
* @return the default encoding associated with the MimeMessage,
- * or null if none found
+ * or {@code null} if none found
*/
protected String getDefaultEncoding(MimeMessage mimeMessage) {
if (mimeMessage instanceof SmartMimeMessage) {
@@ -456,12 +457,12 @@ public class MimeMessageHelper {
}
/**
- * Set the Java Activation Framework FileTypeMap to use
+ * Set the Java Activation Framework {@code FileTypeMap} to use
* for determining the content type of inline content and attachments
* that get added to the message.
- *
Default is the FileTypeMap that the underlying
+ *
Default is the {@code FileTypeMap} that the underlying
* MimeMessage carries, if any, or the Activation Framework's default
- * FileTypeMap instance else.
+ * {@code FileTypeMap} instance else.
* @see #addInline
* @see #addAttachment
* @see #getDefaultFileTypeMap(javax.mail.internet.MimeMessage)
@@ -474,7 +475,7 @@ public class MimeMessageHelper {
}
/**
- * Return the FileTypeMap used by this MimeMessageHelper.
+ * Return the {@code FileTypeMap} used by this MimeMessageHelper.
*/
public FileTypeMap getFileTypeMap() {
return this.fileTypeMap;
@@ -485,7 +486,7 @@ public class MimeMessageHelper {
* Set whether to validate all addresses which get passed to this helper.
* Default is "false".
*
Note that this is by default just available for JavaMail >= 1.3.
- * You can override the default validateAddress method for
+ * You can override the default {@code validateAddress method} for
* validation on older JavaMail versions (or for custom validation).
* @see #validateAddress
*/
@@ -503,7 +504,7 @@ public class MimeMessageHelper {
/**
* Validate the given mail address.
* Called by all of MimeMessageHelper's address setters and adders.
- *
Default implementation invokes InternetAddress.validate(),
+ *
Default implementation invokes {@code InternetAddress.validate()}, * provided that address validation is activated for the helper instance. *
Note that this method will just work on JavaMail >= 1.3. You can override
* it for validation on older JavaMail versions or for custom validation.
@@ -546,7 +547,7 @@ public class MimeMessageHelper {
public void setFrom(String from, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(from, "From address must not be null");
setFrom(getEncoding() != null ?
- new InternetAddress(from, personal, getEncoding()) : new InternetAddress(from, personal));
+ new InternetAddress(from, personal, getEncoding()) : new InternetAddress(from, personal));
}
public void setReplyTo(InternetAddress replyTo) throws MessagingException {
@@ -608,8 +609,8 @@ public class MimeMessageHelper {
public void addTo(String to, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(to, "To address must not be null");
addTo(getEncoding() != null ?
- new InternetAddress(to, personal, getEncoding()) :
- new InternetAddress(to, personal));
+ new InternetAddress(to, personal, getEncoding()) :
+ new InternetAddress(to, personal));
}
@@ -653,8 +654,8 @@ public class MimeMessageHelper {
public void addCc(String cc, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(cc, "Cc address must not be null");
addCc(getEncoding() != null ?
- new InternetAddress(cc, personal, getEncoding()) :
- new InternetAddress(cc, personal));
+ new InternetAddress(cc, personal, getEncoding()) :
+ new InternetAddress(cc, personal));
}
@@ -698,8 +699,8 @@ public class MimeMessageHelper {
public void addBcc(String bcc, String personal) throws MessagingException, UnsupportedEncodingException {
Assert.notNull(bcc, "Bcc address must not be null");
addBcc(getEncoding() != null ?
- new InternetAddress(bcc, personal, getEncoding()) :
- new InternetAddress(bcc, personal));
+ new InternetAddress(bcc, personal, getEncoding()) :
+ new InternetAddress(bcc, personal));
}
private InternetAddress parseAddress(String address) throws MessagingException {
@@ -730,7 +731,7 @@ public class MimeMessageHelper {
/**
* Set the sent-date of the message.
- * @param sentDate the date to set (never null)
+ * @param sentDate the date to set (never {@code null})
* @throws MessagingException in case of errors
*/
public void setSentDate(Date sentDate) throws MessagingException {
@@ -758,7 +759,7 @@ public class MimeMessageHelper {
* Set the given text directly as content in non-multipart mode
* or as default body part in multipart mode.
* Always applies the default content type "text/plain".
- *
NOTE: Invoke {@link #addInline} after setText;
+ *
NOTE: Invoke {@link #addInline} after {@code setText}; * else, mail readers might not be able to resolve inline references correctly. * @param text the text for the message * @throws MessagingException in case of errors @@ -771,7 +772,7 @@ public class MimeMessageHelper { * Set the given text directly as content in non-multipart mode * or as default body part in multipart mode. * The "html" flag determines the content type to apply. - *
NOTE: Invoke {@link #addInline} after setText;
+ *
NOTE: Invoke {@link #addInline} after {@code setText}; * else, mail readers might not be able to resolve inline references correctly. * @param text the text for the message * @param html whether to apply content type "text/html" for an @@ -798,7 +799,7 @@ public class MimeMessageHelper { /** * Set the given plain text and HTML text as alternatives, offering * both options to the email client. Requires multipart mode. - *
NOTE: Invoke {@link #addInline} after setText;
+ *
NOTE: Invoke {@link #addInline} after {@code setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param plainText the plain text for the message
* @param htmlText the HTML text for the message
@@ -860,16 +861,16 @@ public class MimeMessageHelper {
/**
* Add an inline element to the MimeMessage, taking the content from a
- * javax.activation.DataSource.
+ * {@code javax.activation.DataSource}.
*
Note that the InputStream returned by the DataSource implementation
* needs to be a fresh one on each call, as JavaMail will invoke
- * getInputStream() multiple times.
- *
NOTE: Invoke addInline after {@link #setText};
+ * {@code getInputStream()} multiple times.
+ *
NOTE: Invoke {@code addInline} after {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
* Can be referenced in HTML source via src="cid:myId" expressions.
- * @param dataSource the javax.activation.DataSource to take
+ * @param dataSource the {@code javax.activation.DataSource} to take
* the content from, determining the InputStream and the content type
* @throws MessagingException in case of errors
* @see #addInline(String, java.io.File)
@@ -889,11 +890,11 @@ public class MimeMessageHelper {
/**
* Add an inline element to the MimeMessage, taking the content from a
- * java.io.File.
+ * {@code java.io.File}.
*
The content type will be determined by the name of the given * content file. Do not use this for temporary files with arbitrary * filenames (possibly ending in ".tmp" or the like)! - *
NOTE: Invoke addInline after {@link #setText};
+ *
NOTE: Invoke {@code addInline} after {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
@@ -913,14 +914,14 @@ public class MimeMessageHelper {
/**
* Add an inline element to the MimeMessage, taking the content from a
- * org.springframework.core.io.Resource.
+ * {@code org.springframework.core.io.Resource}.
*
The content type will be determined by the name of the given * content file. Do not use this for temporary files with arbitrary * filenames (possibly ending in ".tmp" or the like)! *
Note that the InputStream returned by the Resource implementation
* needs to be a fresh one on each call, as JavaMail will invoke
- * getInputStream() multiple times.
- *
NOTE: Invoke addInline after {@link #setText};
+ * {@code getInputStream()} multiple times.
+ *
NOTE: Invoke {@code addInline} after {@link #setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
@@ -939,14 +940,14 @@ public class MimeMessageHelper {
/**
* Add an inline element to the MimeMessage, taking the content from an
- * org.springframework.core.InputStreamResource, and
+ * {@code org.springframework.core.InputStreamResource}, and
* specifying the content type explicitly.
*
You can determine the content type for any given filename via a Java * Activation Framework's FileTypeMap, for example the one held by this helper. *
Note that the InputStream returned by the InputStreamSource implementation
* needs to be a fresh one on each call, as JavaMail will invoke
- * getInputStream() multiple times.
- *
NOTE: Invoke addInline after setText;
+ * {@code getInputStream()} multiple times.
+ *
NOTE: Invoke {@code addInline} after {@code setText};
* else, mail readers might not be able to resolve inline references correctly.
* @param contentId the content ID to use. Will end up as "Content-ID" header
* in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
@@ -960,7 +961,7 @@ public class MimeMessageHelper {
* @see #addInline(String, javax.activation.DataSource)
*/
public void addInline(String contentId, InputStreamSource inputStreamSource, String contentType)
- throws MessagingException {
+ throws MessagingException {
Assert.notNull(inputStreamSource, "InputStreamSource must not be null");
if (inputStreamSource instanceof Resource && ((Resource) inputStreamSource).isOpen()) {
@@ -974,13 +975,13 @@ public class MimeMessageHelper {
/**
* Add an attachment to the MimeMessage, taking the content from a
- * javax.activation.DataSource.
+ * {@code javax.activation.DataSource}.
*
Note that the InputStream returned by the DataSource implementation
* needs to be a fresh one on each call, as JavaMail will invoke
- * getInputStream() multiple times.
+ * {@code getInputStream()} multiple times.
* @param attachmentFilename the name of the attachment as it will
* appear in the mail (the content type will be determined by this)
- * @param dataSource the javax.activation.DataSource to take
+ * @param dataSource the {@code javax.activation.DataSource} to take
* the content from, determining the InputStream and the content type
* @throws MessagingException in case of errors
* @see #addAttachment(String, org.springframework.core.io.InputStreamSource)
@@ -989,16 +990,21 @@ public class MimeMessageHelper {
public void addAttachment(String attachmentFilename, DataSource dataSource) throws MessagingException {
Assert.notNull(attachmentFilename, "Attachment filename must not be null");
Assert.notNull(dataSource, "DataSource must not be null");
- MimeBodyPart mimeBodyPart = new MimeBodyPart();
- mimeBodyPart.setDisposition(MimeBodyPart.ATTACHMENT);
- mimeBodyPart.setFileName(attachmentFilename);
- mimeBodyPart.setDataHandler(new DataHandler(dataSource));
- getRootMimeMultipart().addBodyPart(mimeBodyPart);
+ try {
+ MimeBodyPart mimeBodyPart = new MimeBodyPart();
+ mimeBodyPart.setDisposition(MimeBodyPart.ATTACHMENT);
+ mimeBodyPart.setFileName(MimeUtility.encodeText(attachmentFilename));
+ mimeBodyPart.setDataHandler(new DataHandler(dataSource));
+ getRootMimeMultipart().addBodyPart(mimeBodyPart);
+ }
+ catch (UnsupportedEncodingException ex) {
+ throw new MessagingException("Failed to encode attachment filename", ex);
+ }
}
/**
* Add an attachment to the MimeMessage, taking the content from a
- * java.io.File.
+ * {@code java.io.File}.
*
The content type will be determined by the name of the given
* content file. Do not use this for temporary files with arbitrary
* filenames (possibly ending in ".tmp" or the like)!
@@ -1018,13 +1024,13 @@ public class MimeMessageHelper {
/**
* Add an attachment to the MimeMessage, taking the content from an
- * org.springframework.core.io.InputStreamResource.
+ * {@code org.springframework.core.io.InputStreamResource}.
*
The content type will be determined by the given filename for * the attachment. Thus, any content source will be fine, including * temporary files with arbitrary filenames. *
Note that the InputStream returned by the InputStreamSource
* implementation needs to be a fresh one on each call, as
- * JavaMail will invoke getInputStream() multiple times.
+ * JavaMail will invoke {@code getInputStream()} multiple times.
* @param attachmentFilename the name of the attachment as it will
* appear in the mail
* @param inputStreamSource the resource to take the content from
@@ -1035,7 +1041,7 @@ public class MimeMessageHelper {
* @see org.springframework.core.io.Resource
*/
public void addAttachment(String attachmentFilename, InputStreamSource inputStreamSource)
- throws MessagingException {
+ throws MessagingException {
String contentType = getFileTypeMap().getContentType(attachmentFilename);
addAttachment(attachmentFilename, inputStreamSource, contentType);
@@ -1043,10 +1049,10 @@ public class MimeMessageHelper {
/**
* Add an attachment to the MimeMessage, taking the content from an
- * org.springframework.core.io.InputStreamResource.
+ * {@code org.springframework.core.io.InputStreamResource}.
*
Note that the InputStream returned by the InputStreamSource
* implementation needs to be a fresh one on each call, as
- * JavaMail will invoke getInputStream() multiple times.
+ * JavaMail will invoke {@code getInputStream()} multiple times.
* @param attachmentFilename the name of the attachment as it will
* appear in the mail
* @param inputStreamSource the resource to take the content from
@@ -1059,7 +1065,7 @@ public class MimeMessageHelper {
*/
public void addAttachment(
String attachmentFilename, InputStreamSource inputStreamSource, String contentType)
- throws MessagingException {
+ throws MessagingException {
Assert.notNull(inputStreamSource, "InputStreamSource must not be null");
if (inputStreamSource instanceof Resource && ((Resource) inputStreamSource).isOpen()) {
@@ -1079,7 +1085,7 @@ public class MimeMessageHelper {
* @return the Activation Framework DataSource
*/
protected DataSource createDataSource(
- final InputStreamSource inputStreamSource, final String contentType, final String name) {
+ final InputStreamSource inputStreamSource, final String contentType, final String name) {
return new DataSource() {
public InputStream getInputStream() throws IOException {