001    /**
002     * Copyright (c) 2000-2010 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.mail.service.MailServiceUtil;
018    import com.liferay.portal.NoSuchUserException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.mail.Account;
022    import com.liferay.portal.kernel.mail.MailMessage;
023    import com.liferay.portal.kernel.mail.SMTPAccount;
024    import com.liferay.portal.kernel.messaging.MessageListener;
025    import com.liferay.portal.kernel.util.StringPool;
026    import com.liferay.portal.kernel.util.StringUtil;
027    import com.liferay.portal.model.Subscription;
028    import com.liferay.portal.model.User;
029    import com.liferay.portal.service.SubscriptionLocalServiceUtil;
030    import com.liferay.portal.service.UserLocalServiceUtil;
031    import com.liferay.portlet.messageboards.NoSuchMailingListException;
032    import com.liferay.portlet.messageboards.model.MBCategory;
033    import com.liferay.portlet.messageboards.model.MBMailingList;
034    import com.liferay.portlet.messageboards.model.MBThread;
035    import com.liferay.portlet.messageboards.service.MBMailingListLocalServiceUtil;
036    import com.liferay.portlet.messageboards.util.BBCodeUtil;
037    
038    import java.util.ArrayList;
039    import java.util.HashSet;
040    import java.util.List;
041    import java.util.Set;
042    
043    import javax.mail.internet.InternetAddress;
044    
045    /**
046     * @author Brian Wing Shun Chan
047     * @author Thiago Moreira
048     */
049    public class MBMessageListener implements MessageListener {
050    
051            public void receive(com.liferay.portal.kernel.messaging.Message message) {
052                    try {
053                            doReceive(message);
054                    }
055                    catch (Exception e) {
056                            _log.error("Unable to process message " + message, e);
057                    }
058            }
059    
060            protected void doReceive(
061                            com.liferay.portal.kernel.messaging.Message message)
062                    throws Exception {
063    
064                    long companyId = message.getLong("companyId");
065                    long userId = message.getLong("userId");
066                    long groupId = message.getLong("groupId");
067                    String categoryIds = message.getString("categoryIds");
068                    long threadId = message.getLong("threadId");
069                    String fromName = message.getString("fromName");
070                    String fromAddress = message.getString("fromAddress");
071                    String subject = message.getString("subject");
072                    String body = message.getString("body");
073                    String replyToAddress = message.getString("replyToAddress");
074                    String mailId = message.getString("mailId");
075                    String inReplyTo = message.getString("inReplyTo");
076                    boolean htmlFormat = message.getBoolean("htmlFormat");
077                    boolean sourceMailingList = message.getBoolean("sourceMailingList");
078    
079                    if (sourceMailingList) {
080                            subject = getMailingListSubject(subject, mailId);
081                    }
082    
083                    Set<Long> sent = new HashSet<Long>();
084    
085                    if (_log.isInfoEnabled()) {
086                            _log.info(
087                                    "Sending notifications for {mailId=" + mailId + ", threadId=" +
088                                            threadId + ", categoryIds=" + categoryIds + "}");
089                    }
090    
091                    // Threads
092    
093                    List<Subscription> subscriptions =
094                            SubscriptionLocalServiceUtil.getSubscriptions(
095                                    companyId, MBThread.class.getName(), threadId);
096    
097                    sendEmail(
098                            userId, fromName, fromAddress, subject, body, subscriptions, sent,
099                            replyToAddress, mailId, inReplyTo, htmlFormat);
100    
101                    // Categories
102    
103                    long[] categoryIdsArray = StringUtil.split(categoryIds, 0L);
104    
105                    for (long categoryId : categoryIdsArray) {
106                            subscriptions = SubscriptionLocalServiceUtil.getSubscriptions(
107                                    companyId, MBCategory.class.getName(), categoryId);
108    
109                            sendEmail(
110                                    userId, fromName, fromAddress, subject, body, subscriptions,
111                                    sent, replyToAddress, mailId, inReplyTo, htmlFormat);
112                    }
113    
114                    // Mailing list
115    
116                    if (!sourceMailingList) {
117                            for (long categoryId : categoryIdsArray) {
118                                    try {
119                                            notifyMailingList(
120                                                    subject, body, replyToAddress, mailId, inReplyTo,
121                                                    htmlFormat, groupId, categoryId);
122                                    }
123                                    catch (NoSuchMailingListException nsmle) {
124                                    }
125                            }
126                    }
127    
128                    if (_log.isInfoEnabled()) {
129                            _log.info("Finished sending notifications");
130                    }
131            }
132    
133            protected String getMailingListSubject(String subject, String mailId) {
134                    return subject + StringPool.SPACE + mailId;
135            }
136    
137            protected void notifyMailingList(
138                            String subject, String body, String replyToAddress, String mailId,
139                            String inReplyTo, boolean htmlFormat, long groupId, long categoryId)
140                    throws Exception {
141    
142                    MBMailingList mailingList =
143                            MBMailingListLocalServiceUtil.getCategoryMailingList(
144                                    groupId, categoryId);
145    
146                    if (!mailingList.isActive()) {
147                            return;
148                    }
149    
150                    subject = getMailingListSubject(subject, mailId);
151    
152                    String fromAddress = mailingList.getOutEmailAddress();
153    
154                    InternetAddress[] bulkAddresses = new InternetAddress[] {
155                            new InternetAddress(mailingList.getEmailAddress())
156                    };
157    
158                    SMTPAccount account = null;
159    
160                    if (mailingList.isOutCustom()) {
161                            String protocol = Account.PROTOCOL_SMTP;
162    
163                            if (mailingList.isOutUseSSL()) {
164                                    protocol = Account.PROTOCOL_SMTPS;
165                            }
166    
167                            account = (SMTPAccount)Account.getInstance(
168                                    protocol, mailingList.getOutServerPort());
169    
170                            account.setHost(mailingList.getOutServerName());
171                            account.setUser(mailingList.getOutUserName());
172                            account.setPassword(mailingList.getOutPassword());
173                    }
174    
175                    sendMail(
176                            fromAddress, null, bulkAddresses, subject, body, replyToAddress,
177                            mailId, inReplyTo, htmlFormat, account);
178            }
179    
180            protected void sendEmail(
181                            long userId, String fromName, String fromAddress, String subject,
182                            String body, List<Subscription> subscriptions, Set<Long> sent,
183                            String replyToAddress, String mailId, String inReplyTo,
184                            boolean htmlFormat)
185                    throws Exception {
186    
187                    List<InternetAddress> addresses = new ArrayList<InternetAddress>();
188    
189                    for (Subscription subscription : subscriptions) {
190                            long subscribedUserId = subscription.getUserId();
191    
192                            if (sent.contains(subscribedUserId)) {
193                                    if (_log.isDebugEnabled()) {
194                                            _log.debug(
195                                                    "Do not send a duplicate email to user " +
196                                                            subscribedUserId);
197                                    }
198    
199                                    continue;
200                            }
201                            else {
202                                    if (_log.isDebugEnabled()) {
203                                            _log.debug(
204                                                    "Add user " + subscribedUserId +
205                                                            " to the list of users who have received an email");
206                                    }
207    
208                                    sent.add(subscribedUserId);
209                            }
210    
211                            User user = null;
212    
213                            try {
214                                    user = UserLocalServiceUtil.getUserById(subscribedUserId);
215                            }
216                            catch (NoSuchUserException nsue) {
217                                    if (_log.isInfoEnabled()) {
218                                            _log.info(
219                                                    "Subscription " + subscription.getSubscriptionId() +
220                                                            " is stale and will be deleted");
221                                    }
222    
223                                    SubscriptionLocalServiceUtil.deleteSubscription(
224                                            subscription.getSubscriptionId());
225    
226                                    continue;
227                            }
228    
229                            if (!user.isActive()) {
230                                    continue;
231                            }
232    
233                            InternetAddress userAddress = new InternetAddress(
234                                    user.getEmailAddress(), user.getFullName());
235    
236                            addresses.add(userAddress);
237                    }
238    
239                    InternetAddress[] bulkAddresses = addresses.toArray(
240                            new InternetAddress[addresses.size()]);
241    
242                    sendMail(
243                            fromAddress, fromName, bulkAddresses, subject, body, replyToAddress,
244                            mailId, inReplyTo, htmlFormat, null);
245            }
246    
247            protected void sendMail(
248                    String fromAddress, String fromName, InternetAddress[] bulkAddresses,
249                    String subject, String body, String replyToAddress, String mailId,
250                    String inReplyTo, boolean htmlFormat, SMTPAccount account) {
251    
252                    try {
253                            if (bulkAddresses.length == 0) {
254                                    return;
255                            }
256    
257                            InternetAddress from = new InternetAddress(fromAddress, fromName);
258    
259                            InternetAddress to = new InternetAddress(
260                                    replyToAddress, replyToAddress);
261    
262                            String curSubject = StringUtil.replace(
263                                    subject,
264                                    new String[] {
265                                            "[$TO_ADDRESS$]",
266                                            "[$TO_NAME$]"
267                                    },
268                                    new String[] {
269                                            replyToAddress,
270                                            replyToAddress
271                                    });
272    
273                            String curBody = StringUtil.replace(
274                                    body,
275                                    new String[] {
276                                            "[$TO_ADDRESS$]",
277                                            "[$TO_NAME$]"
278                                    },
279                                    new String[] {
280                                            replyToAddress,
281                                            replyToAddress
282                                    });
283    
284                            InternetAddress replyTo = new InternetAddress(
285                                    replyToAddress, replyToAddress);
286    
287                            if (htmlFormat) {
288                                    try {
289                                            curBody = BBCodeUtil.getHTML(curBody);
290                                    }
291                                    catch (Exception e) {
292                                            _log.error(
293                                                    "Could not parse message " + mailId + " " +
294                                                            e.getMessage());
295                                    }
296                            }
297    
298                            MailMessage message = new MailMessage(
299                                    from, to, curSubject, curBody, htmlFormat);
300    
301                            message.setBulkAddresses(bulkAddresses);
302                            message.setMessageId(mailId);
303                            message.setInReplyTo(inReplyTo);
304                            message.setReplyTo(new InternetAddress[] {replyTo});
305                            message.setSMTPAccount(account);
306    
307                            MailServiceUtil.sendEmail(message);
308                    }
309                    catch (Exception e) {
310                            _log.error(e);
311                    }
312            }
313    
314            private static Log _log = LogFactoryUtil.getLog(MBMessageListener.class);
315    
316    }