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.portlet.messageboards.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.messaging.BaseMessageListener;
021    import com.liferay.portal.kernel.util.ObjectValuePair;
022    import com.liferay.portal.kernel.util.StreamUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.model.User;
025    import com.liferay.portal.security.permission.PermissionCheckerUtil;
026    import com.liferay.portal.service.ServiceContext;
027    import com.liferay.portal.service.UserLocalServiceUtil;
028    import com.liferay.portal.util.PortalUtil;
029    import com.liferay.portal.util.PortletKeys;
030    import com.liferay.portlet.messageboards.NoSuchMessageException;
031    import com.liferay.portlet.messageboards.model.MBMessage;
032    import com.liferay.portlet.messageboards.model.MBMessageConstants;
033    import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
034    import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
035    import com.liferay.portlet.messageboards.util.MBMailMessage;
036    import com.liferay.portlet.messageboards.util.MBUtil;
037    import com.liferay.portlet.messageboards.util.MailingListThreadLocal;
038    import com.liferay.util.mail.MailEngine;
039    
040    import java.io.InputStream;
041    
042    import java.util.List;
043    
044    import javax.mail.Address;
045    import javax.mail.Flags;
046    import javax.mail.Folder;
047    import javax.mail.Message;
048    import javax.mail.MessagingException;
049    import javax.mail.Session;
050    import javax.mail.Store;
051    import javax.mail.URLName;
052    import javax.mail.internet.InternetAddress;
053    
054    /**
055     * @author Thiago Moreira
056     */
057    public class MailingListMessageListener extends BaseMessageListener {
058    
059            @Override
060            protected void doReceive(
061                            com.liferay.portal.kernel.messaging.Message message)
062                    throws Exception {
063    
064                    MailingListRequest mailingListRequest =
065                            (MailingListRequest)message.getPayload();
066    
067                    Store store = null;
068    
069                    Folder folder = null;
070    
071                    Message[] messages = null;
072    
073                    try {
074                            store = getStore(mailingListRequest);
075    
076                            store.connect();
077    
078                            folder = getFolder(store);
079    
080                            messages = folder.getMessages();
081    
082                            processMessages(mailingListRequest, messages);
083                    }
084                    finally {
085                            if ((folder != null) && folder.isOpen()) {
086                                    try {
087                                            folder.setFlags(
088                                                    messages, new Flags(Flags.Flag.DELETED), true);
089                                    }
090                                    catch (Exception e) {
091                                    }
092    
093                                    try {
094                                            folder.close(true);
095                                    }
096                                    catch (Exception e) {
097                                    }
098                            }
099    
100                            if ((store != null) && store.isConnected()) {
101                                    try {
102                                            store.close();
103                                    }
104                                    catch (MessagingException me) {
105                                    }
106                            }
107                    }
108            }
109    
110            protected Folder getFolder(Store store) throws Exception {
111                    Folder folder = store.getFolder("INBOX");
112    
113                    if (!folder.exists()) {
114                            throw new MessagingException("Inbox not found");
115                    }
116    
117                    folder.open(Folder.READ_WRITE);
118    
119                    return folder;
120            }
121    
122            protected Store getStore(MailingListRequest mailingListRequest)
123                    throws Exception {
124    
125                    String protocol = mailingListRequest.getInProtocol();
126                    String host = mailingListRequest.getInServerName();
127                    int port = mailingListRequest.getInServerPort();
128                    String user = mailingListRequest.getInUserName();
129                    String password = mailingListRequest.getInPassword();
130    
131                    Account account = Account.getInstance(protocol, port);
132    
133                    account.setHost(host);
134                    account.setPort(port);
135                    account.setUser(user);
136                    account.setPassword(password);
137    
138                    Session session = MailEngine.getSession(account);
139    
140                    URLName urlName = new URLName(
141                            protocol, host, port, StringPool.BLANK, user, password);
142    
143                    Store store = session.getStore(urlName);
144    
145                    return store;
146            }
147    
148            protected void processMessage(
149                            MailingListRequest mailingListRequest, Message mailMessage)
150                    throws Exception {
151    
152                    if (MBUtil.hasMailIdHeader(mailMessage)) {
153                            return;
154                    }
155    
156                    String from = null;
157    
158                    Address[] addresses = mailMessage.getFrom();
159    
160                    if ((addresses != null) && (addresses.length > 0)) {
161                            Address address = addresses[0];
162    
163                            if (address instanceof InternetAddress) {
164                                    from = ((InternetAddress)address).getAddress();
165                            }
166                            else {
167                                    from = address.toString();
168                            }
169                    }
170    
171                    long companyId = mailingListRequest.getCompanyId();
172                    long groupId = mailingListRequest.getGroupId();
173                    long categoryId = mailingListRequest.getCategoryId();
174    
175                    if (_log.isDebugEnabled()) {
176                            _log.debug("Category id " + categoryId);
177                    }
178    
179                    boolean anonymous = false;
180    
181                    User user = UserLocalServiceUtil.fetchUserByEmailAddress(
182                            companyId, from);
183    
184                    if (user == null) {
185                            if (!mailingListRequest.isAllowAnonymous()) {
186                                    return;
187                            }
188    
189                            anonymous = true;
190    
191                            user = UserLocalServiceUtil.getUserById(
192                                    companyId, mailingListRequest.getUserId());
193                    }
194    
195                    long parentMessageId = MBUtil.getParentMessageId(mailMessage);
196    
197                    if (_log.isDebugEnabled()) {
198                            _log.debug("Parent message id " + parentMessageId);
199                    }
200    
201                    MBMessage parentMessage = null;
202    
203                    try {
204                            if (parentMessageId > 0) {
205                                    parentMessage = MBMessageLocalServiceUtil.getMessage(
206                                            parentMessageId);
207                            }
208                    }
209                    catch (NoSuchMessageException nsme) {
210                    }
211    
212                    if (_log.isDebugEnabled()) {
213                            _log.debug("Parent message " + parentMessage);
214                    }
215    
216                    MBMailMessage mbMailMessage = new MBMailMessage();
217    
218                    MBUtil.collectPartContent(mailMessage, mbMailMessage);
219    
220                    PermissionCheckerUtil.setThreadValues(user);
221    
222                    MailingListThreadLocal.setSourceMailingList(true);
223    
224                    String subject = MBUtil.getSubjectWithoutMessageId(mailMessage);
225    
226                    ServiceContext serviceContext = new ServiceContext();
227    
228                    serviceContext.setAddGroupPermissions(true);
229                    serviceContext.setAddGuestPermissions(true);
230                    serviceContext.setLayoutFullURL(
231                            PortalUtil.getLayoutFullURL(groupId, PortletKeys.MESSAGE_BOARDS));
232                    serviceContext.setScopeGroupId(groupId);
233    
234                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
235                            mbMailMessage.getInputStreamOVPs();
236    
237                    try {
238                            if (parentMessage == null) {
239                                    MBMessageServiceUtil.addMessage(
240                                            groupId, categoryId, subject, mbMailMessage.getBody(),
241                                            MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs,
242                                            anonymous, 0.0, true, serviceContext);
243                            }
244                            else {
245                                    MBMessageServiceUtil.addMessage(
246                                            parentMessage.getMessageId(), subject,
247                                            mbMailMessage.getBody(), MBMessageConstants.DEFAULT_FORMAT,
248                                            inputStreamOVPs, anonymous, 0.0, true, serviceContext);
249                            }
250                    }
251                    finally {
252                            for (ObjectValuePair<String, InputStream> inputStreamOVP :
253                                            inputStreamOVPs) {
254    
255                                    InputStream inputStream = inputStreamOVP.getValue();
256    
257                                    StreamUtil.cleanUp(inputStream);
258                            }
259                    }
260            }
261    
262            protected void processMessages(
263                            MailingListRequest mailingListRequest, Message[] messages)
264                    throws Exception {
265    
266                    for (Message message : messages) {
267                            try {
268                                    processMessage(mailingListRequest, message);
269                            }
270                            finally {
271                                    PermissionCheckerUtil.setThreadValues(null);
272                            }
273                    }
274            }
275    
276            private static Log _log = LogFactoryUtil.getLog(
277                    MailingListMessageListener.class);
278    
279    }