| /* |
| * 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.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; |
| |
| /** |
| * 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 |
| * @version $Id$ |
| */ |
| 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 boolHasAttachments; |
| |
| /** |
| * Set the MIME subtype of the email. |
| * |
| * @param aSubType MIME subtype of the email |
| * @since 1.0 |
| */ |
| public void setSubType(String aSubType) |
| { |
| this.subType = aSubType; |
| } |
| |
| /** |
| * 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. |
| * |
| * @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(String partContent, String partContentType) |
| throws EmailException |
| { |
| BodyPart bodyPart = createBodyPart(); |
| try |
| { |
| bodyPart.setContent(partContent, partContentType); |
| getContainer().addBodyPart(bodyPart); |
| } |
| catch (MessagingException me) |
| { |
| throw new EmailException(me); |
| } |
| |
| return this; |
| } |
| |
| /** |
| * 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(MimeMultipart multipart) throws EmailException |
| { |
| try |
| { |
| return addPart(multipart, getContainer().getCount()); |
| } |
| catch (MessagingException me) |
| { |
| throw new EmailException(me); |
| } |
| } |
| |
| /** |
| * 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(MimeMultipart multipart, int index) throws EmailException |
| { |
| BodyPart bodyPart = createBodyPart(); |
| try |
| { |
| bodyPart.setContent(multipart); |
| getContainer().addBodyPart(bodyPart, index); |
| } |
| catch (MessagingException me) |
| { |
| throw new EmailException(me); |
| } |
| |
| return this; |
| } |
| |
| /** |
| * 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. |
| * |
| * @param msg A String. |
| * @return An Email. |
| * @throws EmailException see javax.mail.internet.MimeBodyPart |
| * for definitions |
| * @since 1.0 |
| */ |
| @Override |
| public Email setMsg(String msg) throws EmailException |
| { |
| // throw exception on null message |
| if (EmailUtils.isEmpty(msg)) |
| { |
| throw new EmailException("Invalid message supplied"); |
| } |
| try |
| { |
| BodyPart primary = getPrimaryBodyPart(); |
| |
| if ((primary instanceof MimePart) && EmailUtils.isNotEmpty(charset)) |
| { |
| ((MimePart) primary).setText(msg, charset); |
| } |
| else |
| { |
| primary.setText(msg); |
| } |
| } |
| catch (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. |
| * |
| * @exception 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(). |
| |
| BodyPart body = this.getPrimaryBodyPart(); |
| try |
| { |
| body.getContent(); |
| } |
| catch (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 (MessagingException me) |
| { |
| throw new EmailException(me); |
| } |
| } |
| |
| /** |
| * 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(File file) |
| throws EmailException |
| { |
| String fileName = file.getAbsolutePath(); |
| |
| try |
| { |
| if (!file.exists()) |
| { |
| throw new IOException("\"" + fileName + "\" does not exist"); |
| } |
| |
| FileDataSource fds = new FileDataSource(file); |
| |
| return attach(fds, file.getName(), null, EmailAttachment.ATTACHMENT); |
| } |
| catch (IOException e) |
| { |
| throw new EmailException("Cannot attach file \"" + fileName + "\"", e); |
| } |
| } |
| |
| /** |
| * 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(EmailAttachment attachment) |
| throws EmailException |
| { |
| MultiPartEmail result = null; |
| |
| if (attachment == null) |
| { |
| throw new EmailException("Invalid attachment supplied"); |
| } |
| |
| URL url = attachment.getURL(); |
| |
| if (url == null) |
| { |
| String fileName = null; |
| try |
| { |
| fileName = attachment.getPath(); |
| 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 (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. |
| * |
| * @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(URL url, String name, String description) |
| throws EmailException |
| { |
| return attach(url, name, description, EmailAttachment.ATTACHMENT); |
| } |
| |
| /** |
| * 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( |
| URL url, |
| String name, |
| String description, |
| String disposition) |
| throws EmailException |
| { |
| // verify that the URL is valid |
| try |
| { |
| InputStream is = url.openStream(); |
| is.close(); |
| } |
| catch (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. |
| * |
| * @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( |
| DataSource ds, |
| String name, |
| 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 (IOException e) |
| { |
| throw new EmailException("Invalid Datasource", e); |
| } |
| |
| return attach(ds, name, description, EmailAttachment.ATTACHMENT); |
| } |
| |
| /** |
| * 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( |
| DataSource ds, |
| String name, |
| String description, |
| String disposition) |
| throws EmailException |
| { |
| if (EmailUtils.isEmpty(name)) |
| { |
| name = ds.getName(); |
| } |
| BodyPart bodyPart = createBodyPart(); |
| try |
| { |
| getContainer().addBodyPart(bodyPart); |
| |
| bodyPart.setDisposition(disposition); |
| bodyPart.setFileName(name); |
| bodyPart.setDescription(description); |
| bodyPart.setDataHandler(new DataHandler(ds)); |
| } |
| catch (MessagingException me) |
| { |
| throw new EmailException(me); |
| } |
| setBoolHasAttachments(true); |
| |
| return this; |
| } |
| |
| /** |
| * 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. |
| * |
| * @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. |
| * |
| * @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(); |
| } |
| |
| /** |
| * Checks whether there are attachments. |
| * |
| * @return true if there are attachments |
| * @since 1.0 |
| */ |
| public boolean isBoolHasAttachments() |
| { |
| return boolHasAttachments; |
| } |
| |
| /** |
| * Sets whether there are attachments. |
| * |
| * @param b the attachments flag |
| * @since 1.0 |
| */ |
| public void setBoolHasAttachments(boolean b) |
| { |
| boolHasAttachments = b; |
| } |
| |
| /** |
| * Checks if this object is initialized. |
| * |
| * @return true if initialized |
| */ |
| protected boolean isInitialized() |
| { |
| return initialized; |
| } |
| |
| /** |
| * Sets the initialized status of this object. |
| * |
| * @param b the initialized status flag |
| */ |
| protected void setInitialized(boolean b) |
| { |
| initialized = b; |
| } |
| |
| } |