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