Package ariba.appcore.util

Source Code of ariba.appcore.util.MailMonitor

package ariba.appcore.util;

import ariba.ui.meta.persistence.ObjectContext;
import ariba.ui.aribaweb.util.AWGenericException;
import ariba.ui.aribaweb.util.AWMimeParsedMessage;
import ariba.util.core.Assert;
import ariba.util.core.ProgressMonitor;
import ariba.util.core.Fmt;
import ariba.appcore.Global;
import ariba.appcore.User;

import com.sun.mail.imap.IMAPFolder;

import javax.mail.Store;
import javax.mail.Folder;
import javax.mail.Session;
import javax.mail.MessagingException;
import javax.mail.AuthenticationFailedException;
import javax.mail.Message;
import javax.mail.event.MessageCountAdapter;
import javax.mail.event.MessageCountEvent;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.InternetAddress;
import java.util.Properties;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;


public class MailMonitor
{
    public interface MessageHandler
    {
        void process (MimeMessage message);
    }

    Store _store;
    Folder _inbox;
    Properties _loginParams;

    static final String ProtocolProperty = "mail.store.protocol";
    static final int NewMessagePollIntervalMsec = 10*1000;
    static Session session;

    static void initialize (Properties loginParams)
    {
        if (session == null) {
            session = Session.getDefaultInstance(loginParams, null);
        }
    }

    static Session sharedSession ()
    {
        Assert.that(session != null, "sharedSession called before initialize");
        return session;
    }

    public static MimeMessage mimeForData (byte[] mimeData)
    {
        ByteArrayInputStream is = new ByteArrayInputStream(mimeData);
        try {
            return new MimeMessage(sharedSession(), is);
        } catch (MessagingException e) {
            throw new AWGenericException(e);
        }
    }

    public static byte[] bytesForMime (MimeMessage message)
    {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            message.writeTo(os);
        } catch (IOException e) {
            throw new AWGenericException(e);
        } catch (MessagingException e) {
            throw new AWGenericException(e);
        }
        return os.toByteArray();       
    }

    public MailMonitor (Properties loginParams)
    {
        _loginParams = loginParams;
    }

    public static Store connect (Properties loginParams) throws AuthenticationFailedException
    {
        initialize(loginParams);
        ProgressMonitor.instance().prepare("Connecting to mail server...", 0);
        String protocol = (String)loginParams.get(ProtocolProperty);
        Store store = null;
        try {
            store = session.getStore(protocol);
            String host = (String)loginParams.get(Fmt.S("mail.%s.host", protocol));
            String userName = (String)loginParams.get("mail.username");
            String password = (String)loginParams.get("mail.password");
            store.connect(host, userName, password);
        } catch (MessagingException e) {
           throw new AWGenericException(e);
        }
        return store;
    }

    void connect ()
    {
        try {
            _store = connect(_loginParams);
            _inbox = _store.getFolder("INBOX");
            ProgressMonitor.instance().prepare("Fetching messages for folder ${inbox.name}...".toString(), 0);
            _inbox.open(Folder.READ_ONLY);
        } catch (AuthenticationFailedException e) {
            throw new AWGenericException("Failed to login: ${e.getMessage()}".toString(), e);
        } catch (MessagingException e) {
            throw new AWGenericException("Failed to login: ${e.getMessage()}".toString(), e);
        }
    }

    static final String _LastProcessedKey = MailMonitor.class.getName();

    static String getMessageID (Message message)
    {
        try {
            return ((MimeMessage)message).getMessageID();
        } catch (MessagingException e) {
            throw new AWGenericException(e);
        }
    }

    // Todo:  add support for getNewMessagesSince...
    public void process (int atMost, MessageHandler handler)
    {
        ObjectContext.bindNewContext();
        connect();

        Message[] messages;
        try {
            messages = _inbox.getMessages();
        } catch (MessagingException e) {
            throw new AWGenericException(e);
        }
        int count = messages.length;
        int start = Math.max(0, count-atMost);

        // we persist the ID of the last message that we processed
        Global proceededRecord = Global.findOrCreate(_LastProcessedKey);
        String lastId = proceededRecord.getStringValue();
        if (lastId != null) {
            // backup until we hit our id (or the start
            for (int i=count-1; i >=start; i--) {
                if (getMessageID(messages[i]).equals(lastId)) {
                    start = i + 1;
                    break;
                }
            }
        }

        // process backlog
        for (int i=start; i < count; i++) {
            MimeMessage message = (MimeMessage)messages[i];
            proceededRecord.setStringValue(getMessageID(message));
            ObjectContext.get().save();
            handler.process(message);
        }

      processIncomingMessages(_inbox, handler, proceededRecord);
    }

    void processIncomingMessages (Folder folder, final MessageHandler handler, final Global proceededRecord)
    {
        // event handler for new ones
        MessageCountAdapter listener = new MessageCountAdapter() {
            public void messagesAdded (MessageCountEvent ev)
            {
                Message[] messages = ev.getMessages();

                System.out.printf("New messages: %s\n", messages.length);
                ObjectContext.bindNewContext();
                for (Message m : messages) {
                    MimeMessage message = (MimeMessage)m;
                    proceededRecord.setStringValue(getMessageID(message));
                    ObjectContext.get().save();

                    handler.process(message);
                }
            }
        };

        folder.addMessageCountListener(listener);

        try {
            while (true) {
                if (folder instanceof IMAPFolder) {
                    System.out.println("Using IMAP IDLE...");
                    try {
                        ((IMAPFolder)folder).idle();
                    } catch (Exception e) {
                        // Continue / reconnect
                    } finally {
                        folder.removeMessageCountListener(listener);
                        if (!folder.isOpen()) folder.open(Folder.READ_ONLY);
                        folder.addMessageCountListener(listener);
                    }
                } else {
                        int count = _inbox.getMessageCount();
                        System.out.printf("Checked Inbox... count = %s", count);
                        Thread.currentThread().sleep(NewMessagePollIntervalMsec);
                }
            }
        } catch (Exception e) {
            throw new AWGenericException(e);
        }
    }


    private static final Pattern _FromPattern = Pattern.compile(
            "(?m)^From: (?:\"(.+?)\")?\\s?<(.+?)>$");

    public static User findOrCreateSender (AWMimeParsedMessage parsedMessage)
    {
        User sender = null;
        if (parsedMessage.getIsPureForward()) {
            String text = parsedMessage.plainTextForPart(parsedMessage.getTopLevelParts().get(0));
            Matcher m = _FromPattern.matcher(text);
            if (m.find()) {
                sender = User.findOrCreate(m.group(2), m.group(1));
            }
        }

        if (sender == null) {
            MimeMessage message = parsedMessage.getMessage();
            InternetAddress from = null;
            try {
                from = (InternetAddress)message.getFrom()[0];
            } catch (MessagingException e) {
                throw new AWGenericException(e);
            }
            sender = User.findOrCreate(from.getAddress(), from.getPersonal());
        }
        return sender;
    }
}
TOP

Related Classes of ariba.appcore.util.MailMonitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.