1
22
23 package com.liferay.portlet.messageboards.pop;
24
25 import com.liferay.portal.PortalException;
26 import com.liferay.portal.SystemException;
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.UserLocalServiceUtil;
38 import com.liferay.portal.util.PropsValues;
39 import com.liferay.portlet.messageboards.NoSuchMessageException;
40 import com.liferay.portlet.messageboards.model.MBCategory;
41 import com.liferay.portlet.messageboards.model.MBMessage;
42 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
43 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
44 import com.liferay.portlet.messageboards.service.MBMessageServiceUtil;
45 import com.liferay.portlet.messageboards.util.MBUtil;
46 import com.liferay.util.mail.JavaMailUtil;
47
48 import java.io.IOException;
49 import java.io.InputStream;
50
51 import javax.mail.BodyPart;
52 import javax.mail.Message;
53 import javax.mail.MessagingException;
54 import javax.mail.Part;
55 import javax.mail.internet.MimeMessage;
56 import javax.mail.internet.MimeMultipart;
57
58 import org.apache.commons.lang.time.StopWatch;
59 import org.apache.commons.logging.Log;
60 import org.apache.commons.logging.LogFactory;
61
62
69 public class MessageListenerImpl implements MessageListener {
70
71 public boolean accept(String from, String recipient) {
72 try {
73 if (!recipient.startsWith(MBUtil.POP_PORTLET_PREFIX)) {
74 return false;
75 }
76
77 Company company = getCompany(recipient);
78 long categoryId = getCategoryId(recipient);
79
80 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
81 categoryId);
82
83 if (category.getCompanyId() != company.getCompanyId()) {
84 return false;
85 }
86
87 if (_log.isDebugEnabled()) {
88 _log.debug("Check to see if user " + from + " exists");
89 }
90
91 UserLocalServiceUtil.getUserByEmailAddress(
92 company.getCompanyId(), from);
93
94 return true;
95 }
96 catch (Exception e) {
97 if (_log.isWarnEnabled()) {
98 _log.warn("Mail rejected", e);
99 }
100
101 return false;
102 }
103 }
104
105 public void deliver(String from, String recipient, Message message)
106 throws MessageListenerException {
107
108 try {
109 StopWatch stopWatch = null;
110
111 if (_log.isDebugEnabled()) {
112 stopWatch = new StopWatch();
113
114 stopWatch.start();
115
116 _log.debug(
117 "Deliver message from " + from + " to " + recipient);
118 }
119
120 Company company = getCompany(recipient);
121 long categoryId = getCategoryId(recipient);
122
123 if (_log.isDebugEnabled()) {
124 _log.debug("Category id " + categoryId);
125 }
126
127 User user = UserLocalServiceUtil.getUserByEmailAddress(
128 company.getCompanyId(), from);
129
130 long parentMessageId = getParentMessageId(recipient, message);
131
132 if (_log.isDebugEnabled()) {
133 _log.debug("Parent message id " + parentMessageId);
134 }
135
136 MBMessage parentMessage = null;
137
138 try {
139 if (parentMessageId > 0) {
140 parentMessage = MBMessageLocalServiceUtil.getMessage(
141 parentMessageId);
142 }
143 }
144 catch (NoSuchMessageException nsme) {
145
146
149 }
150
151 if (_log.isDebugEnabled()) {
152 _log.debug("Parent message " + parentMessage);
153 }
154
155 MBMailMessage collector = new MBMailMessage();
156
157 collectPartContent(message, collector);
158
159 PermissionCheckerUtil.setThreadValues(user);
160
161 if (parentMessage == null) {
162 MBMessageServiceUtil.addMessage(
163 categoryId, message.getSubject(), collector.getBody(),
164 collector.getFiles(), false, 0.0, null, true, true);
165 }
166 else {
167 MBMessageServiceUtil.addMessage(
168 categoryId, parentMessage.getThreadId(),
169 parentMessage.getMessageId(), message.getSubject(),
170 collector.getBody(), collector.getFiles(), false, 0.0, null,
171 true, true);
172 }
173
174 if (_log.isDebugEnabled()) {
175 _log.debug(
176 "Delivering message takes " + stopWatch.getTime() + " ms");
177 }
178 }
179 catch (PrincipalException pe) {
180 if (_log.isDebugEnabled()) {
181 _log.debug("Prevented unauthorized post from " + from);
182 }
183
184 throw new MessageListenerException(pe);
185 }
186 catch (Exception e) {
187 _log.error(e, e);
188
189 throw new MessageListenerException(e);
190 }
191 }
192
193 public String getId() {
194 return MessageListenerImpl.class.getName();
195 }
196
197 protected void collectMultipartContent(
198 MimeMultipart multipart, MBMailMessage collector)
199 throws IOException, MessagingException {
200
201 for (int i = 0; i < multipart.getCount(); i++) {
202 BodyPart part = multipart.getBodyPart(i);
203
204 collectPartContent(part, collector);
205 }
206 }
207
208 protected void collectPartContent(Part part, MBMailMessage collector)
209 throws IOException, MessagingException {
210
211 Object partContent = part.getContent();
212
213 String contentType = part.getContentType().toLowerCase();
214
215 if ((part.getDisposition() != null) &&
216 (part.getDisposition().equalsIgnoreCase(MimeMessage.ATTACHMENT))) {
217
218 if (_log.isDebugEnabled()) {
219 _log.debug("Processing attachment");
220 }
221
222 byte[] bytes = null;
223
224 if (partContent instanceof String) {
225 bytes = ((String)partContent).getBytes();
226 }
227 else if (partContent instanceof InputStream) {
228 bytes = JavaMailUtil.getBytes(part);
229 }
230
231 collector.addFile(part.getFileName(), bytes);
232 }
233 else {
234 if (partContent instanceof MimeMultipart) {
235 collectMultipartContent((MimeMultipart)partContent, collector);
236 }
237 else if (partContent instanceof String) {
238 if (contentType.startsWith("text/html")) {
239 collector.setHtmlBody((String)partContent);
240 }
241 else {
242 collector.setPlainBody((String)partContent);
243 }
244 }
245 }
246 }
247
248 protected long getCategoryId(String recipient) {
249 int pos = recipient.indexOf(StringPool.AT);
250
251 String target = recipient.substring(
252 MBUtil.POP_PORTLET_PREFIX.length(), pos);
253
254 String[] parts = StringUtil.split(target, ".");
255
256 long categoryId = GetterUtil.getLong(parts[0]);
257
258 return categoryId;
259 }
260
261 protected Company getCompany(String recipient)
262 throws PortalException, SystemException {
263
264 int pos = recipient.indexOf(StringPool.AT);
265
266 String mx = recipient.substring(
267 pos + PropsValues.POP_SERVER_SUBDOMAIN.length() + 2);
268
269 return CompanyLocalServiceUtil.getCompanyByMx(mx);
270 }
271
272 protected long getParentMessageId(String recipient, Message message)
273 throws MessagingException {
274
275
277 int pos = recipient.indexOf(StringPool.AT);
278
279 String target = recipient.substring(
280 MBUtil.POP_PORTLET_PREFIX.length(), pos);
281
282 String[] parts = StringUtil.split(target, StringPool.PERIOD);
283
284 long parentMessageId = 0;
285
286 if (parts.length == 2) {
287 parentMessageId = GetterUtil.getLong(parts[1]);
288 }
289
290 if (parentMessageId > 0) {
291 return parentMessageId;
292 }
293
294
299 String parentHeader = null;
300
301 String[] references = message.getHeader("References");
302
303 if ((references != null) && (references.length > 0)) {
304 parentHeader = references[0].substring(
305 references[0].lastIndexOf("<"));
306 }
307
308 if (parentHeader == null) {
309 String[] inReplyToHeaders = message.getHeader("In-Reply-To");
310
311 if ((inReplyToHeaders != null) &&
312 (inReplyToHeaders.length > 0)) {
313
314 parentHeader = inReplyToHeaders[0];
315 }
316 }
317
318 if (parentHeader != null) {
319 if (_log.isDebugEnabled()) {
320 _log.debug("Parent header " + parentHeader);
321 }
322
323 if (parentMessageId == -1) {
324 parentMessageId = MBUtil.getMessageId(parentHeader);
325 }
326
327 if (_log.isDebugEnabled()) {
328 _log.debug("Previous message id " + parentMessageId);
329 }
330 }
331
332 return parentMessageId;
333 }
334
335 private static Log _log = LogFactory.getLog(MessageListenerImpl.class);
336
337 }