001: /*
002: * Copyright 2001-2005 The Apache Software Foundation
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016: package org.apache.commons.mail;
017:
018: import java.io.File;
019: import java.io.IOException;
020: import java.io.InputStream;
021: import java.net.URL;
022:
023: import javax.activation.DataHandler;
024: import javax.activation.DataSource;
025: import javax.activation.FileDataSource;
026: import javax.activation.URLDataSource;
027: import javax.mail.BodyPart;
028: import javax.mail.MessagingException;
029: import javax.mail.internet.MimeBodyPart;
030: import javax.mail.internet.MimeMultipart;
031: import javax.mail.internet.MimePart;
032:
033: /**
034: * A multipart email.
035: *
036: * <p>This class is used to send multi-part internet email like
037: * messages with attachments.
038: *
039: * <p>To create a multi-part email, call the default constructor and
040: * then you can call setMsg() to set the message and call the
041: * different attach() methods.
042: *
043: * @since 1.0
044: * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
045: * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
046: * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
047: * @author <a href="mailto:bmclaugh@algx.net">Brett McLaughlin</a>
048: * @author <a href="mailto:unknown">Regis Koenig</a>
049: * @author <a href="mailto:corey.scott@gmail.com">Corey Scott</a>
050: * @version $Id: MultiPartEmail.java 279285 2005-09-07 09:52:44Z henning $
051: */
052: public class MultiPartEmail extends Email {
053: /** Body portion of the email. */
054: private MimeMultipart container;
055:
056: /** The message container. */
057: private BodyPart primaryBodyPart = null;
058:
059: /** The MIME subtype. */
060: private String subType;
061:
062: /** Indicates if the message has been initialized */
063: private boolean initialized;
064:
065: /** Indicates if attachments have been added to the message */
066: private boolean boolHasAttachments;
067:
068: /**
069: * Set the MIME subtype of the email.
070: *
071: * @param aSubType MIME subtype of the email
072: * @since 1.0
073: */
074: public void setSubType(String aSubType) {
075: this .subType = aSubType;
076: }
077:
078: /**
079: * Get the MIME subtype of the email.
080: *
081: * @return MIME subtype of the email
082: * @since 1.0
083: */
084: public String getSubType() {
085: return subType;
086: }
087:
088: /**
089: * Add a new part to the email.
090: *
091: * @param partContent The content.
092: * @param partContentType The content type.
093: * @return An Email.
094: * @throws EmailException see javax.mail.internet.MimeBodyPart
095: * for definitions
096: * @since 1.0
097: */
098: public Email addPart(String partContent, String partContentType)
099: throws EmailException {
100: BodyPart bodyPart = createBodyPart();
101: try {
102: bodyPart.setContent(partContent, partContentType);
103: getContainer().addBodyPart(bodyPart);
104: } catch (MessagingException me) {
105: throw new EmailException(me);
106: }
107:
108: return this ;
109: }
110:
111: /**
112: * Add a new part to the email.
113: *
114: * @param multipart The MimeMultipart.
115: * @return An Email.
116: * @throws EmailException see javax.mail.internet.MimeBodyPart
117: * for definitions
118: * @since 1.0
119: */
120: public Email addPart(MimeMultipart multipart) throws EmailException {
121: try {
122: return addPart(multipart, getContainer().getCount());
123: } catch (MessagingException me) {
124: throw new EmailException(me);
125: }
126: }
127:
128: /**
129: * Add a new part to the email.
130: *
131: * @param multipart The part to add.
132: * @param index The index to add at.
133: * @return The email.
134: * @throws EmailException An error occured while adding the part.
135: * @since 1.0
136: */
137: public Email addPart(MimeMultipart multipart, int index)
138: throws EmailException {
139: BodyPart bodyPart = createBodyPart();
140: try {
141: bodyPart.setContent(multipart);
142: getContainer().addBodyPart(bodyPart, index);
143: } catch (MessagingException me) {
144: throw new EmailException(me);
145: }
146:
147: return this ;
148: }
149:
150: /**
151: * Initialize the multipart email.
152: * @since 1.0
153: */
154: protected void init() {
155: if (initialized) {
156: throw new IllegalStateException("Already initialized");
157: }
158:
159: container = createMimeMultipart();
160: super .setContent(container);
161:
162: initialized = true;
163: }
164:
165: /**
166: * Set the message of the email.
167: *
168: * @param msg A String.
169: * @return An Email.
170: * @throws EmailException see javax.mail.internet.MimeBodyPart
171: * for definitions
172: * @since 1.0
173: */
174: public Email setMsg(String msg) throws EmailException {
175: // throw exception on null message
176: if (EmailUtils.isEmpty(msg)) {
177: throw new EmailException("Invalid message supplied");
178: }
179: try {
180: BodyPart primary = getPrimaryBodyPart();
181:
182: if ((primary instanceof MimePart)
183: && EmailUtils.isNotEmpty(charset)) {
184: ((MimePart) primary).setText(msg, charset);
185: } else {
186: primary.setText(msg);
187: }
188: } catch (MessagingException me) {
189: throw new EmailException(me);
190: }
191: return this ;
192: }
193:
194: /**
195: * Builds the actual MimeMessage
196: *
197: * @throws EmailException see javax.mail.internet.MimeBodyPart
198: * for definitions
199: * @since 1.0
200: */
201: public void buildMimeMessage() throws EmailException {
202: try {
203: if (primaryBodyPart != null) {
204: // before a multipart message can be sent, we must make sure that
205: // the content for the main body part was actually set. If not,
206: // an IOException will be thrown during super.send().
207:
208: BodyPart body = this .getPrimaryBodyPart();
209: try {
210: body.getContent();
211: } catch (IOException e) {
212: // do nothing here. content will be set to an empty string
213: // as a result.
214: }
215: }
216:
217: if (subType != null) {
218: getContainer().setSubType(subType);
219: }
220:
221: super .buildMimeMessage();
222: } catch (MessagingException me) {
223: throw new EmailException(me);
224: }
225: }
226:
227: /**
228: * Attach an EmailAttachment.
229: *
230: * @param attachment An EmailAttachment.
231: * @return A MultiPartEmail.
232: * @throws EmailException see javax.mail.internet.MimeBodyPart
233: * for definitions
234: * @since 1.0
235: */
236: public MultiPartEmail attach(EmailAttachment attachment)
237: throws EmailException {
238: MultiPartEmail result = null;
239:
240: if (attachment == null) {
241: throw new EmailException("Invalid attachment supplied");
242: }
243:
244: URL url = attachment.getURL();
245:
246: if (url == null) {
247: String fileName = null;
248: try {
249: fileName = attachment.getPath();
250: File file = new File(fileName);
251: if (!file.exists()) {
252: throw new IOException("\"" + fileName
253: + "\" does not exist");
254: }
255: result = attach(new FileDataSource(file), attachment
256: .getName(), attachment.getDescription(),
257: attachment.getDisposition());
258: } catch (Exception e) {
259: throw new EmailException("Cannot attach file \""
260: + fileName + "\"", e);
261: }
262: } else {
263: result = attach(url, attachment.getName(), attachment
264: .getDescription(), attachment.getDisposition());
265: }
266:
267: return result;
268: }
269:
270: /**
271: * Attach a file located by its URL. The disposition of the file
272: * is set to mixed.
273: *
274: * @param url The URL of the file (may be any valid URL).
275: * @param name The name field for the attachment.
276: * @param description A description for the attachment.
277: * @return A MultiPartEmail.
278: * @throws EmailException see javax.mail.internet.MimeBodyPart
279: * for definitions
280: * @since 1.0
281: */
282: public MultiPartEmail attach(URL url, String name,
283: String description) throws EmailException {
284: return attach(url, name, description,
285: EmailAttachment.ATTACHMENT);
286: }
287:
288: /**
289: * Attach a file located by its URL.
290: *
291: * @param url The URL of the file (may be any valid URL).
292: * @param name The name field for the attachment.
293: * @param description A description for the attachment.
294: * @param disposition Either mixed or inline.
295: * @return A MultiPartEmail.
296: * @throws EmailException see javax.mail.internet.MimeBodyPart
297: * for definitions
298: * @since 1.0
299: */
300: public MultiPartEmail attach(URL url, String name,
301: String description, String disposition)
302: throws EmailException {
303: // verify that the URL is valid
304: try {
305: InputStream is = url.openStream();
306: is.close();
307: } catch (IOException e) {
308: throw new EmailException("Invalid URL set");
309: }
310:
311: return attach(new URLDataSource(url), name, description,
312: disposition);
313: }
314:
315: /**
316: * Attach a file specified as a DataSource interface.
317: *
318: * @param ds A DataSource interface for the file.
319: * @param name The name field for the attachment.
320: * @param description A description for the attachment.
321: * @return A MultiPartEmail.
322: * @throws EmailException see javax.mail.internet.MimeBodyPart
323: * for definitions
324: * @since 1.0
325: */
326: public MultiPartEmail attach(DataSource ds, String name,
327: String description) throws EmailException {
328: // verify that the DataSource is valid
329: try {
330: if (ds == null || ds.getInputStream() == null) {
331: throw new EmailException("Invalid Datasource");
332: }
333: } catch (IOException e) {
334: throw new EmailException("Invalid Datasource");
335: }
336:
337: return attach(ds, name, description, EmailAttachment.ATTACHMENT);
338: }
339:
340: /**
341: * Attach a file specified as a DataSource interface.
342: *
343: * @param ds A DataSource interface for the file.
344: * @param name The name field for the attachment.
345: * @param description A description for the attachment.
346: * @param disposition Either mixed or inline.
347: * @return A MultiPartEmail.
348: * @throws EmailException see javax.mail.internet.MimeBodyPart
349: * for definitions
350: * @since 1.0
351: */
352: public MultiPartEmail attach(DataSource ds, String name,
353: String description, String disposition)
354: throws EmailException {
355: if (EmailUtils.isEmpty(name)) {
356: name = ds.getName();
357: }
358: BodyPart bodyPart = createBodyPart();
359: try {
360: getContainer().addBodyPart(bodyPart);
361:
362: bodyPart.setDisposition(disposition);
363: bodyPart.setFileName(name);
364: bodyPart.setDescription(description);
365: bodyPart.setDataHandler(new DataHandler(ds));
366: } catch (MessagingException me) {
367: throw new EmailException(me);
368: }
369: setBoolHasAttachments(true);
370:
371: return this ;
372: }
373:
374: /**
375: * Gets first body part of the message.
376: *
377: * @return The primary body part.
378: * @throws MessagingException An error occured while getting the primary body part.
379: * @since 1.0
380: */
381: protected BodyPart getPrimaryBodyPart() throws MessagingException {
382: if (!initialized) {
383: init();
384: }
385:
386: // Add the first body part to the message. The fist body part must be
387: if (this .primaryBodyPart == null) {
388: primaryBodyPart = createBodyPart();
389: getContainer().addBodyPart(primaryBodyPart, 0);
390: }
391:
392: return primaryBodyPart;
393: }
394:
395: /**
396: * Gets the message container.
397: *
398: * @return The message container.
399: * @since 1.0
400: */
401: protected MimeMultipart getContainer() {
402: if (!initialized) {
403: init();
404: }
405: return container;
406: }
407:
408: /**
409: * Method that can be overridden if you don't
410: * want to create a MimeBodyPart.
411: * @return
412: */
413: protected BodyPart createBodyPart() {
414: BodyPart bodyPart = new MimeBodyPart();
415: return bodyPart;
416: }
417:
418: /**
419: *
420: * @return
421: */
422: protected MimeMultipart createMimeMultipart() {
423: MimeMultipart mmp = new MimeMultipart();
424: return mmp;
425: }
426:
427: /**
428: * @return boolHasAttachments
429: * @since 1.0
430: */
431: public boolean isBoolHasAttachments() {
432: return boolHasAttachments;
433: }
434:
435: /**
436: * @param b boolHasAttachments
437: * @since 1.0
438: */
439: public void setBoolHasAttachments(boolean b) {
440: boolHasAttachments = b;
441: }
442:
443: /**
444: *
445: * @return
446: */
447: protected boolean isInitialized() {
448: return initialized;
449: }
450:
451: /**
452: *
453: * @param b
454: */
455: protected void setInitialized(boolean b) {
456: initialized = b;
457: }
458:
459: }
|