1   /**
2    * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.messageboards.messaging;
24  
25  import com.liferay.mail.service.MailServiceUtil;
26  import com.liferay.portal.NoSuchUserException;
27  import com.liferay.portal.kernel.mail.MailMessage;
28  import com.liferay.portal.kernel.messaging.MessageListener;
29  import com.liferay.portal.kernel.util.GetterUtil;
30  import com.liferay.portal.kernel.util.StringPool;
31  import com.liferay.portal.kernel.util.StringUtil;
32  import com.liferay.portal.model.Subscription;
33  import com.liferay.portal.model.User;
34  import com.liferay.portal.service.SubscriptionLocalServiceUtil;
35  import com.liferay.portal.service.UserLocalServiceUtil;
36  import com.liferay.portlet.messageboards.model.MBCategory;
37  import com.liferay.portlet.messageboards.model.MBThread;
38  import com.liferay.portlet.messageboards.util.BBCodeUtil;
39  
40  import java.util.ArrayList;
41  import java.util.HashSet;
42  import java.util.List;
43  import java.util.Set;
44  
45  import javax.mail.internet.InternetAddress;
46  
47  import org.apache.commons.logging.Log;
48  import org.apache.commons.logging.LogFactory;
49  
50  /**
51   * <a href="MBMessageListener.java.html"><b><i>View Source</i></b></a>
52   *
53   * @author Brian Wing Shun Chan
54   *
55   */
56  public class MBMessageListener implements MessageListener {
57  
58      public void receive(com.liferay.portal.kernel.messaging.Message message) {
59          try {
60              doReceive(message);
61          }
62          catch (Exception e) {
63              _log.error("Unable to process message " + message, e);
64          }
65      }
66  
67      public void doReceive(com.liferay.portal.kernel.messaging.Message message)
68          throws Exception {
69  
70          long companyId = message.getLong("companyId");
71          long userId = message.getLong("userId");
72          String categoryIds = message.getString("categoryIds");
73          String threadId = message.getString("threadId");
74          String fromName = message.getString("fromName");
75          String fromAddress = message.getString("fromAddress");
76          String subject = message.getString("subject");
77          String body = message.getString("body");
78          String replyToAddress = message.getString("replyToAddress");
79          String mailId = message.getString("mailId");
80          String inReplyTo = message.getString("inReplyTo");
81          boolean htmlFormat = message.getBoolean("htmlFormat");
82  
83          subject = subject + StringPool.SPACE + mailId;
84  
85          Set<Long> sent = new HashSet<Long>();
86  
87          if (_log.isInfoEnabled()) {
88              _log.info(
89                  "Sending notifications for {mailId=" + mailId + ", threadId=" +
90                      threadId + ", categoryIds=" + categoryIds + "}");
91          }
92  
93          // Threads
94  
95          List<Subscription> subscriptions =
96              SubscriptionLocalServiceUtil.getSubscriptions(
97                  companyId, MBThread.class.getName(),
98                  GetterUtil.getLong(threadId));
99  
100         sendEmail(
101             userId, fromName, fromAddress, subject, body, subscriptions, sent,
102             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, fromName, fromAddress, subject, body, subscriptions,
114                 sent, replyToAddress, mailId, inReplyTo, htmlFormat);
115         }
116 
117         if (_log.isInfoEnabled()) {
118             _log.info("Finished sending notifications");
119         }
120     }
121 
122     protected void sendEmail(
123             long userId, String fromName, String fromAddress, String subject,
124             String body, List<Subscription> subscriptions, Set<Long> sent,
125             String replyToAddress, String mailId, String inReplyTo,
126             boolean htmlFormat)
127         throws Exception {
128 
129         List<InternetAddress> addresses =
130             new ArrayList<InternetAddress>();
131 
132         for (Subscription subscription : subscriptions) {
133             long subscribedUserId = subscription.getUserId();
134 
135             if (sent.contains(subscribedUserId)) {
136                 if (_log.isDebugEnabled()) {
137                     _log.debug(
138                         "Do not send a duplicate email to user " +
139                             subscribedUserId);
140                 }
141 
142                 continue;
143             }
144             else {
145                 if (_log.isDebugEnabled()) {
146                     _log.debug(
147                         "Add user " + subscribedUserId +
148                             " to the list of users who have received an email");
149                 }
150 
151                 sent.add(subscribedUserId);
152             }
153 
154             User user = null;
155 
156             try {
157                 user = UserLocalServiceUtil.getUserById(
158                     subscription.getUserId());
159             }
160             catch (NoSuchUserException nsue) {
161                 if (_log.isInfoEnabled()) {
162                     _log.info(
163                         "Subscription " + subscription.getSubscriptionId() +
164                             " is stale and will be deleted");
165                 }
166 
167                 SubscriptionLocalServiceUtil.deleteSubscription(
168                     subscription.getSubscriptionId());
169 
170                 continue;
171             }
172 
173             InternetAddress userAddress = new InternetAddress(
174                 user.getEmailAddress(), user.getFullName());
175 
176             addresses.add(userAddress);
177         }
178 
179         try {
180             InternetAddress[] bulkAddresses = addresses.toArray(
181                 new InternetAddress[addresses.size()]);
182 
183             if (bulkAddresses.length == 0) {
184                 return;
185             }
186 
187             InternetAddress from = new InternetAddress(fromAddress, fromName);
188 
189             InternetAddress to = new InternetAddress(
190                 replyToAddress, replyToAddress);
191 
192             String curSubject = StringUtil.replace(
193                 subject,
194                 new String[] {
195                     "[$TO_ADDRESS$]",
196                     "[$TO_NAME$]"
197                 },
198                 new String[] {
199                     replyToAddress,
200                     replyToAddress
201                 });
202 
203             String curBody = StringUtil.replace(
204                 body,
205                 new String[] {
206                     "[$TO_ADDRESS$]",
207                     "[$TO_NAME$]"
208                 },
209                 new String[] {
210                     replyToAddress,
211                     replyToAddress
212                 });
213 
214             InternetAddress replyTo = new InternetAddress(
215                 replyToAddress, replyToAddress);
216 
217             if (htmlFormat) {
218                 try {
219                     curBody = BBCodeUtil.getHTML(curBody);
220                 }
221                 catch (Exception e) {
222                     _log.error(
223                         "Could not parse message " + mailId + " " +
224                             e.getMessage());
225                 }
226             }
227 
228             MailMessage message = new MailMessage(
229                 from, to, curSubject, curBody, htmlFormat);
230 
231             message.setBulkAddresses(bulkAddresses);
232             message.setMessageId(mailId);
233             message.setInReplyTo(inReplyTo);
234             message.setReplyTo(new InternetAddress[] {replyTo});
235 
236             MailServiceUtil.sendEmail(message);
237         }
238         catch (Exception e) {
239             _log.error(e);
240         }
241     }
242 
243     private static Log _log = LogFactory.getLog(MBMessageListener.class);
244 
245 }