All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.mail2.jakarta.MultiPartEmail Maven / Gradle / Ivy

/*
 * 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.mail2.jakarta;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.util.Objects;

import org.apache.commons.mail2.core.EmailException;
import org.apache.commons.mail2.core.EmailUtils;
import org.apache.commons.mail2.jakarta.activation.PathDataSource;

import jakarta.activation.DataHandler;
import jakarta.activation.DataSource;
import jakarta.activation.FileDataSource;
import jakarta.activation.FileTypeMap;
import jakarta.activation.URLDataSource;
import jakarta.mail.BodyPart;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeBodyPart;
import jakarta.mail.internet.MimeMultipart;
import jakarta.mail.internet.MimePart;
import jakarta.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 */ public class MultiPartEmail extends Email { /** Body portion of the email. */ private MimeMultipart container; /** The message container. */ private BodyPart primaryBodyPart; /** The MIME subtype. */ private String subType; /** Indicates if the message has been initialized. */ private boolean initialized; /** Indicates if attachments have been added to the message. */ private boolean hasAttachments; /** * Constructs a new instance. */ public MultiPartEmail() { // empty } /** * Adds a new part to the email. * * @param multipart The MimeMultipart. * @return An Email. * @throws EmailException see jakarta.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 e) { throw new EmailException(e); } } /** * Adds 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 e) { throw new EmailException(e); } return this; } /** * Adds a new part to the email. * * @param partContent The content. * @param partContentType The content type. * @return An Email. * @throws EmailException see jakarta.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 e) { throw new EmailException(e); } return this; } /** * Attaches a file specified as a DataSource interface. * * @param dataSource 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 jakarta.mail.internet.MimeBodyPart for definitions * @since 1.0 */ public MultiPartEmail attach(final DataSource dataSource, final String name, final String description) throws EmailException { EmailException.checkNonNull(dataSource, () -> "Invalid Datasource."); // verify that the DataSource is valid try (InputStream inputStream = dataSource.getInputStream()) { EmailException.checkNonNull(inputStream, () -> "Invalid Datasource."); } catch (final IOException e) { throw new EmailException("Invalid Datasource.", e); } return attach(dataSource, name, description, EmailAttachment.ATTACHMENT); } /** * Attaches a file specified as a DataSource interface. * * @param dataSource 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 jakarta.mail.internet.MimeBodyPart for definitions * @since 1.0 */ public MultiPartEmail attach(final DataSource dataSource, String name, final String description, final String disposition) throws EmailException { if (EmailUtils.isEmpty(name)) { name = dataSource.getName(); } try { final BodyPart bodyPart = createBodyPart(); bodyPart.setDisposition(disposition); bodyPart.setFileName(MimeUtility.encodeText(name)); bodyPart.setDescription(description); bodyPart.setDataHandler(new DataHandler(dataSource)); getContainer().addBodyPart(bodyPart); } catch (final UnsupportedEncodingException | MessagingException e) { // in case the file name could not be encoded throw new EmailException(e); } setBoolHasAttachments(true); return this; } /** * Attaches an EmailAttachment. * * @param attachment An EmailAttachment. * @return A MultiPartEmail. * @throws EmailException see jakarta.mail.internet.MimeBodyPart for definitions * @since 1.0 */ public MultiPartEmail attach(final EmailAttachment attachment) throws EmailException { EmailException.checkNonNull(attachment, () -> "Invalid attachment."); MultiPartEmail result = null; 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; } /** * Attaches a file. * * @param file A file attachment * @return A MultiPartEmail. * @throws EmailException see jakarta.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"); } return attach(new FileDataSource(file), file.getName(), null, EmailAttachment.ATTACHMENT); } catch (final IOException e) { throw new EmailException("Cannot attach file \"" + fileName + "\"", e); } } /** * Attaches a path. * * @param file A file attachment. * @param options options for opening file streams. * @return A MultiPartEmail. * @throws EmailException see jakarta.mail.internet.MimeBodyPart for definitions * @since 1.6.0 */ public MultiPartEmail attach(final Path file, final OpenOption... options) throws EmailException { final Path fileName = file.toAbsolutePath(); try { if (!Files.exists(file)) { throw new IOException("\"" + fileName + "\" does not exist"); } return attach(new PathDataSource(file, FileTypeMap.getDefaultFileTypeMap(), options), Objects.toString(file.getFileName(), null), null, EmailAttachment.ATTACHMENT); } catch (final IOException e) { throw new EmailException("Cannot attach file \"" + fileName + "\"", e); } } /** * Attaches 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 jakarta.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); } /** * Attaches 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 jakarta.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 { url.openStream().close(); } catch (final IOException e) { throw new EmailException("Invalid URL set:" + url, e); } return attach(new URLDataSource(url), name, description, disposition); } /** * Builds 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 = 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 e) { throw new EmailException(e); } } /** * 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. * * @return the created mime part */ protected MimeMultipart createMimeMultipart() { return new MimeMultipart(); } /** * Gets the message container. * * @return The message container. * @since 1.0 */ protected MimeMultipart getContainer() { if (!initialized) { init(); } return container; } /** * 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 (primaryBodyPart == null) { primaryBodyPart = createBodyPart(); getContainer().addBodyPart(primaryBodyPart, 0); } return primaryBodyPart; } /** * Gets the MIME subtype of the email. * * @return MIME subtype of the email * @since 1.0 */ public String getSubType() { return subType; } /** * Initialize the multipart email. * * @since 1.0 */ protected void init() { if (initialized) { throw new IllegalStateException("Already initialized"); } container = createMimeMultipart(); super.setContent(container); initialized = true; } /** * Tests whether there are attachments. * * @return true if there are attachments * @since 1.0 */ public boolean isBoolHasAttachments() { return hasAttachments; } /** * Tests if this object is initialized. * * @return true if initialized */ protected boolean isInitialized() { return initialized; } /** * Sets whether there are attachments. * * @param hasAttachments the attachments flag * @since 1.0 */ public void setBoolHasAttachments(final boolean hasAttachments) { this.hasAttachments = hasAttachments; } /** * Sets the initialized status of this object. * * @param initialized the initialized status flag */ protected void setInitialized(final boolean initialized) { this.initialized = initialized; } /** * Sets the message of the email. * * @param msg A String. * @return An Email. * @throws EmailException see jakarta.mail.internet.MimeBodyPart for definitions * @since 1.0 */ @Override public Email setMsg(final String msg) throws EmailException { EmailException.checkNonEmpty(msg, () -> "Invalid message."); try { final BodyPart primary = getPrimaryBodyPart(); if (primary instanceof MimePart && EmailUtils.isNotEmpty(getCharsetName())) { ((MimePart) primary).setText(msg, getCharsetName()); } else { primary.setText(msg); } } catch (final MessagingException e) { throw new EmailException(e); } return this; } /** * Sets the MIME subtype of the email. * * @param subType MIME subtype of the email * @since 1.0 */ public void setSubType(final String subType) { this.subType = subType; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy