001    /**
002     * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.messageboards.pop;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.pop.MessageListener;
020    import com.liferay.portal.kernel.pop.MessageListenerException;
021    import com.liferay.portal.kernel.util.CharPool;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.model.Company;
026    import com.liferay.portal.model.User;
027    import com.liferay.portal.security.auth.PrincipalException;
028    import com.liferay.portal.security.permission.PermissionCheckerUtil;
029    import com.liferay.portal.service.CompanyLocalServiceUtil;
030    import com.liferay.portal.service.ServiceContext;
031    import com.liferay.portal.service.UserLocalServiceUtil;
032    import com.liferay.portal.util.PortalUtil;
033    import com.liferay.portal.util.PortletKeys;
034    import com.liferay.portlet.messageboards.NoSuchCategoryException;
035    import com.liferay.portlet.messageboards.NoSuchMessageException;
036    import com.liferay.portlet.messageboards.model.MBCategory;
037    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
038    import com.liferay.portlet.messageboards.model.MBMessage;
039    import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
040    import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
041    import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
042    import com.liferay.portlet.messageboards.util.MBMailMessage;
043    import com.liferay.portlet.messageboards.util.MBUtil;
044    
045    import javax.mail.Message;
046    
047    import org.apache.commons.lang.time.StopWatch;
048    
049    /**
050     * @author Brian Wing Shun Chan
051     * @author Jorge Ferrer
052     * @author Michael C. Han
053     */
054    public class MessageListenerImpl implements MessageListener {
055    
056            public boolean accept(String from, String recipient, Message message) {
057                    try {
058                            String messageId = getMessageId(recipient, message);
059    
060                            if ((messageId == null) ||
061                                    (!messageId.startsWith(
062                                            MBUtil.POP_PORTLET_PREFIX, getOffset()))) {
063    
064                                    return false;
065                            }
066    
067                            Company company = getCompany(recipient);
068                            long categoryId = getCategoryId(messageId);
069    
070                            MBCategory category = MBCategoryLocalServiceUtil.getCategory(
071                                    categoryId);
072    
073                            if (category.getCompanyId() != company.getCompanyId()) {
074                                    return false;
075                            }
076    
077                            if (_log.isDebugEnabled()) {
078                                    _log.debug("Check to see if user " + from + " exists");
079                            }
080    
081                            UserLocalServiceUtil.getUserByEmailAddress(
082                                    company.getCompanyId(), from);
083    
084                            return true;
085                    }
086                    catch (Exception e) {
087                            if (_log.isErrorEnabled()) {
088                                    _log.error("Unable to process message: " + message, e);
089                            }
090    
091                            return false;
092                    }
093            }
094    
095            public void deliver(String from, String recipient, Message message)
096                    throws MessageListenerException {
097    
098                    try {
099                            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 groupId = 0;
118                            long categoryId = getCategoryId(messageId);
119    
120                            try {
121                                    MBCategory category = MBCategoryLocalServiceUtil.getCategory(
122                                            categoryId);
123    
124                                    groupId = category.getGroupId();
125                            }
126                            catch (NoSuchCategoryException nsce) {
127                                    groupId = categoryId;
128                                    categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
129                            }
130    
131                            if (_log.isDebugEnabled()) {
132                                    _log.debug("Group id " + groupId);
133                                    _log.debug("Category id " + categoryId);
134                            }
135    
136                            User user = UserLocalServiceUtil.getUserByEmailAddress(
137                                    company.getCompanyId(), from);
138    
139                            long parentMessageId = getParentMessageId(recipient, message);
140    
141                            if (_log.isDebugEnabled()) {
142                                    _log.debug("Parent message id " + parentMessageId);
143                            }
144    
145                            MBMessage parentMessage = null;
146    
147                            try {
148                                    if (parentMessageId > 0) {
149                                            parentMessage = MBMessageLocalServiceUtil.getMessage(
150                                                    parentMessageId);
151                                    }
152                            }
153                            catch (NoSuchMessageException nsme) {
154    
155                                    // If the parent message does not exist we ignore it and post
156                                    // the message as a new thread.
157    
158                            }
159    
160                            if (_log.isDebugEnabled()) {
161                                    _log.debug("Parent message " + parentMessage);
162                            }
163    
164                            String subject = MBUtil.getSubjectWithoutMessageId(message);
165    
166                            MBMailMessage collector = new MBMailMessage();
167    
168                            MBUtil.collectPartContent(message, collector);
169    
170                            PermissionCheckerUtil.setThreadValues(user);
171    
172                            ServiceContext serviceContext = new ServiceContext();
173    
174                            serviceContext.setAddCommunityPermissions(true);
175                            serviceContext.setAddGuestPermissions(true);
176                            serviceContext.setLayoutFullURL(
177                                    PortalUtil.getLayoutFullURL(
178                                            groupId, PortletKeys.MESSAGE_BOARDS));
179                            serviceContext.setScopeGroupId(groupId);
180    
181                            if (parentMessage == null) {
182                                    MBMessageServiceUtil.addMessage(
183                                            groupId, categoryId, subject, collector.getBody(),
184                                            collector.getFiles(), false, 0.0, true, serviceContext);
185                            }
186                            else {
187                                    MBMessageServiceUtil.addMessage(
188                                            groupId, categoryId, parentMessage.getThreadId(),
189                                            parentMessage.getMessageId(), subject, collector.getBody(),
190                                            collector.getFiles(), false, 0.0, true, serviceContext);
191                            }
192    
193                            if (_log.isDebugEnabled()) {
194                                    _log.debug(
195                                            "Delivering message takes " + stopWatch.getTime() + " ms");
196                            }
197                    }
198                    catch (PrincipalException pe) {
199                            if (_log.isDebugEnabled()) {
200                                    _log.debug("Prevented unauthorized post from " + from);
201                            }
202    
203                            throw new MessageListenerException(pe);
204                    }
205                    catch (Exception e) {
206                            _log.error(e, e);
207    
208                            throw new MessageListenerException(e);
209                    }
210                    finally {
211                            PermissionCheckerUtil.setThreadValues(null);
212                    }
213            }
214    
215            public String getId() {
216                    return MessageListenerImpl.class.getName();
217            }
218    
219            protected long getCategoryId(String recipient) {
220                    int pos = recipient.indexOf(CharPool.AT);
221    
222                    String target = recipient.substring(
223                            MBUtil.POP_PORTLET_PREFIX.length() + getOffset(), pos);
224    
225                    String[] parts = StringUtil.split(target, StringPool.PERIOD);
226    
227                    return GetterUtil.getLong(parts[0]);
228            }
229    
230            protected Company getCompany(String recipient) throws Exception {
231                    int pos =
232                            recipient.indexOf(CharPool.AT) +
233                                    MBUtil.POP_SERVER_SUBDOMAIN_LENGTH + 1;
234    
235                    if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH > 0) {
236                            pos++;
237                    }
238    
239                    String mx = recipient.substring(pos);
240    
241                    return CompanyLocalServiceUtil.getCompanyByMx(mx);
242            }
243    
244            protected String getMessageId(String recipient, Message message)
245                    throws Exception {
246    
247                    if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH > 0) {
248                            return recipient;
249                    }
250                    else {
251                            return MBUtil.getParentMessageIdString(message);
252                    }
253            }
254    
255            protected int getOffset() {
256                    if (MBUtil.POP_SERVER_SUBDOMAIN_LENGTH == 0) {
257                            return 1;
258                    }
259                    return 0;
260            }
261    
262            protected long getParentMessageId(String recipient, Message message)
263                    throws Exception {
264    
265                    // Get the parent message ID from the recipient address
266    
267                    int pos = recipient.indexOf(CharPool.AT);
268    
269                    String target = recipient.substring(
270                            MBUtil.POP_PORTLET_PREFIX.length(), pos);
271    
272                    String[] parts = StringUtil.split(target, StringPool.PERIOD);
273    
274                    long parentMessageId = 0;
275    
276                    if (parts.length == 2) {
277                            parentMessageId = GetterUtil.getLong(parts[1]);
278                    }
279    
280                    if (parentMessageId > 0) {
281                            return parentMessageId;
282                    }
283                    else {
284                            return MBUtil.getParentMessageId(message);
285                    }
286            }
287    
288            private static Log _log = LogFactoryUtil.getLog(MessageListenerImpl.class);
289    
290    }