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