1
14
15 package com.liferay.portlet.messageboards.util;
16
17 import com.liferay.portal.kernel.log.Log;
18 import com.liferay.portal.kernel.log.LogFactoryUtil;
19 import com.liferay.portal.kernel.portlet.LiferayWindowState;
20 import com.liferay.portal.kernel.util.GetterUtil;
21 import com.liferay.portal.kernel.util.Http;
22 import com.liferay.portal.kernel.util.LocaleUtil;
23 import com.liferay.portal.kernel.util.LocalizationUtil;
24 import com.liferay.portal.kernel.util.ParamUtil;
25 import com.liferay.portal.kernel.util.StringBundler;
26 import com.liferay.portal.kernel.util.StringPool;
27 import com.liferay.portal.kernel.util.StringUtil;
28 import com.liferay.portal.kernel.util.Validator;
29 import com.liferay.portal.model.Group;
30 import com.liferay.portal.model.Organization;
31 import com.liferay.portal.model.Role;
32 import com.liferay.portal.model.UserGroup;
33 import com.liferay.portal.service.GroupLocalServiceUtil;
34 import com.liferay.portal.service.OrganizationLocalServiceUtil;
35 import com.liferay.portal.service.RoleLocalServiceUtil;
36 import com.liferay.portal.service.UserGroupLocalServiceUtil;
37 import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
38 import com.liferay.portal.service.UserLocalServiceUtil;
39 import com.liferay.portal.theme.ThemeDisplay;
40 import com.liferay.portal.util.ContentUtil;
41 import com.liferay.portal.util.PortalUtil;
42 import com.liferay.portal.util.PropsValues;
43 import com.liferay.portal.util.WebKeys;
44 import com.liferay.portlet.messageboards.model.MBBan;
45 import com.liferay.portlet.messageboards.model.MBCategory;
46 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
47 import com.liferay.portlet.messageboards.model.MBMailingList;
48 import com.liferay.portlet.messageboards.model.MBMessage;
49 import com.liferay.portlet.messageboards.model.MBStatsUser;
50 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
51 import com.liferay.portlet.messageboards.service.MBMailingListLocalServiceUtil;
52 import com.liferay.util.mail.JavaMailUtil;
53
54 import java.io.InputStream;
55
56 import java.util.Calendar;
57 import java.util.Collections;
58 import java.util.Date;
59 import java.util.List;
60
61 import javax.mail.BodyPart;
62 import javax.mail.Message;
63 import javax.mail.Part;
64 import javax.mail.internet.MimeMessage;
65 import javax.mail.internet.MimeMultipart;
66
67 import javax.portlet.PortletPreferences;
68 import javax.portlet.PortletURL;
69 import javax.portlet.RenderResponse;
70
71 import javax.servlet.http.HttpServletRequest;
72
73
78 public class MBUtil {
79
80 public static final String POP_PORTLET_PREFIX = "mb.";
81
82 public static final int POP_SERVER_SUBDOMAIN_LENGTH =
83 PropsValues.POP_SERVER_SUBDOMAIN.length();
84
85 public static void addPortletBreadcrumbEntries(
86 long categoryId, HttpServletRequest request,
87 RenderResponse renderResponse)
88 throws Exception {
89
90 if ((categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
91 (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
92
93 return;
94 }
95
96 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
97 categoryId);
98
99 addPortletBreadcrumbEntries(category, request, renderResponse);
100 }
101
102 public static void addPortletBreadcrumbEntries(
103 MBCategory category, HttpServletRequest request,
104 RenderResponse renderResponse)
105 throws Exception {
106
107 String strutsAction = ParamUtil.getString(
108 request, "struts_action");
109
110 boolean selectCategory = strutsAction.equals(
111 "/message_boards/select_category");
112
113 PortletURL portletURL = renderResponse.createRenderURL();
114
115 if (selectCategory) {
116 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
117 WebKeys.THEME_DISPLAY);
118
119 portletURL.setWindowState(LiferayWindowState.POP_UP);
120
121 portletURL.setParameter(
122 "struts_action", "/message_boards/select_category");
123
124 PortalUtil.addPortletBreadcrumbEntry(
125 request, themeDisplay.translate("categories"),
126 portletURL.toString());
127 }
128 else {
129 portletURL.setParameter("struts_action", "/message_boards/view");
130 portletURL.setParameter("tabs1", "categories");
131 }
132
133 List<MBCategory> ancestorCategories = category.getAncestors();
134
135 Collections.reverse(ancestorCategories);
136
137 for (MBCategory curCategory : ancestorCategories) {
138 portletURL.setParameter(
139 "mbCategoryId", String.valueOf(curCategory.getCategoryId()));
140
141 PortalUtil.addPortletBreadcrumbEntry(
142 request, curCategory.getName(), portletURL.toString());
143 }
144
145 portletURL.setParameter(
146 "mbCategoryId", String.valueOf(category.getCategoryId()));
147
148 PortalUtil.addPortletBreadcrumbEntry(
149 request, category.getName(), portletURL.toString());
150 }
151
152 public static void addPortletBreadcrumbEntries(
153 MBMessage message, HttpServletRequest request,
154 RenderResponse renderResponse)
155 throws Exception {
156
157 MBCategory category = message.getCategory();
158
159 addPortletBreadcrumbEntries(category, request, renderResponse);
160
161 PortletURL portletURL = renderResponse.createRenderURL();
162
163 portletURL.setParameter(
164 "struts_action", "/message_boards/view_message");
165 portletURL.setParameter("tabs1", "categories");
166 portletURL.setParameter(
167 "messageId", String.valueOf(message.getMessageId()));
168
169 PortalUtil.addPortletBreadcrumbEntry(
170 request, message.getSubject(), portletURL.toString());
171 }
172
173 public static void collectMultipartContent(
174 MimeMultipart multipart, MBMailMessage collector)
175 throws Exception {
176
177 for (int i = 0; i < multipart.getCount(); i++) {
178 BodyPart part = multipart.getBodyPart(i);
179
180 collectPartContent(part, collector);
181 }
182 }
183
184 public static void collectPartContent(Part part, MBMailMessage collector)
185 throws Exception {
186
187 Object partContent = part.getContent();
188
189 String contentType = part.getContentType().toLowerCase();
190
191 if ((part.getDisposition() != null) &&
192 (part.getDisposition().equalsIgnoreCase(MimeMessage.ATTACHMENT))) {
193
194 if (_log.isDebugEnabled()) {
195 _log.debug("Processing attachment");
196 }
197
198 byte[] bytes = null;
199
200 if (partContent instanceof String) {
201 bytes = ((String)partContent).getBytes();
202 }
203 else if (partContent instanceof InputStream) {
204 bytes = JavaMailUtil.getBytes(part);
205 }
206
207 collector.addFile(part.getFileName(), bytes);
208 }
209 else {
210 if (partContent instanceof MimeMultipart) {
211 collectMultipartContent((MimeMultipart)partContent, collector);
212 }
213 else if (partContent instanceof String) {
214 if (contentType.startsWith("text/html")) {
215 collector.setHtmlBody((String)partContent);
216 }
217 else {
218 collector.setPlainBody((String)partContent);
219 }
220 }
221 }
222 }
223
224 public static String getEmailFromAddress(PortletPreferences preferences) {
225 String emailFromAddress = PropsValues.MESSAGE_BOARDS_EMAIL_FROM_ADDRESS;
226
227 return preferences.getValue("email-from-address", emailFromAddress);
228 }
229
230 public static String getEmailFromName(PortletPreferences preferences) {
231 String emailFromName = PropsValues.MESSAGE_BOARDS_EMAIL_FROM_NAME;
232
233 return preferences.getValue("email-from-name", emailFromName);
234 }
235
236 public static boolean getEmailHtmlFormat(PortletPreferences preferences) {
237 String emailHtmlFormat = preferences.getValue(
238 "email-html-format", StringPool.BLANK);
239
240 if (Validator.isNotNull(emailHtmlFormat)) {
241 return GetterUtil.getBoolean(emailHtmlFormat);
242 }
243 else {
244 return PropsValues.MESSAGE_BOARDS_EMAIL_HTML_FORMAT;
245 }
246 }
247
248 public static String getEmailMessageAddedBody(
249 PortletPreferences preferences) {
250
251 String emailMessageAddedBody = preferences.getValue(
252 "email-message-added-body", StringPool.BLANK);
253
254 if (Validator.isNotNull(emailMessageAddedBody)) {
255 return emailMessageAddedBody;
256 }
257 else {
258 return ContentUtil.get(
259 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_BODY);
260 }
261 }
262
263 public static boolean getEmailMessageAddedEnabled(
264 PortletPreferences preferences) {
265
266 String emailMessageAddedEnabled = preferences.getValue(
267 "email-message-added-enabled", StringPool.BLANK);
268
269 if (Validator.isNotNull(emailMessageAddedEnabled)) {
270 return GetterUtil.getBoolean(emailMessageAddedEnabled);
271 }
272 else {
273 return PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_ENABLED;
274 }
275 }
276
277 public static String getEmailMessageAddedSignature(
278 PortletPreferences preferences) {
279
280 String emailMessageAddedSignature = preferences.getValue(
281 "email-message-added-signature", StringPool.BLANK);
282
283 if (Validator.isNotNull(emailMessageAddedSignature)) {
284 return emailMessageAddedSignature;
285 }
286 else {
287 return ContentUtil.get(
288 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_SIGNATURE);
289 }
290 }
291
292 public static String getEmailMessageAddedSubjectPrefix(
293 PortletPreferences preferences) {
294
295 String emailMessageAddedSubjectPrefix = preferences.getValue(
296 "email-message-added-subject-prefix", StringPool.BLANK);
297
298 if (Validator.isNotNull(emailMessageAddedSubjectPrefix)) {
299 return emailMessageAddedSubjectPrefix;
300 }
301 else {
302 return ContentUtil.get(
303 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_SUBJECT_PREFIX);
304 }
305 }
306
307 public static String getEmailMessageUpdatedBody(
308 PortletPreferences preferences) {
309
310 String emailMessageUpdatedBody = preferences.getValue(
311 "email-message-updated-body", StringPool.BLANK);
312
313 if (Validator.isNotNull(emailMessageUpdatedBody)) {
314 return emailMessageUpdatedBody;
315 }
316 else {
317 return ContentUtil.get(
318 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_BODY);
319 }
320 }
321
322 public static boolean getEmailMessageUpdatedEnabled(
323 PortletPreferences preferences) {
324
325 String emailMessageUpdatedEnabled = preferences.getValue(
326 "email-message-updated-enabled", StringPool.BLANK);
327
328 if (Validator.isNotNull(emailMessageUpdatedEnabled)) {
329 return GetterUtil.getBoolean(emailMessageUpdatedEnabled);
330 }
331 else {
332 return PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_ENABLED;
333 }
334 }
335
336 public static String getEmailMessageUpdatedSignature(
337 PortletPreferences preferences) {
338
339 String emailMessageUpdatedSignature = preferences.getValue(
340 "email-message-updated-signature", StringPool.BLANK);
341
342 if (Validator.isNotNull(emailMessageUpdatedSignature)) {
343 return emailMessageUpdatedSignature;
344 }
345 else {
346 return ContentUtil.get(
347 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_SIGNATURE);
348 }
349 }
350
351 public static String getEmailMessageUpdatedSubjectPrefix(
352 PortletPreferences preferences) {
353
354 String emailMessageUpdatedSubject = preferences.getValue(
355 "email-message-updated-subject-prefix", StringPool.BLANK);
356
357 if (Validator.isNotNull(emailMessageUpdatedSubject)) {
358 return emailMessageUpdatedSubject;
359 }
360 else {
361 return ContentUtil.get(
362 PropsValues.
363 MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_SUBJECT_PREFIX);
364 }
365 }
366
367 public static String getMailId(String mx, long categoryId, long messageId) {
368 StringBundler sb = new StringBundler(10);
369
370 sb.append(StringPool.LESS_THAN);
371 sb.append(POP_PORTLET_PREFIX);
372 sb.append(categoryId);
373 sb.append(StringPool.PERIOD);
374 sb.append(messageId);
375 sb.append(StringPool.AT);
376
377 if (Validator.isNotNull(PropsValues.POP_SERVER_SUBDOMAIN)) {
378 sb.append(PropsValues.POP_SERVER_SUBDOMAIN);
379 sb.append(StringPool.PERIOD);
380 }
381
382 sb.append(mx);
383 sb.append(StringPool.GREATER_THAN);
384
385 return sb.toString();
386 }
387
388 public static String getMailingListAddress(
389 long groupId, long categoryId, long messageId, String mx,
390 String defaultMailingListAddress) {
391
392 if (POP_SERVER_SUBDOMAIN_LENGTH <= 0) {
393 String mailingListAddress = defaultMailingListAddress;
394
395 try {
396 MBMailingList mailingList =
397 MBMailingListLocalServiceUtil.getCategoryMailingList(
398 groupId, categoryId);
399
400 if (mailingList.isActive()) {
401 mailingListAddress = mailingList.getEmailAddress();
402 }
403 }
404 catch (Exception e) {
405 }
406
407 return mailingListAddress;
408 }
409
410 StringBundler sb = new StringBundler(8);
411
412 sb.append(POP_PORTLET_PREFIX);
413 sb.append(categoryId);
414 sb.append(StringPool.PERIOD);
415 sb.append(messageId);
416 sb.append(StringPool.AT);
417 sb.append(PropsValues.POP_SERVER_SUBDOMAIN);
418 sb.append(StringPool.PERIOD);
419 sb.append(mx);
420
421 return sb.toString();
422 }
423
424 public static long getMessageId(String mailId) {
425 int x = mailId.indexOf(StringPool.LESS_THAN) + 1;
426 int y = mailId.indexOf(StringPool.AT);
427
428 long messageId = 0;
429
430 if ((x > 0 ) && (y != -1)) {
431 String temp = mailId.substring(x, y);
432
433 int z = temp.lastIndexOf(StringPool.PERIOD);
434
435 if (z != -1) {
436 messageId = GetterUtil.getLong(temp.substring(z + 1));
437 }
438 }
439
440 return messageId;
441 }
442
443 public static long getParentMessageId(Message message) throws Exception {
444 long parentMessageId = -1;
445
446 String parentHeader = getParentMessageIdString(message);
447
448 if (parentHeader != null) {
449 if (_log.isDebugEnabled()) {
450 _log.debug("Parent header " + parentHeader);
451 }
452
453 parentMessageId = getMessageId(parentHeader);
454
455 if (_log.isDebugEnabled()) {
456 _log.debug("Previous message id " + parentMessageId);
457 }
458 }
459
460 return parentMessageId;
461 }
462
463 public static String getParentMessageIdString(Message message)
464 throws Exception {
465
466
471 String parentHeader = null;
472
473 String[] references = message.getHeader("References");
474
475 if ((references != null) && (references.length > 0)) {
476 String reference = references[0];
477
478 int x = reference.lastIndexOf("<mb.");
479
480 if (x > -1) {
481 int y = reference.indexOf(">", x);
482
483 parentHeader = reference.substring(x, y);
484 }
485 }
486
487 if (parentHeader == null) {
488 String[] inReplyToHeaders = message.getHeader("In-Reply-To");
489
490 if ((inReplyToHeaders != null) && (inReplyToHeaders.length > 0)) {
491 parentHeader = inReplyToHeaders[0];
492 }
493 }
494
495 if (Validator.isNull(parentHeader) ||
496 !parentHeader.startsWith(POP_PORTLET_PREFIX, 1)) {
497
498 parentHeader = _getParentMessageIdFromSubject(message);
499 }
500
501 return parentHeader;
502 }
503
504 public static String getSubjectWithoutMessageId(Message message)
505 throws Exception {
506
507 String subject = message.getSubject();
508
509 String parentMessageId = _getParentMessageIdFromSubject(message);
510
511 if (Validator.isNotNull(parentMessageId)) {
512 int pos = subject.indexOf(parentMessageId);
513
514 if (pos != -1) {
515 subject = subject.substring(0, pos);
516 }
517 }
518
519 return subject;
520 }
521
522 public static String[] getThreadPriority(
523 PortletPreferences preferences, String languageId, double value,
524 ThemeDisplay themeDisplay)
525 throws Exception {
526
527 String[] priorities = LocalizationUtil.getPreferencesValues(
528 preferences, "priorities", languageId);
529
530 String[] priorityPair = _findThreadPriority(
531 value, themeDisplay, priorities);
532
533 if (priorityPair == null) {
534 String defaultLanguageId = LocaleUtil.toLanguageId(
535 LocaleUtil.getDefault());
536
537 priorities = LocalizationUtil.getPreferencesValues(
538 preferences, "priorities", defaultLanguageId);
539
540 priorityPair = _findThreadPriority(value, themeDisplay, priorities);
541 }
542
543 return priorityPair;
544 }
545
546 public static Date getUnbanDate(MBBan ban, int expireInterval) {
547 Date banDate = ban.getCreateDate();
548
549 Calendar cal = Calendar.getInstance();
550
551 cal.setTime(banDate);
552
553 cal.add(Calendar.DATE, expireInterval);
554
555 return cal.getTime();
556 }
557
558 public static String getUserRank(
559 PortletPreferences preferences, String languageId, int posts)
560 throws Exception {
561
562 String rank = StringPool.BLANK;
563
564 String[] ranks = LocalizationUtil.getPreferencesValues(
565 preferences, "ranks", languageId);
566
567 for (int i = 0; i < ranks.length; i++) {
568 String[] kvp = StringUtil.split(ranks[i], StringPool.EQUAL);
569
570 String kvpName = kvp[0];
571 int kvpPosts = GetterUtil.getInteger(kvp[1]);
572
573 if (posts >= kvpPosts) {
574 rank = kvpName;
575 }
576 else {
577 break;
578 }
579 }
580
581 return rank;
582 }
583
584 public static String[] getUserRank(
585 PortletPreferences preferences, String languageId,
586 MBStatsUser statsUser)
587 throws Exception {
588
589 String[] rank = {StringPool.BLANK, StringPool.BLANK};
590
591 int maxPosts = 0;
592
593 Group group = GroupLocalServiceUtil.getGroup(
594 statsUser.getGroupId());
595
596 long companyId = group.getCompanyId();
597
598 String[] ranks = LocalizationUtil.getPreferencesValues(
599 preferences, "ranks", languageId);
600
601 for (int i = 0; i < ranks.length; i++) {
602 String[] kvp = StringUtil.split(ranks[i], StringPool.EQUAL);
603
604 String curRank = kvp[0];
605 String curRankValue = kvp[1];
606
607 String[] curRankValueKvp = StringUtil.split(
608 curRankValue, StringPool.COLON);
609
610 if (curRankValueKvp.length <= 1) {
611 int posts = GetterUtil.getInteger(curRankValue);
612
613 if ((posts <= statsUser.getMessageCount()) &&
614 (posts >= maxPosts)) {
615
616 rank[0] = curRank;
617 maxPosts = posts;
618 }
619
620 }
621 else {
622 String entityType = curRankValueKvp[0];
623 String entityValue = curRankValueKvp[1];
624
625 try {
626 if (_isEntityRank(
627 companyId, statsUser, entityType, entityValue)) {
628
629 rank[1] = curRank;
630
631 break;
632 }
633 }
634 catch (Exception e) {
635 if (_log.isWarnEnabled()) {
636 _log.warn(e);
637 }
638 }
639 }
640 }
641
642 return rank;
643 }
644
645 public static boolean hasMailIdHeader(Message message) throws Exception {
646 String[] messageIds = message.getHeader("Message-ID");
647
648 if (messageIds == null) {
649 return false;
650 }
651
652 for (String messageId : messageIds) {
653 if (Validator.isNotNull(PropsValues.POP_SERVER_SUBDOMAIN) &&
654 messageId.contains(PropsValues.POP_SERVER_SUBDOMAIN)) {
655
656 return true;
657 }
658 }
659
660 return false;
661 }
662
663 public static boolean isAllowAnonymousPosting(
664 PortletPreferences preferences) {
665
666 String allowAnonymousPosting = preferences.getValue(
667 "allow-anonymous-posting", StringPool.BLANK);
668
669 if (Validator.isNotNull(allowAnonymousPosting)) {
670 return GetterUtil.getBoolean(allowAnonymousPosting);
671 }
672 else {
673 return PropsValues.MESSAGE_BOARDS_ANONYMOUS_POSTING_ENABLED;
674 }
675 }
676
677 private static String[] _findThreadPriority(
678 double value, ThemeDisplay themeDisplay, String[] priorities) {
679
680 for (int i = 0; i < priorities.length; i++) {
681 String[] priority = StringUtil.split(priorities[i]);
682
683 try {
684 String priorityName = priority[0];
685 String priorityImage = priority[1];
686 double priorityValue = GetterUtil.getDouble(priority[2]);
687
688 if (value == priorityValue) {
689 if (!priorityImage.startsWith(Http.HTTP)) {
690 priorityImage =
691 themeDisplay.getPathThemeImages() + priorityImage;
692 }
693
694 return new String[] {priorityName, priorityImage};
695 }
696 }
697 catch (Exception e) {
698 _log.error("Unable to determine thread priority", e);
699 }
700 }
701
702 return null;
703 }
704
705 private static String _getParentMessageIdFromSubject(Message message)
706 throws Exception {
707
708 String parentMessageId = null;
709
710 String subject = StringUtil.reverse(message.getSubject());
711
712 int pos = subject.indexOf(StringPool.LESS_THAN);
713
714 if (pos != -1) {
715 parentMessageId = StringUtil.reverse(subject.substring(0, pos + 1));
716 }
717
718 return parentMessageId;
719 }
720
721 private static boolean _isEntityRank(
722 long companyId, MBStatsUser statsUser, String entityType,
723 String entityValue)
724 throws Exception {
725
726 long groupId = statsUser.getGroupId();
727 long userId = statsUser.getUserId();
728
729 if (entityType.equals("community-role") ||
730 entityType.equals("organization-role")) {
731
732 Role role = RoleLocalServiceUtil.getRole(companyId, entityValue);
733
734 if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
735 userId, groupId, role.getRoleId(), true)) {
736
737 return true;
738 }
739 }
740 else if (entityType.equals("organization")) {
741 Organization organization =
742 OrganizationLocalServiceUtil.getOrganization(
743 companyId, entityValue);
744
745 if (OrganizationLocalServiceUtil.hasUserOrganization(
746 userId, organization.getOrganizationId(), false, true,
747 false)) {
748
749 return true;
750 }
751 }
752 else if (entityType.equals("regular-role")) {
753 if (RoleLocalServiceUtil.hasUserRole(
754 userId, companyId, entityValue, true)) {
755
756 return true;
757 }
758 }
759 else if (entityType.equals("user-group")) {
760 UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
761 companyId, entityValue);
762
763 if (UserLocalServiceUtil.hasUserGroupUser(
764 userGroup.getUserGroupId(), userId)) {
765
766 return true;
767 }
768 }
769
770 return false;
771 }
772
773 private static Log _log = LogFactoryUtil.getLog(MBUtil.class);
774
775 }