Source code: org/mentawai/mail/HtmlEmail.java
1 /*
2 * Copyright 2001-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.mentawai.mail;
17
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.net.URL;
22 import java.util.ArrayList;
23 import java.util.Iterator;
24 import java.util.List;
25
26 import javax.activation.DataHandler;
27 import javax.activation.URLDataSource;
28 import javax.mail.BodyPart;
29 import javax.mail.MessagingException;
30 import javax.mail.internet.MimeBodyPart;
31 import javax.mail.internet.MimeMultipart;
32
33 // Revision: 191951
34
35 /**
36 * An HTML multipart email.
37 *
38 * <p>This class is used to send HTML formatted email. A text message
39 * can also be set for HTML unaware email clients, such as text-based
40 * email clients.
41 *
42 * <p>This class also inherits from MultiPartEmail, so it is easy to
43 * add attachents to the email.
44 *
45 * <p>To send an email in HTML, one should create a HtmlEmail, then
46 * use the setFrom, addTo, etc. methods. The HTML content can be set
47 * with the setHtmlMsg method. The alternate text content can be set
48 * with setTextMsg.
49 *
50 * <p>Either the text or HTML can be omitted, in which case the "main"
51 * part of the multipart becomes whichever is supplied rather than a
52 * multipart/alternative.
53 *
54 * @author <a href="mailto:unknown">Regis Koenig</a>
55 * @author <a href="mailto:sean@informage.net">Sean Legassick</a>
56 * @version $Id: HtmlEmail.java,v 1.3 2005/07/29 21:23:16 soliveira Exp $
57 */
58 public class HtmlEmail extends MultiPartEmail {
59
60 /** Defintion of the length of generated CID's */
61 public static final int CID_LENGTH = 10;
62
63 /**
64 * Text part of the message. This will be used as alternative text if
65 * the email client does not support HTML messages.
66 */
67 protected String text;
68
69 /** Html part of the message */
70 protected String html;
71
72 /** Embeded images */
73 protected List inlineImages = new ArrayList();
74
75 public HtmlEmail() {
76 super();
77 }
78
79 /**
80 * Set the text content.
81 *
82 * @param aText A String.
83 * @return An HtmlEmail.
84 * @throws EmailException see javax.mail.internet.MimeBodyPart
85 * for defintions
86 */
87 public HtmlEmail setTextMsg(String aText) throws EmailException {
88 if (StringUtils.isEmpty(aText)) {
89 throw new EmailException("Invalid message supplied");
90 }
91
92 this.text = aText;
93 return this;
94 }
95
96 /**
97 * Set the HTML content.
98 *
99 * @param aHtml A String.
100 * @return An HtmlEmail.
101 * @throws EmailException see javax.mail.internet.MimeBodyPart
102 * for defintions
103 */
104 public HtmlEmail setHtmlMsg(String aHtml) throws EmailException {
105 if (StringUtils.isEmpty(aHtml)) {
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 defintions
126 */
127 public Email setMsg(String msg) throws EmailException {
128 if (StringUtils.isEmpty(msg)) {
129 throw new EmailException("Invalid message supplied");
130 }
131
132 setTextMsg(msg);
133
134 setHtmlMsg(
135 new StringBuffer().append("<html><body><pre>").append(msg).append("</pre></body></html>").toString());
136
137 return this;
138 }
139
140 /**
141 * Embeds an URL in the HTML.
142 *
143 * <p>This method allows to embed a file located by an URL into
144 * the mail body. It allows, for instance, to add inline images
145 * to the email. Inline files may be referenced with a
146 * <code>cid:xxxxxx</code> URL, where xxxxxx is the Content-ID
147 * returned by the embed function.
148 *
149 * <p>Example of use:<br><code><pre>
150 * HtmlEmail he = new HtmlEmail();
151 * he.setHtmlMsg("<html><img src=cid:" +
152 * embed("file:/my/image.gif","image.gif") +
153 * "></html>");
154 * // code to set the others email fields (not shown)
155 * </pre></code>
156 *
157 * @param url The URL of the file.
158 * @param name The name that will be set in the filename header
159 * field.
160 * @return A String with the Content-ID of the file.
161 * @throws EmailException when URL suplpied is invalid
162 * also see javax.mail.internet.MimeBodyPart for defintions
163 */
164 public String embed(URL url, String name) throws EmailException {
165 // verify that the URL is valid
166 try {
167 InputStream is = url.openStream();
168
169 is.close();
170 } catch (IOException e) {
171 throw new EmailException("Invalid URL");
172 }
173
174 MimeBodyPart mbp = new MimeBodyPart();
175
176 try {
177 mbp.setDataHandler(new DataHandler(new URLDataSource(url)));
178 mbp.setFileName(name);
179 mbp.setDisposition("inline");
180 String cid = RandomStringUtils.randomAlphabetic(HtmlEmail.CID_LENGTH).toLowerCase();
181
182 mbp.addHeader("Content-ID", "<" + cid + ">");
183 this.inlineImages.add(mbp);
184 return cid;
185 } catch (MessagingException me) {
186 throw new EmailException(me);
187 }
188 }
189
190 /**
191 * Does the work of actually sending the email.
192 *
193 * @exception EmailException if there was an error.
194 */
195 public void send() throws EmailException {
196 try {
197 // if the email has attachments then the base type is mixed,
198 // otherwise it should be related
199 if (this.isBoolHasAttachments()) {
200 this.buildAttachments();
201 } else {
202 this.buildNoAttachments();
203 }
204
205 } catch (MessagingException me) {
206 throw new EmailException(me);
207 }
208 super.send();
209 }
210
211 /**
212 * @throws EmailException EmailException
213 * @throws MessagingException MessagingException
214 */
215 private void buildAttachments() throws MessagingException, EmailException {
216 MimeMultipart container = this.getContainer();
217 MimeMultipart subContainer = null;
218 MimeMultipart subContainerHTML = new MimeMultipart("related");
219 BodyPart msgHtml = null;
220 BodyPart msgText = null;
221
222 container.setSubType("mixed");
223 subContainer = new MimeMultipart("alternative");
224
225 if (StringUtils.isNotEmpty(this.text)) {
226 msgText = new MimeBodyPart();
227 subContainer.addBodyPart(msgText);
228
229 if (StringUtils.isNotEmpty(this.charset)) {
230 msgText.setContent(
231 this.text,
232 Email.TEXT_PLAIN + "; charset=" + this.charset);
233 } else {
234 msgText.setContent(this.text, Email.TEXT_PLAIN);
235 }
236 }
237
238 if (StringUtils.isNotEmpty(this.html)) {
239 if (this.inlineImages.size() > 0) {
240 msgHtml = new MimeBodyPart();
241 subContainerHTML.addBodyPart(msgHtml);
242 } else {
243 msgHtml = new MimeBodyPart();
244 subContainer.addBodyPart(msgHtml);
245 }
246
247 if (StringUtils.isNotEmpty(this.charset)) {
248 msgHtml.setContent(
249 this.html,
250 Email.TEXT_HTML + "; charset=" + this.charset);
251 } else {
252 msgHtml.setContent(this.html, Email.TEXT_HTML);
253 }
254
255 Iterator iter = this.inlineImages.iterator();
256
257 while (iter.hasNext()) {
258 subContainerHTML.addBodyPart((BodyPart) iter.next());
259 }
260 }
261
262 // add sub containers to message
263 this.addPart(subContainer, 0);
264
265 if (this.inlineImages.size() > 0) {
266 // add sub container to message
267 this.addPart(subContainerHTML, 1);
268 }
269 }
270
271 /**
272 * @throws EmailException EmailException
273 * @throws MessagingException MessagingException
274 */
275 private void buildNoAttachments() throws MessagingException, EmailException {
276 MimeMultipart container = this.getContainer();
277 MimeMultipart subContainerHTML = new MimeMultipart("related");
278
279 container.setSubType("alternative");
280
281 BodyPart msgText = null;
282 BodyPart msgHtml = null;
283
284 if (StringUtils.isNotEmpty(this.text)) {
285 msgText = this.getPrimaryBodyPart();
286 if (StringUtils.isNotEmpty(this.charset)) {
287 msgText.setContent(
288 this.text,
289 Email.TEXT_PLAIN + "; charset=" + this.charset);
290 } else {
291 msgText.setContent(this.text, Email.TEXT_PLAIN);
292 }
293 }
294
295 if (StringUtils.isNotEmpty(this.html)) {
296 // if the txt part of the message was null, then the html part
297 // will become the primary body part
298 if (msgText == null) {
299 msgHtml = getPrimaryBodyPart();
300 } else {
301 if (this.inlineImages.size() > 0) {
302 msgHtml = new MimeBodyPart();
303 subContainerHTML.addBodyPart(msgHtml);
304 } else {
305 msgHtml = new MimeBodyPart();
306 container.addBodyPart(msgHtml, 1);
307 }
308 }
309
310 if (StringUtils.isNotEmpty(this.charset)) {
311 msgHtml.setContent(
312 this.html,
313 Email.TEXT_HTML + "; charset=" + this.charset);
314 } else {
315 msgHtml.setContent(this.html, Email.TEXT_HTML);
316 }
317
318 Iterator iter = this.inlineImages.iterator();
319
320 while (iter.hasNext()) {
321 subContainerHTML.addBodyPart((BodyPart) iter.next());
322 }
323
324 if (this.inlineImages.size() > 0) {
325 // add sub container to message
326 this.addPart(subContainerHTML);
327 }
328 }
329 }
330 }