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