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