org.mangelp.fakeSmtpWeb.httpServer.mailBrowser.MailFile.java Source code

Java tutorial

Introduction

Here is the source code for org.mangelp.fakeSmtpWeb.httpServer.mailBrowser.MailFile.java

Source

/**
 * This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
 * If a copy of the MPL was not distributed with this file, You can obtain one at
 * https://mozilla.org/MPL/2.0/.
 */

package org.mangelp.fakeSmtpWeb.httpServer.mailBrowser;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.attribute.BasicFileAttributes;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Properties;

import javax.activation.DataSource;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;

import org.apache.commons.cli.ParseException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.mail.util.MimeMessageParser;
import org.jsoup.Jsoup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Wrapper around a MIME-mail file that is parsed from a real on-disk file when
 * the object is instanced.
 *
 * @author mangelp
 *
 */
public class MailFile {

    private static final Logger logger = LoggerFactory.getLogger(MailFile.class);

    private Date creationDate;
    private long size;
    private String id = null;
    private String fileName = null;
    private File file = null;
    private String subject = null;
    private String from = null;
    private String replyTo = null;
    private String htmlContent = null;
    private String plainContent = null;
    private int order;
    private String[] to = ArrayUtils.EMPTY_STRING_ARRAY;
    private String[] cc = ArrayUtils.EMPTY_STRING_ARRAY;
    private String[] bcc = ArrayUtils.EMPTY_STRING_ARRAY;
    private List<MailAttachment> attachments = new ArrayList<MailAttachment>();

    /**
     * @return the creationDate
     */
    public Date getCreationDate() {
        return this.creationDate;
    }

    /**
     * @param creationDate
     *            the creationDate to set
     */
    protected void setCreationDate(Date creationDate) {
        this.creationDate = creationDate;
    }

    /**
     * @return the size in bytes
     */
    public long getSize() {
        return this.size;
    }

    /**
     * @param size
     *            the size to set
     */
    protected void setSize(long size) {
        this.size = size;
    }

    public String getId() {
        return this.id;
    }

    public void setId(String id) {
        this.id = id;
    }

    protected void setFile(File file) {
        this.file = file;
        String fileName = StringUtils.trimToEmpty(file.getName());
        fileName = Base64.encodeBase64String(fileName.getBytes());

        this.fileName = fileName;
    }

    public File getFile() {
        return this.file;
    }

    public String getFileName() {
        return this.fileName;
    }

    /**
     * @return the subject
     */
    public String getSubject() {
        return this.subject;
    }

    /**
     * @param subject
     *            the subject to set
     */
    protected void setSubject(String subject) {
        this.subject = subject;
    }

    /**
     * @return the from
     */
    public String getFrom() {
        return this.from;
    }

    /**
     * @param from
     *            the from to set
     */
    protected void setFrom(String from) {
        this.from = from;
    }

    /**
     *
     * @return
     */
    public String getReplyTo() {
        return this.replyTo;
    }

    /**
     *
     * @param replyTo
     */
    public void setReplyTo(String replyTo) {
        this.replyTo = replyTo;
    }

    /**
     * @return the to
     */
    public String[] getTo() {
        return this.to;
    }

    /**
     * @param to
     *            the to to set
     */
    protected void setTo(String[] to) {
        this.to = to;
    }

    /**
     * @return the cc
     */
    public String[] getCc() {
        return this.cc;
    }

    /**
     * @param cc
     *            the cc to set
     */
    protected void setCc(String[] cc) {
        this.cc = cc;
    }

    /**
     * @return the bcc
     */
    public String[] getBcc() {
        return this.bcc;
    }

    /**
     * @param bcc
     *            the bcc to set
     */
    protected void setBcc(String[] bcc) {
        this.bcc = bcc;
    }

    public List<MailAttachment> getAttachments() {
        return this.attachments;
    }

    protected void setAttachments(List<MailAttachment> attachments) {
        this.attachments = attachments;
    }

