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.pop;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.pop.MessageListener;
20  import com.liferay.portal.kernel.pop.MessageListenerException;
21  import com.liferay.portal.kernel.util.GetterUtil;
22  import com.liferay.portal.kernel.util.StringPool;
23  import com.liferay.portal.kernel.util.StringUtil;
24  import com.liferay.portal.model.Company;
25  import com.liferay.portal.model.User;
26  import com.liferay.portal.security.auth.PrincipalException;
27  import com.liferay.portal.security.permission.PermissionCheckerUtil;
28  import com.liferay.portal.service.CompanyLocalServiceUtil;
29  import com.liferay.portal.service.ServiceContext;
30  import com.liferay.portal.service.UserLocalServiceUtil;
31  import com.liferay.portal.util.PortalUtil;
32  import com.liferay.portal.util.PortletKeys;
33  import com.liferay.portlet.messageboards.NoSuchCategoryException;
34  import com.liferay.portlet.messageboards.NoSuchMessageException;
35  import com.liferay.portlet.messageboards.model.MBCategory;
36  import com.liferay.portlet.messageboards.model.MBCategoryConstants;
37  import com.liferay.portlet.messageboards.model.MBMessage;
38  import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
39  import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
40  import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
41  import com.liferay.portlet.messageboards.util.MBMailMessage;
42  import com.liferay.portlet.messageboards.util.MBUtil;
43  
44  import javax.mail.Message;
45  
46  import org.apache.commons.lang.time.StopWatch;
47  
48  /**
49   * <a href="MessageListenerImpl.java.html"><b><i>View Source</i></b></a>
50   *
51   * @author Brian Wing Shun Chan
52   * @author Jorge Ferrer
53   * @author Michael C. Han
54   */
55  public class MessageListenerImpl implements MessageListener {
56  
57      public boolean accept(String from, String recipient, Message message) {
58          try {
59              String messageId = getMessageId(recipient, message);
60  
61              if ((messageId == null) ||
62                  (!messageId.startsWith(
63                      MBUtil.POP_PORTLET_PREFIX, getOffset()))) {
64  
65                  return false;
66              }
67  
68              Company company = getCompany(recipient);
69              long categoryId = getCategoryId(messageId);
70  
71              MBCategory category = MBCategoryLocalServiceUtil.getCategory(
72                  categoryId);
73  
74              if (category.getCompanyId() != company.getCompanyId()) {
75                  return false;
76              }
77  
78              if (_log.isDebugEnabled()) {
79                  _log.debug("Check to see if user " + from + " exists");
80              }
81  
82              UserLocalServiceUtil.getUserByEmailAddress(
83                  company.getCompanyId(), from);
84  
85              return true;
86          }
87          catch (Exception e) {
88              if (_log.isErrorEnabled()) {
89                  _log.error("Unable to process message: " + message, e);
90              }
91  
92              return false;
93          }
94      }
95  
96      public void deliver(String from, String recipient, Message message)
97          throws MessageListenerException {
98  
99          try {
100             StopWatch stopWatch = null;
101 
102             if (_log.isDebugEnabled()) {
103                 stopWatch = new StopWatch();
104 
105                 stopWatch.start();
106 
107                 _log.debug("Deliver message from " + from + " to " + recipient);
108             }
109 
110             Company company = getCompany(recipient);
111 
112             String messageId = getMessageId(recipient, message);
113 
114             if (_log.isDebugEnabled()) {
115                 _log.debug("Message id " + messageId);
116             }
117 
118             long groupId = 0;
119             long categoryId = getCategoryId(messageId);
120 
121             try {
122                 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
123                     categoryId);
124 
125                 groupId = category.getGroupId();
126             }
127             catch (NoSuchCategoryException nsce) {
128                 groupId = categoryId;
129                 categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
130             }
131 
132             if (_log.isDebugEnabled()) {
133                 _log.debug("Group id " + groupId);
134                 _log.debug("Category id " + categoryId);
135             }
136 
137             User user = UserLocalServiceUtil.getUserByEmailAddress(
138                 company.getCompanyId(), from);
139 
140             long parentMessageId = getParentMessageId(recipient, message);
141 
142             if (_log.isDebugEnabled()) {
143                 _log.debug("Parent message id " + parentMessageId);
144             }
145 
146             MBMessage parentMessage = null;
147 
148             try {
149                 if (parentMessageId > 0) {
150                     parentMessage = MBMessageLocalServiceUtil.getMessage(
151                         parentMessageId);
152                 }
153             }
154             catch (NoSuchMessageException nsme) {
155 
156                 // If the parent message does not exist we ignore it and post
157                 // the message as a new thread.
158 
159             }
160 
161             if (_log.isDebugEnabled()) {
162                 _log.debug("Parent message " + parentMessage);
163             }
164 
165             String subject = MBUtil.getSubjectWithoutMessageId(message);
166 
167             MBMailMessage collector = new MBMailMessage();
168 
169             MBUtil.collectPartContent(message, collector);
170 
171             PermissionCheckerUtil.setThreadValues(user);
172 
173             ServiceContext serviceContext = new ServiceContext();
174 
175             serviceContext.setAddCommunityPermissions(true);
176             serviceContext.setAddGuestPermissions(true);
177             serviceContext.setLayoutFullURL(
178                 PortalUtil.getLayoutFullURL(
179                     groupId, PortletKeys.MESSAGE_BOARDS));
180             serviceContext.setScopeGroupId(groupId);
181 
182             if (parentMessage == null) {
183                 MBMessageServiceUtil.addMessage(
184                     groupId, categoryId, subject, collector.getBody(),
185                     collector.getFiles(), false, 0.0, true, serviceContext);
186             }
187             else {
188                 MBMessageServiceUtil.addMessage(
189                     groupId, categoryId, parentMessage.getThreadId(),
190                     parentMessage.getMessageId(), subject, collector.getBody(),
191                     collector.getFiles(), false, 0.0, true, serviceContext);
192             }
193 
194             if (_log.isDebugEnabled()) {
195                 _log.debug(
196                     "Delivering message takes " + stopWatch.getTime() + " ms");
197             }
198         }
199         catch (PrincipalException pe) {
200             if (_log.isDebugEnabled()) {
201                 _log.debug("Prevented unauthorized post from " + from);
202             }
203 
204             throw new MessageListenerException(pe);
205         }
206         catch (Exception e) {
207             _log.error(e, e);
208 
209             throw new MessageListenerException(e);
210         }
211         finally {
212             PermissionCheckerUtil.setThreadValues(null);
213         }
214     }
215 
216     public String getId() {
217         return MessageListenerImpl.class.getName();
218     }
219 
220     protected long getCategoryId(String recipient) {
221         int pos = recipient.indexOf(StringPool.AT);
222 
223         String target = recipient.substring(
224             MBUtil.POP_PORTLET_PREFIX.length() + getOffset(), pos);
225 
226         String[] parts = StringUtil.split(target, StringPool.PERIOD);
227 
228         return GetterUtil.getLong(parts[0]);
229     }
230 
231     protected Company getCompany(String recipient) throws Exception {
232         int pos =
233             recipient.indexOf(StringPool.AT) +
234                 MBUtil.POP_SERVER_SUBDOMAIN_LENGTH + 1;
235 
236         if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH > 0) {
237             pos++;
238         }
239 
240         String mx = recipient.substring(pos);
241 
242         return CompanyLocalServiceUtil.getCompanyByMx(mx);
243     }
244 
245     protected String getMessageId(String recipient, Message message)
246         throws Exception {
247 
248         if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH > 0) {
249             return recipient;
250         }
251         else {
252             return MBUtil.getParentMessageIdString(message);
253         }
254     }
255 
256     protected int getOffset() {
257         if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH == 0) {
258             return 1;
259         }
260         return 0;
261     }
262 
263     protected long getParentMessageId(String recipient, Message message)
264         throws Exception {
265 
266         // Get the parent message ID from the recipient address
267 
268         int pos = recipient.indexOf(StringPool.AT);
269 
270         String target = recipient.substring(
271             MBUtil.POP_PORTLET_PREFIX.length(), pos);
272 
273         String[] parts = StringUtil.split(target, StringPool.PERIOD);
274 
275         long parentMessageId = 0;
276 
277         if (parts.length == 2) {
278             parentMessageId = GetterUtil.getLong(parts[1]);
279         }
280 
281         if (parentMessageId > 0) {
282             return parentMessageId;
283         }
284         else {
285             return MBUtil.getParentMessageId(message);
286         }
287     }
288 
289     private static Log _log = LogFactoryUtil.getLog(MessageListenerImpl.class);
290 
291 }