mitm.common.mail.repository.hibernate.MailRepositoryItemEntity.java Source code

Java tutorial

Introduction

Here is the source code for mitm.common.mail.repository.hibernate.MailRepositoryItemEntity.java

Source

/*
 * Copyright (c) 2010-2011, Martijn Brinkers, Djigzo.
 * 
 * This file is part of Djigzo email encryption.
 *
 * Djigzo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License 
 * version 3, 19 November 2007 as published by the Free Software 
 * Foundation.
 *
 * Djigzo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public 
 * License along with Djigzo. If not, see <http://www.gnu.org/licenses/>
 *
 * Additional permission under GNU AGPL version 3 section 7
 * 
 * If you modify this Program, or any covered work, by linking or 
 * combining it with aspectjrt.jar, aspectjweaver.jar, tyrex-1.0.3.jar, 
 * freemarker.jar, dom4j.jar, mx4j-jmx.jar, mx4j-tools.jar, 
 * spice-classman-1.0.jar, spice-loggerstore-0.5.jar, spice-salt-0.8.jar, 
 * spice-xmlpolicy-1.0.jar, saaj-api-1.3.jar, saaj-impl-1.3.jar, 
 * wsdl4j-1.6.1.jar (or modified versions of these libraries), 
 * containing parts covered by the terms of Eclipse Public License, 
 * tyrex license, freemarker license, dom4j license, mx4j license,
 * Spice Software License, Common Development and Distribution License
 * (CDDL), Common Public License (CPL) the licensors of this Program grant 
 * you additional permission to convey the resulting work.
 */
package mitm.common.mail.repository.hibernate;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import mitm.common.mail.EmailAddressUtils;
import mitm.common.mail.MailUtils;
import mitm.common.mail.repository.MailRepositoryItem;
import mitm.common.properties.hibernate.BlobEntity;
import mitm.common.util.Check;

import org.apache.commons.lang.StringUtils;
import org.hibernate.annotations.CollectionOfElements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Hibernate entity for storing MailRepositoryItem in the database.
 * 
 * @author Martijn Brinkers
 *
 */
@Entity(name = MailRepositoryItemEntity.ENTITY_NAME)
@Table(name = "mail_repository")
public class MailRepositoryItemEntity implements MailRepositoryItem {
    private final static Logger logger = LoggerFactory.getLogger(MailRepositoryItemEntity.class);

    protected static final String ENTITY_NAME = "MailRepositoryItem";

    protected static final String ID_COLUMN_NAME = "id";
    protected static final String REPOSITORY_COLUMN_NAME = "repository";
    protected static final String MIME_COLUMN_NAME = "mime";
    protected static final String MESSAGE_ID_COLUMN_NAME = "messageID";
    protected static final String SUBJECT_COLUMN_NAME = "subject";
    protected static final String RECIPIENTS_COLUMN_NAME = "recipients";
    protected static final String SENDER_COLUMN_NAME = "sender";
    protected static final String ORIGINATOR_COLUMN_NAME = "originator";
    protected static final String FROM_HEADER_COLUMN_NAME = "fromHeader";
    protected static final String REMOTE_ADDRESS_COLUMN_NAME = "remoteAddress";
    protected static final String CREATED_COLUMN_NAME = "created";
    protected static final String LAST_UPDATED_COLUMN_NAME = "lastUpdated";
    protected static final String ADDITIONAL_DATA_COLUMN_NAME = "data";

    private static final int MESSAGE_ID_MAX_LENGTH = 1024;
    private static final int SUBJECT_MAX_LENGTH = 1024;
    private static final int SENDER_MAX_LENGTH = 1024;
    private static final int ORIGINATOR_MAX_LENGTH = 1024;
    private static final int RECIPIENT_MAX_LENGTH = 1024;
    private static final int FROM_MAX_LENGTH = 1024;
    private static final int REMOTE_ADDRESS_MAX_LENGTH = 1024;

    /*
     * The id of this item.
     */
    @Id
    @Column(name = ID_COLUMN_NAME)
    private String id;

    /*
     * The repository this item belongs to.
     */
    @Column(name = REPOSITORY_COLUMN_NAME, updatable = false)
    private String repository;

    /*
     * message-ID of the message
     */
    @Column(name = MESSAGE_ID_COLUMN_NAME, length = MESSAGE_ID_MAX_LENGTH, updatable = false)
    private String messageID;

    /*
     * Decoded subject of the message
     */
    @Column(name = SUBJECT_COLUMN_NAME, length = SUBJECT_MAX_LENGTH, updatable = false)
    private String subject;

    /*
     * The from header of the message
     */
    @Column(name = FROM_HEADER_COLUMN_NAME, length = FROM_MAX_LENGTH, updatable = false)
    private String fromHeader;

    /*
     * Envelope recipients of the message
     */
    @CollectionOfElements
    @JoinTable(name = "mail_repository_recipients", joinColumns = @JoinColumn(name = ID_COLUMN_NAME))
    @Column(name = RECIPIENTS_COLUMN_NAME, length = RECIPIENT_MAX_LENGTH)
    private List<String> recipients = new LinkedList<String>();

    /*
     * The envelope sender of the message
     */
    @Column(name = SENDER_COLUMN_NAME, length = SENDER_MAX_LENGTH)
    private String sender;

