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