1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
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.StringPool;
26  import com.liferay.portal.kernel.util.StringUtil;
27  import com.liferay.portal.model.Subscription;
28  import com.liferay.portal.model.User;
29  import com.liferay.portal.service.GroupLocalServiceUtil;
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          long threadId = message.getLong("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(), threadId);
99  
100         sendEmail(
101             userId, groupId, fromName, fromAddress, subject, body,
102             subscriptions, sent, replyToAddress, mailId, inReplyTo, htmlFormat);
103 
104         // Categories
105 
106         long[] categoryIdsArray = StringUtil.split(categoryIds, 0L);
107 
108         for (long categoryId : categoryIdsArray) {
109             subscriptions = SubscriptionLocalServiceUtil.getSubscriptions(
110                 companyId, MBCategory.class.getName(), categoryId);
111 
112             sendEmail(
113                 userId, groupId, fromName, fromAddress, subject, body,
114                 subscriptions, sent, replyToAddress, mailId, inReplyTo,
115                 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, 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 categoryId)
144         throws Exception {
145 
146         MBMailingList mailingList =
147             MBMailingListLocalServiceUtil.getCategoryMailingList(categoryId);
148 
149         if (!mailingList.isActive()) {
150             return;
151         }
152 
153         subject = getMailingListSubject(subject, mailId);
154 
155         String fromAddress = mailingList.getOutEmailAddress();
156 
157         InternetAddress[] bulkAddresses = new InternetAddress[] {
158             new InternetAddress(mailingList.getEmailAddress())
159         };
160 
161         SMTPAccount account = null;
162 
163         if (mailingList.isOutCustom()) {
164             String protocol = Account.PROTOCOL_SMTP;
165 
166             if (mailingList.isOutUseSSL()) {
167                 protocol = Account.PROTOCOL_SMTPS;
168             }
169 
170             account = (SMTPAccount)Account.getInstance(
171                 protocol, mailingList.getOutServerPort());
172 
173             account.setHost(mailingList.getOutServerName());
174             account.setUser(mailingList.getOutUserName());
175             account.setPassword(mailingList.getOutPassword());
176         }
177 
178         sendMail(
179             fromAddress, null, bulkAddresses, subject, body, replyToAddress,
180             mailId, inReplyTo, htmlFormat, account);
181     }
182 
183     protected void sendEmail(
184             long userId, long groupId, String fromName, String fromAddress,
185             String subject, String body, List<Subscription> subscriptions,
186             Set<Long> sent, String replyToAddress, String mailId,
187             String inReplyTo, boolean htmlFormat)
188         throws Exception {
189 
190         List<InternetAddress> addresses = new ArrayList<InternetAddress>();
191 
192         for (Subscription subscription : subscriptions) {
193             long subscribedUserId = subscription.getUserId();
194 
195             if (sent.contains(subscribedUserId)) {
196                 if (_log.isDebugEnabled()) {
197                     _log.debug(
198                         "Do not send a duplicate email to user " +
199                             subscribedUserId);
200                 }
201 
202                 continue;
203             }
204             else {
205                 if (_log.isDebugEnabled()) {
206                     _log.debug(
207                         "Add user " + subscribedUserId +
208                             " to the list of users who have received an email");
209                 }
210 
211                 sent.add(subscribedUserId);
212             }
213 
214             User user = null;
215 
216             try {
217                 user = UserLocalServiceUtil.getUserById(
218                     subscription.getUserId());
219             }
220             catch (NoSuchUserException nsue) {
221                 if (_log.isInfoEnabled()) {
222                     _log.info(
223                         "Subscription " + subscription.getSubscriptionId() +
224                             " is stale and will be deleted");
225                 }
226 
227                 SubscriptionLocalServiceUtil.deleteSubscription(
228                     subscription.getSubscriptionId());
229 
230                 continue;
231             }
232 
233             if (!user.isActive()) {
234                 continue;
235             }
236 
237             if (!GroupLocalServiceUtil.hasUserGroup(userId, groupId)) {
238                 if (_log.isInfoEnabled()) {
239                     _log.info(
240                         "Subscription " + subscription.getSubscriptionId() +
241                             " is stale and will be deleted");
242                 }
243 
244                 SubscriptionLocalServiceUtil.deleteSubscription(
245                     subscription.getSubscriptionId());
246 
247                 continue;
248             }
249 
250             InternetAddress userAddress = new InternetAddress(
251                 user.getEmailAddress(), user.getFullName());
252 
253             addresses.add(userAddress);
254         }
255 
256         InternetAddress[] bulkAddresses = addresses.toArray(
257             new InternetAddress[addresses.size()]);
258 
259         sendMail(
260             fromAddress, fromName, bulkAddresses, subject, body, replyToAddress,
261             mailId, inReplyTo, htmlFormat, null);
262     }
263 
264     protected void sendMail(
265         String fromAddress, String fromName, InternetAddress[] bulkAddresses,
266         String subject, String body, String replyToAddress, String mailId,
267         String inReplyTo, boolean htmlFormat, SMTPAccount account) {
268 
269         try {
270             if (bulkAddresses.length == 0) {
271                 return;
272             }
273 
274             InternetAddress from = new InternetAddress(fromAddress, fromName);
275 
276             InternetAddress to = new InternetAddress(
277                 replyToAddress, replyToAddress);
278 
279             String curSubject = StringUtil.replace(
280                 subject,
281                 new String[] {
282                     "[$TO_ADDRESS$]",
283                     "[$TO_NAME$]"
284                 },
285                 new String[] {
286                     replyToAddress,
287                     replyToAddress
288                 });
289 
290             String curBody = StringUtil.replace(
291                 body,
292                 new String[] {
293                     "[$TO_ADDRESS$]",
294                     "[$TO_NAME$]"
295                 },
296                 new String[] {
297                     replyToAddress,
298                     replyToAddress
299                 });
300 
301             InternetAddress replyTo = new InternetAddress(
302                 replyToAddress, replyToAddress);
303 
304             if (htmlFormat) {
305                 try {
306                     curBody = BBCodeUtil.getHTML(curBody);
307                 }
308                 catch (Exception e) {
309                     _log.error(
310                         "Could not parse message " + mailId + " " +
311                             e.getMessage());
312                 }
313             }
314 
315             MailMessage message = new MailMessage(
316                 from, to, curSubject, curBody, htmlFormat);
317 
318             message.setBulkAddresses(bulkAddresses);
319             message.setMessageId(mailId);
320             message.setInReplyTo(inReplyTo);
321             message.setReplyTo(new InternetAddress[] {replyTo});
322             message.setSMTPAccount(account);
323 
324             MailServiceUtil.sendEmail(message);
325         }
326         catch (Exception e) {
327             _log.error(e);
328         }
329     }
330 
331     private static Log _log = LogFactoryUtil.getLog(MBMessageListener.class);
332 
333 }