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.portlet.messageboards.messaging;
016    
017    import com.liferay.portal.NoSuchUserException;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.mail.Account;
021    import com.liferay.portal.kernel.messaging.BaseMessageListener;
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.NoSuchMessageException;
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 e) {
106                                    }
107                            }
108                    }
109            }
110    
111            protected Folder getFolder(Store store) throws Exception {
112                    Folder defaultFolder = store.getDefaultFolder();
113    
114                    Folder[] folders = defaultFolder.list();
115    
116                    if ((folders != null) && (folders.length == 0)) {
117                            throw new MessagingException("Inbox not found");
118                    }
119    
120                    Folder folder = folders[0];
121    
122                    folder.open(Folder.READ_WRITE);
123    
124                    return folder;
125            }
126    
127            protected Store getStore(MailingListRequest mailingListRequest)
128                    throws Exception {
129    
130                    String protocol = mailingListRequest.getInProtocol();
131                    String host = mailingListRequest.getInServerName();
132                    int port = mailingListRequest.getInServerPort();
133                    String user = mailingListRequest.getInUserName();
134                    String password = mailingListRequest.getInPassword();
135    
136                    Account account = Account.getInstance(protocol, port);
137    
138                    account.setHost(host);
139                    account.setPort(port);
140                    account.setUser(user);
141                    account.setPassword(password);
142    
143                    Session session = MailEngine.getSession(account);
144    
145                    URLName urlName = new URLName(
146                            protocol, host, port, StringPool.BLANK, user, password);
147    
148                    Store store = session.getStore(urlName);
149    
150                    return store;
151            }
152    
153            protected void processMessage(
154                            MailingListRequest mailingListRequest, Message mailMessage)
155                    throws Exception {
156    
157                    if (MBUtil.hasMailIdHeader(mailMessage)) {
158                            return;
159                    }
160    
161                    String from = null;
162    
163                    Address[] addresses = mailMessage.getFrom();
164    
165                    if ((addresses != null) && (addresses.length > 0)) {
166                            Address address = addresses[0];
167    
168                            if (address instanceof InternetAddress) {
169                                    from = ((InternetAddress)address).getAddress();
170                            }
171                            else {
172                                    from = address.toString();
173                            }
174                    }
175    
176                    long companyId = mailingListRequest.getCompanyId();
177                    long groupId = mailingListRequest.getGroupId();
178                    long categoryId = mailingListRequest.getCategoryId();
179    
180                    if (_log.isDebugEnabled()) {
181                            _log.debug("Category id " + categoryId);
182                    }
183    
184                    boolean anonymous = false;
185    
186                    User user = UserLocalServiceUtil.getUserById(
187                            companyId, mailingListRequest.getUserId());
188    
189                    try {
190                            user = UserLocalServiceUtil.getUserByEmailAddress(companyId, from);
191                    }
192                    catch (NoSuchUserException nsue) {
193                            anonymous = true;
194    
195                            if (!mailingListRequest.isAllowAnonymous()) {
196                                    return;
197                            }
198                    }
199    
200                    long parentMessageId = MBUtil.getParentMessageId(mailMessage);
201    
202                    if (_log.isDebugEnabled()) {
203                            _log.debug("Parent message id " + parentMessageId);
204                    }
205    
206                    MBMessage parentMessage = null;
207    
208                    try {
209                            if (parentMessageId > 0) {
210                                    parentMessage = MBMessageLocalServiceUtil.getMessage(
211                                            parentMessageId);
212                            }
213                    }
214                    catch (NoSuchMessageException nsme) {
215                    }
216    
217                    if (_log.isDebugEnabled()) {
218                            _log.debug("Parent message " + parentMessage);
219                    }
220    
221                    MBMailMessage mbMailMessage = new MBMailMessage();
222    
223                    MBUtil.collectPartContent(mailMessage, mbMailMessage);
224    
225                    PermissionCheckerUtil.setThreadValues(user);
226    
227                    MailingListThreadLocal.setSourceMailingList(true);
228    
229                    String subject = MBUtil.getSubjectWithoutMessageId(mailMessage);
230    
231                    ServiceContext serviceContext = new ServiceContext();
232    
233                    serviceContext.setAddGroupPermissions(true);
234                    serviceContext.setAddGuestPermissions(true);
235                    serviceContext.setLayoutFullURL(
236                            PortalUtil.getLayoutFullURL(groupId, PortletKeys.MESSAGE_BOARDS));
237                    serviceContext.setScopeGroupId(groupId);
238    
239                    List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
240                            mbMailMessage.getInputStreamOVPs();
241    
242                    try {
243                            if (parentMessage == null) {
244                                    MBMessageServiceUtil.addMessage(
245                                            groupId, categoryId, subject, mbMailMessage.getBody(),
246                                            MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs,
247                                            anonymous, 0.0, true, serviceContext);
248                            }
249                            else {
250                                    MBMessageServiceUtil.addMessage(
251                                            groupId, categoryId, parentMessage.getThreadId(),
252                                            parentMessage.getMessageId(), subject,
253                                            mbMailMessage.getBody(), MBMessageConstants.DEFAULT_FORMAT,
254                                            inputStreamOVPs, anonymous, 0.0, true, serviceContext);
255                            }
256                    }
257                    finally {
258                            for (ObjectValuePair<String, InputStream> inputStreamOVP :
259                                            inputStreamOVPs) {
260    
261                                    InputStream inputStream = inputStreamOVP.getValue();
262    
263                                    StreamUtil.cleanUp(inputStream);
264                            }
265                    }
266            }
267    
268            protected void processMessages(
269                            MailingListRequest mailingListRequest, Message[] messages)
270                    throws Exception {
271    
272                    for (Message message : messages) {
273                            try {
274                                    processMessage(mailingListRequest, message);
275                            }
276                            finally {
277                                    PermissionCheckerUtil.setThreadValues(null);
278                            }
279                    }
280            }
281    
282            private static Log _log = LogFactoryUtil.getLog(
283                    MailingListMessageListener.class);
284    
285    }