/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.commons.mail;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.activation.URLDataSource;
import javax.mail.BodyPart;
import javax.mail.MessagingException;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimePart;
import javax.mail.internet.MimeUtility;

A multipart email.

This class is used to send multi-part internet email like messages with attachments.

To create a multi-part email, call the default constructor and then you can call setMsg() to set the message and call the different attach() methods.

Since:1.0
/** * A multipart email. * * <p>This class is used to send multi-part internet email like * messages with attachments. * * <p>To create a multi-part email, call the default constructor and * then you can call setMsg() to set the message and call the * different attach() methods. * * @since 1.0 */
public class MultiPartEmail extends Email {
Body portion of the email.
/** Body portion of the email. */
private MimeMultipart container;
The message container.
/** The message container. */
private BodyPart primaryBodyPart;
The MIME subtype.
/** The MIME subtype. */
private String subType;
Indicates if the message has been initialized.
/** Indicates if the message has been initialized. */
private boolean initialized;
Indicates if attachments have been added to the message.
/** Indicates if attachments have been added to the message. */
private boolean boolHasAttachments;
Set the MIME subtype of the email.
Params:
  • aSubType – MIME subtype of the email
Since:1.0
/** * Set the MIME subtype of the email. * * @param aSubType MIME subtype of the email * @since 1.0 */
public void setSubType(final String aSubType) { this.subType = aSubType; }
Get the MIME subtype of the email.
Returns:MIME subtype of the email
Since:1.0
/** * Get the MIME subtype of the email. * * @return MIME subtype of the email * @since 1.0 */
public String getSubType() { return subType; }
Add a new part to the email.
Params:
  • partContent – The content.
  • partContentType – The content type.
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions
Returns:An Email.
Since:1.0
/** * Add a new part to the email. * * @param partContent The content. * @param partContentType The content type. * @return An Email. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */
public Email addPart(final String partContent, final String partContentType) throws EmailException { final BodyPart bodyPart = createBodyPart(); try { bodyPart.setContent(partContent, partContentType); getContainer().addBodyPart(bodyPart); } catch (final MessagingException me) { throw new EmailException(me); } return this; }
Add a new part to the email.
Params:
  • multipart – The MimeMultipart.
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions @since 1.0
Returns:An Email.
/** * Add a new part to the email. * * @param multipart The MimeMultipart. * @return An Email. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */
public Email addPart(final MimeMultipart multipart) throws EmailException { try { return addPart(multipart, getContainer().getCount()); } catch (final MessagingException me) { throw new EmailException(me); } }
Add a new part to the email.
Params:
  • multipart – The part to add.
  • index – The index to add at.
Throws:
Returns:The email.
Since:1.0
/** * Add a new part to the email. * * @param multipart The part to add. * @param index The index to add at. * @return The email. * @throws EmailException An error occurred while adding the part. * @since 1.0 */
public Email addPart(final MimeMultipart multipart, final int index) throws EmailException { final BodyPart bodyPart = createBodyPart(); try { bodyPart.setContent(multipart); getContainer().addBodyPart(bodyPart, index); } catch (final MessagingException me) { throw new EmailException(me); } return this; }
Initialize the multipart email.
Since:1.0
/** * Initialize the multipart email. * @since 1.0 */
protected void init() { if (initialized) { throw new IllegalStateException("Already initialized"); } container = createMimeMultipart(); super.setContent(container); initialized = true; }
Set the message of the email.
Params:
  • msg – A String.
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions
Returns:An Email.
Since:1.0
/** * Set the message of the email. * * @param msg A String. * @return An Email. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */
@Override public Email setMsg(final String msg) throws EmailException { // throw exception on null message if (EmailUtils.isEmpty(msg)) { throw new EmailException("Invalid message supplied"); } try { final BodyPart primary = getPrimaryBodyPart(); if (primary instanceof MimePart && EmailUtils.isNotEmpty(charset)) { ((MimePart) primary).setText(msg, charset); } else { primary.setText(msg); } } catch (final MessagingException me) { throw new EmailException(me); } return this; }
Does the work of actually building the MimeMessage. Please note that a user rarely calls this method directly and only if he/she is interested in the sending the underlying MimeMessage without commons-email.
Throws:
  • EmailException – if there was an error.
Since:1.0
/** * Does the work of actually building the MimeMessage. Please note that * a user rarely calls this method directly and only if he/she is * interested in the sending the underlying MimeMessage without * commons-email. * * @throws EmailException if there was an error. * @since 1.0 */
@Override public void buildMimeMessage() throws EmailException { try { if (primaryBodyPart != null) { // before a multipart message can be sent, we must make sure that // the content for the main body part was actually set. If not, // an IOException will be thrown during super.send(). final BodyPart body = this.getPrimaryBodyPart(); try { body.getContent(); } catch (final IOException e) // NOPMD { // do nothing here. // content will be set to an empty string as a result. // (Should this really be rethrown as an email exception?) // throw new EmailException(e); } } if (subType != null) { getContainer().setSubType(subType); } super.buildMimeMessage(); } catch (final MessagingException me) { throw new EmailException(me); } }
Attach a file.
Params:
  • file – A file attachment
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions
Returns:A MultiPartEmail.
Since:1.3
/** * Attach a file. * * @param file A file attachment * @return A MultiPartEmail. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.3 */
public MultiPartEmail attach(final File file) throws EmailException { final String fileName = file.getAbsolutePath(); try { if (!file.exists()) { throw new IOException("\"" + fileName + "\" does not exist"); } final FileDataSource fds = new FileDataSource(file); return attach(fds, file.getName(), null, EmailAttachment.ATTACHMENT); } catch (final IOException e) { throw new EmailException("Cannot attach file \"" + fileName + "\"", e); } }
Attach an EmailAttachment.
Params:
  • attachment – An EmailAttachment.
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions
Returns:A MultiPartEmail.
Since:1.0
/** * Attach an EmailAttachment. * * @param attachment An EmailAttachment. * @return A MultiPartEmail. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */
public MultiPartEmail attach(final EmailAttachment attachment) throws EmailException { MultiPartEmail result = null; if (attachment == null) { throw new EmailException("Invalid attachment supplied"); } final URL url = attachment.getURL(); if (url == null) { String fileName = null; try { fileName = attachment.getPath(); final File file = new File(fileName); if (!file.exists()) { throw new IOException("\"" + fileName + "\" does not exist"); } result = attach( new FileDataSource(file), attachment.getName(), attachment.getDescription(), attachment.getDisposition()); } catch (final IOException e) { throw new EmailException("Cannot attach file \"" + fileName + "\"", e); } } else { result = attach( url, attachment.getName(), attachment.getDescription(), attachment.getDisposition()); } return result; }
Attach a file located by its URL. The disposition of the file is set to mixed.
Params:
  • url – The URL of the file (may be any valid URL).
  • name – The name field for the attachment.
  • description – A description for the attachment.
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions
Returns:A MultiPartEmail.
Since:1.0
/** * Attach a file located by its URL. The disposition of the file * is set to mixed. * * @param url The URL of the file (may be any valid URL). * @param name The name field for the attachment. * @param description A description for the attachment. * @return A MultiPartEmail. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */
public MultiPartEmail attach(final URL url, final String name, final String description) throws EmailException { return attach(url, name, description, EmailAttachment.ATTACHMENT); }
Attach a file located by its URL.
Params:
  • url – The URL of the file (may be any valid URL).
  • name – The name field for the attachment.
  • description – A description for the attachment.
  • disposition – Either mixed or inline.
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions
Returns:A MultiPartEmail.
Since:1.0
/** * Attach a file located by its URL. * * @param url The URL of the file (may be any valid URL). * @param name The name field for the attachment. * @param description A description for the attachment. * @param disposition Either mixed or inline. * @return A MultiPartEmail. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */
public MultiPartEmail attach( final URL url, final String name, final String description, final String disposition) throws EmailException { // verify that the URL is valid try { final InputStream is = url.openStream(); is.close(); } catch (final IOException e) { throw new EmailException("Invalid URL set:" + url, e); } return attach(new URLDataSource(url), name, description, disposition); }
Attach a file specified as a DataSource interface.
Params:
  • ds – A DataSource interface for the file.
  • name – The name field for the attachment.
  • description – A description for the attachment.
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions
Returns:A MultiPartEmail.
Since:1.0
/** * Attach a file specified as a DataSource interface. * * @param ds A DataSource interface for the file. * @param name The name field for the attachment. * @param description A description for the attachment. * @return A MultiPartEmail. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */
public MultiPartEmail attach( final DataSource ds, final String name, final String description) throws EmailException { // verify that the DataSource is valid try { final InputStream is = ds != null ? ds.getInputStream() : null; if (is != null) { // close the input stream to prevent file locking on windows is.close(); } if (is == null) { throw new EmailException("Invalid Datasource"); } } catch (final IOException e) { throw new EmailException("Invalid Datasource", e); } return attach(ds, name, description, EmailAttachment.ATTACHMENT); }
Attach a file specified as a DataSource interface.
Params:
  • ds – A DataSource interface for the file.
  • name – The name field for the attachment.
  • description – A description for the attachment.
  • disposition – Either mixed or inline.
Throws:
  • EmailException – see javax.mail.internet.MimeBodyPart for definitions
Returns:A MultiPartEmail.
Since:1.0
/** * Attach a file specified as a DataSource interface. * * @param ds A DataSource interface for the file. * @param name The name field for the attachment. * @param description A description for the attachment. * @param disposition Either mixed or inline. * @return A MultiPartEmail. * @throws EmailException see javax.mail.internet.MimeBodyPart * for definitions * @since 1.0 */
public MultiPartEmail attach( final DataSource ds, String name, final String description, final String disposition) throws EmailException { if (EmailUtils.isEmpty(name)) { name = ds.getName(); } final BodyPart bodyPart = createBodyPart(); try { bodyPart.setDisposition(disposition); bodyPart.setFileName(MimeUtility.encodeText(name)); bodyPart.setDescription(description); bodyPart.setDataHandler(new DataHandler(ds)); getContainer().addBodyPart(bodyPart); } catch (final UnsupportedEncodingException uee) { // in case the filename could not be encoded throw new EmailException(uee); } catch (final MessagingException me) { throw new EmailException(me); } setBoolHasAttachments(true); return this; }
Gets first body part of the message.
Throws:
Returns:The primary body part.
Since:1.0
/** * Gets first body part of the message. * * @return The primary body part. * @throws MessagingException An error occurred while getting the primary body part. * @since 1.0 */
protected BodyPart getPrimaryBodyPart() throws MessagingException { if (!initialized) { init(); } // Add the first body part to the message. The fist body part must be if (this.primaryBodyPart == null) { primaryBodyPart = createBodyPart(); getContainer().addBodyPart(primaryBodyPart, 0); } return primaryBodyPart; }
Gets the message container.
Returns:The message container.
Since:1.0
/** * Gets the message container. * * @return The message container. * @since 1.0 */
protected MimeMultipart getContainer() { if (!initialized) { init(); } return container; }
Creates a body part object. Can be overridden if you don't want to create a BodyPart.
Returns:the created body part
/** * Creates a body part object. * Can be overridden if you don't want to create a BodyPart. * * @return the created body part */
protected BodyPart createBodyPart() { return new MimeBodyPart(); }
Creates a mime multipart object.
Returns:the created mime part
/** * Creates a mime multipart object. * * @return the created mime part */
protected MimeMultipart createMimeMultipart() { return new MimeMultipart(); }
Checks whether there are attachments.
Returns:true if there are attachments
Since:1.0
/** * Checks whether there are attachments. * * @return true if there are attachments * @since 1.0 */
public boolean isBoolHasAttachments() { return boolHasAttachments; }
Sets whether there are attachments.
Params:
  • b – the attachments flag
Since:1.0
/** * Sets whether there are attachments. * * @param b the attachments flag * @since 1.0 */
public void setBoolHasAttachments(final boolean b) { boolHasAttachments = b; }
Checks if this object is initialized.
Returns:true if initialized
/** * Checks if this object is initialized. * * @return true if initialized */
protected boolean isInitialized() { return initialized; }
Sets the initialized status of this object.
Params:
  • b – the initialized status flag
/** * Sets the initialized status of this object. * * @param b the initialized status flag */
protected void setInitialized(final boolean b) { initialized = b; } }