com.cubusmail.mail.util.MessageUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.cubusmail.mail.util.MessageUtils.java

Source

/* MessageUtils.java
    
   Copyright (c) 2009 Juergen Schlierf, All Rights Reserved
       
   This file is part of Cubusmail (http://code.google.com/p/cubusmail/).
       
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.
       
   This library 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
   Lesser General Public License for more details.
       
   You should have received a copy of the GNU Lesser General Public
   License along with Cubusmail. If not, see <http://www.gnu.org/licenses/>.
       
 */
package com.cubusmail.mail.util;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Locale;

import javax.mail.Address;
import javax.mail.FetchProfile;
import javax.mail.Flags;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Part;
import javax.mail.UIDFolder;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimePart;
import javax.mail.internet.MimeUtility;
import javax.mail.search.BodyTerm;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;

import com.sun.mail.imap.IMAPFolder;

import com.cubusmail.core.CubusConstants;
import com.cubusmail.gwtui.domain.MessageListFields;
import com.cubusmail.gwtui.domain.SearchFields;
import com.cubusmail.mail.IMailFolder;

/**
 * Util class for general message functions.
 * 
 * @author Juergen Schlierf
 */
public class MessageUtils {

    /**
     * Type of address string
     * 
     * @author Juergen Schlierf
     */
    public enum AddressStringType {
        // personal name and Email
        COMPLETE,

        // personal name or email if therse no personal name
        PERSONAL,

        // personal name or empty if therse no personal name
        PERSONAL_ONLY,

        // email only
        EMAIL
    };

    public static final int BUFSIZE = 8192; // 8K

    private static Logger log = Logger.getLogger(MessageUtils.class.getName());

    /**
     * @param part
     * @return
     * @throws MessagingException
     */
    public static boolean isImagepart(Part part) throws MessagingException {

        return part.isMimeType("image/png") || part.isMimeType("image/gif") || part.isMimeType("image/jpg")
                || part.isMimeType("image/jpeg");
    }

    /**
     * @param emailAddress
     * @param displayName
     * @return
     */
    public static String toInternetAddress(String emailAddress, String displayName) {

        InternetAddress address;
        try {
            if (!StringUtils.isEmpty(displayName)) {
                address = new InternetAddress(emailAddress, displayName);
                return address.toUnicodeString();
            } else {
                return emailAddress;
            }
        } catch (UnsupportedEncodingException e) {
            return null;
        }
    }

    /**
     * Parses the adresslist.
     * 
     * @param addresslist
     * @param charset
     * @return
     */
    public static InternetAddress[] parseInternetAddress(String addresslist, String charset)
            throws MessagingException {

        if (addresslist != null) {
            addresslist = addresslist.replace(';', ',');
            InternetAddress[] addressArray = InternetAddress.parse(addresslist);

            if (addressArray != null) {
                for (InternetAddress address : addressArray) {
                    String personal = address.getPersonal();
                    if (personal != null) {
                        try {
                            address.setPersonal(personal, charset);
                        } catch (UnsupportedEncodingException e) {
                            log.error(e.getMessage(), e);
                        }
                    }
                }
            }

            return addressArray;
        }

        return null;
    }

