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