    /**
     * @return the htmlContent
     */
    public String getHtmlContent() {
        return this.htmlContent;
    }

    /**
     * @param htmlContent
     *            the htmlContent to set
     */
    protected void setHtmlContent(String htmlContent) {
        this.htmlContent = htmlContent;
    }

    /**
     * @return the plainContent
     */
    public String getPlainContent() {
        return this.plainContent;
    }

    /**
     * @param plainContent
     *            the plainContent to set
     */
    protected void setPlainContent(String plainContent) {
        this.plainContent = plainContent;
    }

    public int getOrder() {
        return this.order;
    }

    public void setOrder(int order) {
        this.order = order;
    }

    /**
     *
     * @param file
     * @throws MessagingException
     * @throws ParseException
     * @throws IOException
     */
    public MailFile(File file) throws MessagingException, ParseException, IOException {
        this.setFile(file);
        this.getAttributes();
        this.parseEmail();
    }

    protected void getAttributes() throws IOException {
        BasicFileAttributes attr = Files.readAttributes(this.getFile().toPath(), BasicFileAttributes.class);

        this.setCreationDate(new Date(attr.creationTime().toMillis()));
        this.setSize(attr.size());
    }

    /**
     * Parse the file on disk using a MimeMessageParser and set all the instance
     * properties we will be using.
     *
     * @throws FileNotFoundException
     * @throws MessagingException
     * @throws ParseException
     * @throws IOException
     */
    protected void parseEmail() throws FileNotFoundException, MessagingException, ParseException, IOException {

        InputStream inputStream = new BufferedInputStream(new FileInputStream(this.getFile()));

        try {
            final Session session = Session.getDefaultInstance(new Properties());

            MimeMessage message = new MimeMessage(session, inputStream);
            MimeMessageParser mimeParser = new MimeMessageParser(message);

            mimeParser.parse();

            this.setSubject(mimeParser.getSubject());
            this.setFrom(mimeParser.getFrom());
            this.setReplyTo(mimeParser.getReplyTo());

            ArrayList<String> toList = new ArrayList<String>();
            for (Address emailAddress : mimeParser.getTo()) {
                toList.add(emailAddress.toString());
            }

            this.setTo(toList.toArray(this.getTo()));

            ArrayList<String> ccList = new ArrayList<String>();
            for (Address emailAddress : mimeParser.getCc()) {
                ccList.add(emailAddress.toString());
            }

            this.setCc(ccList.toArray(this.getCc()));

            ArrayList<String> bccList = new ArrayList<String>();
            for (Address emailAddress : mimeParser.getBcc()) {
                bccList.add(emailAddress.toString());
            }

            this.setBcc(bccList.toArray(this.getBcc()));

            if (mimeParser.hasAttachments()) {
                attachments = new ArrayList<MailAttachment>(mimeParser.getAttachmentList().size());

                int index = 0;
                for (DataSource ds : mimeParser.getAttachmentList()) {
                    attachments.add(new MailAttachment(++index, ds));
                }
            }

            if (mimeParser.hasHtmlContent()) {
                this.setHtmlContent(mimeParser.getHtmlContent());
            }

            if (mimeParser.hasPlainContent()) {
                this.setPlainContent(mimeParser.getPlainContent());
            }

        } catch (Exception e) {
            throw new ParseException("Failed to parse file " + this.getFile().toString() + ": " + e.getMessage());
        }

        this.setId(DigestUtils.sha1Hex(inputStream));

        inputStream.close();
    }

