1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * This library is free software; you can redistribute it and/or modify it under
5    * the terms of the GNU Lesser General Public License as published by the Free
6    * Software Foundation; either version 2.1 of the License, or (at your option)
7    * any later version.
8    *
9    * This library is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   * details.
13   */
14  
15  package com.liferay.portlet.messageboards.messaging;
16  
17  import com.liferay.mail.service.MailServiceUtil;
18  import com.liferay.portal.NoSuchUserException;
19  import com.liferay.portal.kernel.log.Log;
20  import com.liferay.portal.kernel.log.LogFactoryUtil;
21  import com.liferay.portal.kernel.mail.Account;
22  import com.liferay.portal.kernel.mail.MailMessage;
23  import com.liferay.portal.kernel.mail.SMTPAccount;
24  import com.liferay.portal.kernel.messaging.MessageListener;
25  import com.liferay.portal.kernel.util.GetterUtil;
26  import com.liferay.portal.kernel.util.StringPool;
27  import com.liferay.portal.kernel.util.StringUtil;
28  import com.liferay.portal.model.Subscription;
29  import com.liferay.portal.model.User;
30  import com.liferay.portal.service.SubscriptionLocalServiceUtil;
31  import com.liferay.portal.service.UserLocalServiceUtil;
32  import com.liferay.portlet.messageboards.NoSuchMailingListException;
33  import com.liferay.portlet.messageboards.model.MBCategory;
34  import com.liferay.portlet.messageboards.model.MBMailingList;
35  import com.liferay.portlet.messageboards.model.MBThread;
36  import com.liferay.portlet.messageboards.service.MBMailingListLocalServiceUtil;
37  import com.liferay.portlet.messageboards.util.BBCodeUtil;
38  
39  import java.util.ArrayList;
40  import java.util.HashSet;
41  import java.util.List;
42  import java.util.Set;
43  
44  import javax.mail.internet.InternetAddress;
45  
46  /**
47   * <a href="MBMessageListener.java.html"><b><i>View Source</i></b></a>
48   *
49   * @author Brian Wing Shun Chan
50   * @author Thiago Moreira
51   */
52  public class MBMessageListener implements MessageListener {
53  
54      public void receive(com.liferay.portal.kernel.messaging.Message message) {
55          try {
56              doReceive(message);
57          }
58          catch (Exception e) {
59              _log.error("Unable to process message " + message, e);
60          }
61      }
62  
63      protected void doReceive(
64              com.liferay.portal.kernel.messaging.Message message)
65          throws Exception {
66  
67          long companyId = message.getLong("companyId");
68          long userId = message.getLong("userId");
69          long groupId = message.getLong("groupId");
70          String categoryIds = message.getString("categoryIds");
71          String threadId = message.getString("threadId");
72          String fromName = message.getString("fromName");
73          String fromAddress = message.getString("fromAddress");
74          String subject = message.getString("subject");
75          String body = message.getString("body");
76          String replyToAddress = message.getString("replyToAddress");
77          String mailId = message.getString("mailId");
78          String inReplyTo = message.getString("inReplyTo");
79          boolean htmlFormat = message.getBoolean("htmlFormat");
80          boolean sourceMailingList = message.getBoolean("sourceMailingList");
81  
82          if (sourceMailingList) {
83              subject = getMailingListSubject(subject, mailId);
84          }
85  
86          Set<Long> sent = new HashSet<Long>();
87  
88          if (_log.isInfoEnabled()) {
89              _log.info(
90                  "Sending notifications for {mailId=" + mailId + ", threadId=" +
91                      threadId + ", categoryIds=" + categoryIds + "}");
92          }
93  
94          // Threads
95  
96          List<Subscription> subscriptions =
97              SubscriptionLocalServiceUtil.getSubscriptions(
98                  companyId, MBThread.class.getName(),
99                  GetterUtil.getLong(threadId));
100 
101         sendEmail(
102             userId, fromName, fromAddress, subject, body, subscriptions, sent,
103             replyToAddress, mailId, inReplyTo, htmlFormat);
104 
105         // Categories
106 
107         long[] categoryIdsArray = StringUtil.split(categoryIds, 0L);
108 
109         for (long categoryId : categoryIdsArray) {
110             subscriptions = SubscriptionLocalServiceUtil.getSubscriptions(
111                 companyId, MBCategory.class.getName(), categoryId);
112 
113             sendEmail(
114                 userId, fromName, fromAddress, subject, body, subscriptions,
115                 sent, replyToAddress, mailId, inReplyTo, htmlFormat);
116         }
117 
118         // Mailing list
119 
120         if (!sourceMailingList) {
121             for (long categoryId : categoryIdsArray) {
122                 try {
123                     notifyMailingList(
124                         subject, body, replyToAddress, mailId, inReplyTo,
125                         htmlFormat, groupId, categoryId);
126                 }
127                 catch (NoSuchMailingListException nsmle) {
128                 }
129             }
130         }
131 
132         if (_log.isInfoEnabled()) {
133             _log.info("Finished sending notifications");
134         }
135     }
136 
137     protected String getMailingListSubject(String subject, String mailId) {
138         return subject + StringPool.SPACE + mailId;
139     }
140 
141     protected void notifyMailingList(
142             String subject, String body, String replyToAddress, String mailId,
143             String inReplyTo, boolean htmlFormat, long groupId, long categoryId)
144         throws Exception {
145 
146         MBMailingList mailingList =
147             MBMailingListLocalServiceUtil.getCategoryMailingList(
148                 groupId, categoryId);
149 
150         if (!mailingList.isActive()) {
151             return;
152         }
153 
154         subject = getMailingListSubject(subject, mailId);
155 
156         String fromAddress = mailingList.getOutEmailAddress();
157 
158         InternetAddress[] bulkAddresses = new InternetAddress[] {
159             new InternetAddress(mailingList.getEmailAddress())
160         };
161 
162         SMTPAccount account = null;
163 
164         if (mailingList.isOutCustom()) {
165             String protocol = Account.PROTOCOL_SMTP;
166 
167             if (mailingList.isOutUseSSL()) {
168                 protocol = Account.PROTOCOL_SMTPS;
169             }
170 
171             account = (SMTPAccount)Account.getInstance(
172                 protocol, mailingList.getOutServerPort());
173 
174             account.setHost(mailingList.getOutServerName());
175             account.setUser(mailingList.getOutUserName());
176             account.setPassword(mailingList.getOutPassword());
177         }
178 
179         sendMail(
180             fromAddress, null, bulkAddresses, subject, body, replyToAddress,
181             mailId, inReplyTo, htmlFormat, account);
182     }
183 
184     protected void sendEmail(
185             long userId, String fromName, String fromAddress, String subject,
186             String body, List<Subscription> subscriptions, Set<Long> sent,
187             String replyToAddress, String mailId, String inReplyTo,
188             boolean htmlFormat)
189         throws Exception {
190 
191         List<InternetAddress> addresses = new ArrayList<InternetAddress>();
192 
193         for (Subscription subscription : subscriptions) {
194             long subscribedUserId = subscription.getUserId();
195 
196             if (sent.contains(subscribedUserId)) {
197                 if (_log.isDebugEnabled()) {
198                     _log.debug(
199                         "Do not send a duplicate email to user " +
200                             subscribedUserId);
201                 }
202 
203                 continue;
204             }
205             else {
206                 if (_log.isDebugEnabled()) {
207                     _log.debug(
208                         "Add user " + subscribedUserId +
209                             " to the list of users who have received an email");
210                 }
211 
212                 sent.add(subscribedUserId);
213             }
214 
215             User user = null;
216 
217             try {
218                 user = UserLocalServiceUtil.getUserById(
219                     subscription.getUserId());
220             }
221             catch (NoSuchUserException nsue) {
222                 if (_log.isInfoEnabled()) {
223                     _log.info(
224                         "Subscription " + subscription.getSubscriptionId() +
225                             " is stale and will be deleted");
226                 }
227 
228                 SubscriptionLocalServiceUtil.deleteSubscription(
229                     subscription.getSubscriptionId());
230 
231                 continue;
232             }
233 
234             if (!user.isActive()) {
235                 continue;
236             }
237 
238             InternetAddress userAddress = new InternetAddress(
239                 user.getEmailAddress(), user.getFullName());
240 
241             addresses.add(userAddress);
242         }
243 
244         InternetAddress[] bulkAddresses = addresses.toArray(
245             new InternetAddress[addresses.size()]);
246 
247         sendMail(
248             fromAddress, fromName, bulkAddresses, subject, body, replyToAddress,
249             mailId, inReplyTo, htmlFormat, null);
250     }
251 
252     protected void sendMail(
253         String fromAddress, String fromName, InternetAddress[] bulkAddresses,
254         String subject, String body, String replyToAddress, String mailId,
255         String inReplyTo, boolean htmlFormat, SMTPAccount account) {
256 
257         try {
258             if (bulkAddresses.length == 0) {
259                 return;
260             }
261 
262             InternetAddress from = new InternetAddress(fromAddress, fromName);
263 
264             InternetAddress to = new InternetAddress(
265                 replyToAddress, replyToAddress);
266 
267             String curSubject = StringUtil.replace(
268                 subject,
269                 new String[] {
270                     "[$TO_ADDRESS$]",
271                     "[$TO_NAME$]"
272                 },
273                 new String[] {
274                     replyToAddress,
275                     replyToAddress
276                 });
277 
278             String curBody = StringUtil.replace(
279                 body,
280                 new String[] {
281                     "[$TO_ADDRESS$]",
282                     "[$TO_NAME$]"
283                 },
284                 new String[] {
285                     replyToAddress,
286                     replyToAddress
287                 });
288 
289             InternetAddress replyTo = new InternetAddress(
290                 replyToAddress, replyToAddress);
291 
292             if (htmlFormat) {
293                 try {
294                     curBody = BBCodeUtil.getHTML(curBody);
295                 }
296                 catch (Exception e) {
297                     _log.error(
298                         "Could not parse message " + mailId + " " +
299                             e.getMessage());
300                 }
301             }
302 
303             MailMessage message = new MailMessage(
304                 from, to, curSubject, curBody, htmlFormat);
305 
306             message.setBulkAddresses(bulkAddresses);
307             message.setMessageId(mailId);
308             message.setInReplyTo(inReplyTo);
309             message.setReplyTo(new InternetAddress[] {replyTo});
310             message.setSMTPAccount(account);
311 
312             MailServiceUtil.sendEmail(message);
313         }
314         catch (Exception e) {
315             _log.error(e);
316         }
317     }
318 
319     private static Log _log = LogFactoryUtil.getLog(MBMessageListener.class);
320 
321 }