001
014
015 package com.liferay.portlet.messageboards.util;
016
017 import com.liferay.portal.kernel.concurrent.PortalCallable;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.log.Log;
021 import com.liferay.portal.kernel.log.LogFactoryUtil;
022 import com.liferay.portal.kernel.portlet.LiferayWindowState;
023 import com.liferay.portal.kernel.sanitizer.Sanitizer;
024 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
025 import com.liferay.portal.kernel.search.Document;
026 import com.liferay.portal.kernel.search.Field;
027 import com.liferay.portal.kernel.search.Hits;
028 import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
029 import com.liferay.portal.kernel.util.CharPool;
030 import com.liferay.portal.kernel.util.ContentTypes;
031 import com.liferay.portal.kernel.util.GetterUtil;
032 import com.liferay.portal.kernel.util.Http;
033 import com.liferay.portal.kernel.util.LocaleUtil;
034 import com.liferay.portal.kernel.util.LocalizationUtil;
035 import com.liferay.portal.kernel.util.ParamUtil;
036 import com.liferay.portal.kernel.util.PropsUtil;
037 import com.liferay.portal.kernel.util.StringBundler;
038 import com.liferay.portal.kernel.util.StringPool;
039 import com.liferay.portal.kernel.util.StringUtil;
040 import com.liferay.portal.kernel.util.Validator;
041 import com.liferay.portal.kernel.workflow.WorkflowConstants;
042 import com.liferay.portal.model.Group;
043 import com.liferay.portal.model.Organization;
044 import com.liferay.portal.model.Role;
045 import com.liferay.portal.model.Subscription;
046 import com.liferay.portal.model.UserGroup;
047 import com.liferay.portal.security.permission.ActionKeys;
048 import com.liferay.portal.security.permission.PermissionChecker;
049 import com.liferay.portal.service.GroupLocalServiceUtil;
050 import com.liferay.portal.service.OrganizationLocalServiceUtil;
051 import com.liferay.portal.service.RoleLocalServiceUtil;
052 import com.liferay.portal.service.SubscriptionLocalServiceUtil;
053 import com.liferay.portal.service.UserGroupLocalServiceUtil;
054 import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
055 import com.liferay.portal.service.UserLocalServiceUtil;
056 import com.liferay.portal.theme.ThemeDisplay;
057 import com.liferay.portal.util.PortalUtil;
058 import com.liferay.portal.util.PropsValues;
059 import com.liferay.portal.util.WebKeys;
060 import com.liferay.portlet.documentlibrary.model.DLFileEntry;
061 import com.liferay.portlet.documentlibrary.service.DLFileEntryLocalServiceUtil;
062 import com.liferay.portlet.messageboards.model.MBBan;
063 import com.liferay.portlet.messageboards.model.MBCategory;
064 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
065 import com.liferay.portlet.messageboards.model.MBMailingList;
066 import com.liferay.portlet.messageboards.model.MBMessage;
067 import com.liferay.portlet.messageboards.model.MBMessageConstants;
068 import com.liferay.portlet.messageboards.model.MBStatsUser;
069 import com.liferay.portlet.messageboards.model.MBThread;
070 import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
071 import com.liferay.portlet.messageboards.service.MBMailingListLocalServiceUtil;
072 import com.liferay.portlet.messageboards.service.MBMessageLocalServiceUtil;
073 import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
074 import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
075 import com.liferay.util.ContentUtil;
076 import com.liferay.util.mail.JavaMailUtil;
077
078 import java.io.InputStream;
079
080 import java.util.ArrayList;
081 import java.util.Calendar;
082 import java.util.Collections;
083 import java.util.Date;
084 import java.util.HashMap;
085 import java.util.HashSet;
086 import java.util.List;
087 import java.util.Map;
088 import java.util.Set;
089 import java.util.concurrent.Callable;
090
091 import javax.mail.BodyPart;
092 import javax.mail.Message;
093 import javax.mail.Part;
094 import javax.mail.internet.MimeMessage;
095 import javax.mail.internet.MimeMultipart;
096
097 import javax.portlet.PortletPreferences;
098 import javax.portlet.PortletRequest;
099 import javax.portlet.PortletURL;
100 import javax.portlet.RenderResponse;
101
102 import javax.servlet.http.HttpServletRequest;
103
104
107 public class MBUtil {
108
109 public static final String BB_CODE_EDITOR_WYSIWYG_IMPL_KEY =
110 "editor.wysiwyg.portal-web.docroot.html.portlet.message_boards." +
111 "edit_message.bb_code.jsp";
112
113 public static final String MESSAGE_POP_PORTLET_PREFIX = "mb_message.";
114
115 public static void addPortletBreadcrumbEntries(
116 long categoryId, HttpServletRequest request,
117 RenderResponse renderResponse)
118 throws Exception {
119
120 if ((categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
121 (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
122
123 return;
124 }
125
126 MBCategory category = MBCategoryLocalServiceUtil.getCategory(
127 categoryId);
128
129 addPortletBreadcrumbEntries(category, request, renderResponse);
130 }
131
132 public static void addPortletBreadcrumbEntries(
133 MBCategory category, HttpServletRequest request,
134 RenderResponse renderResponse)
135 throws Exception {
136
137 String strutsAction = ParamUtil.getString(request, "struts_action");
138
139 PortletURL portletURL = renderResponse.createRenderURL();
140
141 if (strutsAction.equals("/message_boards/select_category") ||
142 strutsAction.equals("/message_boards_admin/select_category")) {
143
144 ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
145 WebKeys.THEME_DISPLAY);
146
147 portletURL.setWindowState(LiferayWindowState.POP_UP);
148
149 portletURL.setParameter(
150 "struts_action", "/message_boards/select_category");
151
152 PortalUtil.addPortletBreadcrumbEntry(
153 request, themeDisplay.translate("categories"),
154 portletURL.toString());
155 }
156 else {
157 portletURL.setParameter("struts_action", "/message_boards/view");
158 }
159
160 List<MBCategory> ancestorCategories = category.getAncestors();
161
162 Collections.reverse(ancestorCategories);
163
164 for (MBCategory curCategory : ancestorCategories) {
165 portletURL.setParameter(
166 "mbCategoryId", String.valueOf(curCategory.getCategoryId()));
167
168 PortalUtil.addPortletBreadcrumbEntry(
169 request, curCategory.getName(), portletURL.toString());
170 }
171
172 portletURL.setParameter(
173 "mbCategoryId", String.valueOf(category.getCategoryId()));
174
175 PortalUtil.addPortletBreadcrumbEntry(
176 request, category.getName(), portletURL.toString());
177 }
178
179 public static void addPortletBreadcrumbEntries(
180 MBMessage message, HttpServletRequest request,
181 RenderResponse renderResponse)
182 throws Exception {
183
184 if (message.getCategoryId() ==
185 MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
186
187 return;
188 }
189
190 if (message.getCategoryId() !=
191 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
192
193 addPortletBreadcrumbEntries(
194 message.getCategory(), request, renderResponse);
195 }
196
197 PortletURL portletURL = renderResponse.createRenderURL();
198
199 portletURL.setParameter(
200 "struts_action", "/message_boards/view_message");
201 portletURL.setParameter(
202 "messageId", String.valueOf(message.getMessageId()));
203
204 PortalUtil.addPortletBreadcrumbEntry(
205 request, message.getSubject(), portletURL.toString());
206 }
207
208 public static void collectMultipartContent(
209 MimeMultipart multipart, MBMailMessage collector)
210 throws Exception {
211
212 for (int i = 0; i < multipart.getCount(); i++) {
213 BodyPart part = multipart.getBodyPart(i);
214
215 collectPartContent(part, collector);
216 }
217 }
218
219 public static void collectPartContent(
220 Part part, MBMailMessage mbMailMessage)
221 throws Exception {
222
223 Object partContent = part.getContent();
224
225 String contentType = part.getContentType().toLowerCase();
226
227 if ((part.getDisposition() != null) &&
228 part.getDisposition().equalsIgnoreCase(MimeMessage.ATTACHMENT)) {
229
230 if (_log.isDebugEnabled()) {
231 _log.debug("Processing attachment");
232 }
233
234 byte[] bytes = null;
235
236 if (partContent instanceof String) {
237 bytes = ((String)partContent).getBytes();
238 }
239 else if (partContent instanceof InputStream) {
240 bytes = JavaMailUtil.getBytes(part);
241 }
242
243 mbMailMessage.addBytes(part.getFileName(), bytes);
244 }
245 else {
246 if (partContent instanceof MimeMultipart) {
247 MimeMultipart mimeMultipart = (MimeMultipart)partContent;
248
249 collectMultipartContent(mimeMultipart, mbMailMessage);
250 }
251 else if (partContent instanceof String) {
252 Map<String, Object> options = new HashMap<String, Object>();
253
254 options.put("emailPartToMBMessageBody", Boolean.TRUE);
255
256 String messageBody = SanitizerUtil.sanitize(
257 0, 0, 0, MBMessage.class.getName(), 0, contentType,
258 Sanitizer.MODE_ALL, (String)partContent, options);
259
260 if (contentType.startsWith(ContentTypes.TEXT_HTML)) {
261 mbMailMessage.setHtmlBody(messageBody);
262 }
263 else {
264 mbMailMessage.setPlainBody(messageBody);
265 }
266 }
267 }
268 }
269
270 public static String getAbsolutePath(
271 PortletRequest portletRequest, long mbCategoryId)
272 throws PortalException, SystemException {
273
274 ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
275 WebKeys.THEME_DISPLAY);
276
277 if (mbCategoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
278 return themeDisplay.translate("home");
279 }
280
281 MBCategory mbCategory = MBCategoryLocalServiceUtil.fetchMBCategory(
282 mbCategoryId);
283
284 List<MBCategory> categories = mbCategory.getAncestors();
285
286 Collections.reverse(categories);
287
288 StringBundler sb = new StringBundler((categories.size() * 3) + 5);
289
290 sb.append(themeDisplay.translate("home"));
291 sb.append(StringPool.SPACE);
292
293 for (MBCategory curCategory : categories) {
294 sb.append(StringPool.RAQUO);
295 sb.append(StringPool.SPACE);
296 sb.append(curCategory.getName());
297 }
298
299 sb.append(StringPool.RAQUO);
300 sb.append(StringPool.SPACE);
301 sb.append(mbCategory.getName());
302
303 return sb.toString();
304 }
305
306 public static long getCategoryId(
307 HttpServletRequest request, MBCategory category) {
308
309 long categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
310
311 if (category != null) {
312 categoryId = category.getCategoryId();
313 }
314
315 categoryId = ParamUtil.getLong(request, "mbCategoryId", categoryId);
316
317 return categoryId;
318 }
319
320 public static long getCategoryId(
321 HttpServletRequest request, MBMessage message) {
322
323 long categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
324
325 if (message != null) {
326 categoryId = message.getCategoryId();
327 }
328
329 categoryId = ParamUtil.getLong(request, "mbCategoryId", categoryId);
330
331 return categoryId;
332 }
333
334 public static Set<Long> getCategorySubscriptionClassPKs(long userId)
335 throws SystemException {
336
337 List<Subscription> subscriptions =
338 SubscriptionLocalServiceUtil.getUserSubscriptions(
339 userId, MBCategory.class.getName());
340
341 Set<Long> classPKs = new HashSet<Long>(subscriptions.size());
342
343 for (Subscription subscription : subscriptions) {
344 classPKs.add(subscription.getClassPK());
345 }
346
347 return classPKs;
348 }
349
350 public static String getEmailFromAddress(
351 PortletPreferences preferences, long companyId)
352 throws SystemException {
353
354 return PortalUtil.getEmailFromAddress(
355 preferences, companyId,
356 PropsValues.MESSAGE_BOARDS_EMAIL_FROM_ADDRESS);
357 }
358
359 public static String getEmailFromName(
360 PortletPreferences preferences, long companyId)
361 throws SystemException {
362
363 return PortalUtil.getEmailFromName(
364 preferences, companyId, PropsValues.MESSAGE_BOARDS_EMAIL_FROM_NAME);
365 }
366
367 public static boolean getEmailHtmlFormat(PortletPreferences preferences) {
368 String emailHtmlFormat = preferences.getValue(
369 "emailHtmlFormat", StringPool.BLANK);
370
371 if (Validator.isNotNull(emailHtmlFormat)) {
372 return GetterUtil.getBoolean(emailHtmlFormat);
373 }
374 else {
375 return PropsValues.MESSAGE_BOARDS_EMAIL_HTML_FORMAT;
376 }
377 }
378
379 public static String getEmailMessageAddedBody(
380 PortletPreferences preferences) {
381
382 String emailMessageAddedBody = preferences.getValue(
383 "emailMessageAddedBody", StringPool.BLANK);
384
385 if (Validator.isNotNull(emailMessageAddedBody)) {
386 return emailMessageAddedBody;
387 }
388 else {
389 return ContentUtil.get(
390 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_BODY);
391 }
392 }
393
394 public static boolean getEmailMessageAddedEnabled(
395 PortletPreferences preferences) {
396
397 String emailMessageAddedEnabled = preferences.getValue(
398 "emailMessageAddedEnabled", StringPool.BLANK);
399
400 if (Validator.isNotNull(emailMessageAddedEnabled)) {
401 return GetterUtil.getBoolean(emailMessageAddedEnabled);
402 }
403 else {
404 return PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_ENABLED;
405 }
406 }
407
408 public static String getEmailMessageAddedSignature(
409 PortletPreferences preferences) {
410
411 String emailMessageAddedSignature = preferences.getValue(
412 "emailMessageAddedSignature", StringPool.BLANK);
413
414 if (Validator.isNotNull(emailMessageAddedSignature)) {
415 return emailMessageAddedSignature;
416 }
417 else {
418 return ContentUtil.get(
419 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_SIGNATURE);
420 }
421 }
422
423 public static String getEmailMessageAddedSubjectPrefix(
424 PortletPreferences preferences) {
425
426 String emailMessageAddedSubjectPrefix = preferences.getValue(
427 "emailMessageAddedSubjectPrefix", StringPool.BLANK);
428
429 if (Validator.isNotNull(emailMessageAddedSubjectPrefix)) {
430 return emailMessageAddedSubjectPrefix;
431 }
432 else {
433 return ContentUtil.get(
434 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_SUBJECT_PREFIX);
435 }
436 }
437
438 public static String getEmailMessageUpdatedBody(
439 PortletPreferences preferences) {
440
441 String emailMessageUpdatedBody = preferences.getValue(
442 "emailMessageUpdatedBody", StringPool.BLANK);
443
444 if (Validator.isNotNull(emailMessageUpdatedBody)) {
445 return emailMessageUpdatedBody;
446 }
447 else {
448 return ContentUtil.get(
449 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_BODY);
450 }
451 }
452
453 public static boolean getEmailMessageUpdatedEnabled(
454 PortletPreferences preferences) {
455
456 String emailMessageUpdatedEnabled = preferences.getValue(
457 "emailMessageUpdatedEnabled", StringPool.BLANK);
458
459 if (Validator.isNotNull(emailMessageUpdatedEnabled)) {
460 return GetterUtil.getBoolean(emailMessageUpdatedEnabled);
461 }
462 else {
463 return PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_ENABLED;
464 }
465 }
466
467 public static String getEmailMessageUpdatedSignature(
468 PortletPreferences preferences) {
469
470 String emailMessageUpdatedSignature = preferences.getValue(
471 "emailMessageUpdatedSignature", StringPool.BLANK);
472
473 if (Validator.isNotNull(emailMessageUpdatedSignature)) {
474 return emailMessageUpdatedSignature;
475 }
476 else {
477 return ContentUtil.get(
478 PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_SIGNATURE);
479 }
480 }
481
482 public static String getEmailMessageUpdatedSubjectPrefix(
483 PortletPreferences preferences) {
484
485 String emailMessageUpdatedSubject = preferences.getValue(
486 "emailMessageUpdatedSubjectPrefix", StringPool.BLANK);
487
488 if (Validator.isNotNull(emailMessageUpdatedSubject)) {
489 return emailMessageUpdatedSubject;
490 }
491 else {
492 return ContentUtil.get(
493 PropsValues.
494 MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_SUBJECT_PREFIX);
495 }
496 }
497
498 public static List<Object> getEntries(Hits hits) {
499 List<Object> entries = new ArrayList<Object>();
500
501 for (Document document : hits.getDocs()) {
502 long categoryId = GetterUtil.getLong(
503 document.get(Field.CATEGORY_ID));
504
505 try {
506 MBCategoryLocalServiceUtil.getCategory(categoryId);
507 }
508 catch (Exception e) {
509 if (_log.isWarnEnabled()) {
510 _log.warn(
511 "Message boards search index is stale and contains " +
512 "category " + categoryId);
513 }
514
515 continue;
516 }
517
518 long threadId = GetterUtil.getLong(document.get("threadId"));
519
520 try {
521 MBThreadLocalServiceUtil.getThread(threadId);
522 }
523 catch (Exception e) {
524 if (_log.isWarnEnabled()) {
525 _log.warn(
526 "Message boards search index is stale and contains " +
527 "thread " + threadId);
528 }
529
530 continue;
531 }
532
533 String entryClassName = document.get(Field.ENTRY_CLASS_NAME);
534 long entryClassPK = GetterUtil.getLong(
535 document.get(Field.ENTRY_CLASS_PK));
536
537 Object obj = null;
538
539 try {
540 if (entryClassName.equals(DLFileEntry.class.getName())) {
541 long classPK = GetterUtil.getLong(
542 document.get(Field.CLASS_PK));
543
544 MBMessageLocalServiceUtil.getMessage(classPK);
545
546 obj = DLFileEntryLocalServiceUtil.getDLFileEntry(
547 entryClassPK);
548 }
549 else if (entryClassName.equals(MBMessage.class.getName())) {
550 obj = MBMessageLocalServiceUtil.getMessage(entryClassPK);
551 }
552
553 entries.add(obj);
554 }
555 catch (Exception e) {
556 if (_log.isWarnEnabled()) {
557 _log.warn(
558 "Message boards search index is stale and contains " +
559 "entry {className=" + entryClassName + ", " +
560 "classPK=" + entryClassPK + "}");
561 }
562
563 continue;
564 }
565 }
566
567 return entries;
568 }
569
570 public static String getMailingListAddress(
571 long groupId, long categoryId, long messageId, String mx,
572 String defaultMailingListAddress) {
573
574 if (PropsValues.POP_SERVER_SUBDOMAIN.length() <= 0) {
575 String mailingListAddress = defaultMailingListAddress;
576
577 try {
578 MBMailingList mailingList =
579 MBMailingListLocalServiceUtil.getCategoryMailingList(
580 groupId, categoryId);
581
582 if (mailingList.isActive()) {
583 mailingListAddress = mailingList.getEmailAddress();
584 }
585 }
586 catch (Exception e) {
587 }
588
589 return mailingListAddress;
590 }
591
592 StringBundler sb = new StringBundler(8);
593
594 sb.append(MESSAGE_POP_PORTLET_PREFIX);
595 sb.append(categoryId);
596 sb.append(StringPool.PERIOD);
597 sb.append(messageId);
598 sb.append(StringPool.AT);
599 sb.append(PropsValues.POP_SERVER_SUBDOMAIN);
600 sb.append(StringPool.PERIOD);
601 sb.append(mx);
602
603 return sb.toString();
604 }
605
606 public static String getMessageFormat(PortletPreferences preferences) {
607 String messageFormat = preferences.getValue(
608 "messageFormat", MBMessageConstants.DEFAULT_FORMAT);
609
610 String editorImpl = PropsUtil.get(BB_CODE_EDITOR_WYSIWYG_IMPL_KEY);
611
612 if (messageFormat.equals("bbcode") &&
613 !(editorImpl.equals("bbcode") ||
614 editorImpl.equals("ckeditor_bbcode"))) {
615
616 messageFormat = "html";
617 }
618
619 return messageFormat;
620 }
621
622 public static long getMessageId(String mailId) {
623 int x = mailId.indexOf(CharPool.LESS_THAN) + 1;
624 int y = mailId.indexOf(CharPool.AT);
625
626 long messageId = 0;
627
628 if ((x > 0 ) && (y != -1)) {
629 String temp = mailId.substring(x, y);
630
631 int z = temp.lastIndexOf(CharPool.PERIOD);
632
633 if (z != -1) {
634 messageId = GetterUtil.getLong(temp.substring(z + 1));
635 }
636 }
637
638 return messageId;
639 }
640
641 public static long getParentMessageId(Message message) throws Exception {
642 long parentMessageId = -1;
643
644 String parentHeader = getParentMessageIdString(message);
645
646 if (parentHeader != null) {
647 if (_log.isDebugEnabled()) {
648 _log.debug("Parent header " + parentHeader);
649 }
650
651 parentMessageId = getMessageId(parentHeader);
652
653 if (_log.isDebugEnabled()) {
654 _log.debug("Previous message id " + parentMessageId);
655 }
656 }
657
658 return parentMessageId;
659 }
660
661 public static String getParentMessageIdString(Message message)
662 throws Exception {
663
664
665
666
667
668
669 String parentHeader = null;
670
671 String[] references = message.getHeader("References");
672
673 if ((references != null) && (references.length > 0)) {
674 String reference = references[0];
675
676 int x = reference.lastIndexOf("<mb.");
677
678 if (x > -1) {
679 int y = reference.indexOf(">", x);
680
681 parentHeader = reference.substring(x, y);
682 }
683 }
684
685 if (parentHeader == null) {
686 String[] inReplyToHeaders = message.getHeader("In-Reply-To");
687
688 if ((inReplyToHeaders != null) && (inReplyToHeaders.length > 0)) {
689 parentHeader = inReplyToHeaders[0];
690 }
691 }
692
693 if (Validator.isNull(parentHeader) ||
694 !parentHeader.startsWith(MESSAGE_POP_PORTLET_PREFIX, 1)) {
695
696 parentHeader = _getParentMessageIdFromSubject(message);
697 }
698
699 return parentHeader;
700 }
701
702 public static String getSubjectWithoutMessageId(Message message)
703 throws Exception {
704
705 String subject = message.getSubject();
706
707 String parentMessageId = _getParentMessageIdFromSubject(message);
708
709 if (Validator.isNotNull(parentMessageId)) {
710 int pos = subject.indexOf(parentMessageId);
711
712 if (pos != -1) {
713 subject = subject.substring(0, pos);
714 }
715 }
716
717 return subject;
718 }
719
720 public static String[] getThreadPriority(
721 PortletPreferences preferences, String languageId, double value,
722 ThemeDisplay themeDisplay)
723 throws Exception {
724
725 String[] priorities = LocalizationUtil.getPreferencesValues(
726 preferences, "priorities", languageId);
727
728 String[] priorityPair = _findThreadPriority(
729 value, themeDisplay, priorities);
730
731 if (priorityPair == null) {
732 String defaultLanguageId = LocaleUtil.toLanguageId(
733 LocaleUtil.getDefault());
734
735 priorities = LocalizationUtil.getPreferencesValues(
736 preferences, "priorities", defaultLanguageId);
737
738 priorityPair = _findThreadPriority(value, themeDisplay, priorities);
739 }
740
741 return priorityPair;
742 }
743
744 public static Set<Long> getThreadSubscriptionClassPKs(long userId)
745 throws SystemException {
746
747 List<Subscription> subscriptions =
748 SubscriptionLocalServiceUtil.getUserSubscriptions(
749 userId, MBThread.class.getName());
750
751 Set<Long> classPKs = new HashSet<Long>(subscriptions.size());
752
753 for (Subscription subscription : subscriptions) {
754 classPKs.add(subscription.getClassPK());
755 }
756
757 return classPKs;
758 }
759
760 public static Date getUnbanDate(MBBan ban, int expireInterval) {
761 Date banDate = ban.getCreateDate();
762
763 Calendar cal = Calendar.getInstance();
764
765 cal.setTime(banDate);
766
767 cal.add(Calendar.DATE, expireInterval);
768
769 return cal.getTime();
770 }
771
772 public static String getUserRank(
773 PortletPreferences preferences, String languageId, int posts)
774 throws Exception {
775
776 String rank = StringPool.BLANK;
777
778 String[] ranks = LocalizationUtil.getPreferencesValues(
779 preferences, "ranks", languageId);
780
781 for (int i = 0; i < ranks.length; i++) {
782 String[] kvp = StringUtil.split(ranks[i], CharPool.EQUAL);
783
784 String kvpName = kvp[0];
785 int kvpPosts = GetterUtil.getInteger(kvp[1]);
786
787 if (posts >= kvpPosts) {
788 rank = kvpName;
789 }
790 else {
791 break;
792 }
793 }
794
795 return rank;
796 }
797
798 public static String[] getUserRank(
799 PortletPreferences preferences, String languageId,
800 MBStatsUser statsUser)
801 throws Exception {
802
803 String[] rank = {StringPool.BLANK, StringPool.BLANK};
804
805 int maxPosts = 0;
806
807 Group group = GroupLocalServiceUtil.getGroup(statsUser.getGroupId());
808
809 long companyId = group.getCompanyId();
810
811 String[] ranks = LocalizationUtil.getPreferencesValues(
812 preferences, "ranks", languageId);
813
814 for (int i = 0; i < ranks.length; i++) {
815 String[] kvp = StringUtil.split(ranks[i], CharPool.EQUAL);
816
817 String curRank = kvp[0];
818 String curRankValue = kvp[1];
819
820 String[] curRankValueKvp = StringUtil.split(
821 curRankValue, CharPool.COLON);
822
823 if (curRankValueKvp.length <= 1) {
824 int posts = GetterUtil.getInteger(curRankValue);
825
826 if ((posts <= statsUser.getMessageCount()) &&
827 (posts >= maxPosts)) {
828
829 rank[0] = curRank;
830 maxPosts = posts;
831 }
832
833 }
834 else {
835 String entityType = curRankValueKvp[0];
836 String entityValue = curRankValueKvp[1];
837
838 try {
839 if (_isEntityRank(
840 companyId, statsUser, entityType, entityValue)) {
841
842 rank[1] = curRank;
843
844 break;
845 }
846 }
847 catch (Exception e) {
848 if (_log.isWarnEnabled()) {
849 _log.warn(e);
850 }
851 }
852 }
853 }
854
855 return rank;
856 }
857
858 public static boolean hasMailIdHeader(Message message) throws Exception {
859 String[] messageIds = message.getHeader("Message-ID");
860
861 if (messageIds == null) {
862 return false;
863 }
864
865 for (String messageId : messageIds) {
866 if (Validator.isNotNull(PropsValues.POP_SERVER_SUBDOMAIN) &&
867 messageId.contains(PropsValues.POP_SERVER_SUBDOMAIN)) {
868
869 return true;
870 }
871 }
872
873 return false;
874 }
875
876 public static boolean isAllowAnonymousPosting(
877 PortletPreferences preferences) {
878
879 return GetterUtil.getBoolean(
880 preferences.getValue("allowAnonymousPosting", null),
881 PropsValues.MESSAGE_BOARDS_ANONYMOUS_POSTING_ENABLED);
882 }
883
884 public static boolean isViewableMessage(
885 ThemeDisplay themeDisplay, MBMessage message)
886 throws Exception {
887
888 return isViewableMessage(themeDisplay, message, message);
889 }
890
891 public static boolean isViewableMessage(
892 ThemeDisplay themeDisplay, MBMessage message,
893 MBMessage parentMessage)
894 throws Exception {
895
896 PermissionChecker permissionChecker =
897 themeDisplay.getPermissionChecker();
898
899 if (!MBMessagePermission.contains(
900 permissionChecker, parentMessage, ActionKeys.VIEW)) {
901
902 return false;
903 }
904
905 if ((message.getMessageId() != parentMessage.getMessageId()) &&
906 !MBMessagePermission.contains(
907 permissionChecker, message, ActionKeys.VIEW)) {
908
909 return false;
910 }
911
912 if (!message.isApproved() &&
913 !Validator.equals(message.getUserId(), themeDisplay.getUserId()) &&
914 !permissionChecker.isGroupAdmin(themeDisplay.getScopeGroupId())) {
915
916 return false;
917 }
918
919 return true;
920 }
921
922 public static String replaceMessageBodyPaths(
923 ThemeDisplay themeDisplay, String messageBody) {
924
925 return StringUtil.replace(
926 messageBody,
927 new String[] {
928 "@theme_images_path@", "href=\"/", "src=\"/"
929 },
930 new String[] {
931 themeDisplay.getPathThemeImages(),
932 "href=\"" + themeDisplay.getURLPortal() + "/",
933 "src=\"" + themeDisplay.getURLPortal() + "/"
934 });
935 }
936
937 public static void updateCategoryMessageCount(final MBCategory category) {
938 Callable<Void> callable = new PortalCallable<Void>(
939 category.getCompanyId()) {
940
941 @Override
942 protected Void doCall() throws Exception {
943 int messageCount =
944 MBMessageLocalServiceUtil.getCategoryMessagesCount(
945 category.getGroupId(), category.getCategoryId(),
946 WorkflowConstants.STATUS_APPROVED);
947
948 category.setMessageCount(messageCount);
949
950 MBCategoryLocalServiceUtil.updateMBCategory(category);
951
952 return null;
953 }
954 };
955
956 TransactionCommitCallbackRegistryUtil.registerCallback(callable);
957 }
958
959 public static void updateCategoryStatistics(final MBCategory category) {
960 Callable<Void> callable = new PortalCallable<Void>(
961 category.getCompanyId()) {
962
963 @Override
964 protected Void doCall() throws Exception {
965 int messageCount =
966 MBMessageLocalServiceUtil.getCategoryMessagesCount(
967 category.getGroupId(), category.getCategoryId(),
968 WorkflowConstants.STATUS_APPROVED);
969
970 int threadCount =
971 MBThreadLocalServiceUtil.getCategoryThreadsCount(
972 category.getGroupId(), category.getCategoryId(),
973 WorkflowConstants.STATUS_APPROVED);
974
975 category.setMessageCount(messageCount);
976 category.setThreadCount(threadCount);
977
978 MBCategoryLocalServiceUtil.updateMBCategory(category);
979
980 return null;
981 }
982 };
983
984 TransactionCommitCallbackRegistryUtil.registerCallback(callable);
985 }
986
987 public static void updateCategoryThreadCount(final MBCategory category) {
988 Callable<Void> callable = new PortalCallable<Void>(
989 category.getCompanyId()) {
990
991 @Override
992 protected Void doCall() throws Exception {
993 int threadCount =
994 MBThreadLocalServiceUtil.getCategoryThreadsCount(
995 category.getGroupId(), category.getCategoryId(),
996 WorkflowConstants.STATUS_APPROVED);
997
998 category.setThreadCount(threadCount);
999
1000 MBCategoryLocalServiceUtil.updateMBCategory(category);
1001
1002 return null;
1003 }
1004 };
1005
1006 TransactionCommitCallbackRegistryUtil.registerCallback(callable);
1007 }
1008
1009 public static void updateThreadMessageCount(final MBThread thread) {
1010 Callable<Void> callable = new PortalCallable<Void>(
1011 thread.getCompanyId()) {
1012
1013 @Override
1014 protected Void doCall() throws Exception {
1015 int messageCount =
1016 MBMessageLocalServiceUtil.getThreadMessagesCount(
1017 thread.getThreadId(),
1018 WorkflowConstants.STATUS_APPROVED);
1019
1020 thread.setMessageCount(messageCount);
1021
1022 MBThreadLocalServiceUtil.updateMBThread(thread);
1023
1024 return null;
1025 }
1026 };
1027
1028 TransactionCommitCallbackRegistryUtil.registerCallback(callable);
1029 }
1030
1031 private static String[] _findThreadPriority(
1032 double value, ThemeDisplay themeDisplay, String[] priorities) {
1033
1034 for (int i = 0; i < priorities.length; i++) {
1035 String[] priority = StringUtil.split(priorities[i]);
1036
1037 try {
1038 String priorityName = priority[0];
1039 String priorityImage = priority[1];
1040 double priorityValue = GetterUtil.getDouble(priority[2]);
1041
1042 if (value == priorityValue) {
1043 if (!priorityImage.startsWith(Http.HTTP)) {
1044 priorityImage =
1045 themeDisplay.getPathThemeImages() + priorityImage;
1046 }
1047
1048 return new String[] {priorityName, priorityImage};
1049 }
1050 }
1051 catch (Exception e) {
1052 _log.error("Unable to determine thread priority", e);
1053 }
1054 }
1055
1056 return null;
1057 }
1058
1059 private static String _getParentMessageIdFromSubject(Message message)
1060 throws Exception {
1061
1062 if (message.getSubject() == null) {
1063 return null;
1064 }
1065
1066 String parentMessageId = null;
1067
1068 String subject = StringUtil.reverse(message.getSubject());
1069
1070 int pos = subject.indexOf(CharPool.LESS_THAN);
1071
1072 if (pos != -1) {
1073 parentMessageId = StringUtil.reverse(subject.substring(0, pos + 1));
1074 }
1075
1076 return parentMessageId;
1077 }
1078
1079 private static boolean _isEntityRank(
1080 long companyId, MBStatsUser statsUser, String entityType,
1081 String entityValue)
1082 throws Exception {
1083
1084 long groupId = statsUser.getGroupId();
1085 long userId = statsUser.getUserId();
1086
1087 if (entityType.equals("organization-role") ||
1088 entityType.equals("site-role")) {
1089
1090 Role role = RoleLocalServiceUtil.getRole(companyId, entityValue);
1091
1092 if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
1093 userId, groupId, role.getRoleId(), true)) {
1094
1095 return true;
1096 }
1097 }
1098 else if (entityType.equals("organization")) {
1099 Organization organization =
1100 OrganizationLocalServiceUtil.getOrganization(
1101 companyId, entityValue);
1102
1103 if (OrganizationLocalServiceUtil.hasUserOrganization(
1104 userId, organization.getOrganizationId(), false, false)) {
1105
1106 return true;
1107 }
1108 }
1109 else if (entityType.equals("regular-role")) {
1110 if (RoleLocalServiceUtil.hasUserRole(
1111 userId, companyId, entityValue, true)) {
1112
1113 return true;
1114 }
1115 }
1116 else if (entityType.equals("user-group")) {
1117 UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
1118 companyId, entityValue);
1119
1120 if (UserLocalServiceUtil.hasUserGroupUser(
1121 userGroup.getUserGroupId(), userId)) {
1122
1123 return true;
1124 }
1125 }
1126
1127 return false;
1128 }
1129
1130 private static Log _log = LogFactoryUtil.getLog(MBUtil.class);
1131
1132 }