    /**
     * Format the date.
     * 
     * @param date
     * @return
     */
    public static String formatMailDate(Date date) {

        if (date != null) {
            DateFormat format = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.MEDIUM,
                    SimpleDateFormat.SHORT, Locale.GERMAN);

            return format.format(date);
        } else {
            return "";
        }
    }

    /**
     * Format the size of a part like message or attachment.
     * 
     * @param size
     * @return
     */
    public static String formatPartSize(int size, NumberFormat format) {

        String value = null;
        if (size >= 1024) {
            value = format.format(size / 1024) + " KB";
        } else {
            if (size > 0) {
                value = Integer.toString(size) + " B";
            } else {
                value = "n/a";
            }
        }
        return value;
    }

    /**
     * @param locale
     * @return
     */
    public static NumberFormat createSizeFormat(Locale locale) {

        NumberFormat sizeFormat = DecimalFormat.getNumberInstance(locale);
        sizeFormat.setGroupingUsed(true);
        sizeFormat.setMaximumFractionDigits(0);
        sizeFormat.setMinimumFractionDigits(0);

        return sizeFormat;
    }

    /**
     * Calculate the real size bytes.
     * 
     * @param orgSize
     * @return
     */
    public static int calculateAttachmentSize(int orgSize) {

        if (orgSize > 0) {
            double size = (double) orgSize;
            size = size * CubusConstants.MESSAGE_SIZE_FACTOR;
            return (int) Math.round(size);
        }
        return orgSize;
    }

    /**
     * @param addressArray
     * @param emailAddress
     * @return
     */
    public static boolean findEmailAddress(Address[] addressArray, Address addressToFind) {

        if (addressArray != null) {
            for (Address address : addressArray) {
                if (address.equals(addressToFind)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * @param msg
     * @return
     * @throws MessagingException
     */
    public static boolean isHtmlMessage(Message msg) throws MessagingException {

        return msg.isMimeType("text/html");
    }

    /**
     * Method for checking if the message has attachments.
     */
    public static List<MimePart> attachmentsFromPart(Part part) throws MessagingException, IOException {

        List<MimePart> attachmentParts = new ArrayList<MimePart>();
        if (part instanceof MimePart) {
            MimePart mimePart = (MimePart) part;

            if (part.isMimeType("multipart/*")) {
                Multipart mp = (Multipart) mimePart.getContent();
                for (int i = 0; i < mp.getCount(); i++) {
                    MimeBodyPart bodyPart = (MimeBodyPart) mp.getBodyPart(i);
                    if (Part.ATTACHMENT.equals(bodyPart.getDisposition())
                            || Part.INLINE.equals(bodyPart.getDisposition())) {
                        attachmentParts.add(bodyPart);
                    }
                }
            } else if (part.isMimeType("application/*")) {
                attachmentParts.add(mimePart);
            }
        }

        return attachmentParts;
    }

    /**
     * @param part
     * @return
     * @throws MessagingException
     * @throws IOException
     */
    public static boolean hasAttachments(Part part) throws MessagingException, IOException {

        try {
            if (part.isMimeType("multipart/*")) {
                Multipart mp = (Multipart) part.getContent();
                for (int i = 0; i < mp.getCount(); i++) {
                    MimeBodyPart bodyPart = (MimeBodyPart) mp.getBodyPart(i);
                    if (Part.ATTACHMENT.equals(bodyPart.getDisposition())
                            || Part.INLINE.equals(bodyPart.getDisposition())) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return false;
    }

    /**
     * @param addressArray
     * @param personalOnly
     * @return
     * @throws MessagingException
     */
    public static String getMailAdressString(Address[] addressArray, AddressStringType type)
            throws MessagingException {

        String addressString = "";

        if (addressArray != null) {
            for (int i = 0; i < addressArray.length; i++) {

                String address = getMailAdressString(addressArray[i], type);
                if (i < (addressArray.length - 1)) {
                    addressString += address + ", ";
                } else {
                    addressString += address;
                }
            }
        } else {
            addressString = "";
        }

        return addressString;
    }

    /**
     * @param address
     * @param personalOnly
     * @return
     * @throws MessagingException
     */
    public static String getMailAdressString(Address address, AddressStringType type) throws MessagingException {

        String addressString = null;

        if (type == AddressStringType.PERSONAL || type == AddressStringType.PERSONAL_ONLY) {
            addressString = ((InternetAddress) address).getPersonal();
            if (StringUtils.isEmpty(addressString) && type == AddressStringType.PERSONAL) {
                addressString = ((InternetAddress) address).getAddress();
            }
        } else if (type == AddressStringType.COMPLETE) {
            addressString = ((InternetAddress) address).toUnicodeString();
        } else if (type == AddressStringType.EMAIL) {
            addressString = ((InternetAddress) address).getAddress();
        }

        return addressString;
    }

    /**
     * @param data
     * @return
     */
    public static String decodeText(String data) {

        int start = 0, i;
        StringBuffer sb = new StringBuffer();
        while ((i = data.indexOf("=?", start)) >= 0) {
            sb.append(data.substring(start, i));
            int end = data.indexOf("?=", i);
            if (end < 0) {
                break;
            }
            String s = data.substring(i, end + 2);
            try {
                sb.append(MimeUtility.decodeWord(s));
            } catch (Exception e) {
                sb.append(s);
            }
            start = end + 2;
        }
        if (start == 0)
            return data;
        if (start < data.length())
            sb.append(data.substring(start));
        return sb.toString();
    }

    /**
     * @param msg
     * @param flag
     * @param readFlag
     * @throws MessagingException
     */
    public static void setMessageFlag(Message msg, Flags.Flag flag, boolean readFlag) throws MessagingException {

        boolean currentFlag = msg.isSet(flag);

        if (currentFlag != readFlag) {
            msg.setFlag(flag, readFlag);
        }
    }

    /**
     * @param msg
     * @return
     * @throws MessagingException
     */
    public static boolean isMessageReadFlag(Message msg) throws MessagingException {

        return msg.isSet(Flags.Flag.SEEN);

    }

    /**
     * 
     * 
     * @param msg
     * @return
     */
    public static int getMessagePriority(Message msg) {

        int prio = CubusConstants.PRIORITY_NONE;

        try {
            String header[] = msg.getHeader(CubusConstants.FETCH_ITEM_PRIORITY);
            if (header != null && header.length > 0 && header[0].length() > 0) {
                String first = header[0].substring(0, 1);
                if (StringUtils.isNumeric(first)) {
                    return Integer.parseInt(first);
                }
            }
        } catch (MessagingException e) {
            log.error(e.getMessage(), e);
        }

        return prio;
    }

    /**
     * Sort the messages.
     * 
     * @param fieldName
     * @param ascending
     */
    public static void sortMessages(Message[] msgs, String fieldName, boolean ascending) {

        if (msgs != null && msgs.length > 0) {
            if (!StringUtils.isEmpty(fieldName)) {
                Arrays.sort(msgs, new MessageComparator(fieldName, ascending));
            } else {
                // reverse order
                ArrayUtils.reverse(msgs);
            }
        }
    }

    /**
     * Filter the messages.
     * 
     * @param msgs
     * @param searchFields
     * @param searchText
     * @return
     */
    public static Message[] quickFilterMessages(Message[] msgs, String searchFields, String searchText) {

        if (!StringUtils.isEmpty(searchFields) && !StringUtils.isEmpty(searchText)) {
            searchFields = StringUtils.remove(searchFields, '[');
            searchFields = StringUtils.remove(searchFields, ']');
            searchFields = StringUtils.remove(searchFields, '\"');
            String[] fields = StringUtils.split(searchFields, ',');
            List<Message> filteredMsgs = new ArrayList<Message>();

            Date searchDate = null;
            try {
                searchDate = DateUtils.parseDate(searchText, new String[] { "dd.MM.yyyy" });
            } catch (Exception e) {
                // do nothing
            }

            try {
                for (Message message : msgs) {
                    boolean contains = false;
                    for (String searchField : fields) {
                        if (MessageListFields.SUBJECT.name().equals(searchField)) {
                            String subject = message.getSubject();
                            contains = StringUtils.containsIgnoreCase(subject, searchText);
                        } else if (MessageListFields.FROM.name().equals(searchField)) {
                            String from = MessageUtils.getMailAdressString(message.getFrom(),
                                    AddressStringType.COMPLETE);
                            contains = StringUtils.containsIgnoreCase(from, searchText) || contains;
                        } else if (searchDate != null && MessageListFields.DATE.name().equals(searchField)) {
                            Date sendDate = message.getSentDate();
                            contains = (sendDate != null && DateUtils.isSameDay(searchDate, sendDate)) || contains;
                        }
                    }
                    if (contains) {
                        filteredMsgs.add(message);
                    }
                }
            } catch (MessagingException ex) {
                log.warn(ex.getMessage(), ex);
            }

            return filteredMsgs.toArray(new Message[0]);
        }

        return msgs;
    }

    /**
     * @param mailFolder
     * @param msgs
     * @param extendedSearchFields
     * @param params
     * @return
     */
    public static Message[] filterMessages(IMailFolder mailFolder, Message[] msgs, String extendedSearchFields,
            String[][] params) {

        if (!StringUtils.isEmpty(extendedSearchFields)) {
            String[] fields = StringUtils.split(extendedSearchFields, ',');

            List<Message> filteredMsgs = new ArrayList<Message>();
            String fromValue = getParamValue(params, SearchFields.FROM.name());
            String toValue = getParamValue(params, SearchFields.TO.name());
            String ccValue = getParamValue(params, SearchFields.CC.name());
            String subjectValue = getParamValue(params, SearchFields.SUBJECT.name());
            String contentValue = getParamValue(params, SearchFields.CONTENT.name());
            String dateFromValue = getParamValue(params, SearchFields.DATE_FROM.name());
            String dateToValue = getParamValue(params, SearchFields.DATE_TO.name());

            try {
                // Body search
                if (StringUtils.contains(extendedSearchFields, SearchFields.CONTENT.name())) {
                    BodyTerm term = new BodyTerm(contentValue);
                    msgs = mailFolder.search(term, msgs);
                    if (msgs == null) {
                        msgs = new Message[0];
                    }
                }

                for (Message message : msgs) {
                    boolean contains = true;
                    for (String searchField : fields) {
                        if (SearchFields.FROM.name().equals(searchField)) {
                            String from = MessageUtils.getMailAdressString(message.getFrom(),
                                    AddressStringType.COMPLETE);
                            contains = StringUtils.containsIgnoreCase(from, fromValue);
                        }
                        if (contains && SearchFields.TO.name().equals(searchField)) {
                            String to = MessageUtils.getMailAdressString(
                                    message.getRecipients(Message.RecipientType.TO), AddressStringType.COMPLETE);
                            if (!StringUtils.isEmpty(to)) {
                                contains = StringUtils.containsIgnoreCase(to, toValue);
                            } else {
                                contains = false;
                            }
                        }
                        if (contains && SearchFields.CC.name().equals(searchField)) {
                            String cc = MessageUtils.getMailAdressString(
                                    message.getRecipients(Message.RecipientType.CC), AddressStringType.COMPLETE);
                            if (!StringUtils.isEmpty(cc)) {
                                contains = StringUtils.containsIgnoreCase(cc, ccValue);
                            } else {
                                contains = false;
                            }
                        }
                        if (contains && SearchFields.SUBJECT.name().equals(searchField)) {
                            if (!StringUtils.isEmpty(message.getSubject())) {
                                contains = StringUtils.containsIgnoreCase(message.getSubject(), subjectValue);
                            } else {
                                contains = false;
                            }
                        }
                        if (contains && SearchFields.DATE_FROM.name().equals(searchField)) {
                            Date dateFrom = new Date(Long.parseLong(dateFromValue));
                            if (message.getSentDate() != null) {
                                contains = !message.getSentDate().before(dateFrom);
                            } else {
                                contains = false;
                            }
                        }
                        if (contains && SearchFields.DATE_TO.name().equals(searchField)) {
                            Date dateTo = new Date(Long.parseLong(dateToValue));
                            if (message.getSentDate() != null) {
                                contains = !message.getSentDate().after(dateTo);
                            } else {
                                contains = false;
                            }
                        }
                    }
                    if (contains) {
                        filteredMsgs.add(message);
                    }
                }
            } catch (MessagingException ex) {
                log.warn(ex.getMessage());
            }

            return filteredMsgs.toArray(new Message[0]);
        }

        return msgs;
    }

    /**
     * @param complete
     * @param sortfield
     * @return
     */
    public static FetchProfile createFetchProfile(boolean complete, String sortfield) {

        FetchProfile fp = new FetchProfile();
        if (complete) {
            fp.add(FetchProfile.Item.ENVELOPE);
            fp.add(FetchProfile.Item.FLAGS);
            fp.add(FetchProfile.Item.CONTENT_INFO);
            fp.add(IMAPFolder.FetchProfileItem.SIZE);
            fp.add(CubusConstants.FETCH_ITEM_PRIORITY);
            fp.add(UIDFolder.FetchProfileItem.UID);
        } else {
            if (sortfield != null) {
                if (MessageListFields.ATTACHMENT_FLAG.name().equals(sortfield)) {
                    fp.add(FetchProfile.Item.CONTENT_INFO);
                } else if (MessageListFields.SUBJECT.name().equals(sortfield)
                        || MessageListFields.FROM.name().equals(sortfield)
                        || MessageListFields.TO.name().equals(sortfield)
                        || MessageListFields.DATE.name().equals(sortfield)) {
                    fp.add(FetchProfile.Item.ENVELOPE);
                } else if (MessageListFields.SIZE.name().equals(sortfield)) {
                    fp.add(IMAPFolder.FetchProfileItem.SIZE);
                }
            }
        }
        return fp;
    }

    /**
     * @param params
     * @param paramName
     * @return
     */
    public static String getParamValue(String[][] params, String paramName) {

        String result = null;

        if (params != null) {
            for (int i = 0; i < params.length; i++) {
                if (params[i] != null && params[i].length == 2 && paramName.equals(params[i][0])) {
                    return params[i][1];
                }
            }
        }

        return result;
    }
}