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            categoryIds.add(new Long(category.getCategoryId()));
1236            categoryIds.addAll(category.getAncestorCategoryIds());
1237
1238            String portletName = PortalUtil.getPortletTitle(
1239                PortletKeys.MESSAGE_BOARDS, user);
1240
1241            String fromName = MBUtil.getEmailFromName(prefs);
1242            String fromAddress = MBUtil.getEmailFromAddress(prefs);
1243
1244            String mailingListAddress = StringPool.BLANK;
1245
1246            if (GetterUtil.getBoolean(PropsUtil.get(
1247                    PropsUtil.SMTP_SERVER_ENABLED))) {
1248
1249                mailingListAddress = MBUtil.getMailingListAddress(
1250                    message.getCategoryId(), message.getMessageId(),
1251                    company.getMx());
1252            }
1253
1254            String replyToAddress = mailingListAddress;
1255            String messageId = MBUtil.getMailId(
1256                company.getMx(), message.getCategoryId(),
1257                message.getMessageId());
1258
1259            fromName = StringUtil.replace(
1260                fromName,
1261                new String[] {
1262                    "[$COMPANY_ID$]",
1263                    "[$COMPANY_MX$]",
1264                    "[$COMPANY_NAME$]",
1265                    "[$COMMUNITY_NAME$]",
1266                    "[$MAILING_LIST_ADDRESS$]",
1267                    "[$MESSAGE_USER_ADDRESS$]",
1268                    "[$MESSAGE_USER_NAME$]",
1269                    "[$PORTLET_NAME$]"
1270                },
1271                new String[] {
1272                    String.valueOf(company.getCompanyId()),
1273                    company.getMx(),
1274                    company.getName(),
1275                    group.getName(),
1276                    mailingListAddress,
1277                    user.getEmailAddress(),
1278                    user.getFullName(),
1279                    portletName
1280                });
1281
1282            fromAddress = StringUtil.replace(
1283                fromAddress,
1284                new String[] {
1285                    "[$COMPANY_ID$]",
1286                    "[$COMPANY_MX$]",
1287                    "[$COMPANY_NAME$]",
1288                    "[$COMMUNITY_NAME$]",
1289                    "[$MAILING_LIST_ADDRESS$]",
1290                    "[$MESSAGE_USER_ADDRESS$]",
1291                    "[$MESSAGE_USER_NAME$]",
1292                    "[$PORTLET_NAME$]"
1293                },
1294                new String[] {
1295                    String.valueOf(company.getCompanyId()),
1296                    company.getMx(),
1297                    company.getName(),
1298                    group.getName(),
1299                    mailingListAddress,
1300                    user.getEmailAddress(),
1301                    user.getFullName(),
1302                    portletName
1303                });
1304
1305            String subjectPrefix = null;
1306            String body = null;
1307            String signature = null;
1308
1309            if (update) {
1310                subjectPrefix = MBUtil.getEmailMessageUpdatedSubjectPrefix(
1311                    prefs);
1312                body = MBUtil.getEmailMessageUpdatedBody(prefs);
1313                signature = MBUtil.getEmailMessageUpdatedSignature(prefs);
1314            }
1315            else {
1316                subjectPrefix = MBUtil.getEmailMessageAddedSubjectPrefix(prefs);
1317                body = MBUtil.getEmailMessageAddedBody(prefs);
1318                signature = MBUtil.getEmailMessageAddedSignature(prefs);
1319            }
1320
1321            if (Validator.isNotNull(signature)) {
1322                body +=  "\n--\n" + signature;
1323            }
1324
1325            subjectPrefix = StringUtil.replace(
1326                subjectPrefix,
1327                new String[] {
1328                    "[$CATEGORY_NAME$]",
1329                    "[$COMPANY_ID$]",
1330                    "[$COMPANY_MX$]",
1331                    "[$COMPANY_NAME$]",
1332                    "[$COMMUNITY_NAME$]",
1333                    "[$FROM_ADDRESS$]",
1334                    "[$FROM_NAME$]",
1335                    "[$MAILING_LIST_ADDRESS$]",
1336                    "[$MESSAGE_BODY$]",
1337                    "[$MESSAGE_ID$]",
1338                    "[$MESSAGE_SUBJECT$]",
1339                    "[$MESSAGE_USER_ADDRESS$]",
1340                    "[$MESSAGE_USER_NAME$]",
1341                    "[$PORTAL_URL$]",
1342                    "[$PORTLET_NAME$]"
1343                },
1344                new String[] {
1345                    category.getName(),
1346                    String.valueOf(company.getCompanyId()),
1347                    company.getMx(),
1348                    company.getName(),
1349                    group.getName(),
1350                    fromAddress,
1351                    fromName,
1352                    mailingListAddress,
1353                    message.getBody(),
1354                    String.valueOf(message.getMessageId()),
1355                    message.getSubject(),
1356                    user.getEmailAddress(),
1357                    user.getFullName(),
1358                    company.getVirtualHost(),
1359                    portletName
1360                });
1361
1362            body = StringUtil.replace(
1363                body,
1364                new String[] {
1365                    "[$CATEGORY_NAME$]",
1366                    "[$COMPANY_ID$]",
1367                    "[$COMPANY_MX$]",
1368                    "[$COMPANY_NAME$]",
1369                    "[$COMMUNITY_NAME$]",
1370                    "[$FROM_ADDRESS$]",
1371                    "[$FROM_NAME$]",
1372                    "[$MAILING_LIST_ADDRESS$]",
1373                    "[$MESSAGE_BODY$]",
1374                    "[$MESSAGE_ID$]",
1375                    "[$MESSAGE_SUBJECT$]",
1376                    "[$MESSAGE_USER_ADDRESS$]",
1377                    "[$MESSAGE_USER_NAME$]",
1378                    "[$PORTAL_URL$]",
1379                    "[$PORTLET_NAME$]"
1380                },
1381                new String[] {
1382                    category.getName(),
1383                    String.valueOf(company.getCompanyId()),
1384                    company.getMx(),
1385                    company.getName(),
1386                    group.getName(),
1387                    fromAddress,
1388                    fromName,
1389                    mailingListAddress,
1390                    message.getBody(),
1391                    String.valueOf(message.getMessageId()),
1392                    message.getSubject(),
1393                    user.getEmailAddress(),
1394                    user.getFullName(),
1395                    company.getVirtualHost(),
1396                    portletName
1397                });
1398
1399            String subject = message.getSubject();
1400
1401            if (subject.indexOf(subjectPrefix) == -1) {
1402                subject = subjectPrefix + subject;
1403            }
1404
1405            String inReplyTo = null;
1406
1407            if (message.getParentMessageId() !=
1408                    MBMessageImpl.DEFAULT_PARENT_MESSAGE_ID) {
1409
1410                inReplyTo = MBUtil.getMailId(
1411                    company.getMx(), message.getCategoryId(),
1412                    message.getParentMessageId());
1413            }
1414
1415            MBMessageProducer.produce(
1416                new String[] {
1417                    String.valueOf(message.getCompanyId()),
1418                    String.valueOf(message.getUserId()),
1419                    StringUtil.merge(categoryIds),
1420                    String.valueOf(message.getThreadId()),
1421                    fromName, fromAddress, subject, body, replyToAddress,
1422                    messageId, inReplyTo
1423                });
1424        }
1425        catch (IOException ioe) {
1426            throw new SystemException(ioe);
1427        }
1428    }
1429
1430    protected void sendBlogsCommentsEmail(
1431            long userId, long entryId, MBMessage message,
1432            ThemeDisplay themeDisplay)
1433        throws IOException, PortalException, SystemException {
1434
1435        long companyId = message.getCompanyId();
1436
1437        if (!PrefsPropsUtil.getBoolean(
1438                companyId, PropsUtil.BLOGS_EMAIL_COMMENTS_ADDED_ENABLED)) {
1439
1440            return;
1441        }
1442
1443        BlogsEntry entry = BlogsEntryUtil.findByPrimaryKey(entryId);
1444
1445        String portalURL = PortalUtil.getPortalURL(themeDisplay);
1446        String layoutURL = PortalUtil.getLayoutURL(themeDisplay);
1447
1448        String blogsEntryURL =
1449            portalURL + layoutURL + "/blogs/" + entry.getUrlTitle();
1450
1451        User blogsUser = UserUtil.findByPrimaryKey(entry.getUserId());
1452        User commentsUser = UserUtil.findByPrimaryKey(userId);
1453
1454        String fromName = PrefsPropsUtil.getString(
1455            companyId, PropsUtil.ADMIN_EMAIL_FROM_NAME);
1456        String fromAddress = PrefsPropsUtil.getString(
1457            companyId, PropsUtil.ADMIN_EMAIL_FROM_ADDRESS);
1458
1459        String toName = blogsUser.getFullName();
1460        String toAddress = blogsUser.getEmailAddress();
1461
1462        String subject = PrefsPropsUtil.getContent(
1463            companyId, PropsUtil.BLOGS_EMAIL_COMMENTS_ADDED_SUBJECT);
1464        String body = PrefsPropsUtil.getContent(
1465            companyId, PropsUtil.BLOGS_EMAIL_COMMENTS_ADDED_BODY);
1466
1467        subject = StringUtil.replace(
1468            subject,
1469            new String[] {
1470                "[$BLOGS_COMMENTS_USER_ADDRESS$]",
1471                "[$BLOGS_COMMENTS_USER_NAME$]",
1472                "[$BLOGS_ENTRY_URL$]",
1473                "[$FROM_ADDRESS$]",
1474                "[$FROM_NAME$]",
1475                "[$TO_ADDRESS$]",
1476                "[$TO_NAME$]"
1477            },
1478            new String[] {
1479                commentsUser.getEmailAddress(),
1480                commentsUser.getFullName(),
1481                blogsEntryURL,
1482                fromAddress,
1483                fromName,
1484                toAddress,
1485                toName
1486            });
1487
1488        body = StringUtil.replace(
1489            body,
1490            new String[] {
1491                "[$BLOGS_COMMENTS_USER_ADDRESS$]",
1492                "[$BLOGS_COMMENTS_USER_NAME$]",
1493                "[$BLOGS_ENTRY_URL$]",
1494                "[$FROM_ADDRESS$]",
1495                "[$FROM_NAME$]",
1496                "[$TO_ADDRESS$]",
1497                "[$TO_NAME$]"
1498            },
1499            new String[] {
1500                commentsUser.getEmailAddress(),
1501                commentsUser.getFullName(),
1502                blogsEntryURL,
1503                fromAddress,
1504                fromName,
1505                toAddress,
1506                toName
1507            });
1508
1509        InternetAddress from = new InternetAddress(fromAddress, fromName);
1510
1511        InternetAddress to = new InternetAddress(toAddress, toName);
1512
1513        MailMessage mailMessage = new MailMessage(
1514            from, to, subject, body, true);
1515
1516        MailServiceUtil.sendEmail(mailMessage);
1517    }
1518
1519    protected void updateAsset(MBMessage message, String[] tagsEntries)
1520        throws PortalException, SystemException {
1521
1522        if (tagsEntries == null) {
1523            return;
1524        }
1525
1526        TagsAssetLocalServiceUtil.updateAsset(
1527            message.getUserId(), MBMessage.class.getName(),
1528            message.getMessageId(), tagsEntries, null, null, null, null,
1529            ContentTypes.TEXT_HTML, message.getSubject(), message.getSubject(),
1530            message.getSubject(), null, 0, 0);
1531    }
1532
1533    protected void validate(String subject, String body)
1534        throws PortalException {
1535
1536        if (Validator.isNull(subject)) {
1537            throw new MessageSubjectException();
1538        }
1539
1540        if (Validator.isNull(body)) {
1541            throw new MessageBodyException();
1542        }
1543    }
1544
1545    private static Log _log =
1546        LogFactory.getLog(MBMessageLocalServiceImpl.class);
1547
1548}