001    /**
002     * Copyright (c) 2000-present 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.ArrayUtil;
022    import com.liferay.portal.kernel.util.ObjectValuePair;
023    import com.liferay.portal.kernel.util.StreamUtil;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.model.User;
026    import com.liferay.portal.security.permission.PermissionCheckerUtil;
027    import com.liferay.portal.service.ServiceContext;
028    import com.liferay.portal.service.UserLocalServiceUtil;
029    import com.liferay.portal.util.PortalUtil;
030    import com.liferay.portal.util.PortletKeys;
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 (ArrayUtil.isNotEmpty(addresses)) {
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                    if (parentMessageId > 0) {
204                            parentMessage = MBMessageLocalServiceUtil.fetchMBMessage(
205                                    parentMessageId);
206                    }
207    
208                    if (_log.isDebugEnabled()) {
209                            _log.debug("Parent message " + parentMessage);
210                    }
211    
212                    MBMailMessage mbMailMessage = new MBMailMessage();
213    
214                    MBUtil.collectPartContent(mailMessage, mbMailMessage);
215    
216                    PermissionCheckerUtil.setThreadValues(user);
217    
218                    MailingListThreadLocal.setSourceMailingList(true);
219    
220                    String subject = MBUtil.getSubjectWithoutMessageId(mailMessage);
221    
222                    ServiceContext serviceContext = new ServiceContext();
223    
224                    serviceContext.setAddGroupPermissions(true);
225                    serviceContext.setAddGuestPermissions(true);
226                    serviceContext.setLayoutFullURL(
227                            PortalUtil.getLayoutFullURL(groupId, PortletKeys.MESSAGE_BOARDS));
228                    serviceContext.setScopeGroupId(groupId);
229    
230                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
231                            mbMailMessage.getInputStreamOVPs();
232    
233                    try {
234                            if (parentMessage == null) {
235                                    MBMessageServiceUtil.addMessage(
236                                            groupId, categoryId, subject, mbMailMessage.getBody(),
237                                            MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs,
238                                            anonymous, 0.0, true, serviceContext);
239                            }
240                            else {
241                                    MBMessageServiceUtil.addMessage(
242                                            parentMessage.getMessageId(), subject,
243                                            mbMailMessage.getBody(), MBMessageConstants.DEFAULT_FORMAT,
244                                            inputStreamOVPs, anonymous, 0.0, true, serviceContext);
245                            }
246                    }
247                    finally {
248                            for (ObjectValuePair<String, InputStream> inputStreamOVP :
249                                            inputStreamOVPs) {
250    
251                                    InputStream inputStream = inputStreamOVP.getValue();
252    
253                                    StreamUtil.cleanUp(inputStream);
254                            }
255                    }
256            }
257    
258            protected void processMessages(
259                            MailingListRequest mailingListRequest, Message[] messages)
260                    throws Exception {
261    
262                    for (Message message : messages) {
263                            try {
264                                    processMessage(mailingListRequest, message);
265                            }
266                            finally {
267                                    PermissionCheckerUtil.setThreadValues(null);
268                            }
269                    }
270            }
271    
272            private static final Log _log = LogFactoryUtil.getLog(
273                    MailingListMessageListener.class);
274    
275    }