de.bht.fpa.mail.s000000.common.mail.imapsync.MessageConverter.java Source code

Java tutorial

Introduction

Here is the source code for de.bht.fpa.mail.s000000.common.mail.imapsync.MessageConverter.java

Source

/*******************************************************************************
 * Copyright (c) 2011 - 2012 Siamak Haschemi & Benjamin Haupt
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/

package de.bht.fpa.mail.s000000.common.mail.imapsync;

import static de.bht.fpa.mail.s000000.common.mail.model.builder.Builders.newAttachmentBuilder;
import static de.bht.fpa.mail.s000000.common.mail.model.builder.Builders.newMessageBuilder;
import static de.bht.fpa.mail.s000000.common.mail.model.builder.Builders.newRecipientBuilder;
import static de.bht.fpa.mail.s000000.common.mail.model.builder.Builders.newSenderBuilder;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Flags;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.UIDFolder;
import javax.mail.internet.InternetAddress;

import org.apache.commons.codec.binary.Base64;

import com.sun.mail.imap.IMAPFolder;

import de.bht.fpa.mail.s000000.common.mail.model.Importance;
import de.bht.fpa.mail.s000000.common.mail.model.Message;
import de.bht.fpa.mail.s000000.common.mail.model.RecipientType;
import de.bht.fpa.mail.s000000.common.mail.model.builder.MessageBuilder;

/**
 * This class is responsible for converting Java Mail Message Objects (coming
 * from IMAP or POP3 accounts) to our own {@link Message} objects.
 * 
 * @author Siamak Haschemi
 */
public final class MessageConverter {
    private static final String X_PRIORITY = "X-Priority";
    private static final Pattern X_PRIORITY_VALUE_PATTERN = Pattern.compile("(\\d).*");
    private static final int X_PRIORITY_HIGH_END = 4;
    private static final int X_PRIORITY_HIGH_START = 2;
    private static final Map<RecipientType, javax.mail.Message.RecipientType> recipientType = new HashMap<RecipientType, javax.mail.Message.RecipientType>();

    public MessageConverter() {
        recipientType.put(RecipientType.TO, javax.mail.Message.RecipientType.TO);
        recipientType.put(RecipientType.CC, javax.mail.Message.RecipientType.CC);
        recipientType.put(RecipientType.BCC, javax.mail.Message.RecipientType.BCC);
    }

    /**
     * Converts a javax {@link javax.mail.Message} to a {@link Message}.
     * 
     * @param uidFolder
     *          the {@link UIDFolder} (i.e. the {@link IMAPFolder} to obtain the
     *          UID of the message from
     * @param javaMailMessage
     *          the {@link javax.mail.Message} to convert
     * @return the converted {@link Message}, or <code>null</code> if conversion
     *         failed.
     * @throws MessageConversionException
     */
    public Message convertJavaxMessage(UIDFolder uidFolder, javax.mail.Message javaMailMessage)
            throws MessageConversionException {
        try {
            // @formatter:off
            MessageBuilder messageBuilder = newMessageBuilder();

            messageBuilder.id(convertId(uidFolder, javaMailMessage)).subject(convertSubject(javaMailMessage))
                    .received(convertReceived(javaMailMessage)).sent(convertSent(javaMailMessage))
                    .read(convertRead(javaMailMessage)).importance(convertImportance(javaMailMessage));

            convertContent(javaMailMessage.getContent(), messageBuilder);
            convertRecipients(javaMailMessage, messageBuilder);
            convertSender(javaMailMessage, messageBuilder);

            return messageBuilder.build();
            // @formatter:on
        } catch (Exception e) {
            throw new MessageConversionException("Could not convert message " + javaMailMessage, e);
        }
    }

    private static long convertId(UIDFolder uidFolder, javax.mail.Message javaMailMessage)
            throws MessagingException {
        return uidFolder.getUID(javaMailMessage);
    }

    private static String convertSubject(javax.mail.Message javaMailMessage) throws MessagingException {
        return javaMailMessage.getSubject();
    }

    private static Date convertReceived(javax.mail.Message javaMailMessage) throws MessagingException {
        return javaMailMessage.getReceivedDate();
    }

    private static Date convertSent(javax.mail.Message javaMailMessage) throws MessagingException {
        return javaMailMessage.getSentDate();
    }

    private static boolean convertRead(javax.mail.Message javaMailMessage) throws MessagingException {
        return javaMailMessage.isSet(Flags.Flag.SEEN);
    }

    private static void convertSender(javax.mail.Message javaMailMessage, MessageBuilder messageBuilder)
            throws MessagingException {
        Address[] from = javaMailMessage.getFrom();
        if (from == null || from.length <= 0) {
            return;
        }

        Address firstFrom = from[0];
        if (!(firstFrom instanceof InternetAddress)) {
            return;
        }
        InternetAddress internetAddress = (InternetAddress) firstFrom;
        messageBuilder.sender(
                newSenderBuilder().email(internetAddress.getAddress()).personal(internetAddress.getPersonal()));
    }

