001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.pop.messaging;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.mail.Account;
020    import com.liferay.portal.kernel.pop.MessageListener;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.StringPool;
023    import com.liferay.portal.kernel.util.Validator;
024    import com.liferay.portal.pop.POPServerUtil;
025    import com.liferay.util.mail.MailEngine;
026    
027    import java.util.List;
028    
029    import javax.mail.Address;
030    import javax.mail.Flags;
031    import javax.mail.Folder;
032    import javax.mail.Message;
033    import javax.mail.Message.RecipientType;
034    import javax.mail.MessagingException;
035    import javax.mail.Session;
036    import javax.mail.Store;
037    import javax.mail.internet.InternetAddress;
038    
039    /**
040     * @author Brian Wing Shun Chan
041     */
042    public class POPNotificationsMessageListener
043            extends com.liferay.portal.kernel.messaging.BaseMessageListener {
044    
045            @Override
046            protected void doReceive(
047                            com.liferay.portal.kernel.messaging.Message message)
048                    throws Exception {
049    
050                    try {
051                            pollPopServer();
052                    }
053                    finally {
054                            _store = null;
055                            _inboxFolder = null;
056                    }
057            }
058    
059            protected String getEmailAddress(Address[] addresses) {
060                    if ((addresses == null) || (addresses.length == 0)) {
061                            return StringPool.BLANK;
062                    }
063    
064                    InternetAddress internetAddress = (InternetAddress)addresses[0];
065    
066                    return internetAddress.getAddress();
067            }
068    
069            protected void initInboxFolder() throws Exception {
070                    if ((_inboxFolder == null) || !_inboxFolder.isOpen()) {
071                            initStore();
072    
073                            Folder defaultFolder = _store.getDefaultFolder();
074    
075                            Folder[] folders = defaultFolder.list();
076    
077                            if (folders.length == 0) {
078                                    throw new MessagingException("Inbox not found");
079                            }
080                            else {
081                                    _inboxFolder = folders[0];
082    
083                                    _inboxFolder.open(Folder.READ_WRITE);
084                            }
085                    }
086            }
087    
088            protected void initStore() throws Exception {
089                    if ((_store != null) && _store.isConnected()) {
090                            return;
091                    }
092    
093                    Session session = MailEngine.getSession();
094    
095                    String storeProtocol = GetterUtil.getString(
096                            session.getProperty("mail.store.protocol"));
097    
098                    if (!storeProtocol.equals(Account.PROTOCOL_POPS)) {
099                            storeProtocol = Account.PROTOCOL_POP;
100                    }
101    
102                    _store = session.getStore(storeProtocol);
103    
104                    String prefix = "mail." + storeProtocol + ".";
105    
106                    String host = session.getProperty(prefix + "host");
107    
108                    String user = session.getProperty(prefix + "user");
109    
110                    if (Validator.isNull(user)) {
111                            user = session.getProperty("mail.smtp.user");
112                    }
113    
114                    String password = session.getProperty(prefix + "password");
115    
116                    if (Validator.isNull(password)) {
117                            password = session.getProperty("mail.smtp.password");
118                    }
119    
120                    _store.connect(host, user, password);
121            }
122    
123            protected void notifyMessageListeners(
124                            List<MessageListener> messageListeners, Message message)
125                    throws Exception {
126    
127                    String from = getEmailAddress(message.getFrom());
128                    String recipient = getEmailAddress(
129                            message.getRecipients(RecipientType.TO));
130    
131                    if (_log.isDebugEnabled()) {
132                            _log.debug("From " + from);
133                            _log.debug("Recipient " + recipient);
134                    }
135    
136                    for (MessageListener messageListener : messageListeners) {
137                            try {
138                                    if (messageListener.accept(from, recipient, message)) {
139                                            messageListener.deliver(from, recipient, message);
140                                    }
141                            }
142                            catch (Exception e) {
143                                    _log.error(e, e);
144                            }
145                    }
146            }
147    
148            protected void notifyMessageListeners(Message[] messages) throws Exception {
149                    if (_log.isDebugEnabled()) {
150                            _log.debug("Messages " + messages.length);
151                    }
152    
153                    List<MessageListener> messageListeners = POPServerUtil.getListeners();
154    
155                    for (int i = 0; i < messages.length; i++) {
156                            Message message = messages[i];
157    
158                            if (_log.isDebugEnabled()) {
159                                    _log.debug("Message " + message);
160                            }
161    
162                            notifyMessageListeners(messageListeners, message);
163                    }
164            }
165    
166            protected void pollPopServer() throws Exception {
167                    initInboxFolder();
168    
169                    Message[] messages = _inboxFolder.getMessages();
170    
171                    try {
172                            notifyMessageListeners(messages);
173                    }
174                    finally {
175                            if (_log.isDebugEnabled()) {
176                                    _log.debug("Deleting messages");
177                            }
178    
179                            _inboxFolder.setFlags(
180                                    messages, new Flags(Flags.Flag.DELETED), true);
181    
182                            _inboxFolder.close(true);
183                    }
184            }
185    
186            private static Log _log = LogFactoryUtil.getLog(
187                    POPNotificationsMessageListener.class);
188    
189            private Folder _inboxFolder;
190            private Store _store;
191    
192    }