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.json.JSONFactoryUtil;
28  import com.liferay.portal.kernel.json.JSONObject;
29  import com.liferay.portal.kernel.mail.MailMessage;
30  import com.liferay.portal.kernel.messaging.MessageListener;
31  import com.liferay.portal.kernel.util.GetterUtil;
32  import com.liferay.portal.kernel.util.StringUtil;
33  import com.liferay.portal.model.Subscription;
34  import com.liferay.portal.model.User;
35  import com.liferay.portal.service.SubscriptionLocalServiceUtil;
36  import com.liferay.portal.service.UserLocalServiceUtil;
37  import com.liferay.portlet.messageboards.model.MBCategory;
38  import com.liferay.portlet.messageboards.model.MBThread;
39  import com.liferay.portlet.messageboards.util.BBCodeUtil;
40  
41  import java.util.ArrayList;
42  import java.util.HashSet;
43  import java.util.List;
44  import java.util.Set;
45  
46  import javax.mail.internet.InternetAddress;
47  
48  import org.apache.commons.logging.Log;
49  import org.apache.commons.logging.LogFactory;
50  
51  /**
52   * <a href="MBMessageListener.java.html"><b><i>View Source</i></b></a>
53   *
54   * @author Brian Wing Shun Chan
55   *
56   */
57  public class MBMessageListener implements MessageListener {
58  
59      public void receive(Object message) {
60          throw new UnsupportedOperationException();
61      }
62  
63      public void receive(String message) {
64          try {
65              doReceive(message);
66          }
67          catch (Exception e) {
68              _log.error("Unable to process message " + message, e);
69          }
70      }
71  
72      public void doReceive(String message) throws Exception {
73          JSONObject jsonObj = JSONFactoryUtil.createJSONObject(message);
74  
75          long companyId = jsonObj.getLong("companyId");
76          long userId = jsonObj.getLong("userId");
77          String categoryIds = jsonObj.getString("categoryIds");
78          String threadId = jsonObj.getString("threadId");
79          String fromName = jsonObj.getString("fromName");
80          String fromAddress = jsonObj.getString("fromAddress");
81          String subject = jsonObj.getString("subject");
82          String body = jsonObj.getString("body");
83          String replyToAddress = jsonObj.getString("replyToAddress");
84          String mailId = jsonObj.getString("mailId");
85          String inReplyTo = jsonObj.getString("inReplyTo");
86          boolean htmlFormat = jsonObj.getBoolean("htmlFormat");
87  
88          Set<Long> sent = new HashSet<Long>();
89  
90          if (_log.isInfoEnabled()) {
91              _log.info(
92                  "Sending notifications for {mailId=" + mailId + ", threadId=" +
93                      threadId + ", categoryIds=" + categoryIds + "}");
94          }
95  
96          // Threads
97  
98          List<Subscription> subscriptions =
99              SubscriptionLocalServiceUtil.getSubscriptions(
100                 companyId, MBThread.class.getName(),
101                 GetterUtil.getLong(threadId));
102 
103         sendEmail(
104             userId, fromName, fromAddress, subject, body, subscriptions, sent,
105             replyToAddress, mailId, inReplyTo, htmlFormat);
106 
107         // Categories
108 
109         long[] categoryIdsArray = StringUtil.split(categoryIds, 0L);
110 
111         for (long categoryId : categoryIdsArray) {
112             subscriptions = SubscriptionLocalServiceUtil.getSubscriptions(
113                 companyId, MBCategory.class.getName(), categoryId);
114 
115             sendEmail(
116                 userId, fromName, fromAddress, subject, body, subscriptions,
117                 sent, replyToAddress, mailId, inReplyTo, htmlFormat);
118         }
119 
120         if (_log.isInfoEnabled()) {
121             _log.info("Finished sending notifications");
122         }
123     }
124 
125     protected void sendEmail(
126             long userId, String fromName, String fromAddress, String subject,
127             String body, List<Subscription> subscriptions, Set<Long> sent,
128             String replyToAddress, String mailId, String inReplyTo,
129             boolean htmlFormat)
130         throws Exception {
131 
132         List<InternetAddress> addresses =
133             new ArrayList<InternetAddress>();
134 
135         for (Subscription subscription : subscriptions) {
136             long subscribedUserId = subscription.getUserId();
137 
138             if (sent.contains(subscribedUserId)) {
139                 if (_log.isDebugEnabled()) {
140                     _log.debug(
141                         "Do not send a duplicate email to user " +
142                             subscribedUserId);
143                 }
144 
145                 continue;
146             }
147             else {
148                 if (_log.isDebugEnabled()) {
149                     _log.debug(
150                         "Add user " + subscribedUserId +
151                             " to the list of users who have received an email");
152                 }
153 
154                 sent.add(subscribedUserId);
155             }
156 
157             User user = null;
158 
159             try {
160                 user = UserLocalServiceUtil.getUserById(
161                     subscription.getUserId());
162             }
163             catch (NoSuchUserException nsue) {
164                 if (_log.isInfoEnabled()) {
165                     _log.info(
166                         "Subscription " + subscription.getSubscriptionId() +
167                             " is stale and will be deleted");
168                 }
169 
170                 SubscriptionLocalServiceUtil.deleteSubscription(
171                     subscription.getSubscriptionId());
172 
173                 continue;
174             }
175 
176             InternetAddress userAddress = new InternetAddress(
177                 user.getEmailAddress(), user.getFullName());
178 
179             addresses.add(userAddress);
180         }
181 
182         try {
183             InternetAddress[] bulkAddresses = addresses.toArray(
184                 new InternetAddress[addresses.size()]);
185 
186             if (bulkAddresses.length == 0) {
187                 return;
188             }
189 
190             InternetAddress from = new InternetAddress(fromAddress, fromName);
191 
192             InternetAddress[] to = new InternetAddress[] {
193                 new InternetAddress(replyToAddress, replyToAddress)};
194 
195             String curSubject = StringUtil.replace(
196                 subject,
197                 new String[] {
198                     "[$TO_ADDRESS$]",
199                     "[$TO_NAME$]"
200                 },
201                 new String[] {
202                     replyToAddress,
203                     replyToAddress
204                 });
205 
206             String curBody = StringUtil.replace(
207                 body,
208                 new String[] {
209                     "[$TO_ADDRESS$]",
210                     "[$TO_NAME$]"
211                 },
212                 new String[] {
213                     replyToAddress,
214                     replyToAddress
215                 });
216 
217             InternetAddress replyTo = new InternetAddress(
218                 replyToAddress, replyToAddress);
219 
220             if (htmlFormat) {
221                 try {
222                     curBody = BBCodeUtil.getHTML(curBody);
223                 }
224                 catch (Exception e) {
225                     _log.error(
226                         "Could not parse message " + mailId + " " +
227                             e.getMessage());
228                 }
229             }
230 
231             MailMessage message = new MailMessage(
232                 from, to, null, null, bulkAddresses, curSubject, curBody,
233                 htmlFormat);
234 
235             message.setMessageId(mailId);
236             message.setInReplyTo(inReplyTo);
237             message.setReplyTo(new InternetAddress[] {replyTo});
238 
239             MailServiceUtil.sendEmail(message);
240         }
241         catch (Exception e) {
242             _log.error(e);
243         }
244     }
245 
246     private static Log _log = LogFactory.getLog(MBMessageListener.class);
247 
248 }