    /*
     * The originator of the message
     */
    @Column(name = ORIGINATOR_COLUMN_NAME, length = ORIGINATOR_MAX_LENGTH)
    private String originator;

    /*
     * The IP address of the sender
     */
    @Column(name = REMOTE_ADDRESS_COLUMN_NAME, length = REMOTE_ADDRESS_MAX_LENGTH)
    private String remoteAddress;

    /*
     * The date this item was created
     */
    @Column(name = CREATED_COLUMN_NAME)
    private Date created;

    /*
     * The date this item was last updated
     */
    @Column(name = LAST_UPDATED_COLUMN_NAME)
    private Date lastUpdated;

    /*
     * General purpose data 
     */
    @Column(name = ADDITIONAL_DATA_COLUMN_NAME)
    private byte[] additionalData;

    /*
     * The mime message is stored as an entity to allow lazy loading (a byte[] cannot be lazy loaded). Lazy 
     * loading is required because the message can be very large which will result in an Out of Memory when
     * a list of entities is loaded.
     */
    @OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
    private BlobEntity mime;

    protected MailRepositoryItemEntity() {
        /* required by Hibernate */
    }

    public MailRepositoryItemEntity(String id, String repository, MimeMessage message, Date created)
            throws MessagingException, IOException {
        Check.notNull(id, "id");
        Check.notNull(message, "message");

        this.id = id;
        this.repository = repository;
        this.created = created;

        parseMessage(message);
    }

    public MailRepositoryItemEntity(String id, String repository, MimeMessage message)
            throws MessagingException, IOException {
        this(id, repository, message, new Date());
    }

    private void initMessageID(MimeMessage message) {
        try {
            messageID = StringUtils.abbreviate(message.getMessageID(), MESSAGE_ID_MAX_LENGTH);
        } catch (MessagingException e) {
            logger.debug("Error getting messageID.", e);
        }
    }

    private void initSubject(MimeMessage message) {
        try {
            try {
                subject = message.getSubject();
            } catch (MessagingException e) {
                /*
                 * Fallback to raw headers
                 */
                subject = message.getHeader("subject", ", ");
            }

            subject = StringUtils.abbreviate(subject, SUBJECT_MAX_LENGTH);
        } catch (MessagingException e) {
            logger.debug("Error getting subject.", e);
        }
    }

    private void initFrom(MimeMessage message) {
        try {
            String decodedFrom = null;

            try {
                decodedFrom = StringUtils.join(
                        EmailAddressUtils.addressesToStrings(message.getFrom(), true /* mime decode */), ", ");
            } catch (MessagingException e) {
                /*
                 * Fallback to raw headers
                 */
                decodedFrom = message.getHeader("from", ", ");
            }

            fromHeader = StringUtils.abbreviate(decodedFrom, FROM_MAX_LENGTH);
        } catch (MessagingException e) {
            logger.debug("Error getting from.", e);
        }
    }

    private void parseMessage(MimeMessage message) throws IOException, MessagingException {
        initMessageID(message);
        initSubject(message);
        initFrom(message);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        MailUtils.writeMessage(message, bos);

        mime = new BlobEntity(bos.toByteArray());
    }

    @Override
    public String getID() {
        return id;
    }

    @Override
    public String getRepository() {
        return repository;
    }

    @Override
    public MimeMessage getMimeMessage() throws MessagingException {
        return MailUtils.byteArrayToMessage(mime.getBlob());
    }

    @Override
    public String getMessageID() {
        return messageID;
    }

    @Override
    public String getSubject() {
        return subject;
    }

    @Override
    public String getFromHeader() {
        return fromHeader;
    }

    @Override
    public Collection<InternetAddress> getRecipients() throws AddressException {
        List<InternetAddress> addresses = new ArrayList<InternetAddress>(recipients.size());

        for (String recipient : recipients) {
            addresses.add(new InternetAddress(recipient, false));
        }

        return addresses;
    }

    @Override
    public void setRecipients(Collection<InternetAddress> recipients) throws AddressException {
        this.recipients.clear();

        if (recipients != null) {
            for (InternetAddress recipient : recipients) {
                this.recipients.add(recipient.getAddress());
            }
        }
    }

    @Override
    public InternetAddress getSender() throws AddressException {
        return sender != null ? new InternetAddress(sender, false) : null;
    }

    @Override
    public void setSender(InternetAddress sender) throws AddressException {
        this.sender = sender != null ? sender.getAddress() : null;
    }

    @Override
    public InternetAddress getOriginator() throws AddressException {
        return originator != null ? new InternetAddress(originator, false) : null;
    }

    @Override
    public void setOriginator(InternetAddress originator) throws AddressException {
        this.originator = originator != null ? originator.getAddress() : null;
    }

    @Override
    public String getRemoteAddress() {
        return remoteAddress;
    }

    @Override
    public void setRemoteAddress(String remoteAddress) {
        this.remoteAddress = remoteAddress;
    }

    @Override
    public Date getCreated() {
        return created;
    }

    @Override
    public Date getLastUpdated() {
        return lastUpdated;
    }

    @Override
    public void setLastUpdated(Date lastUpdated) {
        this.lastUpdated = lastUpdated;
    }

    @Override
    public byte[] getAdditionalData() {
        return additionalData;
    }

    @Override
    public void setAdditionalData(byte[] data) {
        this.additionalData = data;
    }
}