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