11/*
2- * Copyright 2002-2010 the original author or authors.
2+ * Copyright 2002-2013 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
3535import javax .mail .internet .MimeMessage ;
3636import javax .mail .internet .MimeMultipart ;
3737import javax .mail .internet .MimePart ;
38+ import javax .mail .internet .MimeUtility ;
3839
3940import org .springframework .core .io .InputStreamSource ;
4041import org .springframework .core .io .Resource ;
@@ -241,7 +242,7 @@ public MimeMessageHelper(MimeMessage mimeMessage, boolean multipart) throws Mess
241242 * @see #MimeMessageHelper(javax.mail.internet.MimeMessage, int, String)
242243 */
243244 public MimeMessageHelper (MimeMessage mimeMessage , boolean multipart , String encoding )
244- throws MessagingException {
245+ throws MessagingException {
245246
246247 this (mimeMessage , (multipart ? MULTIPART_MODE_MIXED_RELATED : MULTIPART_MODE_NO ), encoding );
247248 }
@@ -283,7 +284,7 @@ public MimeMessageHelper(MimeMessage mimeMessage, int multipartMode) throws Mess
283284 * @see #MULTIPART_MODE_MIXED_RELATED
284285 */
285286 public MimeMessageHelper (MimeMessage mimeMessage , int multipartMode , String encoding )
286- throws MessagingException {
287+ throws MessagingException {
287288
288289 this .mimeMessage = mimeMessage ;
289290 createMimeMultiparts (mimeMessage , multipartMode );
@@ -355,7 +356,7 @@ protected void createMimeMultiparts(MimeMessage mimeMessage, int multipartMode)
355356 /**
356357 * Set the given MimeMultipart objects for use by this MimeMessageHelper.
357358 * @param root the root MimeMultipart object, which attachments will be added to;
358- * or < code> null</code> to indicate no multipart at all
359+ * or {@ code null} to indicate no multipart at all
359360 * @param main the main MimeMultipart object, which text(s) and inline elements
360361 * will be added to (can be the same as the root multipart object, or an element
361362 * nested underneath the root multipart element)
@@ -380,8 +381,8 @@ public final boolean isMultipart() {
380381 private void checkMultipart () throws IllegalStateException {
381382 if (!isMultipart ()) {
382383 throw new IllegalStateException ("Not in multipart mode - " +
383- "create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag " +
384- "if you need to set alternative texts or add inline elements or attachments." );
384+ "create an appropriate MimeMessageHelper via a constructor that takes a 'multipart' flag " +
385+ "if you need to set alternative texts or add inline elements or attachments." );
385386 }
386387 }
387388
@@ -420,7 +421,7 @@ public final MimeMultipart getMimeMultipart() throws IllegalStateException {
420421 * Determine the default encoding for the given MimeMessage.
421422 * @param mimeMessage the passed-in MimeMessage
422423 * @return the default encoding associated with the MimeMessage,
423- * or < code> null</code> if none found
424+ * or {@ code null} if none found
424425 */
425426 protected String getDefaultEncoding (MimeMessage mimeMessage ) {
426427 if (mimeMessage instanceof SmartMimeMessage ) {
@@ -456,12 +457,12 @@ protected FileTypeMap getDefaultFileTypeMap(MimeMessage mimeMessage) {
456457 }
457458
458459 /**
459- * Set the Java Activation Framework < code> FileTypeMap</code> to use
460+ * Set the Java Activation Framework {@ code FileTypeMap} to use
460461 * for determining the content type of inline content and attachments
461462 * that get added to the message.
462- * <p>Default is the < code> FileTypeMap</code> that the underlying
463+ * <p>Default is the {@ code FileTypeMap} that the underlying
463464 * MimeMessage carries, if any, or the Activation Framework's default
464- * < code> FileTypeMap</code> instance else.
465+ * {@ code FileTypeMap} instance else.
465466 * @see #addInline
466467 * @see #addAttachment
467468 * @see #getDefaultFileTypeMap(javax.mail.internet.MimeMessage)
@@ -474,7 +475,7 @@ public void setFileTypeMap(FileTypeMap fileTypeMap) {
474475 }
475476
476477 /**
477- * Return the < code> FileTypeMap</code> used by this MimeMessageHelper.
478+ * Return the {@ code FileTypeMap} used by this MimeMessageHelper.
478479 */
479480 public FileTypeMap getFileTypeMap () {
480481 return this .fileTypeMap ;
@@ -485,7 +486,7 @@ public FileTypeMap getFileTypeMap() {
485486 * Set whether to validate all addresses which get passed to this helper.
486487 * Default is "false".
487488 * <p>Note that this is by default just available for JavaMail >= 1.3.
488- * You can override the default < code> validateAddress method</code> for
489+ * You can override the default {@ code validateAddress method} for
489490 * validation on older JavaMail versions (or for custom validation).
490491 * @see #validateAddress
491492 */
@@ -503,7 +504,7 @@ public boolean isValidateAddresses() {
503504 /**
504505 * Validate the given mail address.
505506 * Called by all of MimeMessageHelper's address setters and adders.
506- * <p>Default implementation invokes < code> InternetAddress.validate()</code> ,
507+ * <p>Default implementation invokes {@ code InternetAddress.validate()} ,
507508 * provided that address validation is activated for the helper instance.
508509 * <p>Note that this method will just work on JavaMail >= 1.3. You can override
509510 * it for validation on older JavaMail versions or for custom validation.
@@ -546,7 +547,7 @@ public void setFrom(String from) throws MessagingException {
546547 public void setFrom (String from , String personal ) throws MessagingException , UnsupportedEncodingException {
547548 Assert .notNull (from , "From address must not be null" );
548549 setFrom (getEncoding () != null ?
549- new InternetAddress (from , personal , getEncoding ()) : new InternetAddress (from , personal ));
550+ new InternetAddress (from , personal , getEncoding ()) : new InternetAddress (from , personal ));
550551 }
551552
552553 public void setReplyTo (InternetAddress replyTo ) throws MessagingException {
@@ -608,8 +609,8 @@ public void addTo(String to) throws MessagingException {
608609 public void addTo (String to , String personal ) throws MessagingException , UnsupportedEncodingException {
609610 Assert .notNull (to , "To address must not be null" );
610611 addTo (getEncoding () != null ?
611- new InternetAddress (to , personal , getEncoding ()) :
612- new InternetAddress (to , personal ));
612+ new InternetAddress (to , personal , getEncoding ()) :
613+ new InternetAddress (to , personal ));
613614 }
614615
615616
@@ -653,8 +654,8 @@ public void addCc(String cc) throws MessagingException {
653654 public void addCc (String cc , String personal ) throws MessagingException , UnsupportedEncodingException {
654655 Assert .notNull (cc , "Cc address must not be null" );
655656 addCc (getEncoding () != null ?
656- new InternetAddress (cc , personal , getEncoding ()) :
657- new InternetAddress (cc , personal ));
657+ new InternetAddress (cc , personal , getEncoding ()) :
658+ new InternetAddress (cc , personal ));
658659 }
659660
660661
@@ -698,8 +699,8 @@ public void addBcc(String bcc) throws MessagingException {
698699 public void addBcc (String bcc , String personal ) throws MessagingException , UnsupportedEncodingException {
699700 Assert .notNull (bcc , "Bcc address must not be null" );
700701 addBcc (getEncoding () != null ?
701- new InternetAddress (bcc , personal , getEncoding ()) :
702- new InternetAddress (bcc , personal ));
702+ new InternetAddress (bcc , personal , getEncoding ()) :
703+ new InternetAddress (bcc , personal ));
703704 }
704705
705706 private InternetAddress parseAddress (String address ) throws MessagingException {
@@ -730,7 +731,7 @@ public void setPriority(int priority) throws MessagingException {
730731
731732 /**
732733 * Set the sent-date of the message.
733- * @param sentDate the date to set (never < code> null</code> )
734+ * @param sentDate the date to set (never {@ code null} )
734735 * @throws MessagingException in case of errors
735736 */
736737 public void setSentDate (Date sentDate ) throws MessagingException {
@@ -758,7 +759,7 @@ public void setSubject(String subject) throws MessagingException {
758759 * Set the given text directly as content in non-multipart mode
759760 * or as default body part in multipart mode.
760761 * Always applies the default content type "text/plain".
761- * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> < code> setText</code> ;
762+ * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> {@ code setText} ;
762763 * else, mail readers might not be able to resolve inline references correctly.
763764 * @param text the text for the message
764765 * @throws MessagingException in case of errors
@@ -771,7 +772,7 @@ public void setText(String text) throws MessagingException {
771772 * Set the given text directly as content in non-multipart mode
772773 * or as default body part in multipart mode.
773774 * The "html" flag determines the content type to apply.
774- * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> < code> setText</code> ;
775+ * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> {@ code setText} ;
775776 * else, mail readers might not be able to resolve inline references correctly.
776777 * @param text the text for the message
777778 * @param html whether to apply content type "text/html" for an
@@ -798,7 +799,7 @@ public void setText(String text, boolean html) throws MessagingException {
798799 /**
799800 * Set the given plain text and HTML text as alternatives, offering
800801 * both options to the email client. Requires multipart mode.
801- * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> < code> setText</code> ;
802+ * <p><b>NOTE:</b> Invoke {@link #addInline} <i>after</i> {@ code setText} ;
802803 * else, mail readers might not be able to resolve inline references correctly.
803804 * @param plainText the plain text for the message
804805 * @param htmlText the HTML text for the message
@@ -860,16 +861,16 @@ private void setHtmlTextToMimePart(MimePart mimePart, String text) throws Messag
860861
861862 /**
862863 * Add an inline element to the MimeMessage, taking the content from a
863- * < code> javax.activation.DataSource</code> .
864+ * {@ code javax.activation.DataSource} .
864865 * <p>Note that the InputStream returned by the DataSource implementation
865866 * needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
866- * < code> getInputStream()</code> multiple times.
867- * <p><b>NOTE:</b> Invoke < code> addInline</code> <i>after</i> {@link #setText};
867+ * {@ code getInputStream()} multiple times.
868+ * <p><b>NOTE:</b> Invoke {@ code addInline} <i>after</i> {@link #setText};
868869 * else, mail readers might not be able to resolve inline references correctly.
869870 * @param contentId the content ID to use. Will end up as "Content-ID" header
870871 * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
871872 * Can be referenced in HTML source via src="cid:myId" expressions.
872- * @param dataSource the < code> javax.activation.DataSource</code> to take
873+ * @param dataSource the {@ code javax.activation.DataSource} to take
873874 * the content from, determining the InputStream and the content type
874875 * @throws MessagingException in case of errors
875876 * @see #addInline(String, java.io.File)
@@ -889,11 +890,11 @@ public void addInline(String contentId, DataSource dataSource) throws MessagingE
889890
890891 /**
891892 * Add an inline element to the MimeMessage, taking the content from a
892- * < code> java.io.File</code> .
893+ * {@ code java.io.File} .
893894 * <p>The content type will be determined by the name of the given
894895 * content file. Do not use this for temporary files with arbitrary
895896 * filenames (possibly ending in ".tmp" or the like)!
896- * <p><b>NOTE:</b> Invoke < code> addInline</code> <i>after</i> {@link #setText};
897+ * <p><b>NOTE:</b> Invoke {@ code addInline} <i>after</i> {@link #setText};
897898 * else, mail readers might not be able to resolve inline references correctly.
898899 * @param contentId the content ID to use. Will end up as "Content-ID" header
899900 * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
@@ -913,14 +914,14 @@ public void addInline(String contentId, File file) throws MessagingException {
913914
914915 /**
915916 * Add an inline element to the MimeMessage, taking the content from a
916- * < code> org.springframework.core.io.Resource</code> .
917+ * {@ code org.springframework.core.io.Resource} .
917918 * <p>The content type will be determined by the name of the given
918919 * content file. Do not use this for temporary files with arbitrary
919920 * filenames (possibly ending in ".tmp" or the like)!
920921 * <p>Note that the InputStream returned by the Resource implementation
921922 * needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
922- * < code> getInputStream()</code> multiple times.
923- * <p><b>NOTE:</b> Invoke < code> addInline</code> <i>after</i> {@link #setText};
923+ * {@ code getInputStream()} multiple times.
924+ * <p><b>NOTE:</b> Invoke {@ code addInline} <i>after</i> {@link #setText};
924925 * else, mail readers might not be able to resolve inline references correctly.
925926 * @param contentId the content ID to use. Will end up as "Content-ID" header
926927 * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
@@ -939,14 +940,14 @@ public void addInline(String contentId, Resource resource) throws MessagingExcep
939940
940941 /**
941942 * Add an inline element to the MimeMessage, taking the content from an
942- * < code> org.springframework.core.InputStreamResource</code> , and
943+ * {@ code org.springframework.core.InputStreamResource} , and
943944 * specifying the content type explicitly.
944945 * <p>You can determine the content type for any given filename via a Java
945946 * Activation Framework's FileTypeMap, for example the one held by this helper.
946947 * <p>Note that the InputStream returned by the InputStreamSource implementation
947948 * needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
948- * < code> getInputStream()</code> multiple times.
949- * <p><b>NOTE:</b> Invoke < code> addInline</code> <i>after</i> < code> setText</code> ;
949+ * {@ code getInputStream()} multiple times.
950+ * <p><b>NOTE:</b> Invoke {@ code addInline} <i>after</i> {@ code setText} ;
950951 * else, mail readers might not be able to resolve inline references correctly.
951952 * @param contentId the content ID to use. Will end up as "Content-ID" header
952953 * in the body part, surrounded by angle brackets: e.g. "myId" -> "<myId>".
@@ -960,7 +961,7 @@ public void addInline(String contentId, Resource resource) throws MessagingExcep
960961 * @see #addInline(String, javax.activation.DataSource)
961962 */
962963 public void addInline (String contentId , InputStreamSource inputStreamSource , String contentType )
963- throws MessagingException {
964+ throws MessagingException {
964965
965966 Assert .notNull (inputStreamSource , "InputStreamSource must not be null" );
966967 if (inputStreamSource instanceof Resource && ((Resource ) inputStreamSource ).isOpen ()) {
@@ -974,13 +975,13 @@ public void addInline(String contentId, InputStreamSource inputStreamSource, Str
974975
975976 /**
976977 * Add an attachment to the MimeMessage, taking the content from a
977- * < code> javax.activation.DataSource</code> .
978+ * {@ code javax.activation.DataSource} .
978979 * <p>Note that the InputStream returned by the DataSource implementation
979980 * needs to be a <i>fresh one on each call</i>, as JavaMail will invoke
980- * < code> getInputStream()</code> multiple times.
981+ * {@ code getInputStream()} multiple times.
981982 * @param attachmentFilename the name of the attachment as it will
982983 * appear in the mail (the content type will be determined by this)
983- * @param dataSource the < code> javax.activation.DataSource</code> to take
984+ * @param dataSource the {@ code javax.activation.DataSource} to take
984985 * the content from, determining the InputStream and the content type
985986 * @throws MessagingException in case of errors
986987 * @see #addAttachment(String, org.springframework.core.io.InputStreamSource)
@@ -989,16 +990,21 @@ public void addInline(String contentId, InputStreamSource inputStreamSource, Str
989990 public void addAttachment (String attachmentFilename , DataSource dataSource ) throws MessagingException {
990991 Assert .notNull (attachmentFilename , "Attachment filename must not be null" );
991992 Assert .notNull (dataSource , "DataSource must not be null" );
992- MimeBodyPart mimeBodyPart = new MimeBodyPart ();
993- mimeBodyPart .setDisposition (MimeBodyPart .ATTACHMENT );
994- mimeBodyPart .setFileName (attachmentFilename );
995- mimeBodyPart .setDataHandler (new DataHandler (dataSource ));
996- getRootMimeMultipart ().addBodyPart (mimeBodyPart );
993+ try {
994+ MimeBodyPart mimeBodyPart = new MimeBodyPart ();
995+ mimeBodyPart .setDisposition (MimeBodyPart .ATTACHMENT );
996+ mimeBodyPart .setFileName (MimeUtility .encodeText (attachmentFilename ));
997+ mimeBodyPart .setDataHandler (new DataHandler (dataSource ));
998+ getRootMimeMultipart ().addBodyPart (mimeBodyPart );
999+ }
1000+ catch (UnsupportedEncodingException ex ) {
1001+ throw new MessagingException ("Failed to encode attachment filename" , ex );
1002+ }
9971003 }
9981004
9991005 /**
10001006 * Add an attachment to the MimeMessage, taking the content from a
1001- * < code> java.io.File</code> .
1007+ * {@ code java.io.File} .
10021008 * <p>The content type will be determined by the name of the given
10031009 * content file. Do not use this for temporary files with arbitrary
10041010 * filenames (possibly ending in ".tmp" or the like)!
@@ -1018,13 +1024,13 @@ public void addAttachment(String attachmentFilename, File file) throws Messaging
10181024
10191025 /**
10201026 * Add an attachment to the MimeMessage, taking the content from an
1021- * < code> org.springframework.core.io.InputStreamResource</code> .
1027+ * {@ code org.springframework.core.io.InputStreamResource} .
10221028 * <p>The content type will be determined by the given filename for
10231029 * the attachment. Thus, any content source will be fine, including
10241030 * temporary files with arbitrary filenames.
10251031 * <p>Note that the InputStream returned by the InputStreamSource
10261032 * implementation needs to be a <i>fresh one on each call</i>, as
1027- * JavaMail will invoke < code> getInputStream()</code> multiple times.
1033+ * JavaMail will invoke {@ code getInputStream()} multiple times.
10281034 * @param attachmentFilename the name of the attachment as it will
10291035 * appear in the mail
10301036 * @param inputStreamSource the resource to take the content from
@@ -1035,18 +1041,18 @@ public void addAttachment(String attachmentFilename, File file) throws Messaging
10351041 * @see org.springframework.core.io.Resource
10361042 */
10371043 public void addAttachment (String attachmentFilename , InputStreamSource inputStreamSource )
1038- throws MessagingException {
1044+ throws MessagingException {
10391045
10401046 String contentType = getFileTypeMap ().getContentType (attachmentFilename );
10411047 addAttachment (attachmentFilename , inputStreamSource , contentType );
10421048 }
10431049
10441050 /**
10451051 * Add an attachment to the MimeMessage, taking the content from an
1046- * < code> org.springframework.core.io.InputStreamResource</code> .
1052+ * {@ code org.springframework.core.io.InputStreamResource} .
10471053 * <p>Note that the InputStream returned by the InputStreamSource
10481054 * implementation needs to be a <i>fresh one on each call</i>, as
1049- * JavaMail will invoke < code> getInputStream()</code> multiple times.
1055+ * JavaMail will invoke {@ code getInputStream()} multiple times.
10501056 * @param attachmentFilename the name of the attachment as it will
10511057 * appear in the mail
10521058 * @param inputStreamSource the resource to take the content from
@@ -1059,7 +1065,7 @@ public void addAttachment(String attachmentFilename, InputStreamSource inputStre
10591065 */
10601066 public void addAttachment (
10611067 String attachmentFilename , InputStreamSource inputStreamSource , String contentType )
1062- throws MessagingException {
1068+ throws MessagingException {
10631069
10641070 Assert .notNull (inputStreamSource , "InputStreamSource must not be null" );
10651071 if (inputStreamSource instanceof Resource && ((Resource ) inputStreamSource ).isOpen ()) {
@@ -1079,7 +1085,7 @@ public void addAttachment(
10791085 * @return the Activation Framework DataSource
10801086 */
10811087 protected DataSource createDataSource (
1082- final InputStreamSource inputStreamSource , final String contentType , final String name ) {
1088+ final InputStreamSource inputStreamSource , final String contentType , final String name ) {
10831089
10841090 return new DataSource () {
10851091 public InputStream getInputStream () throws IOException {
0 commit comments