1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.mail;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.net.URL;
21 import java.util.ArrayList;
22 import java.util.Iterator;
23 import java.util.List;
24
25 import javax.activation.DataHandler;
26 import javax.activation.URLDataSource;
27 import javax.mail.BodyPart;
28 import javax.mail.MessagingException;
29 import javax.mail.internet.MimeBodyPart;
30 import javax.mail.internet.MimeMultipart;
31
32 /***
33 * An HTML multipart email.
34 *
35 * <p>This class is used to send HTML formatted email. A text message
36 * can also be set for HTML unaware email clients, such as text-based
37 * email clients.
38 *
39 * <p>This class also inherits from MultiPartEmail, so it is easy to
40 * add attachments to the email.
41 *
42 * <p>To send an email in HTML, one should create a HtmlEmail, then
43 * use the setFrom, addTo, etc. methods. The HTML content can be set
44 * with the setHtmlMsg method. The alternative text content can be set
45 * with setTextMsg.
46 *
47 * <p>Either the text or HTML can be omitted, in which case the "main"
48 * part of the multipart becomes whichever is supplied rather than a
49 * multipart/alternative.
50 *
51 * @since 1.0
52 * @author <a href="mailto:unknown">Regis Koenig</a>
53 * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
54 * @version $Id: HtmlEmail.java 279285 2005-09-07 09:52:44Z henning $
55 */
56 public class HtmlEmail extends MultiPartEmail
57 {
58 /*** Definition of the length of generated CID's */
59 public static final int CID_LENGTH = 10;
60
61 /***
62 * Text part of the message. This will be used as alternative text if
63 * the email client does not support HTML messages.
64 */
65 protected String text;
66
67 /*** Html part of the message */
68 protected String html;
69
70 /*** Embedded images */
71 protected List inlineImages = new ArrayList();
72
73 /***
74 * Set the text content.
75 *
76 * @param aText A String.
77 * @return An HtmlEmail.
78 * @throws EmailException see javax.mail.internet.MimeBodyPart
79 * for definitions
80 * @since 1.0
81 */
82 public HtmlEmail setTextMsg(String aText) throws EmailException
83 {
84 if (EmailUtils.isEmpty(aText))
85 {
86 throw new EmailException("Invalid message supplied");
87 }
88
89 this.text = aText;
90 return this;
91 }
92
93 /***
94 * Set the HTML content.
95 *
96 * @param aHtml A String.
97 * @return An HtmlEmail.
98 * @throws EmailException see javax.mail.internet.MimeBodyPart
99 * for definitions
100 * @since 1.0
101 */
102 public HtmlEmail setHtmlMsg(String aHtml) throws EmailException
103 {
104 if (EmailUtils.isEmpty(aHtml))
105 {
106 throw new EmailException("Invalid message supplied");
107 }
108
109 this.html = aHtml;
110 return this;
111 }
112
113 /***
114 * Set the message.
115 *
116 * <p>This method overrides the MultiPartEmail setMsg() method in
117 * order to send an HTML message instead of a full text message in
118 * the mail body. The message is formatted in HTML for the HTML
119 * part of the message, it is let as is in the alternate text
120 * part.
121 *
122 * @param msg A String.
123 * @return An Email.
124 * @throws EmailException see javax.mail.internet.MimeBodyPart
125 * for definitions
126 * @since 1.0
127 */
128 public Email setMsg(String msg) throws EmailException
129 {
130 if (EmailUtils.isEmpty(msg))
131 {
132 throw new EmailException("Invalid message supplied");
133 }
134
135 setTextMsg(msg);
136
137 setHtmlMsg(
138 new StringBuffer()
139 .append("<html><body><pre>")
140 .append(msg)
141 .append("</pre></body></html>")
142 .toString());
143
144 return this;
145 }
146
147 /***
148 * Embeds an URL in the HTML.
149 *
150 * <p>This method allows to embed a file located by an URL into
151 * the mail body. It allows, for instance, to add inline images
152 * to the email. Inline files may be referenced with a
153 * <code>cid:xxxxxx</code> URL, where xxxxxx is the Content-ID
154 * returned by the embed function.
155 *
156 * <p>Example of use:<br><code><pre>
157 * HtmlEmail he = new HtmlEmail();
158 * he.setHtmlMsg("<html><img src=cid:" +
159 * embed("file:/my/image.gif","image.gif") +
160 * "></html>");
161 * // code to set the others email fields (not shown)
162 * </pre></code>
163 *
164 * @param url The URL of the file.
165 * @param name The name that will be set in the filename header
166 * field.
167 * @return A String with the Content-ID of the file.
168 * @throws EmailException when URL supplied is invalid
169 * also see javax.mail.internet.MimeBodyPart for definitions
170 * @since 1.0
171 */
172 public String embed(URL url, String name) throws EmailException
173 {
174
175 try
176 {
177 InputStream is = url.openStream();
178 is.close();
179 }
180 catch (IOException e)
181 {
182 throw new EmailException("Invalid URL");
183 }
184
185 MimeBodyPart mbp = new MimeBodyPart();
186
187 try
188 {
189 mbp.setDataHandler(new DataHandler(new URLDataSource(url)));
190 mbp.setFileName(name);
191 mbp.setDisposition("inline");
192 String cid = EmailUtils.randomAlphabetic(HtmlEmail.CID_LENGTH).toLowerCase();
193 mbp.addHeader("Content-ID", "<" + cid + ">");
194 this.inlineImages.add(mbp);
195 return cid;
196 }
197 catch (MessagingException me)
198 {
199 throw new EmailException(me);
200 }
201 }
202
203 /***
204 * Does the work of actually building the email.
205 *
206 * @exception EmailException if there was an error.
207 * @since 1.0
208 */
209 public void buildMimeMessage() throws EmailException
210 {
211 try
212 {
213
214
215 if (this.isBoolHasAttachments())
216 {
217 this.buildAttachments();
218 }
219 else
220 {
221 this.buildNoAttachments();
222 }
223
224 }
225 catch (MessagingException me)
226 {
227 throw new EmailException(me);
228 }
229 super.buildMimeMessage();
230 }
231
232 /***
233 * @throws EmailException EmailException
234 * @throws MessagingException MessagingException
235 */
236 private void buildAttachments() throws MessagingException, EmailException
237 {
238 MimeMultipart container = this.getContainer();
239 MimeMultipart subContainer = null;
240 MimeMultipart subContainerHTML = new MimeMultipart("related");
241 BodyPart msgHtml = null;
242 BodyPart msgText = null;
243
244 container.setSubType("mixed");
245 subContainer = new MimeMultipart("alternative");
246
247 if (EmailUtils.isNotEmpty(this.text))
248 {
249 msgText = new MimeBodyPart();
250 subContainer.addBodyPart(msgText);
251
252 if (EmailUtils.isNotEmpty(this.charset))
253 {
254 msgText.setContent(
255 this.text,
256 Email.TEXT_PLAIN + "; charset=" + this.charset);
257 }
258 else
259 {
260 msgText.setContent(this.text, Email.TEXT_PLAIN);
261 }
262 }
263
264 if (EmailUtils.isNotEmpty(this.html))
265 {
266 if (this.inlineImages.size() > 0)
267 {
268 msgHtml = new MimeBodyPart();
269 subContainerHTML.addBodyPart(msgHtml);
270 }
271 else
272 {
273 msgHtml = new MimeBodyPart();
274 subContainer.addBodyPart(msgHtml);
275 }
276
277 if (EmailUtils.isNotEmpty(this.charset))
278 {
279 msgHtml.setContent(
280 this.html,
281 Email.TEXT_HTML + "; charset=" + this.charset);
282 }
283 else
284 {
285 msgHtml.setContent(this.html, Email.TEXT_HTML);
286 }
287
288 Iterator iter = this.inlineImages.iterator();
289 while (iter.hasNext())
290 {
291 subContainerHTML.addBodyPart((BodyPart) iter.next());
292 }
293 }
294
295
296 this.addPart(subContainer, 0);
297
298 if (this.inlineImages.size() > 0)
299 {
300
301 this.addPart(subContainerHTML, 1);
302 }
303 }
304
305 /***
306 * @throws EmailException EmailException
307 * @throws MessagingException MessagingException
308 */
309 private void buildNoAttachments() throws MessagingException, EmailException
310 {
311 MimeMultipart container = this.getContainer();
312 MimeMultipart subContainerHTML = new MimeMultipart("related");
313
314 container.setSubType("alternative");
315
316 BodyPart msgText = null;
317 BodyPart msgHtml = null;
318
319 if (EmailUtils.isNotEmpty(this.text))
320 {
321 msgText = this.getPrimaryBodyPart();
322 if (EmailUtils.isNotEmpty(this.charset))
323 {
324 msgText.setContent(
325 this.text,
326 Email.TEXT_PLAIN + "; charset=" + this.charset);
327 }
328 else
329 {
330 msgText.setContent(this.text, Email.TEXT_PLAIN);
331 }
332 }
333
334 if (EmailUtils.isNotEmpty(this.html))
335 {
336
337
338 if (msgText == null)
339 {
340 msgHtml = getPrimaryBodyPart();
341 }
342 else
343 {
344 if (this.inlineImages.size() > 0)
345 {
346 msgHtml = new MimeBodyPart();
347 subContainerHTML.addBodyPart(msgHtml);
348 }
349 else
350 {
351 msgHtml = new MimeBodyPart();
352 container.addBodyPart(msgHtml, 1);
353 }
354 }
355
356 if (EmailUtils.isNotEmpty(this.charset))
357 {
358 msgHtml.setContent(
359 this.html,
360 Email.TEXT_HTML + "; charset=" + this.charset);
361 }
362 else
363 {
364 msgHtml.setContent(this.html, Email.TEXT_HTML);
365 }
366
367 Iterator iter = this.inlineImages.iterator();
368 while (iter.hasNext())
369 {
370 subContainerHTML.addBodyPart((BodyPart) iter.next());
371 }
372
373 if (this.inlineImages.size() > 0)
374 {
375
376 this.addPart(subContainerHTML);
377 }
378 }
379 }
380 }