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