    private static void convertRecipients(javax.mail.Message javaMailMessage, MessageBuilder messageBuilder)
            throws MessagingException {
        for (RecipientType type : RecipientType.values()) {
            addRecipients(messageBuilder, type, javaMailMessage.getRecipients(recipientType.get(type)));
        }
    }

    private static void addRecipients(MessageBuilder messageBuilder, RecipientType recipientType,
            Address[] recipients) {
        if (recipients == null) {
            return;
        }
        for (Address address : recipients) {
            if (!(address instanceof InternetAddress)) {
                continue;
            }
            InternetAddress internetAddress = (InternetAddress) address;

            // @formatter:off
            messageBuilder.recipient(newRecipientBuilder().email(internetAddress.getAddress())
                    .personal(internetAddress.getPersonal()).type(recipientType));
            // @formatter:on
        }
    }

    private static Importance convertImportance(javax.mail.Message javaMailMessage) throws MessagingException {
        Importance handleImportanceBasedOnXPriority = handleImportanceBasedOnXPriority(javaMailMessage);
        if (handleImportanceBasedOnXPriority != null) {
            return handleImportanceBasedOnXPriority;
        }

        Importance handleImportanceBasedOnXMSMailPriority = handleImportanceBasedOnXMSMailPriority(javaMailMessage);
        if (handleImportanceBasedOnXMSMailPriority != null) {
            return handleImportanceBasedOnXMSMailPriority;
        }

        Importance handleImportance = handleImportance(javaMailMessage);
        if (handleImportance != null) {
            return handleImportance;
        }

        return Importance.NORMAL;
    }

    private static Importance handleImportance(javax.mail.Message javaMailMessage) throws MessagingException {
        String[] header = javaMailMessage.getHeader("Importance");
        if (header == null) {
            return null;
        }

        for (String entry : header) {
            if (entry.equals("high")) {
                return Importance.HIGH;
            }
            if (entry.equals("normal")) {
                return Importance.NORMAL;
            }
            if (entry.equals("low")) {
                return Importance.LOW;
            }
        }
        return null;
    }

    private static Importance handleImportanceBasedOnXMSMailPriority(javax.mail.Message javaMailMessage)
            throws MessagingException {
        String[] header = javaMailMessage.getHeader("X-MSMail-Priority");
        if (header == null) {
            return null;
        }

        for (String entry : header) {
            if (entry.equals("High")) {
                return Importance.HIGH;
            }
            if (entry.equals("Normal")) {
                return Importance.NORMAL;
            }
            if (entry.equals("Low")) {
                return Importance.LOW;
            }
        }
        return null;
    }

    private static Importance handleImportanceBasedOnXPriority(javax.mail.Message javaMailMessage)
            throws MessagingException {
        String[] header = javaMailMessage.getHeader(X_PRIORITY);
        if (header == null) {
            return null;
        }

        for (String entry : header) {
            Matcher matcher = X_PRIORITY_VALUE_PATTERN.matcher(entry);
            if (!matcher.matches()) {
                continue;
            }

            Integer flag = Integer.valueOf(matcher.group(1));
            if (flag < X_PRIORITY_HIGH_START) {
                return Importance.HIGH;
            }
            if (X_PRIORITY_HIGH_START <= flag && flag <= X_PRIORITY_HIGH_END) {
                return Importance.NORMAL;
            }
            if (flag > X_PRIORITY_HIGH_END) {
                return Importance.LOW;
            }
        }
        return null;
    }

    private static void convertContent(Object content, MessageBuilder messageBuilder)
            throws MessagingException, IOException {
        handleContent(content, null, messageBuilder);
    }

    private static void handleContent(Object content, BodyPart bodyPart, MessageBuilder messageBuilder)
            throws MessagingException, IOException {
        if (content instanceof String) {
            handleText(content, messageBuilder);
        } else if (content instanceof Multipart) {
            handleMultipart((Multipart) content, messageBuilder);
        } else if (content instanceof InputStream) {
            handleInputStream((InputStream) content, bodyPart, messageBuilder);
        }
    }

    private static void handleInputStream(InputStream content, BodyPart bodyPart, MessageBuilder messageBuilder) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            int thisLine;
            while ((thisLine = content.read()) != -1) {
                bos.write(thisLine);
            }
            bos.flush();
            byte[] bytes = bos.toByteArray();
            bos.close();

            String encodeBase64String = new String(Base64.encodeBase64(bytes));
            // @formatter:off
            messageBuilder
                    .attachment(newAttachmentBuilder().fileName(bodyPart.getFileName()).body(encodeBase64String));
            // @formatter:on
        } catch (Exception e) {
            // ignore
            return;
        }
    }

    private static void handleText(Object content, MessageBuilder messageBuilder) {
        messageBuilder.text((String) content);
    }

    private static void handleMultipart(Multipart content, MessageBuilder messageBuilder)
            throws MessagingException, IOException {
        for (int i = 0; i < content.getCount(); i++) {
            BodyPart bodyPart = content.getBodyPart(i);
            handleContent(bodyPart.getContent(), bodyPart, messageBuilder);
        }
    }
}