001    /**
002     * Copyright (c) 2000-2010 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.Iterator;
028    import java.util.List;
029    
030    import javax.mail.Address;
031    import javax.mail.Flags;
032    import javax.mail.Folder;
033    import javax.mail.Message.RecipientType;
034    import javax.mail.Message;
035    import javax.mail.MessagingException;
036    import javax.mail.Session;
037    import javax.mail.Store;
038    import javax.mail.internet.InternetAddress;
039    
040    /**
041     * @author Brian Wing Shun Chan
042     */
043    public class POPNotificationsMessageListener
044            implements com.liferay.portal.kernel.messaging.MessageListener {
045    
046            public void receive(com.liferay.portal.kernel.messaging.Message message) {
047                    try {
048                            doReceive(message);
049                    }
050                    catch (Exception e) {
051                            _log.error("Unable to process message " + message, e);
052                    }
053            }
054    
055            protected void doReceive(
056                            com.liferay.portal.kernel.messaging.Message message)
057                    throws Exception {
058    
059                    try {
060                            pollPopServer();
061                    }
062                    finally {
063                            _store = null;
064                            _inboxFolder = null;
065                    }
066            }
067    
068            protected String getEmailAddress(Address[] addresses) {
069                    if ((addresses == null) || (addresses.length == 0)) {
070                            return StringPool.BLANK;
071                    }
072    
073                    InternetAddress internetAddress = (InternetAddress)addresses[0];
074    
075                    return internetAddress.getAddress();
076            }
077    
078            protected void initInboxFolder() throws Exception {
079                    if ((_inboxFolder == null) || !_inboxFolder.isOpen()) {
080                            initStore();
081    
082                            Folder defaultFolder = _store.getDefaultFolder();
083    
084                            Folder[] folders = defaultFolder.list();
085    
086                            if (folders.length == 0) {
087                                    throw new MessagingException("Inbox not found");
088                            }
089                            else {
090                                    _inboxFolder = folders[0];
091    
092                                    _inboxFolder.open(Folder.READ_WRITE);
093                            }
094                    }
095            }
096    
097            protected void initStore() throws Exception {
098                    if ((_store == null) || !_store.isConnected()) {
099                            Session session = MailEngine.getSession();
100    
101                            String storeProtocol = GetterUtil.getString(
102                                    session.getProperty("mail.store.protocol"));
103    
104                            if (!storeProtocol.equals(Account.PROTOCOL_POPS)) {
105                                    storeProtocol = Account.PROTOCOL_POP;
106                            }
107    
108                            _store = session.getStore(storeProtocol);
109    
110                            String prefix = "mail." + storeProtocol + ".";
111    
112                            String host = session.getProperty(prefix + "host");
113    
114                            String user = session.getProperty(prefix + "user");
115    
116                            if (Validator.isNull(user)) {
117                                    user = session.getProperty("mail.smtp.user");
118                            }
119    
120                            String password = session.getProperty(prefix + "password");
121    
122                            if (Validator.isNull(password)) {
123                                    password = session.getProperty("mail.smtp.password");
124                            }
125    
126                            _store.connect(host, user, password);
127                    }
128            }
129    
130            protected void nostifyListeners(
131                            List<MessageListener> listeners, Message message)
132                    throws Exception {
133    
134                    String from = getEmailAddress(message.getFrom());
135                    String recipient = getEmailAddress(
136                            message.getRecipients(RecipientType.TO));
137    
138                    if (_log.isDebugEnabled()) {
139                            _log.debug("From " + from);
140                            _log.debug("Recipient " + recipient);
141                    }
142    
143                    Iterator<MessageListener> itr = listeners.iterator();
144    
145                    while (itr.hasNext()) {
146                            MessageListener messageListener = itr.next();
147    
148                            try {
149                                    if (messageListener.accept(from, recipient, message)) {
150                                            messageListener.deliver(from, recipient, message);
151                                    }
152                            }
153                            catch (Exception e) {
154                                    _log.error(e, e);
155                            }
156                    }
157            }
158    
159            protected void nostifyListeners(Message[] messages) throws Exception {
160                    if (_log.isDebugEnabled()) {
161                            _log.debug("Messages " + messages.length);
162                    }
163    
164                    List<MessageListener> listeners = POPServerUtil.getListeners();
165    
166                    for (int i = 0; i < messages.length; i++) {
167                            Message message = messages[i];
168    
169                            if (_log.isDebugEnabled()) {
170                                    _log.debug("Message " + message);
171                            }
172    
173                            nostifyListeners(listeners, message);
174                    }
175            }
176    
177            protected void pollPopServer() throws Exception {
178                    initInboxFolder();
179    
180                    Message[] messages = _inboxFolder.getMessages();
181    
182                    try {
183                            nostifyListeners(messages);
184                    }
185                    finally {
186                            if (_log.isDebugEnabled()) {
187                                    _log.debug("Deleting messages");
188                            }
189    
190                            _inboxFolder.setFlags(
191                                    messages, new Flags(Flags.Flag.DELETED), true);
192    
193                            _inboxFolder.close(true);
194                    }
195            }
196    
197            private static Log _log = LogFactoryUtil.getLog(
198                    POPNotificationsMessageListener.class);
199    
200            private Folder _inboxFolder;
201            private Store _store;
202    
203    }