1   /**
2    * Copyright (c) 2000-2007 Liferay, Inc. All rights reserved.
3    *
4    * Permission is hereby granted, free of charge, to any person obtaining a copy
5    * of this software and associated documentation files (the "Software"), to deal
6    * in the Software without restriction, including without limitation the rights
7    * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8    * copies of the Software, and to permit persons to whom the Software is
9    * furnished to do so, subject to the following conditions:
10   *
11   * The above copyright notice and this permission notice shall be included in
12   * all copies or substantial portions of the Software.
13   *
14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20   * SOFTWARE.
21   */
22  
23  package com.liferay.portlet.messageboards.service.impl;
24  
25  import com.liferay.counter.service.CounterLocalServiceUtil;
26  import com.liferay.documentlibrary.DuplicateFileException;
27  import com.liferay.documentlibrary.NoSuchDirectoryException;
28  import com.liferay.documentlibrary.service.DLServiceUtil;
29  import com.liferay.mail.service.MailServiceUtil;
30  import com.liferay.portal.PortalException;
31  import com.liferay.portal.SystemException;
32  import com.liferay.portal.kernel.mail.MailMessage;
33  import com.liferay.portal.kernel.util.ContentTypes;
34  import com.liferay.portal.kernel.util.GetterUtil;
35  import com.liferay.portal.kernel.util.ObjectValuePair;
36  import com.liferay.portal.kernel.util.OrderByComparator;
37  import com.liferay.portal.kernel.util.StringPool;
38  import com.liferay.portal.kernel.util.StringUtil;
39  import com.liferay.portal.kernel.util.Validator;
40  import com.liferay.portal.model.Company;
41  import com.liferay.portal.model.Group;
42  import com.liferay.portal.model.ModelHintsUtil;
43  import com.liferay.portal.model.User;
44  import com.liferay.portal.model.impl.CompanyImpl;
45  import com.liferay.portal.model.impl.GroupImpl;
46  import com.liferay.portal.model.impl.ResourceImpl;
47  import com.liferay.portal.service.GroupLocalServiceUtil;
48  import com.liferay.portal.service.PortletPreferencesLocalServiceUtil;
49  import com.liferay.portal.service.ResourceLocalServiceUtil;
50  import com.liferay.portal.service.SubscriptionLocalServiceUtil;
51  import com.liferay.portal.service.persistence.CompanyUtil;
52  import com.liferay.portal.service.persistence.UserUtil;
53  import com.liferay.portal.theme.ThemeDisplay;
54  import com.liferay.portal.util.PortalUtil;
55  import com.liferay.portal.util.PortletKeys;
56  import com.liferay.portal.util.PrefsPropsUtil;
57  import com.liferay.portal.util.PropsUtil;
58  import com.liferay.portlet.blogs.model.BlogsEntry;
59  import com.liferay.portlet.blogs.service.persistence.BlogsEntryUtil;
60  import com.liferay.portlet.messageboards.MessageBodyException;
61  import com.liferay.portlet.messageboards.MessageSubjectException;
62  import com.liferay.portlet.messageboards.NoSuchDiscussionException;
63  import com.liferay.portlet.messageboards.NoSuchThreadException;
64  import com.liferay.portlet.messageboards.RequiredMessageException;
65  import com.liferay.portlet.messageboards.model.MBCategory;
66  import com.liferay.portlet.messageboards.model.MBDiscussion;
67  import com.liferay.portlet.messageboards.model.MBMessage;
68  import com.liferay.portlet.messageboards.model.MBMessageDisplay;
69  import com.liferay.portlet.messageboards.model.MBStatsUser;
70  import com.liferay.portlet.messageboards.model.MBThread;
71  import com.liferay.portlet.messageboards.model.MBTreeWalker;
72  import com.liferay.portlet.messageboards.model.impl.MBMessageDisplayImpl;
73  import com.liferay.portlet.messageboards.model.impl.MBMessageImpl;
74  import com.liferay.portlet.messageboards.model.impl.MBThreadImpl;
75  import com.liferay.portlet.messageboards.model.impl.MBTreeWalkerImpl;
76  import com.liferay.portlet.messageboards.service.MBCategoryLocalServiceUtil;
77  import com.liferay.portlet.messageboards.service.MBStatsUserLocalServiceUtil;
78  import com.liferay.portlet.messageboards.service.MBThreadLocalServiceUtil;
79  import com.liferay.portlet.messageboards.service.base.MBMessageLocalServiceBaseImpl;
80  import com.liferay.portlet.messageboards.service.jms.MBMessageProducer;
81  import com.liferay.portlet.messageboards.service.persistence.MBCategoryUtil;
82  import com.liferay.portlet.messageboards.service.persistence.MBDiscussionUtil;
83  import com.liferay.portlet.messageboards.service.persistence.MBMessageFinder;
84  import com.liferay.portlet.messageboards.service.persistence.MBMessageFlagUtil;
85  import com.liferay.portlet.messageboards.service.persistence.MBMessageUtil;
86  import com.liferay.portlet.messageboards.service.persistence.MBStatsUserUtil;
87  import com.liferay.portlet.messageboards.service.persistence.MBThreadUtil;
88  import com.liferay.portlet.messageboards.util.Indexer;
89  import com.liferay.portlet.messageboards.util.MBUtil;
90  import com.liferay.portlet.messageboards.util.comparator.MessageThreadComparator;
91  import com.liferay.portlet.messageboards.util.comparator.ThreadLastPostDateComparator;
92  import com.liferay.portlet.tags.service.TagsAssetLocalServiceUtil;
93  
94  import java.io.IOException;
95  
96  import java.rmi.RemoteException;
97  
98  import java.util.ArrayList;
99  import java.util.Collections;
100 import java.util.Comparator;
101 import java.util.Date;
102 import java.util.Iterator;
103 import java.util.List;
104 
105 import javax.mail.internet.InternetAddress;
106 
107 import javax.portlet.PortletPreferences;
108 
109 import org.apache.commons.lang.time.StopWatch;
110 import org.apache.commons.logging.Log;
111 import org.apache.commons.logging.LogFactory;
112 
113 /**
114  * <a href="MBMessageLocalServiceImpl.java.html"><b><i>View Source</i></b></a>
115  *
116  * @author Brian Wing Shun Chan
117  *
118  */
119 public class MBMessageLocalServiceImpl extends MBMessageLocalServiceBaseImpl {
120 
121     public MBMessage addDiscussionMessage(
122             long userId, String subject, String body)
123         throws PortalException, SystemException {
124 
125         long groupId = 0;
126         String className = StringPool.BLANK;
127         long classPK = 0;
128         long threadId = 0;
129         long parentMessageId = 0;
130         ThemeDisplay themeDisplay = null;
131 
132         return addDiscussionMessage(
133             userId, groupId, className, classPK, threadId, parentMessageId,
134             subject, body, themeDisplay);
135     }
136 
137     public MBMessage addDiscussionMessage(
138             long userId, long groupId, String className, long classPK,
139             long threadId, long parentMessageId, String subject, String body,
140             ThemeDisplay themeDisplay)
141         throws PortalException, SystemException {
142 
143         long categoryId = CompanyImpl.SYSTEM;
144 
145         if (Validator.isNull(subject)) {
146             subject = "N/A";
147         }
148 
149         List files = new ArrayList();
150         boolean anonymous = false;
151         double priority = 0.0;
152         String[] tagsEntries = null;
153         PortletPreferences prefs = null;
154         boolean addCommunityPermissions = true;
155         boolean addGuestPermissions = true;
156 
157         MBCategoryLocalServiceUtil.getSystemCategory();
158 
159         MBMessage message = addMessage(
160             userId, categoryId, threadId, parentMessageId, subject, body, files,
161             anonymous, priority, tagsEntries, prefs, addCommunityPermissions,
162             addGuestPermissions);
163 
164         if (className.equals(BlogsEntry.class.getName())) {
165             try {
166                 sendBlogsCommentsEmail(userId, classPK, message, themeDisplay);
167             }
168             catch (Exception e) {
169                 _log.error(e, e);
170             }
171         }
172 
173         return message;
174     }
175 
176     public MBMessage addMessage(
177             long userId, long categoryId, String subject, String body,
178             List files, boolean anonymous, double priority,
179             String[] tagsEntries, PortletPreferences prefs,
180             boolean addCommunityPermissions, boolean addGuestPermissions)
181         throws PortalException, SystemException {
182 
183         return addMessage(
184             userId, categoryId, subject, body, files, anonymous, priority,
185             tagsEntries, prefs, Boolean.valueOf(addCommunityPermissions),
186             Boolean.valueOf(addGuestPermissions), null, null);
187     }
188 
189     public MBMessage addMessage(
190             long userId, long categoryId, String subject, String body,
191             List files, boolean anonymous, double priority,
192             String[] tagsEntries, PortletPreferences prefs,
193             String[] communityPermissions, String[] guestPermissions)
194         throws PortalException, SystemException {
195 
196         return addMessage(
197             userId, categoryId, subject, body, files, anonymous, priority,
198             tagsEntries, prefs, null, null, communityPermissions,
199             guestPermissions);
200     }
201 
202     public MBMessage addMessage(
203             long userId, long categoryId, String subject, String body,
204             List files, boolean anonymous, double priority,
205             String[] tagsEntries, PortletPreferences prefs,
206             Boolean addCommunityPermissions, Boolean addGuestPermissions,
207             String[] communityPermissions, String[] guestPermissions)
208         throws PortalException, SystemException {
209 
210         long threadId = 0;
211         long parentMessageId = 0;
212 
213         return addMessage(
214             userId, categoryId, threadId, parentMessageId, subject, body, files,
215             anonymous, priority, tagsEntries, prefs, addCommunityPermissions,
216             addGuestPermissions, communityPermissions, guestPermissions);
217     }
218 
219     public MBMessage addMessage(
220             long userId, long categoryId, long threadId, long parentMessageId,
221             String subject, String body, List files, boolean anonymous,
222             double priority, String[] tagsEntries, PortletPreferences prefs,
223             boolean addCommunityPermissions, boolean addGuestPermissions)
224         throws PortalException, SystemException {
225 
226         return addMessage(
227             userId, categoryId, threadId, parentMessageId, subject, body, files,
228             anonymous, priority, tagsEntries, prefs,
229             Boolean.valueOf(addCommunityPermissions),
230             Boolean.valueOf(addGuestPermissions), null, null);
231     }
232 
233     public MBMessage addMessage(
234             long userId, long categoryId, long threadId, long parentMessageId,
235             String subject, String body, List files, boolean anonymous,
236             double priority, String[] tagsEntries, PortletPreferences prefs,
237             String[] communityPermissions, String[] guestPermissions)
238         throws PortalException, SystemException {
239 
240         return addMessage(
241             userId, categoryId, threadId, parentMessageId, subject, body, files,
242             anonymous, priority, tagsEntries, prefs, null, null,
243             communityPermissions, guestPermissions);
244     }
245 
246     public MBMessage addMessage(
247             long userId, long categoryId, long threadId, long parentMessageId,
248             String subject, String body, List files, boolean anonymous,
249             double priority, String[] tagsEntries, PortletPreferences prefs,
250             Boolean addCommunityPermissions, Boolean addGuestPermissions,
251             String[] communityPermissions, String[] guestPermissions)
252         throws PortalException, SystemException {
253 
254         StopWatch stopWatch = null;
255 
256         if (_log.isDebugEnabled()) {
257             stopWatch = new StopWatch();
258 
259             stopWatch.start();
260         }
261 
262         // Message
263 
264         User user = UserUtil.findByPrimaryKey(userId);
265         MBCategory category = MBCategoryUtil.findByPrimaryKey(categoryId);
266         subject = ModelHintsUtil.trimString(
267             MBMessage.class.getName(), "subject", subject);
268         anonymous = user.isDefaultUser() ? true : anonymous;
269         Date now = new Date();
270 
271         validate(subject, body);
272 
273         long messageId = CounterLocalServiceUtil.increment();
274 
275         logAddMessage(messageId, stopWatch, 1);
276 
277         MBMessage message = MBMessageUtil.create(messageId);
278 
279         message.setCompanyId(user.getCompanyId());
280         message.setUserId(user.getUserId());
281         message.setUserName(user.getFullName());
282         message.setCreateDate(now);
283         message.setModifiedDate(now);
284 
285         // Thread
286 
287         MBMessage parentMessage = MBMessageUtil.fetchByPrimaryKey(
288             parentMessageId);
289 
290         if (parentMessage == null) {
291             parentMessageId = MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID;
292         }
293 
294         MBThread thread = null;
295 
296         if (threadId > 0) {
297             thread = MBThreadUtil.fetchByPrimaryKey(threadId);
298         }
299 
300         if ((thread == null) ||
301             (parentMessageId == MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID)) {
302 
303             threadId = CounterLocalServiceUtil.increment();
304 
305             thread = MBThreadUtil.create(threadId);
306 
307             thread.setCategoryId(categoryId);
308             thread.setRootMessageId(messageId);
309         }
310 
311         thread.setMessageCount(thread.getMessageCount() + 1);
312 
313         if (anonymous) {
314             thread.setLastPostByUserId(0);
315         }
316         else {
317             thread.setLastPostByUserId(userId);
318         }
319 
320         thread.setLastPostDate(now);
321 
322         if (priority != MBThreadImpl.PRIORITY_NOT_GIVEN) {
323             thread.setPriority(priority);
324         }
325 
326         logAddMessage(messageId, stopWatch, 2);
327 
328         // Message
329 
330         message.setCategoryId(categoryId);
331         message.setThreadId(threadId);
332         message.setParentMessageId(parentMessageId);
333         message.setSubject(subject);
334         message.setBody(body);
335         message.setAttachments((files.size() > 0 ? true : false));
336         message.setAnonymous(anonymous);
337 
338         // File attachments
339 
340         if (files.size() > 0) {
341             long companyId = message.getCompanyId();
342             String portletId = CompanyImpl.SYSTEM_STRING;
343             long groupId = GroupImpl.DEFAULT_PARENT_GROUP_ID;
344             long repositoryId = CompanyImpl.SYSTEM;
345             String dirName = message.getAttachmentsDir();
346 
347             try {
348                 try {
349                     DLServiceUtil.deleteDirectory(
350                         companyId, portletId, repositoryId, dirName);
351                 }
352                 catch (NoSuchDirectoryException nsde) {
353                 }
354 
355                 DLServiceUtil.addDirectory(companyId, repositoryId, dirName);
356 
357                 for (int i = 0; i < files.size(); i++) {
358                     ObjectValuePair ovp = (ObjectValuePair)files.get(i);
359 
360                     String fileName = (String)ovp.getKey();
361                     byte[] byteArray = (byte[])ovp.getValue();
362 
363                     try {
364                         DLServiceUtil.addFile(
365                             companyId, portletId, groupId, repositoryId,
366                             dirName + "/" + fileName, StringPool.BLANK,
367                             byteArray);
368                     }
369                     catch (DuplicateFileException dfe) {
370                     }
371                 }
372             }
373             catch (RemoteException re) {
374                 throw new SystemException(re);
375             }
376         }
377 
378         logAddMessage(messageId, stopWatch, 3);
379 
380         // Commit
381 
382         MBThreadUtil.update(thread);
383         MBMessageUtil.update(message);
384 
385         logAddMessage(messageId, stopWatch, 4);
386 
387         // Resources
388 
389         if (!category.isDiscussion()) {
390             if (user.isDefaultUser()) {
391                 addMessageResources(category, message, true, true);
392             }
393             else if ((addCommunityPermissions != null) &&
394                      (addGuestPermissions != null)) {
395 
396                 addMessageResources(
397                     category, message, addCommunityPermissions.booleanValue(),
398                     addGuestPermissions.booleanValue());
399             }
400             else {
401                 addMessageResources(
402                     category, message, communityPermissions, guestPermissions);
403             }
404         }
405 
406         logAddMessage(messageId, stopWatch, 5);
407 
408         // Statistics
409 
410         if (!category.isDiscussion()) {
411             MBStatsUserLocalServiceUtil.updateStatsUser(
412                 category.getGroupId(), userId);
413         }
414 
415         logAddMessage(messageId, stopWatch, 6);
416 
417         // Subscriptions
418 
419         notifySubscribers(category, message, prefs, false);
420 
421         logAddMessage(messageId, stopWatch, 7);
422 
423         // Category
424 
425         category.setLastPostDate(now);
426 
427         MBCategoryUtil.update(category);
428 
429         logAddMessage(messageId, stopWatch, 8);
430 
431         // Tags
432 
433         updateAsset(message, tagsEntries);
434 
435         logAddMessage(messageId, stopWatch, 9);
436 
437         // Testing roll back
438 
439         /*if (true) {
440             throw new SystemException("Testing roll back");
441         }*/
442 
443         // Lucene
444 
445         try {
446             if (!category.isDiscussion()) {
447                 Indexer.addMessage(
448                     message.getCompanyId(), category.getGroupId(),
449                     user.getFullName(), category.getCategoryId(), threadId,
450                     messageId, subject, body);
451             }
452         }
453         catch (IOException ioe) {
454             _log.error("Indexing " + messageId, ioe);
455         }
456 
457         logAddMessage(messageId, stopWatch, 9);
458 
459         return message;
460     }
461 
462     public void addMessageResources(
463             long categoryId, long messageId, boolean addCommunityPermissions,
464             boolean addGuestPermissions)
465         throws PortalException, SystemException {
466 
467         addMessageResources(
468             categoryId, null, messageId, addCommunityPermissions,
469             addGuestPermissions);
470     }
471 
472     public void addMessageResources(
473             long categoryId, String topicId, long messageId,
474             boolean addCommunityPermissions, boolean addGuestPermissions)
475         throws PortalException, SystemException {
476 
477         MBCategory category = MBCategoryUtil.findByPrimaryKey(categoryId);
478         MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
479 
480         addMessageResources(
481             category, message, addCommunityPermissions, addGuestPermissions);
482     }
483 
484     public void addMessageResources(
485             MBCategory category, MBMessage message,
486             boolean addCommunityPermissions, boolean addGuestPermissions)
487         throws PortalException, SystemException {
488 
489         ResourceLocalServiceUtil.addResources(
490             message.getCompanyId(), category.getGroupId(), message.getUserId(),
491             MBMessage.class.getName(), message.getMessageId(),
492             false, addCommunityPermissions, addGuestPermissions);
493     }
494 
495     public void addMessageResources(
496             long categoryId, long messageId, String[] communityPermissions,
497             String[] guestPermissions)
498         throws PortalException, SystemException {
499 
500         addMessageResources(
501             categoryId, null, messageId, communityPermissions,
502             guestPermissions);
503     }
504 
505     public void addMessageResources(
506             long categoryId, String topicId, long messageId,
507             String[] communityPermissions, String[] guestPermissions)
508         throws PortalException, SystemException {
509 
510         MBCategory category = MBCategoryUtil.findByPrimaryKey(categoryId);
511         MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
512 
513         addMessageResources(
514             category, message, communityPermissions, guestPermissions);
515     }
516 
517     public void addMessageResources(
518             MBCategory category, MBMessage message,
519             String[] communityPermissions, String[] guestPermissions)
520         throws PortalException, SystemException {
521 
522         ResourceLocalServiceUtil.addModelResources(
523             message.getCompanyId(), category.getGroupId(), message.getUserId(),
524             MBMessage.class.getName(), message.getMessageId(),
525             communityPermissions, guestPermissions);
526     }
527 
528     public void deleteDiscussionMessage(long messageId)
529         throws PortalException, SystemException {
530 
531         deleteMessage(messageId);
532     }
533 
534     public void deleteDiscussionMessages(String className, long classPK)
535         throws PortalException, SystemException {
536 
537         try {
538             long classNameId = PortalUtil.getClassNameId(className);
539 
540             MBDiscussion discussion =
541                 MBDiscussionUtil.findByC_C(classNameId, classPK);
542 
543             List messages = MBMessageUtil.findByT_P(
544                 discussion.getThreadId(),
545                 MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID, 0, 1);
546 
547             if (messages.size() > 0) {
548                 MBMessage message = (MBMessage)messages.get(0);
549 
550                 MBThreadLocalServiceUtil.deleteThread(message.getThreadId());
551             }
552 
553             MBDiscussionUtil.remove(discussion.getDiscussionId());
554         }
555         catch (NoSuchDiscussionException nsde) {
556         }
557     }
558 
559     public void deleteMessage(long messageId)
560         throws PortalException, SystemException {
561 
562         MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
563 
564         deleteMessage(message);
565     }
566 
567     public void deleteMessage(MBMessage message)
568         throws PortalException, SystemException {
569 
570         // Lucene
571 
572         try {
573             Indexer.deleteMessage(
574                 message.getCompanyId(), message.getMessageId());
575         }
576         catch (IOException ioe) {
577             _log.error("Deleting index " + message.getMessageId(), ioe);
578         }
579 
580         // File attachments
581 
582         if (message.isAttachments()) {
583             long companyId = message.getCompanyId();
584             String portletId = CompanyImpl.SYSTEM_STRING;
585             long repositoryId = CompanyImpl.SYSTEM;
586             String dirName = message.getAttachmentsDir();
587 
588             try {
589                 DLServiceUtil.deleteDirectory(
590                     companyId, portletId, repositoryId, dirName);
591             }
592             catch (NoSuchDirectoryException nsde) {
593             }
594             catch (RemoteException re) {
595                 throw new SystemException(re);
596             }
597         }
598 
599         // Thread
600 
601         int count = MBMessageUtil.countByThreadId(message.getThreadId());
602 
603         if (count == 1) {
604 
605             // File attachments
606 
607             long companyId = message.getCompanyId();
608             String portletId = CompanyImpl.SYSTEM_STRING;
609             long repositoryId = CompanyImpl.SYSTEM;
610             String dirName = message.getThreadAttachmentsDir();
611 
612             try {
613                 DLServiceUtil.deleteDirectory(
614                     companyId, portletId, repositoryId, dirName);
615             }
616             catch (NoSuchDirectoryException nsde) {
617             }
618             catch (RemoteException re) {
619                 throw new SystemException(re);
620             }
621 
622             // Subscriptions
623 
624             SubscriptionLocalServiceUtil.deleteSubscriptions(
625                 message.getCompanyId(), MBThread.class.getName(),
626                 message.getThreadId());
627 
628             // Thread
629 
630             MBThreadUtil.remove(message.getThreadId());
631         }
632         else if (count > 1) {
633             MBThread thread = MBThreadUtil.findByPrimaryKey(
634                 message.getThreadId());
635 
636             // Message is a root message
637 
638             if (thread.getRootMessageId() == message.getMessageId()) {
639                 List childrenMessages = MBMessageUtil.findByT_P(
640                     message.getThreadId(), message.getMessageId());
641 
642                 if (childrenMessages.size() > 1) {
643                     throw new RequiredMessageException(
644                         String.valueOf(message.getMessageId()));
645                 }
646                 else if (childrenMessages.size() == 1) {
647                     MBMessage childMessage = (MBMessage)childrenMessages.get(0);
648 
649                     childMessage.setParentMessageId(
650                         MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID);
651 
652                     MBMessageUtil.update(childMessage);
653 
654                     thread.setRootMessageId(childMessage.getMessageId());
655 
656                     MBThreadUtil.update(thread);
657                 }
658             }
659 
660             // Message is a child message
661 
662             else {
663                 List childrenMessages = MBMessageUtil.findByT_P(
664                     message.getThreadId(), message.getMessageId());
665 
666                 // Message has children messages
667 
668                 if (childrenMessages.size() > 0) {
669                     Iterator itr = childrenMessages.iterator();
670 
671                     while (itr.hasNext()) {
672                         MBMessage childMessage = (MBMessage)itr.next();
673 
674                         childMessage.setParentMessageId(
675                             message.getParentMessageId());
676 
677                         MBMessageUtil.update(childMessage);
678                     }
679                 }
680             }
681 
682             // Thread
683 
684             thread.setMessageCount(count - 1);
685 
686             MBThreadUtil.update(thread);
687         }
688 
689         // Tags
690 
691         TagsAssetLocalServiceUtil.deleteAsset(
692             MBMessage.class.getName(), message.getMessageId());
693 
694         // Message flags
695 
696         MBMessageFlagUtil.removeByMessageId(message.getMessageId());
697 
698         // Resources
699 
700         if (!message.isDiscussion()) {
701             ResourceLocalServiceUtil.deleteResource(
702                 message.getCompanyId(), MBMessage.class.getName(),
703                 ResourceImpl.SCOPE_INDIVIDUAL, message.getMessageId());
704         }
705 
706         // Message
707 
708         MBMessageUtil.remove(message.getPrimaryKey());
709     }
710 
711     public List getCategoryMessages(long categoryId, int begin, int end)
712         throws SystemException {
713 
714         return MBMessageUtil.findByCategoryId(categoryId, begin, end);
715     }
716 
717     public List getCategoryMessages(
718             long categoryId, int begin, int end, OrderByComparator obc)
719         throws SystemException {
720 
721         return MBMessageUtil.findByCategoryId(categoryId, begin, end, obc);
722     }
723 
724     public int getCategoryMessagesCount(long categoryId)
725         throws SystemException {
726 
727         return MBMessageUtil.countByCategoryId(categoryId);
728     }
729 
730     public int getCategoriesMessagesCount(List categoryIds)
731         throws SystemException {
732 
733         return MBMessageFinder.countByCategoryIds(categoryIds);
734     }
735 
736     public List getCompanyMessages(long companyId, int begin, int end)
737         throws SystemException {
738 
739         return MBMessageUtil.findByCompanyId(companyId, begin, end);
740     }
741 
742     public List getCompanyMessages(
743             long companyId, int begin, int end, OrderByComparator obc)
744         throws SystemException {
745 
746         return MBMessageUtil.findByCompanyId(companyId, begin, end, obc);
747     }
748 
749     public int getCompanyMessagesCount(long companyId)
750         throws SystemException {
751 
752         return MBMessageUtil.countByCompanyId(companyId);
753     }
754 
755     public MBMessageDisplay getDiscussionMessageDisplay(
756             long userId, String className, long classPK)
757         throws PortalException, SystemException {
758 
759         long classNameId = PortalUtil.getClassNameId(className);
760 
761         MBMessage message = null;
762 
763         try {
764             MBDiscussion discussion = MBDiscussionUtil.findByC_C(
765                 classNameId, classPK);
766 
767             List messages = MBMessageUtil.findByT_P(
768                 discussion.getThreadId(),
769                 MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID);
770 
771             message = (MBMessage)messages.get(0);
772         }
773         catch (NoSuchDiscussionException nsde) {
774             String subject = String.valueOf(classPK);
775             String body = subject;
776 
777             message = addDiscussionMessage(userId, subject, body);
778 
779             long discussionId = CounterLocalServiceUtil.increment();
780 
781             MBDiscussion discussion = MBDiscussionUtil.create(discussionId);
782 
783             discussion.setClassNameId(classNameId);
784             discussion.setClassPK(classPK);
785             discussion.setThreadId(message.getThreadId());
786 
787             MBDiscussionUtil.update(discussion);
788         }
789 
790         return getMessageDisplay(message);
791     }
792 
793     public int getDiscussionMessagesCount(long classNameId, long classPK)
794         throws SystemException {
795 
796         MBDiscussion discussion = MBDiscussionUtil.fetchByC_C(
797             classNameId, classPK);
798 
799         if (discussion == null) {
800             return 0;
801         }
802 
803         int count = MBMessageUtil.countByThreadId(discussion.getThreadId());
804 
805         if (count >= 1) {
806             return count - 1;
807         }
808         else {
809             return 0;
810         }
811     }
812 
813     public List getGroupMessages(long groupId, int begin, int end)
814         throws SystemException {
815 
816         return MBMessageFinder.findByGroupId(groupId, begin, end);
817     }
818 
819     public List getGroupMessages(
820             long groupId, int begin, int end, OrderByComparator obc)
821         throws SystemException {
822 
823         return MBMessageFinder.findByGroupId(groupId, begin, end, obc);
824     }
825 
826     public int getGroupMessagesCount(long groupId) throws SystemException {
827         return MBMessageFinder.countByGroupId(groupId);
828     }
829 
830     public MBMessage getMessage(long messageId)
831         throws PortalException, SystemException {
832 
833         return MBMessageUtil.findByPrimaryKey(messageId);
834     }
835 
836     public MBMessageDisplay getMessageDisplay(long messageId)
837         throws PortalException, SystemException {
838 
839         MBMessage message = getMessage(messageId);
840 
841         return getMessageDisplay(message);
842     }
843 
844     public MBMessageDisplay getMessageDisplay(MBMessage message)
845         throws PortalException, SystemException {
846 
847         MBCategory category = MBCategoryUtil.findByPrimaryKey(
848             message.getCategoryId());
849 
850         MBMessage parentMessage = null;
851 
852         if (message.isReply()) {
853             parentMessage = MBMessageUtil.findByPrimaryKey(
854                 message.getParentMessageId());
855         }
856 
857         MBThread thread = MBThreadUtil.findByPrimaryKey(message.getThreadId());
858 
859         thread.setViewCount(thread.getViewCount() + 1);
860 
861         MBThreadUtil.update(thread);
862 
863         MBTreeWalker treeWalker = new MBTreeWalkerImpl(message);
864 
865         ThreadLastPostDateComparator comparator =
866             new ThreadLastPostDateComparator(false);
867 
868         MBThread[] prevAndNextThreads =
869             MBThreadUtil.findByCategoryId_PrevAndNext(
870                 message.getThreadId(), message.getCategoryId(), comparator);
871 
872         MBThread previousThread = prevAndNextThreads[0];
873         MBThread nextThread = prevAndNextThreads[2];
874 
875         MBThread firstThread = null;
876 
877         try {
878             firstThread = MBThreadUtil.findByCategoryId_First(
879                 message.getCategoryId(), comparator);
880         }
881         catch (NoSuchThreadException nste) {
882         }
883 
884         MBThread lastThread = null;
885 
886         try {
887             lastThread = MBThreadUtil.findByCategoryId_Last(
888                 message.getCategoryId(), comparator);
889         }
890         catch (NoSuchThreadException nste) {
891         }
892 
893         return new MBMessageDisplayImpl(
894             message, parentMessage, category, thread, treeWalker,
895             previousThread, nextThread, firstThread, lastThread);
896     }
897 
898     public List getThreadMessages(long threadId) throws SystemException {
899         return getThreadMessages(threadId, new MessageThreadComparator());
900     }
901 
902     public List getThreadMessages(long threadId, Comparator comparator)
903         throws SystemException {
904 
905         List messages = MBMessageUtil.findByThreadId(threadId);
906 
907         Collections.sort(messages, comparator);
908 
909         return messages;
910     }
911 
912     public int getThreadMessagesCount(long threadId) throws SystemException {
913         return MBMessageUtil.countByThreadId(threadId);
914     }
915 
916     public void subscribeMessage(long userId, long messageId)
917         throws PortalException, SystemException {
918 
919         MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
920 
921         SubscriptionLocalServiceUtil.addSubscription(
922             userId, MBThread.class.getName(), message.getThreadId());
923     }
924 
925     public void unsubscribeMessage(long userId, long messageId)
926         throws PortalException, SystemException {
927 
928         MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
929 
930         SubscriptionLocalServiceUtil.deleteSubscription(
931             userId, MBThread.class.getName(), message.getThreadId());
932     }
933 
934     public MBMessage updateDiscussionMessage(
935             long messageId, String subject, String body)
936         throws PortalException, SystemException {
937 
938         long categoryId = CompanyImpl.SYSTEM;
939 
940         if (Validator.isNull(subject)) {
941             subject = "N/A";
942         }
943 
944         List files = new ArrayList();
945         double priority = 0.0;
946         String[] tagsEntries = null;
947         PortletPreferences prefs = null;
948 
949         return updateMessage(
950             messageId, categoryId, subject, body, files, priority, tagsEntries,
951             prefs);
952     }
953 
954     public MBMessage updateMessage(
955             long messageId, long categoryId, String subject, String body,
956             List files, double priority, String[] tagsEntries,
957             PortletPreferences prefs)
958         throws PortalException, SystemException {
959 
960         // Message
961 
962         MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
963 
964         MBCategory category = getCategory(message, categoryId);
965         long oldCategoryId = message.getCategoryId();
966         subject = ModelHintsUtil.trimString(
967             MBMessage.class.getName(), "subject", subject);
968         Date now = new Date();
969 
970         validate(subject, body);
971 
972         // File attachments
973 
974         if (files.size() > 0) {
975             long companyId = message.getCompanyId();
976             String portletId = CompanyImpl.SYSTEM_STRING;
977             long groupId = GroupImpl.DEFAULT_PARENT_GROUP_ID;
978             long repositoryId = CompanyImpl.SYSTEM;
979             String dirName = message.getAttachmentsDir();
980 
981             try {
982                 try {
983                     DLServiceUtil.deleteDirectory(
984                         companyId, portletId, repositoryId, dirName);
985                 }
986                 catch (NoSuchDirectoryException nsde) {
987                 }
988 
989                 DLServiceUtil.addDirectory(companyId, repositoryId, dirName);
990 
991                 for (int i = 0; i < files.size(); i++) {
992                     ObjectValuePair ovp = (ObjectValuePair)files.get(i);
993 
994                     String fileName = (String)ovp.getKey();
995                     byte[] byteArray = (byte[])ovp.getValue();
996 
997                     try {
998                         DLServiceUtil.addFile(
999                             companyId, portletId, groupId, repositoryId,
1000                            dirName + "/" + fileName, StringPool.BLANK,
1001                            byteArray);
1002                    }
1003                    catch (DuplicateFileException dfe) {
1004                    }
1005                }
1006            }
1007            catch (RemoteException re) {
1008                throw new SystemException(re);
1009            }
1010        }
1011
1012        // Message
1013
1014        message.setModifiedDate(now);
1015        message.setSubject(subject);
1016        message.setBody(body);
1017        message.setAttachments((files.size() > 0 ? true : false));
1018
1019        MBMessageUtil.update(message);
1020
1021        // Subscriptions
1022
1023        notifySubscribers(category, message, prefs, true);
1024
1025        // Thread
1026
1027        MBThread thread = MBThreadUtil.findByPrimaryKey(message.getThreadId());
1028
1029        if (priority != MBThreadImpl.PRIORITY_NOT_GIVEN) {
1030            thread.setPriority(priority);
1031        }
1032
1033        MBThreadUtil.update(thread);
1034
1035        // Category
1036
1037        category.setLastPostDate(now);
1038
1039        MBCategoryUtil.update(category);
1040
1041        if (oldCategoryId != category.getCategoryId()) {
1042
1043            // Messages
1044
1045            Iterator itr = MBMessageUtil.findByC_T(
1046                oldCategoryId, thread.getThreadId()).iterator();
1047
1048            while (itr.hasNext()) {
1049                MBMessage curMessage = (MBMessage)itr.next();
1050
1051                curMessage.setCategoryId(category.getCategoryId());
1052
1053                MBMessageUtil.update(curMessage);
1054
1055                // Lucene
1056
1057                try {
1058                    if (!category.isDiscussion()) {
1059                        Indexer.updateMessage(
1060                            curMessage.getCompanyId(), category.getGroupId(),
1061                            curMessage.getUserName(), category.getCategoryId(),
1062                            curMessage.getThreadId(), curMessage.getMessageId(),
1063                            curMessage.getSubject(), curMessage.getBody());
1064                    }
1065                }
1066                catch (IOException ioe) {
1067                    _log.error("Indexing " + messageId, ioe);
1068                }
1069            }
1070
1071            // Thread
1072
1073            thread.setCategoryId(category.getCategoryId());
1074
1075            MBThreadUtil.update(thread);
1076        }
1077
1078        // Tags
1079
1080        updateAsset(message, tagsEntries);
1081
1082        // Lucene
1083
1084        try {
1085            if (!category.isDiscussion()) {
1086                Indexer.updateMessage(
1087                    message.getCompanyId(), category.getGroupId(),
1088                    message.getUserName(), category.getCategoryId(),
1089                    message.getThreadId(), messageId, subject, body);
1090            }
1091        }
1092        catch (IOException ioe) {
1093            _log.error("Indexing " + messageId, ioe);
1094        }
1095
1096        return message;
1097    }
1098
1099    public MBMessage updateMessage(
1100            long messageId, Date createDate, Date modifiedDate)
1101        throws PortalException, SystemException {
1102
1103        // Message
1104
1105        MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
1106
1107        message.setCreateDate(createDate);
1108        message.setModifiedDate(modifiedDate);
1109
1110        MBMessageUtil.update(message);
1111
1112        // Thread
1113
1114        MBThread thread = MBThreadUtil.findByPrimaryKey(message.getThreadId());
1115
1116        if (message.isAnonymous()) {
1117            thread.setLastPostByUserId(0);
1118        }
1119        else {
1120            thread.setLastPostByUserId(message.getUserId());
1121        }
1122
1123        thread.setLastPostDate(modifiedDate);
1124
1125        MBThreadUtil.update(thread);
1126
1127        // Category
1128
1129        MBCategory category = MBCategoryUtil.findByPrimaryKey(
1130            message.getCategoryId());
1131
1132        category.setLastPostDate(modifiedDate);
1133
1134        MBCategoryUtil.update(category);
1135
1136        // Statistics
1137
1138        MBStatsUser statsUser = MBStatsUserUtil.fetchByG_U(
1139            category.getGroupId(), message.getUserId());
1140
1141        if (statsUser != null) {
1142            statsUser.setLastPostDate(modifiedDate);
1143
1144            MBStatsUserUtil.update(statsUser);
1145        }
1146
1147        return message;
1148    }
1149
1150    public MBMessage updateMessage(long messageId, String body)
1151        throws PortalException, SystemException {
1152
1153        MBMessage message = MBMessageUtil.findByPrimaryKey(messageId);
1154
1155        message.setBody(body);
1156
1157        MBMessageUtil.update(message);
1158
1159        return message;
1160    }
1161
1162    protected MBCategory getCategory(MBMessage message, long categoryId)
1163        throws PortalException, SystemException {
1164
1165        if (message.getCategoryId() != categoryId) {
1166            MBCategory oldCategory = MBCategoryUtil.findByPrimaryKey(
1167                message.getCategoryId());
1168
1169            MBCategory newCategory = MBCategoryUtil.fetchByPrimaryKey(
1170                categoryId);
1171
1172            if ((newCategory == null) ||
1173                (oldCategory.getGroupId() != newCategory.getGroupId())) {
1174
1175                categoryId = message.getCategoryId();
1176            }
1177        }
1178
1179        return MBCategoryUtil.findByPrimaryKey(categoryId);
1180    }
1181
1182    protected void logAddMessage(
1183        long messageId, StopWatch stopWatch, int block) {
1184
1185        if (_log.isDebugEnabled()) {
1186            if ((messageId != 1) && ((messageId % 10) != 0)) {
1187                return;
1188            }
1189
1190            _log.debug(
1191                "Adding message block " + block + " for " + messageId +
1192                    " takes " + stopWatch.getTime() + " ms");
1193        }
1194    }
1195
1196    protected void notifySubscribers(
1197            MBCategory category, MBMessage message, PortletPreferences prefs,
1198            boolean update)
1199        throws PortalException, SystemException {
1200
1201        try {
1202            if (category.isDiscussion()) {
1203                return;
1204            }
1205
1206            if (prefs == null) {
1207                long ownerId = category.getGroupId();
1208                int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1209                long plid = PortletKeys.PREFS_PLID_SHARED;
1210                String portletId = PortletKeys.MESSAGE_BOARDS;
1211                String defaultPreferences = null;
1212
1213                prefs = PortletPreferencesLocalServiceUtil.getPreferences(
1214                    category.getCompanyId(), ownerId, ownerType, plid,
1215                    portletId, defaultPreferences);
1216            }
1217
1218            if (!update && MBUtil.getEmailMessageAddedEnabled(prefs)) {
1219            }
1220            else if (update && MBUtil.getEmailMessageUpdatedEnabled(prefs)) {
1221            }
1222            else {
1223                return;
1224            }
1225
1226            Company company = CompanyUtil.findByPrimaryKey(
1227                message.getCompanyId());
1228
1229            Group group = GroupLocalServiceUtil.getGroup(category.getGroupId());
1230
1231            User user = UserUtil.findByPrimaryKey(message.getUserId());
1232
1233            List categoryIds = new ArrayList();
1234
1235            MBCategoryLocalServiceUtil.getSubcategoryIds(
1236                categoryIds, category.getGroupId(), category.getCategoryId());
1237
1238            categoryIds.add(new Long(category.getCategoryId()));
1239
1240            String portletName = PortalUtil.getPortletTitle(
1241                PortletKeys.MESSAGE_BOARDS, user);
1242
1243            String fromName = MBUtil.getEmailFromName(prefs);
1244            String fromAddress = MBUtil.getEmailFromAddress(prefs);
1245
1246            String mailingListAddress = StringPool.BLANK;
1247
1248            if (GetterUtil.getBoolean(PropsUtil.get(
1249                    PropsUtil.SMTP_SERVER_ENABLED))) {
1250
1251                mailingListAddress = MBUtil.getMailingListAddress(
1252                    message.getCategoryId(), message.getMessageId(),
1253                    company.getMx());
1254            }
1255
1256            String replyToAddress = mailingListAddress;
1257            String messageId = MBUtil.getMailId(
1258                company.getMx(), message.getCategoryId(),
1259                message.getMessageId());
1260
1261            fromName = StringUtil.replace(
1262                fromName,
1263                new String[] {
1264                    "[$COMPANY_ID$]",
1265                    "[$COMPANY_MX$]",
1266                    "[$COMPANY_NAME$]",
1267                    "[$COMMUNITY_NAME$]",
1268                    "[$MAILING_LIST_ADDRESS$]",
1269                    "[$MESSAGE_USER_ADDRESS$]",
1270                    "[$MESSAGE_USER_NAME$]",
1271                    "[$PORTLET_NAME$]"
1272                },
1273                new String[] {
1274                    String.valueOf(company.getCompanyId()),
1275                    company.getMx(),
1276                    company.getName(),
1277                    group.getName(),
1278                    mailingListAddress,
1279                    user.getEmailAddress(),
1280                    user.getFullName(),
1281                    portletName
1282                });
1283
1284            fromAddress = StringUtil.replace(
1285                fromAddress,
1286                new String[] {
1287                    "[$COMPANY_ID$]",
1288                    "[$COMPANY_MX$]",
1289                    "[$COMPANY_NAME$]",
1290                    "[$COMMUNITY_NAME$]",
1291                    "[$MAILING_LIST_ADDRESS$]",
1292                    "[$MESSAGE_USER_ADDRESS$]",
1293                    "[$MESSAGE_USER_NAME$]",
1294                    "[$PORTLET_NAME$]"
1295                },
1296                new String[] {
1297                    String.valueOf(company.getCompanyId()),
1298                    company.getMx(),
1299                    company.getName(),
1300                    group.getName(),
1301                    mailingListAddress,
1302                    user.getEmailAddress(),
1303                    user.getFullName(),
1304                    portletName
1305                });
1306
1307            String subjectPrefix = null;
1308            String body = null;
1309            String signature = null;
1310
1311            if (update) {
1312                subjectPrefix = MBUtil.getEmailMessageUpdatedSubjectPrefix(
1313                    prefs);
1314                body = MBUtil.getEmailMessageUpdatedBody(prefs);
1315                signature = MBUtil.getEmailMessageUpdatedSignature(prefs);
1316            }
1317            else {
1318                subjectPrefix = MBUtil.getEmailMessageAddedSubjectPrefix(prefs);
1319                body = MBUtil.getEmailMessageAddedBody(prefs);
1320                signature = MBUtil.getEmailMessageAddedSignature(prefs);
1321            }
1322
1323            if (Validator.isNotNull(signature)) {
1324                body +=  "\n--\n" + signature;
1325            }
1326
1327            subjectPrefix = StringUtil.replace(
1328                subjectPrefix,
1329                new String[] {
1330                    "[$CATEGORY_NAME$]",
1331                    "[$COMPANY_ID$]",
1332                    "[$COMPANY_MX$]",
1333                    "[$COMPANY_NAME$]",
1334                    "[$COMMUNITY_NAME$]",
1335                    "[$FROM_ADDRESS$]",
1336                    "[$FROM_NAME$]",
1337                    "[$MAILING_LIST_ADDRESS$]",
1338                    "[$MESSAGE_BODY$]",
1339                    "[$MESSAGE_ID$]",
1340                    "[$MESSAGE_SUBJECT$]",
1341                    "[$MESSAGE_USER_ADDRESS$]",
1342                    "[$MESSAGE_USER_NAME$]",
1343                    "[$PORTAL_URL$]",
1344                    "[$PORTLET_NAME$]"
1345                },
1346                new String[] {
1347                    category.getName(),
1348                    String.valueOf(company.getCompanyId()),
1349                    company.getMx(),
1350                    company.getName(),
1351                    group.getName(),
1352                    fromAddress,
1353                    fromName,
1354                    mailingListAddress,
1355                    message.getBody(),
1356                    String.valueOf(message.getMessageId()),
1357                    message.getSubject(),
1358                    user.getEmailAddress(),
1359                    user.getFullName(),
1360                    company.getVirtualHost(),
1361                    portletName
1362                });
1363
1364            body = StringUtil.replace(
1365                body,
1366                new String[] {
1367                    "[$CATEGORY_NAME$]",
1368                    "[$COMPANY_ID$]",
1369                    "[$COMPANY_MX$]",
1370                    "[$COMPANY_NAME$]",
1371                    "[$COMMUNITY_NAME$]",
1372                    "[$FROM_ADDRESS$]",
1373                    "[$FROM_NAME$]",
1374                    "[$MAILING_LIST_ADDRESS$]",
1375                    "[$MESSAGE_BODY$]",
1376                    "[$MESSAGE_ID$]",
1377                    "[$MESSAGE_SUBJECT$]",
1378                    "[$MESSAGE_USER_ADDRESS$]",
1379                    "[$MESSAGE_USER_NAME$]",
1380                    "[$PORTAL_URL$]",
1381                    "[$PORTLET_NAME$]"
1382                },
1383                new String[] {
1384                    category.getName(),
1385                    String.valueOf(company.getCompanyId()),
1386                    company.getMx(),
1387                    company.getName(),
1388                    group.getName(),
1389                    fromAddress,
1390                    fromName,
1391                    mailingListAddress,
1392                    message.getBody(),
1393                    String.valueOf(message.getMessageId()),
1394                    message.getSubject(),
1395                    user.getEmailAddress(),
1396                    user.getFullName(),
1397                    company.getVirtualHost(),
1398                    portletName
1399                });
1400
1401            String subject = message.getSubject();
1402
1403            if (subject.indexOf(subjectPrefix) == -1) {
1404                subject = subjectPrefix + subject;
1405            }
1406
1407            String inReplyTo = null;
1408
1409            if (message.getParentMessageId() !=
1410                    MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID) {
1411
1412                inReplyTo = MBUtil.getMailId(
1413                    company.getMx(), message.getCategoryId(),
1414                    message.getParentMessageId());
1415            }
1416
1417            MBMessageProducer.produce(
1418                new String[] {
1419                    String.valueOf(message.getCompanyId()),
1420                    String.valueOf(message.getUserId()),
1421                    StringUtil.merge(categoryIds),
1422                    String.valueOf(message.getThreadId()),
1423                    fromName, fromAddress, subject, body, replyToAddress,
1424                    messageId, inReplyTo
1425                });
1426        }
1427        catch (IOException ioe) {
1428            throw new SystemException(ioe);
1429        }
1430    }
1431
1432    protected void sendBlogsCommentsEmail(
1433            long userId, long entryId, MBMessage message,
1434            ThemeDisplay themeDisplay)
1435        throws IOException, PortalException, SystemException {
1436
1437        long companyId = message.getCompanyId();
1438
1439        if (!PrefsPropsUtil.getBoolean(
1440                companyId, PropsUtil.BLOGS_EMAIL_COMMENTS_ADDED_ENABLED)) {
1441
1442            return;
1443        }
1444
1445        BlogsEntry entry = BlogsEntryUtil.findByPrimaryKey(entryId);
1446
1447        String portalURL = PortalUtil.getPortalURL(themeDisplay);
1448        String layoutURL = PortalUtil.getLayoutURL(themeDisplay);
1449
1450        String blogsEntryURL =
1451            portalURL + layoutURL + "/blogs/" + entry.getUrlTitle();
1452
1453        User blogsUser = UserUtil.findByPrimaryKey(entry.getUserId());
1454        User commentsUser = UserUtil.findByPrimaryKey(userId);
1455
1456        String fromName = PrefsPropsUtil.getString(
1457            companyId, PropsUtil.ADMIN_EMAIL_FROM_NAME);
1458        String fromAddress = PrefsPropsUtil.getString(
1459            companyId, PropsUtil.ADMIN_EMAIL_FROM_ADDRESS);
1460
1461        String toName = blogsUser.getFullName();
1462        String toAddress = blogsUser.getEmailAddress();
1463
1464        String subject = PrefsPropsUtil.getContent(
1465            companyId, PropsUtil.BLOGS_EMAIL_COMMENTS_ADDED_SUBJECT);
1466        String body = PrefsPropsUtil.getContent(
1467            companyId, PropsUtil.BLOGS_EMAIL_COMMENTS_ADDED_BODY);
1468
1469        subject = StringUtil.replace(
1470            subject,
1471            new String[] {
1472                "[$BLOGS_COMMENTS_USER_ADDRESS$]",
1473                "[$BLOGS_COMMENTS_USER_NAME$]",
1474                "[$BLOGS_ENTRY_URL$]",
1475                "[$FROM_ADDRESS$]",
1476                "[$FROM_NAME$]",
1477                "[$TO_ADDRESS$]",
1478                "[$TO_NAME$]"
1479            },
1480            new String[] {
1481                commentsUser.getEmailAddress(),
1482                commentsUser.getFullName(),
1483                blogsEntryURL,
1484                fromAddress,
1485                fromName,
1486                toAddress,
1487                toName
1488            });
1489
1490        body = StringUtil.replace(
1491            body,
1492            new String[] {
1493                "[$BLOGS_COMMENTS_USER_ADDRESS$]",
1494                "[$BLOGS_COMMENTS_USER_NAME$]",
1495                "[$BLOGS_ENTRY_URL$]",
1496                "[$FROM_ADDRESS$]",
1497                "[$FROM_NAME$]",
1498                "[$TO_ADDRESS$]",
1499                "[$TO_NAME$]"
1500            },
1501            new String[] {
1502                commentsUser.getEmailAddress(),
1503                commentsUser.getFullName(),
1504                blogsEntryURL,
1505                fromAddress,
1506                fromName,
1507                toAddress,
1508                toName
1509            });
1510
1511        InternetAddress from = new InternetAddress(fromAddress, fromName);
1512
1513        InternetAddress to = new InternetAddress(toAddress, toName);
1514
1515        MailMessage mailMessage = new MailMessage(
1516            from, to, subject, body, true);
1517
1518        MailServiceUtil.sendEmail(mailMessage);
1519    }
1520
1521    protected void updateAsset(MBMessage message, String[] tagsEntries)
1522        throws PortalException, SystemException {
1523
1524        if (tagsEntries == null) {
1525            return;
1526        }
1527
1528        TagsAssetLocalServiceUtil.updateAsset(
1529            message.getUserId(), MBMessage.class.getName(),
1530            message.getMessageId(), tagsEntries, null, null, null, null,
1531            ContentTypes.TEXT_HTML, message.getSubject(), message.getSubject(),
1532            message.getSubject(), null, 0, 0);
1533    }
1534
1535    protected void validate(String subject, String body)
1536        throws PortalException {
1537
1538        if (Validator.isNull(subject)) {
1539            throw new MessageSubjectException();
1540        }
1541
1542        if (Validator.isNull(body)) {
1543            throw new MessageBodyException();
1544        }
1545    }
1546
1547    private static Log _log =
1548        LogFactory.getLog(MBMessageLocalServiceImpl.class);
1549
1550}