    /**
     * Gets one or more email addresses by its type (from, to, cc, bcc and
     * reply-to).
     *
     * @param type
     * @return
     */
    public String getEmailAddressesAsString(String type) {
        String[] addresses = null;

        if (StringUtils.equalsIgnoreCase("from", type)) {
            addresses = new String[] { this.getFrom() };
        } else if (StringUtils.equalsIgnoreCase("reply-to", type)) {
            addresses = new String[] { this.getReplyTo() };
        } else if (StringUtils.equalsIgnoreCase("to", type)) {
            addresses = this.getTo();
        } else if (StringUtils.equalsIgnoreCase("cc", type)) {
            addresses = this.getCc();
        } else if (StringUtils.equalsIgnoreCase("bcc", type)) {
            addresses = this.getBcc();
        }

        return StringUtils.join(addresses, ", ");
    }

    /**
     * Gets email size with the given units
     *
     * @param units
     * @return
     */
    public String getSize(String units) {
        if (StringUtils.isBlank(units)) {
            return this.size + " b";
        } else if (units.length() > 1) {
            throw new IllegalArgumentException("Invalid units: " + units + ". Valid units are: k, m, b");
        }

        return this.getSize(units.charAt(0));
    }

    /**
     * Gets email size with the given units
     *
     * @param units
     * @return
     */
    public String getSize(char units) {
        return this.getSizeInUnits(this.size, units);
    }

    protected String getSizeInUnits(long size, char units) {
        if (StringUtils.isBlank(units + "")) {
            return this.size + " b";
        }

        switch (Character.toLowerCase(units)) {
        case 'k':
            return (Math.round(((float) size) / 1024)) + " KB";
        case 'm':
            return (Math.round(((float) size) / (1024 * 1024))) + " MB";
        case 'b':
            return size + " B";
        default:
            throw new IllegalArgumentException("Invalid units: " + units + ". Valid units are: k, m, b");
        }
    }

    /**
     * Get creation date as an string given the date format
     *
     * @param pattern
     * @return
     */
    public String getCreationDate(String pattern) {
        SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);

        return dateFormat.format(this.getCreationDate());
    }

    /**
     * Gets the email body.
     *
     * First checks the plain email format and returns it first, if not present
     * checks the HTML format and if present removes all the HTML tags and
     * returns it.
     *
     * Whitespace is trimmed from the result and an String instance is always
     * returned (even if empty).
     *
     * @return
     */
    public String getContent() {
        String content = null;

        if (!StringUtils.isBlank(this.getPlainContent())) {
            content = this.getPlainContent();
        } else if (!StringUtils.isBlank(this.getHtmlContent())) {
            content = Jsoup.parse(this.getHtmlContent()).text();
        }

        content = StringUtils.trimToEmpty(content);

        return content;
    }

    public boolean hasHtmlContent() {
        return !StringUtils.isBlank(this.getHtmlContent());
    }

    public boolean hasPlainContent() {
        return !StringUtils.isBlank(this.getPlainContent());
    }

    /**
     * Returns the content but reduced to a maximum of size-4 characters.
     *
     * If the content text size is over size-4 characters then is cut down to
     * that length and an ellipsis is appended to it.
     *
     * @param size
     * @return
     */
    public String getExcerpt(int size) {
        String content = this.getContent();

        if (content.length() > (size - 4)) {
            content = StringUtils.substring(content, 0, size - 4) + " ...";
        }

        return content;
    }

    /**
     * Gets the size of an attachment in bytes
     * 
     * This operation requires the attachment to be read in order to be able to
     * calculate the size.
     * 
     * @param index
     * @return
     */
    public long getAttachmentSize(int index) {
        return this.attachments.get(index).getSize();
    }

    /**
     * Gets the title of an attachment by its position.
     * 
     * The flag withSize controls whether the attachment size will be calculated or not. Attachment sizes require
     * the attachment to be read in full.
     * 
     * @param index
     * @return
     */
    public String getAttachmentTitle(int index) {
        return this.attachments.get(index).getTitle(true);
    }

    /**
     * @return the attachment titles
     */
    public String[] getAttachmentTitles() {
        String[] titles = new String[this.attachments.size()];

        for (int index = 0; index < titles.length; index++) {
            titles[index] = getAttachmentTitle(index);
        }

        return titles;
    }
}