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