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