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