001
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.ObjectValuePair;
024 import com.liferay.portal.kernel.util.PrefsPropsUtil;
025 import com.liferay.portal.kernel.util.PropsKeys;
026 import com.liferay.portal.kernel.util.StreamUtil;
027 import com.liferay.portal.kernel.util.StringUtil;
028 import com.liferay.portal.model.Company;
029 import com.liferay.portal.model.User;
030 import com.liferay.portal.security.auth.PrincipalException;
031 import com.liferay.portal.security.permission.PermissionCheckerUtil;
032 import com.liferay.portal.service.CompanyLocalServiceUtil;
033 import com.liferay.portal.service.ServiceContext;
034 import com.liferay.portal.service.UserLocalServiceUtil;
035 import com.liferay.portal.util.PortalUtil;
036 import com.liferay.portal.util.PortletKeys;
037 import com.liferay.portal.util.PropsValues;
038 import com.liferay.portlet.messageboards.NoSuchMessageException;
039 import com.liferay.portlet.messageboards.model.MBCategory;
040 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
041 import com.liferay.portlet.messageboards.model.MBMessage;
042 import com.liferay.portlet.messageboards.model.MBMessageConstants;
043 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
044 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
045 import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
046 import com.liferay.portlet.messageboards.util.MBMailMessage;
047 import com.liferay.portlet.messageboards.util.MBUtil;
048
049 import java.io.InputStream;
050
051 import java.util.List;
052
053 import javax.mail.Message;
054 import javax.mail.MessagingException;
055
056 import org.apache.commons.lang.time.StopWatch;
057
058
063 public class MessageListenerImpl implements MessageListener {
064
065 @Override
066 public boolean accept(String from, String recipient, Message message) {
067 try {
068 if (isAutoReply(message)) {
069 return false;
070 }
071
072 String messageIdString = getMessageIdString(recipient, message);
073
074 if ((messageIdString == null) ||
075 !messageIdString.startsWith(
076 MBUtil.MESSAGE_POP_PORTLET_PREFIX, getOffset())) {
077
078 return false;
079 }
080
081 Company company = getCompany(messageIdString);
082 long categoryId = getCategoryId(messageIdString);
083
084 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
085 categoryId);
086
087 if ((category.getCompanyId() != company.getCompanyId()) &&
088 !category.isRoot()) {
089
090 return false;
091 }
092
093 if (_log.isDebugEnabled()) {
094 _log.debug("Check to see if user " + from + " exists");
095 }
096
097 String pop3User = PrefsPropsUtil.getString(
098 PropsKeys.MAIL_SESSION_MAIL_POP3_USER,
099 PropsValues.MAIL_SESSION_MAIL_POP3_USER);
100
101 if (from.equalsIgnoreCase(pop3User)) {
102 return false;
103 }
104
105 UserLocalServiceUtil.getUserByEmailAddress(
106 company.getCompanyId(), from);
107
108 return true;
109 }
110 catch (Exception e) {
111 if (_log.isErrorEnabled()) {
112 _log.error("Unable to process message: " + message, e);
113 }
114
115 return false;
116 }
117 }
118
119 @Override
120 public void deliver(String from, String recipient, Message message)
121 throws MessageListenerException {
122
123 List<ObjectValuePair<String, InputStream>> inputStreamOVPs = null;
124
125 try {
126 StopWatch stopWatch = null;
127
128 if (_log.isDebugEnabled()) {
129 stopWatch = new StopWatch();
130
131 stopWatch.start();
132
133 _log.debug("Deliver message from " + from + " to " + recipient);
134 }
135
136 String messageIdString = getMessageIdString(recipient, message);
137
138 Company company = getCompany(messageIdString);
139
140 if (_log.isDebugEnabled()) {
141 _log.debug("Message id " + messageIdString);
142 }
143
144 long groupId = 0;
145 long categoryId = getCategoryId(messageIdString);
146
147 MBCategory category = MBCategoryLocalServiceUtil.fetchMBCategory(
148 categoryId);
149
150 if (category == null) {
151 groupId = categoryId;
152 categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
153 }
154 else {
155 groupId = category.getGroupId();
156
157 if (category.isRoot()) {
158 long messageId = getMessageId(messageIdString);
159
160 MBMessage threadMessage =
161 MBMessageLocalServiceUtil.fetchMBMessage(messageId);
162
163 if (threadMessage != null) {
164 groupId = threadMessage.getGroupId();
165 }
166 }
167 }
168
169 if (_log.isDebugEnabled()) {
170 _log.debug("Group id " + groupId);
171 _log.debug("Category id " + categoryId);
172 }
173
174 User user = UserLocalServiceUtil.getUserByEmailAddress(
175 company.getCompanyId(), from);
176
177 long parentMessageId = getParentMessageId(recipient, message);
178
179 if (_log.isDebugEnabled()) {
180 _log.debug("Parent message id " + parentMessageId);
181 }
182
183 MBMessage parentMessage = null;
184
185 try {
186 if (parentMessageId > 0) {
187 parentMessage = MBMessageLocalServiceUtil.getMessage(
188 parentMessageId);
189 }
190 }
191 catch (NoSuchMessageException nsme) {
192
193
194
195
196 }
197
198 if (_log.isDebugEnabled()) {
199 _log.debug("Parent message " + parentMessage);
200 }
201
202 String subject = MBUtil.getSubjectWithoutMessageId(message);
203
204 MBMailMessage mbMailMessage = new MBMailMessage();
205
206 MBUtil.collectPartContent(message, mbMailMessage);
207
208 inputStreamOVPs = mbMailMessage.getInputStreamOVPs();
209
210 PermissionCheckerUtil.setThreadValues(user);
211
212 ServiceContext serviceContext = new ServiceContext();
213
214 serviceContext.setAddGroupPermissions(true);
215 serviceContext.setAddGuestPermissions(true);
216 serviceContext.setLayoutFullURL(
217 PortalUtil.getLayoutFullURL(
218 groupId, PortletKeys.MESSAGE_BOARDS));
219 serviceContext.setScopeGroupId(groupId);
220
221 if (parentMessage == null) {
222 MBMessageServiceUtil.addMessage(
223 groupId, categoryId, subject, mbMailMessage.getBody(),
224 MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, false,
225 0.0, true, serviceContext);
226 }
227 else {
228 MBMessageServiceUtil.addMessage(
229 parentMessage.getMessageId(), subject,
230 mbMailMessage.getBody(), MBMessageConstants.DEFAULT_FORMAT,
231 inputStreamOVPs, false, 0.0, true, serviceContext);
232 }
233
234 if (_log.isDebugEnabled()) {
235 _log.debug(
236 "Delivering message takes " + stopWatch.getTime() + " ms");
237 }
238 }
239 catch (PrincipalException pe) {
240 if (_log.isDebugEnabled()) {
241 _log.debug("Prevented unauthorized post from " + from);
242 }
243
244 throw new MessageListenerException(pe);
245 }
246 catch (Exception e) {
247 _log.error(e, e);
248
249 throw new MessageListenerException(e);
250 }
251 finally {
252 if (inputStreamOVPs != null) {
253 for (ObjectValuePair<String, InputStream> inputStreamOVP :
254 inputStreamOVPs) {
255
256 InputStream inputStream = inputStreamOVP.getValue();
257
258 StreamUtil.cleanUp(inputStream);
259 }
260 }
261
262 PermissionCheckerUtil.setThreadValues(null);
263 }
264 }
265
266 @Override
267 public String getId() {
268 return MessageListenerImpl.class.getName();
269 }
270
271 protected long getCategoryId(String messageIdString) {
272 String[] parts = getMessageIdStringParts(messageIdString);
273
274 return GetterUtil.getLong(parts[0]);
275 }
276
277 protected Company getCompany(String messageIdString) throws Exception {
278 int pos =
279 messageIdString.indexOf(CharPool.AT) +
280 PropsValues.POP_SERVER_SUBDOMAIN.length() + 1;
281
282 if (PropsValues.POP_SERVER_SUBDOMAIN.length() > 0) {
283 pos++;
284 }
285
286 int endPos = messageIdString.indexOf(CharPool.GREATER_THAN, pos);
287
288 if (endPos == -1) {
289 endPos = messageIdString.length();
290 }
291
292 String mx = messageIdString.substring(pos, endPos);
293
294 return CompanyLocalServiceUtil.getCompanyByMx(mx);
295 }
296
297 protected long getMessageId(String messageIdString) {
298 String[] parts = getMessageIdStringParts(messageIdString);
299
300 return GetterUtil.getLong(parts[1]);
301 }
302
303 protected String getMessageIdString(String recipient, Message message)
304 throws Exception {
305
306 if (PropsValues.POP_SERVER_SUBDOMAIN.length() > 0) {
307 return recipient;
308 }
309 else {
310 return MBUtil.getParentMessageIdString(message);
311 }
312 }
313
314 protected String[] getMessageIdStringParts(String messageIdString) {
315 int pos = messageIdString.indexOf(CharPool.AT);
316
317 String target = messageIdString.substring(
318 MBUtil.MESSAGE_POP_PORTLET_PREFIX.length() + getOffset(), pos);
319
320 return StringUtil.split(target, CharPool.PERIOD);
321 }
322
323 protected int getOffset() {
324 if (PropsValues.POP_SERVER_SUBDOMAIN.length() == 0) {
325 return 1;
326 }
327
328 return 0;
329 }
330
331 protected long getParentMessageId(String recipient, Message message)
332 throws Exception {
333
334 if (!StringUtil.startsWith(
335 recipient, MBUtil.MESSAGE_POP_PORTLET_PREFIX)) {
336
337 return MBUtil.getParentMessageId(message);
338 }
339
340 int pos = recipient.indexOf(CharPool.AT);
341
342 if (pos < 0) {
343 return MBUtil.getParentMessageId(message);
344 }
345
346 String target = recipient.substring(
347 MBUtil.MESSAGE_POP_PORTLET_PREFIX.length(), pos);
348
349 String[] parts = StringUtil.split(target, CharPool.PERIOD);
350
351 long parentMessageId = 0;
352
353 if (parts.length == 2) {
354 parentMessageId = GetterUtil.getLong(parts[1]);
355 }
356
357 if (parentMessageId > 0) {
358 return parentMessageId;
359 }
360
361 return MBUtil.getParentMessageId(message);
362 }
363
364 protected boolean isAutoReply(Message message) throws MessagingException {
365 String[] autoReply = message.getHeader("X-Autoreply");
366
367 if ((autoReply != null) && (autoReply.length > 0)) {
368 return true;
369 }
370
371 String[] autoReplyFrom = message.getHeader("X-Autoreply-From");
372
373 if ((autoReplyFrom != null) && (autoReplyFrom.length > 0)) {
374 return true;
375 }
376
377 String[] mailAutoReply = message.getHeader("X-Mail-Autoreply");
378
379 if ((mailAutoReply != null) && (mailAutoReply.length > 0)) {
380 return true;
381 }
382
383 return false;
384 }
385
386 private static Log _log = LogFactoryUtil.getLog(MessageListenerImpl.class);
387
388 }