001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.messageboards.util;
016    
017    import com.liferay.portal.kernel.exception.PortalException;
018    import com.liferay.portal.kernel.exception.SystemException;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.portlet.LiferayWindowState;
022    import com.liferay.portal.kernel.util.CharPool;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.Http;
025    import com.liferay.portal.kernel.util.LocaleUtil;
026    import com.liferay.portal.kernel.util.LocalizationUtil;
027    import com.liferay.portal.kernel.util.ParamUtil;
028    import com.liferay.portal.kernel.util.PropsUtil;
029    import com.liferay.portal.kernel.util.StringBundler;
030    import com.liferay.portal.kernel.util.StringPool;
031    import com.liferay.portal.kernel.util.StringUtil;
032    import com.liferay.portal.kernel.util.Validator;
033    import com.liferay.portal.model.Group;
034    import com.liferay.portal.model.Organization;
035    import com.liferay.portal.model.Role;
036    import com.liferay.portal.model.UserGroup;
037    import com.liferay.portal.security.permission.ActionKeys;
038    import com.liferay.portal.security.permission.PermissionChecker;
039    import com.liferay.portal.service.GroupLocalServiceUtil;
040    import com.liferay.portal.service.OrganizationLocalServiceUtil;
041    import com.liferay.portal.service.RoleLocalServiceUtil;
042    import com.liferay.portal.service.UserGroupLocalServiceUtil;
043    import com.liferay.portal.service.UserGroupRoleLocalServiceUtil;
044    import com.liferay.portal.service.UserLocalServiceUtil;
045    import com.liferay.portal.theme.ThemeDisplay;
046    import com.liferay.portal.util.PortalUtil;
047    import com.liferay.portal.util.PortletKeys;
048    import com.liferay.portal.util.PropsValues;
049    import com.liferay.portal.util.WebKeys;
050    import com.liferay.portlet.PortletURLFactoryUtil;
051    import com.liferay.portlet.messageboards.model.MBBan;
052    import com.liferay.portlet.messageboards.model.MBCategory;
053    import com.liferay.portlet.messageboards.model.MBCategoryConstants;
054    import com.liferay.portlet.messageboards.model.MBMailingList;
055    import com.liferay.portlet.messageboards.model.MBMessage;
056    import com.liferay.portlet.messageboards.model.MBMessageConstants;
057    import com.liferay.portlet.messageboards.model.MBStatsUser;
058    import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
059    import com.liferay.portlet.messageboards.service.MBMailingListLocalServiceUtil;
060    import com.liferay.portlet.messageboards.service.permission.MBMessagePermission;
061    import com.liferay.util.ContentUtil;
062    import com.liferay.util.mail.JavaMailUtil;
063    
064    import java.io.InputStream;
065    
066    import java.util.Calendar;
067    import java.util.Collections;
068    import java.util.Date;
069    import java.util.List;
070    
071    import javax.mail.BodyPart;
072    import javax.mail.Message;
073    import javax.mail.Part;
074    import javax.mail.internet.MimeMessage;
075    import javax.mail.internet.MimeMultipart;
076    
077    import javax.portlet.PortletPreferences;
078    import javax.portlet.PortletRequest;
079    import javax.portlet.PortletURL;
080    import javax.portlet.RenderResponse;
081    
082    import javax.servlet.http.HttpServletRequest;
083    
084    /**
085     * @author Brian Wing Shun Chan
086     */
087    public class MBUtil {
088    
089            public static final String BB_CODE_EDITOR_WYSIWYG_IMPL_KEY =
090                    "editor.wysiwyg.portal-web.docroot.html.portlet.message_boards." +
091                            "edit_message.bb_code.jsp";
092    
093            public static final String MESSAGE_POP_PORTLET_PREFIX = "mb_message.";
094    
095            public static void addPortletBreadcrumbEntries(
096                            long categoryId, HttpServletRequest request,
097                            RenderResponse renderResponse)
098                    throws Exception {
099    
100                    if ((categoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
101                            (categoryId == MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
102    
103                            return;
104                    }
105    
106                    MBCategory category = MBCategoryLocalServiceUtil.getCategory(
107                            categoryId);
108    
109                    addPortletBreadcrumbEntries(category, request, renderResponse);
110            }
111    
112            public static void addPortletBreadcrumbEntries(
113                            MBCategory category, HttpServletRequest request,
114                            RenderResponse renderResponse)
115                    throws Exception {
116    
117                    String strutsAction = ParamUtil.getString(request, "struts_action");
118    
119                    PortletURL portletURL = renderResponse.createRenderURL();
120    
121                    if (strutsAction.equals("/message_boards/select_category") ||
122                            strutsAction.equals("/message_boards_admin/select_category")) {
123    
124                            ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(
125                                    WebKeys.THEME_DISPLAY);
126    
127                            portletURL.setWindowState(LiferayWindowState.POP_UP);
128    
129                            portletURL.setParameter(
130                                    "struts_action", "/message_boards/select_category");
131    
132                            PortalUtil.addPortletBreadcrumbEntry(
133                                    request, themeDisplay.translate("categories"),
134                                    portletURL.toString());
135                    }
136                    else {
137                            portletURL.setParameter("struts_action", "/message_boards/view");
138                    }
139    
140                    List<MBCategory> ancestorCategories = category.getAncestors();
141    
142                    Collections.reverse(ancestorCategories);
143    
144                    for (MBCategory curCategory : ancestorCategories) {
145                            portletURL.setParameter(
146                                    "mbCategoryId", String.valueOf(curCategory.getCategoryId()));
147    
148                            PortalUtil.addPortletBreadcrumbEntry(
149                                    request, curCategory.getName(), portletURL.toString());
150                    }
151    
152                    portletURL.setParameter(
153                            "mbCategoryId", String.valueOf(category.getCategoryId()));
154    
155                    PortalUtil.addPortletBreadcrumbEntry(
156                            request, category.getName(), portletURL.toString());
157            }
158    
159            public static void addPortletBreadcrumbEntries(
160                            MBMessage message, HttpServletRequest request,
161                            RenderResponse renderResponse)
162                    throws Exception {
163    
164                    if ((message.getCategoryId() ==
165                                    MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) ||
166                            (message.getCategoryId() ==
167                                    MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
168    
169                            return;
170                    }
171    
172                    MBCategory category = message.getCategory();
173    
174                    addPortletBreadcrumbEntries(category, request, renderResponse);
175    
176                    PortletURL portletURL = renderResponse.createRenderURL();
177    
178                    portletURL.setParameter(
179                            "struts_action", "/message_boards/view_message");
180                    portletURL.setParameter(
181                            "messageId", String.valueOf(message.getMessageId()));
182    
183                    PortalUtil.addPortletBreadcrumbEntry(
184                            request, message.getSubject(), portletURL.toString());
185            }
186    
187            public static void collectMultipartContent(
188                            MimeMultipart multipart, MBMailMessage collector)
189                    throws Exception {
190    
191                    for (int i = 0; i < multipart.getCount(); i++) {
192                            BodyPart part = multipart.getBodyPart(i);
193    
194                            collectPartContent(part, collector);
195                    }
196            }
197    
198            public static void collectPartContent(
199                            Part part, MBMailMessage mbMailMessage)
200                    throws Exception {
201    
202                    Object partContent = part.getContent();
203    
204                    String contentType = part.getContentType().toLowerCase();
205    
206                    if ((part.getDisposition() != null) &&
207                            part.getDisposition().equalsIgnoreCase(MimeMessage.ATTACHMENT)) {
208    
209                            if (_log.isDebugEnabled()) {
210                                    _log.debug("Processing attachment");
211                            }
212    
213                            byte[] bytes = null;
214    
215                            if (partContent instanceof String) {
216                                    bytes = ((String)partContent).getBytes();
217                            }
218                            else if (partContent instanceof InputStream) {
219                                    bytes = JavaMailUtil.getBytes(part);
220                            }
221    
222                            mbMailMessage.addBytes(part.getFileName(), bytes);
223                    }
224                    else {
225                            if (partContent instanceof MimeMultipart) {
226                                    MimeMultipart mimeMultipart = (MimeMultipart)partContent;
227    
228                                    collectMultipartContent(mimeMultipart, mbMailMessage);
229                            }
230                            else if (partContent instanceof String) {
231                                    if (contentType.startsWith("text/html")) {
232                                            mbMailMessage.setHtmlBody((String)partContent);
233                                    }
234                                    else {
235                                            mbMailMessage.setPlainBody((String)partContent);
236                                    }
237                            }
238                    }
239            }
240    
241            public static String getAbsolutePath(
242                            PortletRequest portletRequest, long mbCategoryId)
243                    throws PortalException, SystemException {
244    
245                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
246                            WebKeys.THEME_DISPLAY);
247    
248                    if (mbCategoryId == MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
249                            return themeDisplay.translate("home");
250                    }
251    
252                    MBCategory mbCategory = MBCategoryLocalServiceUtil.fetchMBCategory(
253                            mbCategoryId);
254    
255                    List<MBCategory> categories = mbCategory.getAncestors();
256    
257                    StringBundler sb = new StringBundler((categories.size() * 3) + 6);
258    
259                    sb.append(themeDisplay.translate("home"));
260                    sb.append(StringPool.SPACE);
261    
262                    for (int i = categories.size(); i >= 0; i--) {
263                            MBCategory curCategory = categories.get(i);
264    
265                            sb.append(StringPool.RAQUO);
266                            sb.append(StringPool.SPACE);
267                            sb.append(curCategory.getName());
268                    }
269    
270                    sb.append(StringPool.RAQUO);
271                    sb.append(StringPool.SPACE);
272                    sb.append(mbCategory.getName());
273    
274                    return sb.toString();
275            }
276    
277            public static long getCategoryId(
278                    HttpServletRequest request, MBCategory category) {
279    
280                    long categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
281    
282                    if (category != null) {
283                            categoryId = category.getCategoryId();
284                    }
285    
286                    categoryId = ParamUtil.getLong(request, "mbCategoryId", categoryId);
287    
288                    return categoryId;
289            }
290    
291            public static long getCategoryId(
292                    HttpServletRequest request, MBMessage message) {
293    
294                    long categoryId = MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID;
295    
296                    if (message != null) {
297                            categoryId = message.getCategoryId();
298                    }
299    
300                    categoryId = ParamUtil.getLong(request, "mbCategoryId", categoryId);
301    
302                    return categoryId;
303            }
304    
305            public static String getEmailFromAddress(
306                            PortletPreferences preferences, long companyId)
307                    throws SystemException {
308    
309                    return PortalUtil.getEmailFromAddress(
310                            preferences, companyId,
311                            PropsValues.MESSAGE_BOARDS_EMAIL_FROM_ADDRESS);
312            }
313    
314            public static String getEmailFromName(
315                            PortletPreferences preferences, long companyId)
316                    throws SystemException {
317    
318                    return PortalUtil.getEmailFromName(
319                            preferences, companyId, PropsValues.MESSAGE_BOARDS_EMAIL_FROM_NAME);
320            }
321    
322            public static boolean getEmailHtmlFormat(PortletPreferences preferences) {
323                    String emailHtmlFormat = preferences.getValue(
324                            "emailHtmlFormat", StringPool.BLANK);
325    
326                    if (Validator.isNotNull(emailHtmlFormat)) {
327                            return GetterUtil.getBoolean(emailHtmlFormat);
328                    }
329                    else {
330                            return PropsValues.MESSAGE_BOARDS_EMAIL_HTML_FORMAT;
331                    }
332            }
333    
334            public static String getEmailMessageAddedBody(
335                    PortletPreferences preferences) {
336    
337                    String emailMessageAddedBody = preferences.getValue(
338                            "emailMessageAddedBody", StringPool.BLANK);
339    
340                    if (Validator.isNotNull(emailMessageAddedBody)) {
341                            return emailMessageAddedBody;
342                    }
343                    else {
344                            return ContentUtil.get(
345                                    PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_BODY);
346                    }
347            }
348    
349            public static boolean getEmailMessageAddedEnabled(
350                    PortletPreferences preferences) {
351    
352                    String emailMessageAddedEnabled = preferences.getValue(
353                            "emailMessageAddedEnabled", StringPool.BLANK);
354    
355                    if (Validator.isNotNull(emailMessageAddedEnabled)) {
356                            return GetterUtil.getBoolean(emailMessageAddedEnabled);
357                    }
358                    else {
359                            return PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_ENABLED;
360                    }
361            }
362    
363            public static String getEmailMessageAddedSignature(
364                    PortletPreferences preferences) {
365    
366                    String emailMessageAddedSignature = preferences.getValue(
367                            "emailMessageAddedSignature", StringPool.BLANK);
368    
369                    if (Validator.isNotNull(emailMessageAddedSignature)) {
370                            return emailMessageAddedSignature;
371                    }
372                    else {
373                            return ContentUtil.get(
374                                    PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_SIGNATURE);
375                    }
376            }
377    
378            public static String getEmailMessageAddedSubjectPrefix(
379                    PortletPreferences preferences) {
380    
381                    String emailMessageAddedSubjectPrefix = preferences.getValue(
382                            "emailMessageAddedSubjectPrefix", StringPool.BLANK);
383    
384                    if (Validator.isNotNull(emailMessageAddedSubjectPrefix)) {
385                            return emailMessageAddedSubjectPrefix;
386                    }
387                    else {
388                            return ContentUtil.get(
389                                    PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_ADDED_SUBJECT_PREFIX);
390                    }
391            }
392    
393            public static String getEmailMessageUpdatedBody(
394                    PortletPreferences preferences) {
395    
396                    String emailMessageUpdatedBody = preferences.getValue(
397                            "emailMessageUpdatedBody", StringPool.BLANK);
398    
399                    if (Validator.isNotNull(emailMessageUpdatedBody)) {
400                            return emailMessageUpdatedBody;
401                    }
402                    else {
403                            return ContentUtil.get(
404                                    PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_BODY);
405                    }
406            }
407    
408            public static boolean getEmailMessageUpdatedEnabled(
409                    PortletPreferences preferences) {
410    
411                    String emailMessageUpdatedEnabled = preferences.getValue(
412                            "emailMessageUpdatedEnabled", StringPool.BLANK);
413    
414                    if (Validator.isNotNull(emailMessageUpdatedEnabled)) {
415                            return GetterUtil.getBoolean(emailMessageUpdatedEnabled);
416                    }
417                    else {
418                            return PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_ENABLED;
419                    }
420            }
421    
422            public static String getEmailMessageUpdatedSignature(
423                    PortletPreferences preferences) {
424    
425                    String emailMessageUpdatedSignature = preferences.getValue(
426                            "emailMessageUpdatedSignature", StringPool.BLANK);
427    
428                    if (Validator.isNotNull(emailMessageUpdatedSignature)) {
429                            return emailMessageUpdatedSignature;
430                    }
431                    else {
432                            return ContentUtil.get(
433                                    PropsValues.MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_SIGNATURE);
434                    }
435            }
436    
437            public static String getEmailMessageUpdatedSubjectPrefix(
438                    PortletPreferences preferences) {
439    
440                    String emailMessageUpdatedSubject = preferences.getValue(
441                            "emailMessageUpdatedSubjectPrefix", StringPool.BLANK);
442    
443                    if (Validator.isNotNull(emailMessageUpdatedSubject)) {
444                            return emailMessageUpdatedSubject;
445                    }
446                    else {
447                            return ContentUtil.get(
448                                    PropsValues.
449                                            MESSAGE_BOARDS_EMAIL_MESSAGE_UPDATED_SUBJECT_PREFIX);
450                    }
451            }
452    
453            public static String getMailingListAddress(
454                    long groupId, long categoryId, long messageId, String mx,
455                    String defaultMailingListAddress) {
456    
457                    if (PropsValues.POP_SERVER_SUBDOMAIN.length() <= 0) {
458                            String mailingListAddress = defaultMailingListAddress;
459    
460                            try {
461                                    MBMailingList mailingList =
462                                            MBMailingListLocalServiceUtil.getCategoryMailingList(
463                                                    groupId, categoryId);
464    
465                                    if (mailingList.isActive()) {
466                                            mailingListAddress = mailingList.getEmailAddress();
467                                    }
468                            }
469                            catch (Exception e) {
470                            }
471    
472                            return mailingListAddress;
473                    }
474    
475                    StringBundler sb = new StringBundler(8);
476    
477                    sb.append(MESSAGE_POP_PORTLET_PREFIX);
478                    sb.append(categoryId);
479                    sb.append(StringPool.PERIOD);
480                    sb.append(messageId);
481                    sb.append(StringPool.AT);
482                    sb.append(PropsValues.POP_SERVER_SUBDOMAIN);
483                    sb.append(StringPool.PERIOD);
484                    sb.append(mx);
485    
486                    return sb.toString();
487            }
488    
489            public static String getMBControlPanelLink(
490                            PortletRequest portletRequest, long mbCategoryId)
491                    throws PortalException, SystemException {
492    
493                    ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(
494                            com.liferay.portal.kernel.util.WebKeys.THEME_DISPLAY);
495    
496                    PortletURL portletURL = PortletURLFactoryUtil.create(
497                            portletRequest, PortletKeys.MESSAGE_BOARDS_ADMIN,
498                            PortalUtil.getControlPanelPlid(themeDisplay.getCompanyId()),
499                            PortletRequest.RENDER_PHASE);
500    
501                    portletURL.setParameter("struts_action", "/message_boards_admin/view");
502                    portletURL.setParameter("mbCategoryId", String.valueOf(mbCategoryId));
503    
504                    return portletURL.toString();
505            }
506    
507            public static String getMessageFormat(PortletPreferences preferences) {
508                    String messageFormat = preferences.getValue(
509                            "messageFormat", MBMessageConstants.DEFAULT_FORMAT);
510    
511                    String editorImpl = PropsUtil.get(BB_CODE_EDITOR_WYSIWYG_IMPL_KEY);
512    
513                    if (messageFormat.equals("bbcode") &&
514                            !(editorImpl.equals("bbcode") ||
515                              editorImpl.equals("ckeditor_bbcode"))) {
516    
517                            messageFormat = "html";
518                    }
519    
520                    return messageFormat;
521            }
522    
523            public static long getMessageId(String mailId) {
524                    int x = mailId.indexOf(CharPool.LESS_THAN) + 1;
525                    int y = mailId.indexOf(CharPool.AT);
526    
527                    long messageId = 0;
528    
529                    if ((x > 0 ) && (y != -1)) {
530                            String temp = mailId.substring(x, y);
531    
532                            int z = temp.lastIndexOf(CharPool.PERIOD);
533    
534                            if (z != -1) {
535                                    messageId = GetterUtil.getLong(temp.substring(z + 1));
536                            }
537                    }
538    
539                    return messageId;
540            }
541    
542            public static long getParentMessageId(Message message) throws Exception {
543                    long parentMessageId = -1;
544    
545                    String parentHeader = getParentMessageIdString(message);
546    
547                    if (parentHeader != null) {
548                            if (_log.isDebugEnabled()) {
549                                    _log.debug("Parent header " + parentHeader);
550                            }
551    
552                            parentMessageId = getMessageId(parentHeader);
553    
554                            if (_log.isDebugEnabled()) {
555                                    _log.debug("Previous message id " + parentMessageId);
556                            }
557                    }
558    
559                    return parentMessageId;
560            }
561    
562            public static String getParentMessageIdString(Message message)
563                    throws Exception {
564    
565                    // If the previous block failed, try to get the parent message ID from
566                    // the "References" header as explained in
567                    // http://cr.yp.to/immhf/thread.html. Some mail clients such as Yahoo!
568                    // Mail use the "In-Reply-To" header, so we check that as well.
569    
570                    String parentHeader = null;
571    
572                    String[] references = message.getHeader("References");
573    
574                    if ((references != null) && (references.length > 0)) {
575                            String reference = references[0];
576    
577                            int x = reference.lastIndexOf("<mb.");
578    
579                            if (x > -1) {
580                                    int y = reference.indexOf(">", x);
581    
582                                    parentHeader = reference.substring(x, y);
583                            }
584                    }
585    
586                    if (parentHeader == null) {
587                            String[] inReplyToHeaders = message.getHeader("In-Reply-To");
588    
589                            if ((inReplyToHeaders != null) && (inReplyToHeaders.length > 0)) {
590                                    parentHeader = inReplyToHeaders[0];
591                            }
592                    }
593    
594                    if (Validator.isNull(parentHeader) ||
595                            !parentHeader.startsWith(MESSAGE_POP_PORTLET_PREFIX, 1)) {
596    
597                            parentHeader = _getParentMessageIdFromSubject(message);
598                    }
599    
600                    return parentHeader;
601            }
602    
603            public static String getSubjectWithoutMessageId(Message message)
604                    throws Exception {
605    
606                    String subject = message.getSubject();
607    
608                    String parentMessageId = _getParentMessageIdFromSubject(message);
609    
610                    if (Validator.isNotNull(parentMessageId)) {
611                            int pos = subject.indexOf(parentMessageId);
612    
613                            if (pos != -1) {
614                                    subject = subject.substring(0, pos);
615                            }
616                    }
617    
618                    return subject;
619            }
620    
621            public static String[] getThreadPriority(
622                            PortletPreferences preferences, String languageId, double value,
623                            ThemeDisplay themeDisplay)
624                    throws Exception {
625    
626                    String[] priorities = LocalizationUtil.getPreferencesValues(
627                            preferences, "priorities", languageId);
628    
629                    String[] priorityPair = _findThreadPriority(
630                            value, themeDisplay, priorities);
631    
632                    if (priorityPair == null) {
633                            String defaultLanguageId = LocaleUtil.toLanguageId(
634                                    LocaleUtil.getDefault());
635    
636                            priorities = LocalizationUtil.getPreferencesValues(
637                                    preferences, "priorities", defaultLanguageId);
638    
639                            priorityPair = _findThreadPriority(value, themeDisplay, priorities);
640                    }
641    
642                    return priorityPair;
643            }
644    
645            public static Date getUnbanDate(MBBan ban, int expireInterval) {
646                    Date banDate = ban.getCreateDate();
647    
648                    Calendar cal = Calendar.getInstance();
649    
650                    cal.setTime(banDate);
651    
652                    cal.add(Calendar.DATE, expireInterval);
653    
654                    return cal.getTime();
655            }
656    
657            public static String getUserRank(
658                            PortletPreferences preferences, String languageId, int posts)
659                    throws Exception {
660    
661                    String rank = StringPool.BLANK;
662    
663                    String[] ranks = LocalizationUtil.getPreferencesValues(
664                            preferences, "ranks", languageId);
665    
666                    for (int i = 0; i < ranks.length; i++) {
667                            String[] kvp = StringUtil.split(ranks[i], CharPool.EQUAL);
668    
669                            String kvpName = kvp[0];
670                            int kvpPosts = GetterUtil.getInteger(kvp[1]);
671    
672                            if (posts >= kvpPosts) {
673                                    rank = kvpName;
674                            }
675                            else {
676                                    break;
677                            }
678                    }
679    
680                    return rank;
681            }
682    
683            public static String[] getUserRank(
684                            PortletPreferences preferences, String languageId,
685                            MBStatsUser statsUser)
686                    throws Exception {
687    
688                    String[] rank = {StringPool.BLANK, StringPool.BLANK};
689    
690                    int maxPosts = 0;
691    
692                    Group group = GroupLocalServiceUtil.getGroup(statsUser.getGroupId());
693    
694                    long companyId = group.getCompanyId();
695    
696                    String[] ranks = LocalizationUtil.getPreferencesValues(
697                            preferences, "ranks", languageId);
698    
699                    for (int i = 0; i < ranks.length; i++) {
700                            String[] kvp = StringUtil.split(ranks[i], CharPool.EQUAL);
701    
702                            String curRank = kvp[0];
703                            String curRankValue = kvp[1];
704    
705                            String[] curRankValueKvp = StringUtil.split(
706                                    curRankValue, CharPool.COLON);
707    
708                            if (curRankValueKvp.length <= 1) {
709                                    int posts = GetterUtil.getInteger(curRankValue);
710    
711                                    if ((posts <= statsUser.getMessageCount()) &&
712                                            (posts >= maxPosts)) {
713    
714                                            rank[0] = curRank;
715                                            maxPosts = posts;
716                                    }
717    
718                            }
719                            else {
720                                    String entityType = curRankValueKvp[0];
721                                    String entityValue = curRankValueKvp[1];
722    
723                                    try {
724                                            if (_isEntityRank(
725                                                            companyId, statsUser, entityType, entityValue)) {
726    
727                                                    rank[1] = curRank;
728    
729                                                    break;
730                                            }
731                                    }
732                                    catch (Exception e) {
733                                            if (_log.isWarnEnabled()) {
734                                                    _log.warn(e);
735                                            }
736                                    }
737                            }
738                    }
739    
740                    return rank;
741            }
742    
743            public static boolean hasMailIdHeader(Message message) throws Exception {
744                    String[] messageIds = message.getHeader("Message-ID");
745    
746                    if (messageIds == null) {
747                            return false;
748                    }
749    
750                    for (String messageId : messageIds) {
751                            if (Validator.isNotNull(PropsValues.POP_SERVER_SUBDOMAIN) &&
752                                    messageId.contains(PropsValues.POP_SERVER_SUBDOMAIN)) {
753    
754                                    return true;
755                            }
756                    }
757    
758                    return false;
759            }
760    
761            public static boolean isAllowAnonymousPosting(
762                    PortletPreferences preferences) {
763    
764                    return GetterUtil.getBoolean(
765                            preferences.getValue("allowAnonymousPosting", null),
766                            PropsValues.MESSAGE_BOARDS_ANONYMOUS_POSTING_ENABLED);
767            }
768    
769            public static boolean isViewableMessage(
770                            ThemeDisplay themeDisplay, MBMessage message)
771                    throws Exception {
772    
773                    return isViewableMessage(themeDisplay, message, message);
774            }
775    
776            public static boolean isViewableMessage(
777                            ThemeDisplay themeDisplay, MBMessage message,
778                            MBMessage parentMessage)
779                    throws Exception {
780    
781                    PermissionChecker permissionChecker =
782                            themeDisplay.getPermissionChecker();
783    
784                    if (!MBMessagePermission.contains(
785                                    permissionChecker, parentMessage, ActionKeys.VIEW)) {
786    
787                            return false;
788                    }
789    
790                    if ((message.getMessageId() != parentMessage.getMessageId()) &&
791                            !MBMessagePermission.contains(
792                                    permissionChecker, message, ActionKeys.VIEW)) {
793    
794                            return false;
795                    }
796    
797                    if (!message.isApproved() &&
798                            !Validator.equals(message.getUserId(), themeDisplay.getUserId()) &&
799                            !permissionChecker.isGroupAdmin(themeDisplay.getScopeGroupId())) {
800    
801                            return false;
802                    }
803    
804                    return true;
805            }
806    
807            public static String replaceMessageBodyPaths(
808                    ThemeDisplay themeDisplay, String messageBody) {
809    
810                    return StringUtil.replace(
811                            messageBody,
812                            new String[] {
813                                    "@theme_images_path@", "href=\"/", "src=\"/"
814                            },
815                            new String[] {
816                                    themeDisplay.getPathThemeImages(),
817                                    "href=\"" + themeDisplay.getURLPortal() + "/",
818                                    "src=\"" + themeDisplay.getURLPortal() + "/"
819                            });
820            }
821    
822            private static String[] _findThreadPriority(
823                    double value, ThemeDisplay themeDisplay, String[] priorities) {
824    
825                    for (int i = 0; i < priorities.length; i++) {
826                            String[] priority = StringUtil.split(priorities[i]);
827    
828                            try {
829                                    String priorityName = priority[0];
830                                    String priorityImage = priority[1];
831                                    double priorityValue = GetterUtil.getDouble(priority[2]);
832    
833                                    if (value == priorityValue) {
834                                            if (!priorityImage.startsWith(Http.HTTP)) {
835                                                    priorityImage =
836                                                            themeDisplay.getPathThemeImages() + priorityImage;
837                                            }
838    
839                                            return new String[] {priorityName, priorityImage};
840                                    }
841                            }
842                            catch (Exception e) {
843                                    _log.error("Unable to determine thread priority", e);
844                            }
845                    }
846    
847                    return null;
848            }
849    
850            private static String _getParentMessageIdFromSubject(Message message)
851                    throws Exception {
852    
853                    if (message.getSubject() == null) {
854                            return null;
855                    }
856    
857                    String parentMessageId = null;
858    
859                    String subject = StringUtil.reverse(message.getSubject());
860    
861                    int pos = subject.indexOf(CharPool.LESS_THAN);
862    
863                    if (pos != -1) {
864                            parentMessageId = StringUtil.reverse(subject.substring(0, pos + 1));
865                    }
866    
867                    return parentMessageId;
868            }
869    
870            private static boolean _isEntityRank(
871                            long companyId, MBStatsUser statsUser, String entityType,
872                            String entityValue)
873                    throws Exception {
874    
875                    long groupId = statsUser.getGroupId();
876                    long userId = statsUser.getUserId();
877    
878                    if (entityType.equals("organization-role") ||
879                            entityType.equals("site-role")) {
880    
881                            Role role = RoleLocalServiceUtil.getRole(companyId, entityValue);
882    
883                            if (UserGroupRoleLocalServiceUtil.hasUserGroupRole(
884                                            userId, groupId, role.getRoleId(), true)) {
885    
886                                    return true;
887                            }
888                    }
889                    else if (entityType.equals("organization")) {
890                            Organization organization =
891                                    OrganizationLocalServiceUtil.getOrganization(
892                                            companyId, entityValue);
893    
894                            if (OrganizationLocalServiceUtil.hasUserOrganization(
895                                            userId, organization.getOrganizationId(), false, false)) {
896    
897                                    return true;
898                            }
899                    }
900                    else if (entityType.equals("regular-role")) {
901                            if (RoleLocalServiceUtil.hasUserRole(
902                                            userId, companyId, entityValue, true)) {
903    
904                                    return true;
905                            }
906                    }
907                    else if (entityType.equals("user-group")) {
908                            UserGroup userGroup = UserGroupLocalServiceUtil.getUserGroup(
909                                    companyId, entityValue);
910    
911                            if (UserLocalServiceUtil.hasUserGroupUser(
912                                            userGroup.getUserGroupId(), userId)) {
913    
914                                    return true;
915                            }
916                    }
917    
918                    return false;
919            }
920    
921            private static Log _log = LogFactoryUtil.getLog(MBUtil.class);
922    
923    }