001
014
015 package com.liferay.portlet.messageboards.service.impl;
016
017 import com.liferay.portal.kernel.dao.orm.QueryUtil;
018 import com.liferay.portal.kernel.exception.PortalException;
019 import com.liferay.portal.kernel.exception.SystemException;
020 import com.liferay.portal.kernel.json.JSONFactoryUtil;
021 import com.liferay.portal.kernel.json.JSONObject;
022 import com.liferay.portal.kernel.log.Log;
023 import com.liferay.portal.kernel.log.LogFactoryUtil;
024 import com.liferay.portal.kernel.parsers.bbcode.BBCodeTranslatorUtil;
025 import com.liferay.portal.kernel.repository.model.FileEntry;
026 import com.liferay.portal.kernel.repository.model.Folder;
027 import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
028 import com.liferay.portal.kernel.search.Indexable;
029 import com.liferay.portal.kernel.search.IndexableType;
030 import com.liferay.portal.kernel.search.Indexer;
031 import com.liferay.portal.kernel.search.IndexerRegistryUtil;
032 import com.liferay.portal.kernel.util.Constants;
033 import com.liferay.portal.kernel.util.ContentTypes;
034 import com.liferay.portal.kernel.util.GetterUtil;
035 import com.liferay.portal.kernel.util.ListUtil;
036 import com.liferay.portal.kernel.util.ObjectValuePair;
037 import com.liferay.portal.kernel.util.OrderByComparator;
038 import com.liferay.portal.kernel.util.ParamUtil;
039 import com.liferay.portal.kernel.util.PropsKeys;
040 import com.liferay.portal.kernel.util.StringPool;
041 import com.liferay.portal.kernel.util.StringUtil;
042 import com.liferay.portal.kernel.util.Validator;
043 import com.liferay.portal.kernel.util.WebKeys;
044 import com.liferay.portal.kernel.workflow.WorkflowConstants;
045 import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
046 import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
047 import com.liferay.portal.model.Company;
048 import com.liferay.portal.model.Group;
049 import com.liferay.portal.model.ModelHintsUtil;
050 import com.liferay.portal.model.ResourceConstants;
051 import com.liferay.portal.model.User;
052 import com.liferay.portal.portletfilerepository.PortletFileRepositoryUtil;
053 import com.liferay.portal.security.auth.PrincipalException;
054 import com.liferay.portal.service.ServiceContext;
055 import com.liferay.portal.service.ServiceContextUtil;
056 import com.liferay.portal.theme.ThemeDisplay;
057 import com.liferay.portal.util.Portal;
058 import com.liferay.portal.util.PortalUtil;
059 import com.liferay.portal.util.PortletKeys;
060 import com.liferay.portal.util.PrefsPropsUtil;
061 import com.liferay.portal.util.PropsValues;
062 import com.liferay.portal.util.SubscriptionSender;
063 import com.liferay.portlet.PortletURLFactoryUtil;
064 import com.liferay.portlet.asset.model.AssetEntry;
065 import com.liferay.portlet.asset.model.AssetLinkConstants;
066 import com.liferay.portlet.blogs.model.BlogsEntry;
067 import com.liferay.portlet.blogs.util.LinkbackProducerUtil;
068 import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
069 import com.liferay.portlet.messageboards.MessageBodyException;
070 import com.liferay.portlet.messageboards.MessageSubjectException;
071 import com.liferay.portlet.messageboards.NoSuchDiscussionException;
072 import com.liferay.portlet.messageboards.NoSuchThreadException;
073 import com.liferay.portlet.messageboards.RequiredMessageException;
074 import com.liferay.portlet.messageboards.model.MBCategory;
075 import com.liferay.portlet.messageboards.model.MBCategoryConstants;
076 import com.liferay.portlet.messageboards.model.MBDiscussion;
077 import com.liferay.portlet.messageboards.model.MBMessage;
078 import com.liferay.portlet.messageboards.model.MBMessageConstants;
079 import com.liferay.portlet.messageboards.model.MBMessageDisplay;
080 import com.liferay.portlet.messageboards.model.MBThread;
081 import com.liferay.portlet.messageboards.model.MBThreadConstants;
082 import com.liferay.portlet.messageboards.model.impl.MBCategoryImpl;
083 import com.liferay.portlet.messageboards.model.impl.MBMessageDisplayImpl;
084 import com.liferay.portlet.messageboards.service.base.MBMessageLocalServiceBaseImpl;
085 import com.liferay.portlet.messageboards.social.MBActivityKeys;
086 import com.liferay.portlet.messageboards.util.MBMessageDateDigesterUtil;
087 import com.liferay.portlet.messageboards.util.MBSubscriptionSender;
088 import com.liferay.portlet.messageboards.util.MBUtil;
089 import com.liferay.portlet.messageboards.util.MailingListThreadLocal;
090 import com.liferay.portlet.messageboards.util.comparator.MessageCreateDateComparator;
091 import com.liferay.portlet.messageboards.util.comparator.MessageThreadComparator;
092 import com.liferay.portlet.messageboards.util.comparator.ThreadLastPostDateComparator;
093 import com.liferay.portlet.social.model.SocialActivity;
094 import com.liferay.portlet.social.model.SocialActivityConstants;
095 import com.liferay.portlet.trash.util.TrashUtil;
096 import com.liferay.util.SerializableUtil;
097
098 import java.io.File;
099 import java.io.FileInputStream;
100 import java.io.FileNotFoundException;
101 import java.io.InputStream;
102
103 import java.util.ArrayList;
104 import java.util.Collections;
105 import java.util.Comparator;
106 import java.util.Date;
107 import java.util.List;
108
109 import javax.portlet.PortletPreferences;
110 import javax.portlet.PortletRequest;
111 import javax.portlet.PortletURL;
112
113 import javax.servlet.ServletContext;
114 import javax.servlet.http.HttpServletRequest;
115 import javax.servlet.http.HttpSession;
116
117 import net.htmlparser.jericho.Source;
118 import net.htmlparser.jericho.StartTag;
119
120
128 public class MBMessageLocalServiceImpl extends MBMessageLocalServiceBaseImpl {
129
130 @Override
131 public MBMessage addDiscussionMessage(
132 long userId, String userName, long groupId, String className,
133 long classPK, int workflowAction)
134 throws PortalException, SystemException {
135
136 long threadId = 0;
137 long parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
138 String subject = String.valueOf(classPK);
139 String body = subject;
140
141 ServiceContext serviceContext = new ServiceContext();
142
143 serviceContext.setWorkflowAction(workflowAction);
144
145 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
146
147 WorkflowThreadLocal.setEnabled(false);
148
149 try {
150 return addDiscussionMessage(
151 userId, userName, groupId, className, classPK, threadId,
152 parentMessageId, subject, body, serviceContext);
153 }
154 finally {
155 WorkflowThreadLocal.setEnabled(workflowEnabled);
156 }
157 }
158
159 @Override
160 public MBMessage addDiscussionMessage(
161 long userId, String userName, long groupId, String className,
162 long classPK, long threadId, long parentMessageId, String subject,
163 String body, ServiceContext serviceContext)
164 throws PortalException, SystemException {
165
166
167
168 long categoryId = MBCategoryConstants.DISCUSSION_CATEGORY_ID;
169
170 if (Validator.isNull(subject)) {
171 if (Validator.isNotNull(body)) {
172 int pos = Math.min(body.length(), 50);
173
174 subject = body.substring(0, pos) + "...";
175 }
176 else {
177 throw new MessageBodyException();
178 }
179 }
180
181 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
182 Collections.emptyList();
183 boolean anonymous = false;
184 double priority = 0.0;
185 boolean allowPingbacks = false;
186
187 serviceContext.setAddGroupPermissions(true);
188 serviceContext.setAddGuestPermissions(true);
189 serviceContext.setAttribute("className", className);
190 serviceContext.setAttribute("classPK", String.valueOf(classPK));
191
192 MBMessage message = addMessage(
193 userId, userName, groupId, categoryId, threadId, parentMessageId,
194 subject, body, MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs,
195 anonymous, priority, allowPingbacks, serviceContext);
196
197
198
199 if (parentMessageId == MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
200 long classNameId = PortalUtil.getClassNameId(className);
201
202 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
203 classNameId, classPK);
204
205 if (discussion == null) {
206 mbDiscussionLocalService.addDiscussion(
207 userId, classNameId, classPK, message.getThreadId(),
208 serviceContext);
209 }
210 }
211
212 return message;
213 }
214
215 @Override
216 public MBMessage addMessage(
217 long userId, String userName, long groupId, long categoryId,
218 long threadId, long parentMessageId, String subject, String body,
219 String format,
220 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
221 boolean anonymous, double priority, boolean allowPingbacks,
222 ServiceContext serviceContext)
223 throws PortalException, SystemException {
224
225
226
227 User user = userPersistence.findByPrimaryKey(userId);
228 userName = user.isDefaultUser() ? userName : user.getFullName();
229 subject = ModelHintsUtil.trimString(
230 MBMessage.class.getName(), "subject", subject);
231
232 if (!MBUtil.isValidMessageFormat(format)) {
233 format = "html";
234 }
235
236 PortletPreferences preferences =
237 ServiceContextUtil.getPortletPreferences(serviceContext);
238
239 if (preferences != null) {
240 if (!MBUtil.isAllowAnonymousPosting(preferences)) {
241 if (anonymous || user.isDefaultUser()) {
242 throw new PrincipalException();
243 }
244 }
245 }
246
247 if (user.isDefaultUser()) {
248 anonymous = true;
249 }
250
251 Date now = new Date();
252
253 long messageId = counterLocalService.increment();
254
255 subject = getSubject(subject, body);
256 body = getBody(subject, body);
257
258 body = SanitizerUtil.sanitize(
259 user.getCompanyId(), groupId, userId, MBMessage.class.getName(),
260 messageId, "text/" + format, body);
261
262 validate(subject, body);
263
264 MBMessage message = mbMessagePersistence.create(messageId);
265
266 message.setUuid(serviceContext.getUuid());
267 message.setGroupId(groupId);
268 message.setCompanyId(user.getCompanyId());
269 message.setUserId(user.getUserId());
270 message.setUserName(userName);
271 message.setCreateDate(serviceContext.getCreateDate(now));
272 message.setModifiedDate(serviceContext.getModifiedDate(now));
273
274 if (threadId > 0) {
275 message.setThreadId(threadId);
276 }
277
278 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
279 message.setPriority(priority);
280 }
281
282 message.setAllowPingbacks(allowPingbacks);
283 message.setStatus(WorkflowConstants.STATUS_DRAFT);
284 message.setStatusByUserId(user.getUserId());
285 message.setStatusByUserName(userName);
286 message.setStatusDate(serviceContext.getModifiedDate(now));
287
288
289
290 if (parentMessageId != MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
291 MBMessage parentMessage = mbMessagePersistence.fetchByPrimaryKey(
292 parentMessageId);
293
294 if (parentMessage == null) {
295 parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
296 }
297 }
298
299 MBThread thread = null;
300
301 if (threadId > 0) {
302 thread = mbThreadPersistence.fetchByPrimaryKey(threadId);
303 }
304
305 if (thread == null) {
306 if (parentMessageId ==
307 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
308
309 thread = mbThreadLocalService.addThread(
310 categoryId, message, serviceContext);
311 }
312 else {
313 throw new NoSuchThreadException("{threadId=" + threadId + "}");
314 }
315 }
316
317 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
318 (thread.getPriority() != priority)) {
319
320 thread.setPriority(priority);
321
322 mbThreadPersistence.update(thread);
323
324 updatePriorities(thread.getThreadId(), priority);
325 }
326
327
328
329 message.setCategoryId(categoryId);
330 message.setThreadId(thread.getThreadId());
331 message.setRootMessageId(thread.getRootMessageId());
332 message.setParentMessageId(parentMessageId);
333 message.setSubject(subject);
334 message.setBody(body);
335 message.setFormat(format);
336 message.setAnonymous(anonymous);
337
338 if (message.isDiscussion()) {
339 long classNameId = PortalUtil.getClassNameId(
340 (String)serviceContext.getAttribute("className"));
341 long classPK = ParamUtil.getLong(serviceContext, "classPK");
342
343 message.setClassNameId(classNameId);
344 message.setClassPK(classPK);
345 }
346
347 message.setExpandoBridgeAttributes(serviceContext);
348
349 mbMessagePersistence.update(message);
350
351
352
353 if ((parentMessageId !=
354 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) &&
355 GetterUtil.getBoolean(
356 serviceContext.getAttribute("propagatePermissions"))) {
357
358 MBUtil.propagatePermissions(
359 message.getCompanyId(), groupId, parentMessageId,
360 serviceContext);
361 }
362
363 if (!message.isDiscussion()) {
364 if (user.isDefaultUser()) {
365 addMessageResources(message, true, true);
366 }
367 else if (serviceContext.isAddGroupPermissions() ||
368 serviceContext.isAddGuestPermissions()) {
369
370 addMessageResources(
371 message, serviceContext.isAddGroupPermissions(),
372 serviceContext.isAddGuestPermissions());
373 }
374 else {
375 addMessageResources(
376 message, serviceContext.getGroupPermissions(),
377 serviceContext.getGuestPermissions());
378 }
379 }
380
381
382
383 if (!inputStreamOVPs.isEmpty()) {
384 Folder folder = message.addAttachmentsFolder();
385
386 PortletFileRepositoryUtil.addPortletFileEntries(
387 message.getGroupId(), userId, MBMessage.class.getName(),
388 message.getMessageId(), PortletKeys.MESSAGE_BOARDS,
389 folder.getFolderId(), inputStreamOVPs);
390 }
391
392
393
394 updateAsset(
395 userId, message, serviceContext.getAssetCategoryIds(),
396 serviceContext.getAssetTagNames(),
397 serviceContext.getAssetLinkEntryIds(),
398 serviceContext.isAssetEntryVisible());
399
400
401
402 WorkflowHandlerRegistryUtil.startWorkflowInstance(
403 user.getCompanyId(), groupId, userId,
404 message.getWorkflowClassName(), message.getMessageId(), message,
405 serviceContext);
406
407 return message;
408 }
409
410 @Override
411 public MBMessage addMessage(
412 long userId, String userName, long groupId, long categoryId,
413 String subject, String body, String fileName, File file,
414 ServiceContext serviceContext)
415 throws FileNotFoundException, PortalException, SystemException {
416
417 return addMessage(
418 userId, userName, groupId, categoryId, subject, body,
419 MBMessageConstants.DEFAULT_FORMAT, fileName, file, false, 0.0,
420 false, serviceContext);
421 }
422
423 @Override
424 public MBMessage addMessage(
425 long userId, String userName, long groupId, long categoryId,
426 String subject, String body, String format,
427 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
428 boolean anonymous, double priority, boolean allowPingbacks,
429 ServiceContext serviceContext)
430 throws PortalException, SystemException {
431
432 long threadId = 0;
433 long parentMessageId = 0;
434
435 return addMessage(
436 userId, userName, groupId, categoryId, threadId, parentMessageId,
437 subject, body, format, inputStreamOVPs, anonymous, priority,
438 allowPingbacks, serviceContext);
439 }
440
441 @Override
442 public MBMessage addMessage(
443 long userId, String userName, long groupId, long categoryId,
444 String subject, String body, String format, String fileName,
445 File file, boolean anonymous, double priority,
446 boolean allowPingbacks, ServiceContext serviceContext)
447 throws FileNotFoundException, PortalException, SystemException {
448
449 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
450 new ArrayList<ObjectValuePair<String, InputStream>>(1);
451
452 InputStream inputStream = new FileInputStream(file);
453
454 ObjectValuePair<String, InputStream> inputStreamOVP =
455 new ObjectValuePair<String, InputStream>(fileName, inputStream);
456
457 inputStreamOVPs.add(inputStreamOVP);
458
459 return addMessage(
460 userId, userName, groupId, categoryId, 0, 0, subject, body, format,
461 inputStreamOVPs, anonymous, priority, allowPingbacks,
462 serviceContext);
463 }
464
465 @Override
466 public MBMessage addMessage(
467 long userId, String userName, long categoryId, String subject,
468 String body, ServiceContext serviceContext)
469 throws PortalException, SystemException {
470
471 MBCategory category = mbCategoryPersistence.findByPrimaryKey(
472 categoryId);
473
474 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
475 Collections.emptyList();
476
477 return addMessage(
478 userId, userName, category.getGroupId(), categoryId, 0, 0, subject,
479 body, MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, false,
480 0.0, false, serviceContext);
481 }
482
483 @Override
484 public void addMessageResources(
485 long messageId, boolean addGroupPermissions,
486 boolean addGuestPermissions)
487 throws PortalException, SystemException {
488
489 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
490
491 addMessageResources(message, addGroupPermissions, addGuestPermissions);
492 }
493
494 @Override
495 public void addMessageResources(
496 long messageId, String[] groupPermissions,
497 String[] guestPermissions)
498 throws PortalException, SystemException {
499
500 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
501
502 addMessageResources(message, groupPermissions, guestPermissions);
503 }
504
505 @Override
506 public void addMessageResources(
507 MBMessage message, boolean addGroupPermissions,
508 boolean addGuestPermissions)
509 throws PortalException, SystemException {
510
511 resourceLocalService.addResources(
512 message.getCompanyId(), message.getGroupId(), message.getUserId(),
513 MBMessage.class.getName(), message.getMessageId(), false,
514 addGroupPermissions, addGuestPermissions);
515 }
516
517 @Override
518 public void addMessageResources(
519 MBMessage message, String[] groupPermissions,
520 String[] guestPermissions)
521 throws PortalException, SystemException {
522
523 resourceLocalService.addModelResources(
524 message.getCompanyId(), message.getGroupId(), message.getUserId(),
525 MBMessage.class.getName(), message.getMessageId(), groupPermissions,
526 guestPermissions);
527 }
528
529 @Indexable(type = IndexableType.DELETE)
530 @Override
531 public MBMessage deleteDiscussionMessage(long messageId)
532 throws PortalException, SystemException {
533
534 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
535
536 deleteDiscussionSocialActivities(BlogsEntry.class.getName(), message);
537
538 return deleteMessage(message);
539 }
540
541 @Override
542 public void deleteDiscussionMessages(String className, long classPK)
543 throws PortalException, SystemException {
544
545 try {
546 long classNameId = PortalUtil.getClassNameId(className);
547
548 MBDiscussion discussion = mbDiscussionPersistence.findByC_C(
549 classNameId, classPK);
550
551 List<MBMessage> messages = mbMessagePersistence.findByT_P(
552 discussion.getThreadId(),
553 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, 0, 1);
554
555 if (!messages.isEmpty()) {
556 MBMessage message = messages.get(0);
557
558 deleteDiscussionSocialActivities(
559 BlogsEntry.class.getName(), message);
560
561 mbThreadLocalService.deleteThread(message.getThreadId());
562 }
563
564 mbDiscussionPersistence.remove(discussion);
565 }
566 catch (NoSuchDiscussionException nsde) {
567 if (_log.isDebugEnabled()) {
568 _log.debug(nsde.getMessage());
569 }
570 }
571 }
572
573 @Indexable(type = IndexableType.DELETE)
574 @Override
575 public MBMessage deleteMessage(long messageId)
576 throws PortalException, SystemException {
577
578 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
579
580 return deleteMessage(message);
581 }
582
583 @Indexable(type = IndexableType.DELETE)
584 @Override
585 public MBMessage deleteMessage(MBMessage message)
586 throws PortalException, SystemException {
587
588
589
590 long folderId = message.getAttachmentsFolderId();
591
592 if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
593 PortletFileRepositoryUtil.deleteFolder(folderId);
594 }
595
596
597
598 int count = mbMessagePersistence.countByThreadId(message.getThreadId());
599
600 if (count == 1) {
601
602
603
604 long threadAttachmentsFolderId =
605 message.getThreadAttachmentsFolderId();
606
607 if (threadAttachmentsFolderId !=
608 DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
609
610 PortletFileRepositoryUtil.deleteFolder(
611 threadAttachmentsFolderId);
612 }
613
614
615
616 subscriptionLocalService.deleteSubscriptions(
617 message.getCompanyId(), MBThread.class.getName(),
618 message.getThreadId());
619
620
621
622 MBThread thread = mbThreadPersistence.findByPrimaryKey(
623 message.getThreadId());
624
625 mbThreadPersistence.remove(thread);
626
627
628
629 if ((message.getCategoryId() !=
630 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
631 (message.getCategoryId() !=
632 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
633
634 MBUtil.updateCategoryStatistics(
635 message.getCompanyId(), message.getCategoryId());
636 }
637
638
639
640 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
641 MBThread.class);
642
643 indexer.delete(thread);
644 }
645 else {
646 MBThread thread = mbThreadPersistence.findByPrimaryKey(
647 message.getThreadId());
648
649
650
651 if (thread.getRootMessageId() == message.getMessageId()) {
652 List<MBMessage> childrenMessages =
653 mbMessagePersistence.findByT_P(
654 message.getThreadId(), message.getMessageId());
655
656 if (childrenMessages.size() > 1) {
657 throw new RequiredMessageException(
658 String.valueOf(message.getMessageId()));
659 }
660 else if (childrenMessages.size() == 1) {
661 MBMessage childMessage = childrenMessages.get(0);
662
663 childMessage.setRootMessageId(childMessage.getMessageId());
664 childMessage.setParentMessageId(
665 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
666
667 mbMessagePersistence.update(childMessage);
668
669 List<MBMessage> repliesMessages =
670 mbMessagePersistence.findByThreadReplies(
671 message.getThreadId());
672
673 for (MBMessage repliesMessage : repliesMessages) {
674 repliesMessage.setRootMessageId(
675 childMessage.getMessageId());
676
677 mbMessagePersistence.update(repliesMessage);
678 }
679
680 thread.setRootMessageId(childMessage.getMessageId());
681 thread.setRootMessageUserId(childMessage.getUserId());
682
683 mbThreadPersistence.update(thread);
684 }
685 }
686
687
688
689 else {
690 List<MBMessage> childrenMessages =
691 mbMessagePersistence.findByT_P(
692 message.getThreadId(), message.getMessageId());
693
694
695
696 if (!childrenMessages.isEmpty()) {
697 for (MBMessage childMessage : childrenMessages) {
698 childMessage.setParentMessageId(
699 message.getParentMessageId());
700
701 mbMessagePersistence.update(childMessage);
702 }
703 }
704 else {
705 MessageCreateDateComparator comparator =
706 new MessageCreateDateComparator(true);
707
708 MBMessage lastMessage =
709 mbMessagePersistence.fetchByT_S_Last(
710 thread.getThreadId(),
711 WorkflowConstants.STATUS_APPROVED, comparator);
712
713 if ((lastMessage != null) &&
714 (message.getMessageId() ==
715 lastMessage.getMessageId())) {
716
717 MBMessage parentMessage =
718 mbMessagePersistence.findByPrimaryKey(
719 message.getParentMessageId());
720
721 thread.setLastPostByUserId(parentMessage.getUserId());
722 thread.setLastPostDate(parentMessage.getModifiedDate());
723
724 mbThreadPersistence.update(thread);
725 }
726 }
727 }
728
729
730
731 if (message.isApproved()) {
732 MBUtil.updateThreadMessageCount(
733 thread.getCompanyId(), thread.getThreadId());
734 }
735
736
737
738 if ((message.getCategoryId() !=
739 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
740 (message.getCategoryId() !=
741 MBCategoryConstants.DISCUSSION_CATEGORY_ID) &&
742 !message.isDraft()) {
743
744 MBUtil.updateCategoryMessageCount(
745 message.getCompanyId(), message.getCategoryId());
746 }
747
748
749
750 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
751 MBThread.class);
752
753 indexer.reindex(thread);
754 }
755
756
757
758 assetEntryLocalService.deleteEntry(
759 message.getWorkflowClassName(), message.getMessageId());
760
761
762
763 expandoRowLocalService.deleteRows(message.getMessageId());
764
765
766
767 ratingsStatsLocalService.deleteStats(
768 message.getWorkflowClassName(), message.getMessageId());
769
770
771
772 if (!message.isDiscussion()) {
773 resourceLocalService.deleteResource(
774 message.getCompanyId(), message.getWorkflowClassName(),
775 ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
776 }
777
778
779
780 mbMessagePersistence.remove(message);
781
782
783
784 if (!message.isDiscussion()) {
785 mbStatsUserLocalService.updateStatsUser(
786 message.getGroupId(), message.getUserId());
787 }
788
789
790
791 workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
792 message.getCompanyId(), message.getGroupId(),
793 message.getWorkflowClassName(), message.getMessageId());
794
795 return message;
796 }
797
798 @Override
799 public void deleteMessageAttachment(long messageId, String fileName)
800 throws PortalException, SystemException {
801
802 MBMessage message = getMessage(messageId);
803
804 long folderId = message.getAttachmentsFolderId();
805
806 if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
807 return;
808 }
809
810 PortletFileRepositoryUtil.deletePortletFileEntry(
811 message.getGroupId(), folderId, fileName);
812 }
813
814 @Override
815 public void deleteMessageAttachments(long messageId)
816 throws PortalException, SystemException {
817
818 MBMessage message = getMessage(messageId);
819
820 long folderId = message.getAttachmentsFolderId();
821
822 if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
823 return;
824 }
825
826 PortletFileRepositoryUtil.deletePortletFileEntries(
827 message.getGroupId(), folderId);
828 }
829
830 @Override
831 public List<MBMessage> getCategoryMessages(
832 long groupId, long categoryId, int status, int start, int end)
833 throws SystemException {
834
835 if (status == WorkflowConstants.STATUS_ANY) {
836 return mbMessagePersistence.findByG_C(
837 groupId, categoryId, start, end);
838 }
839 else {
840 return mbMessagePersistence.findByG_C_S(
841 groupId, categoryId, status, start, end);
842 }
843 }
844
845 @Override
846 public List<MBMessage> getCategoryMessages(
847 long groupId, long categoryId, int status, int start, int end,
848 OrderByComparator obc)
849 throws SystemException {
850
851 if (status == WorkflowConstants.STATUS_ANY) {
852 return mbMessagePersistence.findByG_C(
853 groupId, categoryId, start, end, obc);
854 }
855 else {
856 return mbMessagePersistence.findByG_C_S(
857 groupId, categoryId, status, start, end, obc);
858 }
859 }
860
861 @Override
862 public int getCategoryMessagesCount(
863 long groupId, long categoryId, int status)
864 throws SystemException {
865
866 if (status == WorkflowConstants.STATUS_ANY) {
867 return mbMessagePersistence.countByG_C(groupId, categoryId);
868 }
869 else {
870 return mbMessagePersistence.countByG_C_S(
871 groupId, categoryId, status);
872 }
873 }
874
875 @Override
876 public List<MBMessage> getCompanyMessages(
877 long companyId, int status, int start, int end)
878 throws SystemException {
879
880 if (status == WorkflowConstants.STATUS_ANY) {
881 return mbMessagePersistence.findByCompanyId(companyId, start, end);
882 }
883 else {
884 return mbMessagePersistence.findByC_S(
885 companyId, status, start, end);
886 }
887 }
888
889 @Override
890 public List<MBMessage> getCompanyMessages(
891 long companyId, int status, int start, int end,
892 OrderByComparator obc)
893 throws SystemException {
894
895 if (status == WorkflowConstants.STATUS_ANY) {
896 return mbMessagePersistence.findByCompanyId(
897 companyId, start, end, obc);
898 }
899 else {
900 return mbMessagePersistence.findByC_S(
901 companyId, status, start, end, obc);
902 }
903 }
904
905 @Override
906 public int getCompanyMessagesCount(long companyId, int status)
907 throws SystemException {
908
909 if (status == WorkflowConstants.STATUS_ANY) {
910 return mbMessagePersistence.countByCompanyId(companyId);
911 }
912 else {
913 return mbMessagePersistence.countByC_S(companyId, status);
914 }
915 }
916
917 @Override
918 public MBMessageDisplay getDiscussionMessageDisplay(
919 long userId, long groupId, String className, long classPK,
920 int status)
921 throws PortalException, SystemException {
922
923 return getDiscussionMessageDisplay(
924 userId, groupId, className, classPK, status,
925 MBThreadConstants.THREAD_VIEW_COMBINATION);
926 }
927
928 @Override
929 public MBMessageDisplay getDiscussionMessageDisplay(
930 long userId, long groupId, String className, long classPK,
931 int status, String threadView)
932 throws PortalException, SystemException {
933
934 long classNameId = PortalUtil.getClassNameId(className);
935
936 MBMessage message = null;
937
938 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
939 classNameId, classPK);
940
941 if (discussion != null) {
942 List<MBMessage> messages = mbMessagePersistence.findByT_P(
943 discussion.getThreadId(),
944 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
945
946 message = messages.get(0);
947 }
948 else {
949 boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
950
951 WorkflowThreadLocal.setEnabled(false);
952
953 try {
954 String subject = String.valueOf(classPK);
955
956
957 message = addDiscussionMessage(
958 userId, null, groupId, className, classPK, 0,
959 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, subject,
960 subject, new ServiceContext());
961 }
962 catch (SystemException se) {
963 if (_log.isWarnEnabled()) {
964 _log.warn(
965 "Add failed, fetch {threadId=0, parentMessageId=" +
966 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID + "}");
967 }
968
969 List<MBMessage> messages = mbMessagePersistence.findByT_P(
970 0, MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID);
971
972 if (messages.isEmpty()) {
973 throw se;
974 }
975
976 message = messages.get(0);
977 }
978 finally {
979 WorkflowThreadLocal.setEnabled(workflowEnabled);
980 }
981 }
982
983 return getMessageDisplay(userId, message, status, threadView, false);
984 }
985
986 @Override
987 public int getDiscussionMessagesCount(
988 long classNameId, long classPK, int status)
989 throws SystemException {
990
991 MBDiscussion discussion = mbDiscussionPersistence.fetchByC_C(
992 classNameId, classPK);
993
994 if (discussion == null) {
995 return 0;
996 }
997
998 int count = 0;
999
1000 if (status == WorkflowConstants.STATUS_ANY) {
1001 count = mbMessagePersistence.countByThreadId(
1002 discussion.getThreadId());
1003 }
1004 else {
1005 count = mbMessagePersistence.countByT_S(
1006 discussion.getThreadId(), status);
1007 }
1008
1009 if (count >= 1) {
1010 return count - 1;
1011 }
1012 else {
1013 return 0;
1014 }
1015 }
1016
1017 @Override
1018 public int getDiscussionMessagesCount(
1019 String className, long classPK, int status)
1020 throws SystemException {
1021
1022 long classNameId = PortalUtil.getClassNameId(className);
1023
1024 return getDiscussionMessagesCount(classNameId, classPK, status);
1025 }
1026
1027 @Override
1028 public List<MBDiscussion> getDiscussions(String className)
1029 throws SystemException {
1030
1031 long classNameId = PortalUtil.getClassNameId(className);
1032
1033 return mbDiscussionPersistence.findByClassNameId(classNameId);
1034 }
1035
1036 @Override
1037 public List<MBMessage> getGroupMessages(
1038 long groupId, int status, int start, int end)
1039 throws SystemException {
1040
1041 if (status == WorkflowConstants.STATUS_ANY) {
1042 return mbMessagePersistence.findByGroupId(groupId, start, end);
1043 }
1044 else {
1045 return mbMessagePersistence.findByG_S(groupId, status, start, end);
1046 }
1047 }
1048
1049 @Override
1050 public List<MBMessage> getGroupMessages(
1051 long groupId, int status, int start, int end, OrderByComparator obc)
1052 throws SystemException {
1053
1054 if (status == WorkflowConstants.STATUS_ANY) {
1055 return mbMessagePersistence.findByGroupId(groupId, start, end, obc);
1056 }
1057 else {
1058 return mbMessagePersistence.findByG_S(
1059 groupId, status, start, end, obc);
1060 }
1061 }
1062
1063 @Override
1064 public List<MBMessage> getGroupMessages(
1065 long groupId, long userId, int status, int start, int end)
1066 throws SystemException {
1067
1068 if (status == WorkflowConstants.STATUS_ANY) {
1069 return mbMessagePersistence.findByG_U(groupId, userId, start, end);
1070 }
1071 else {
1072 return mbMessagePersistence.findByG_U_S(
1073 groupId, userId, status, start, end);
1074 }
1075 }
1076
1077 @Override
1078 public List<MBMessage> getGroupMessages(
1079 long groupId, long userId, int status, int start, int end,
1080 OrderByComparator obc)
1081 throws SystemException {
1082
1083 if (status == WorkflowConstants.STATUS_ANY) {
1084 return mbMessagePersistence.findByG_U(
1085 groupId, userId, start, end, obc);
1086 }
1087 else {
1088 return mbMessagePersistence.findByG_U_S(
1089 groupId, userId, status, start, end, obc);
1090 }
1091 }
1092
1093 @Override
1094 public int getGroupMessagesCount(long groupId, int status)
1095 throws SystemException {
1096
1097 if (status == WorkflowConstants.STATUS_ANY) {
1098 return mbMessagePersistence.countByGroupId(groupId);
1099 }
1100 else {
1101 return mbMessagePersistence.countByG_S(groupId, status);
1102 }
1103 }
1104
1105 @Override
1106 public int getGroupMessagesCount(long groupId, long userId, int status)
1107 throws SystemException {
1108
1109 if (status == WorkflowConstants.STATUS_ANY) {
1110 return mbMessagePersistence.countByG_U(groupId, userId);
1111 }
1112 else {
1113 return mbMessagePersistence.countByG_U_S(groupId, userId, status);
1114 }
1115 }
1116
1117 @Override
1118 public MBMessage getMessage(long messageId)
1119 throws PortalException, SystemException {
1120
1121 return mbMessagePersistence.findByPrimaryKey(messageId);
1122 }
1123
1124 @Override
1125 public MBMessageDisplay getMessageDisplay(
1126 long userId, long messageId, int status, String threadView,
1127 boolean includePrevAndNext)
1128 throws PortalException, SystemException {
1129
1130 MBMessage message = getMessage(messageId);
1131
1132 return getMessageDisplay(
1133 userId, message, status, threadView, includePrevAndNext);
1134 }
1135
1136 @Override
1137 public MBMessageDisplay getMessageDisplay(
1138 long userId, MBMessage message, int status, String threadView,
1139 boolean includePrevAndNext)
1140 throws PortalException, SystemException {
1141
1142 MBCategory category = null;
1143
1144 if ((message.getCategoryId() !=
1145 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
1146 (message.getCategoryId() !=
1147 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
1148
1149 category = mbCategoryPersistence.findByPrimaryKey(
1150 message.getCategoryId());
1151 }
1152 else {
1153 category = new MBCategoryImpl();
1154
1155 category.setCategoryId(message.getCategoryId());
1156 category.setDisplayStyle(MBCategoryConstants.DEFAULT_DISPLAY_STYLE);
1157 }
1158
1159 MBMessage parentMessage = null;
1160
1161 if (message.isReply()) {
1162 parentMessage = mbMessagePersistence.findByPrimaryKey(
1163 message.getParentMessageId());
1164 }
1165
1166 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1167 message.getThreadId());
1168
1169 if (message.isApproved() && !message.isDiscussion()) {
1170 mbThreadLocalService.incrementViewCounter(thread.getThreadId(), 1);
1171
1172 if (thread.getRootMessageUserId() != userId) {
1173 MBMessage rootMessage = mbMessagePersistence.findByPrimaryKey(
1174 thread.getRootMessageId());
1175
1176 socialActivityLocalService.addActivity(
1177 userId, rootMessage.getGroupId(), MBMessage.class.getName(),
1178 rootMessage.getMessageId(),
1179 SocialActivityConstants.TYPE_VIEW, StringPool.BLANK, 0);
1180 }
1181 }
1182
1183 MBThread previousThread = null;
1184 MBThread nextThread = null;
1185
1186 if (includePrevAndNext) {
1187 ThreadLastPostDateComparator comparator =
1188 new ThreadLastPostDateComparator(false);
1189
1190 MBThread[] prevAndNextThreads = null;
1191
1192 if (status == WorkflowConstants.STATUS_ANY) {
1193 prevAndNextThreads =
1194 mbThreadFinder.filterFindByG_C_NotS_PrevAndNext(
1195 message.getThreadId(), message.getGroupId(),
1196 message.getCategoryId(),
1197 WorkflowConstants.STATUS_IN_TRASH, comparator);
1198 }
1199 else {
1200 prevAndNextThreads =
1201 mbThreadFinder.filterFindByG_C_S_PrevAndNext(
1202 message.getThreadId(), message.getGroupId(),
1203 message.getCategoryId(), status, comparator);
1204 }
1205
1206 previousThread = prevAndNextThreads[0];
1207 nextThread = prevAndNextThreads[2];
1208 }
1209
1210 return new MBMessageDisplayImpl(
1211 message, parentMessage, category, thread, previousThread,
1212 nextThread, status, threadView, this);
1213 }
1214
1215 @Override
1216 public List<MBMessage> getMessages(
1217 String className, long classPK, int status)
1218 throws SystemException {
1219
1220 long classNameId = PortalUtil.getClassNameId(className);
1221
1222 if (status == WorkflowConstants.STATUS_ANY) {
1223 return mbMessagePersistence.findByC_C(classNameId, classPK);
1224 }
1225 else {
1226 return mbMessagePersistence.findByC_C_S(
1227 classNameId, classPK, status);
1228 }
1229 }
1230
1231 @Override
1232 public List<MBMessage> getNoAssetMessages() throws SystemException {
1233 return mbMessageFinder.findByNoAssets();
1234 }
1235
1236 @Override
1237 public int getPositionInThread(long messageId)
1238 throws PortalException, SystemException {
1239
1240 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1241
1242 return mbMessageFinder.countByC_T(
1243 message.getCreateDate(), message.getThreadId());
1244 }
1245
1246 @Override
1247 public List<MBMessage> getThreadMessages(long threadId, int status)
1248 throws SystemException {
1249
1250 return getThreadMessages(
1251 threadId, status, new MessageThreadComparator());
1252 }
1253
1254 @Override
1255 public List<MBMessage> getThreadMessages(
1256 long threadId, int status, Comparator<MBMessage> comparator)
1257 throws SystemException {
1258
1259 List<MBMessage> messages = null;
1260
1261 if (status == WorkflowConstants.STATUS_ANY) {
1262 messages = mbMessagePersistence.findByThreadId(threadId);
1263 }
1264 else {
1265 messages = mbMessagePersistence.findByT_S(threadId, status);
1266 }
1267
1268 return ListUtil.sort(messages, comparator);
1269 }
1270
1271 @Override
1272 public List<MBMessage> getThreadMessages(
1273 long threadId, int status, int start, int end)
1274 throws SystemException {
1275
1276 if (status == WorkflowConstants.STATUS_ANY) {
1277 return mbMessagePersistence.findByThreadId(threadId, start, end);
1278 }
1279 else {
1280 return mbMessagePersistence.findByT_S(threadId, status, start, end);
1281 }
1282 }
1283
1284 @Override
1285 public int getThreadMessagesCount(long threadId, int status)
1286 throws SystemException {
1287
1288 if (status == WorkflowConstants.STATUS_ANY) {
1289 return mbMessagePersistence.countByThreadId(threadId);
1290 }
1291 else {
1292 return mbMessagePersistence.countByT_S(threadId, status);
1293 }
1294 }
1295
1296 @Override
1297 public List<MBMessage> getThreadRepliesMessages(
1298 long threadId, int status, int start, int end)
1299 throws SystemException {
1300
1301 if (status == WorkflowConstants.STATUS_ANY) {
1302 return mbMessagePersistence.findByThreadReplies(
1303 threadId, start, end);
1304 }
1305 else {
1306 return mbMessagePersistence.findByTR_S(
1307 threadId, status, start, end);
1308 }
1309 }
1310
1311 @Override
1312 public List<MBMessage> getUserDiscussionMessages(
1313 long userId, long classNameId, long classPK, int status, int start,
1314 int end, OrderByComparator obc)
1315 throws SystemException {
1316
1317 if (status == WorkflowConstants.STATUS_ANY) {
1318 return mbMessagePersistence.findByU_C_C(
1319 userId, classNameId, classPK, start, end, obc);
1320 }
1321 else {
1322 return mbMessagePersistence.findByU_C_C_S(
1323 userId, classNameId, classPK, status, start, end, obc);
1324 }
1325 }
1326
1327 @Override
1328 public List<MBMessage> getUserDiscussionMessages(
1329 long userId, long[] classNameIds, int status, int start, int end,
1330 OrderByComparator obc)
1331 throws SystemException {
1332
1333 if (status == WorkflowConstants.STATUS_ANY) {
1334 return mbMessagePersistence.findByU_C(
1335 userId, classNameIds, start, end, obc);
1336 }
1337 else {
1338 return mbMessagePersistence.findByU_C_S(
1339 userId, classNameIds, status, start, end, obc);
1340 }
1341 }
1342
1343 @Override
1344 public List<MBMessage> getUserDiscussionMessages(
1345 long userId, String className, long classPK, int status, int start,
1346 int end, OrderByComparator obc)
1347 throws SystemException {
1348
1349 long classNameId = PortalUtil.getClassNameId(className);
1350
1351 return getUserDiscussionMessages(
1352 userId, classNameId, classPK, status, start, end, obc);
1353 }
1354
1355 @Override
1356 public int getUserDiscussionMessagesCount(
1357 long userId, long classNameId, long classPK, int status)
1358 throws SystemException {
1359
1360 if (status == WorkflowConstants.STATUS_ANY) {
1361 return mbMessagePersistence.countByU_C_C(
1362 userId, classNameId, classPK);
1363 }
1364 else {
1365 return mbMessagePersistence.countByU_C_C_S(
1366 userId, classNameId, classPK, status);
1367 }
1368 }
1369
1370 @Override
1371 public int getUserDiscussionMessagesCount(
1372 long userId, long[] classNameIds, int status)
1373 throws SystemException {
1374
1375 if (status == WorkflowConstants.STATUS_ANY) {
1376 return mbMessagePersistence.countByU_C(userId, classNameIds);
1377 }
1378 else {
1379 return mbMessagePersistence.countByU_C_S(
1380 userId, classNameIds, status);
1381 }
1382 }
1383
1384 @Override
1385 public int getUserDiscussionMessagesCount(
1386 long userId, String className, long classPK, int status)
1387 throws SystemException {
1388
1389 long classNameId = PortalUtil.getClassNameId(className);
1390
1391 return getUserDiscussionMessagesCount(
1392 userId, classNameId, classPK, status);
1393 }
1394
1395 @Override
1396 public void moveDiscussionToTrash(String className, long classPK)
1397 throws SystemException {
1398
1399 List<MBMessage> messages = getMessages(
1400 className, classPK, WorkflowConstants.STATUS_APPROVED);
1401
1402 for (MBMessage message : messages) {
1403 message.setStatus(WorkflowConstants.STATUS_IN_TRASH);
1404
1405 mbMessageLocalService.updateMBMessage(message);
1406 }
1407 }
1408
1409 @Override
1410 public long moveMessageAttachmentToTrash(
1411 long userId, long messageId, String fileName)
1412 throws PortalException, SystemException {
1413
1414 MBMessage message = getMessage(messageId);
1415
1416 long folderId = message.getAttachmentsFolderId();
1417
1418 FileEntry fileEntry = PortletFileRepositoryUtil.getPortletFileEntry(
1419 message.getGroupId(), folderId, fileName);
1420
1421 PortletFileRepositoryUtil.movePortletFileEntryToTrash(
1422 userId, fileEntry.getFileEntryId());
1423
1424 return fileEntry.getFileEntryId();
1425 }
1426
1427 @Override
1428 public void restoreDiscussionFromTrash(String className, long classPK)
1429 throws SystemException {
1430
1431 List<MBMessage> messages = getMessages(
1432 className, classPK, WorkflowConstants.STATUS_IN_TRASH);
1433
1434 for (MBMessage message : messages) {
1435 message.setStatus(WorkflowConstants.STATUS_APPROVED);
1436
1437 mbMessageLocalService.updateMBMessage(message);
1438 }
1439 }
1440
1441 @Override
1442 public void restoreMessageAttachmentFromTrash(
1443 long userId, long messageId, String deletedFileName)
1444 throws PortalException, SystemException {
1445
1446 MBMessage message = getMessage(messageId);
1447
1448 Folder folder = message.addAttachmentsFolder();
1449
1450 PortletFileRepositoryUtil.restorePortletFileEntryFromTrash(
1451 message.getGroupId(), userId, folder.getFolderId(),
1452 deletedFileName);
1453 }
1454
1455 @Override
1456 public void subscribeMessage(long userId, long messageId)
1457 throws PortalException, SystemException {
1458
1459 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1460
1461 subscriptionLocalService.addSubscription(
1462 userId, message.getGroupId(), MBThread.class.getName(),
1463 message.getThreadId());
1464 }
1465
1466 @Override
1467 public void unsubscribeMessage(long userId, long messageId)
1468 throws PortalException, SystemException {
1469
1470 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1471
1472 subscriptionLocalService.deleteSubscription(
1473 userId, MBThread.class.getName(), message.getThreadId());
1474 }
1475
1476 @Override
1477 public void updateAnswer(long messageId, boolean answer, boolean cascade)
1478 throws PortalException, SystemException {
1479
1480 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1481
1482 updateAnswer(message, answer, cascade);
1483 }
1484
1485 @Override
1486 public void updateAnswer(MBMessage message, boolean answer, boolean cascade)
1487 throws PortalException, SystemException {
1488
1489 if (message.isAnswer() != answer) {
1490 message.setAnswer(answer);
1491
1492 mbMessagePersistence.update(message);
1493 }
1494
1495 if (cascade) {
1496 List<MBMessage> messages = mbMessagePersistence.findByT_P(
1497 message.getThreadId(), message.getMessageId());
1498
1499 for (MBMessage curMessage : messages) {
1500 updateAnswer(curMessage, answer, cascade);
1501 }
1502 }
1503 }
1504
1505 @Override
1506 public void updateAsset(
1507 long userId, MBMessage message, long[] assetCategoryIds,
1508 String[] assetTagNames, long[] assetLinkEntryIds)
1509 throws PortalException, SystemException {
1510
1511 updateAsset(
1512 userId, message, assetCategoryIds, assetTagNames, assetLinkEntryIds,
1513 true);
1514 }
1515
1516 @Override
1517 public MBMessage updateDiscussionMessage(
1518 long userId, long messageId, String className, long classPK,
1519 String subject, String body, ServiceContext serviceContext)
1520 throws PortalException, SystemException {
1521
1522 if (Validator.isNull(subject)) {
1523 if (Validator.isNotNull(body)) {
1524 int pos = Math.min(body.length(), 50);
1525
1526 subject = body.substring(0, pos) + "...";
1527 }
1528 else {
1529 throw new MessageBodyException();
1530 }
1531 }
1532
1533 List<ObjectValuePair<String, InputStream>> inputStreamOVPs =
1534 Collections.emptyList();
1535 List<String> existingFiles = new ArrayList<String>();
1536 double priority = 0.0;
1537 boolean allowPingbacks = false;
1538
1539 serviceContext.setAttribute("className", className);
1540 serviceContext.setAttribute("classPK", String.valueOf(classPK));
1541
1542 return updateMessage(
1543 userId, messageId, subject, body, inputStreamOVPs, existingFiles,
1544 priority, allowPingbacks, serviceContext);
1545 }
1546
1547 @Override
1548 public MBMessage updateMessage(
1549 long userId, long messageId, String subject, String body,
1550 List<ObjectValuePair<String, InputStream>> inputStreamOVPs,
1551 List<String> existingFiles, double priority, boolean allowPingbacks,
1552 ServiceContext serviceContext)
1553 throws PortalException, SystemException {
1554
1555
1556
1557 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1558
1559 int oldStatus = message.getStatus();
1560
1561 Date modifiedDate = serviceContext.getModifiedDate(new Date());
1562 subject = ModelHintsUtil.trimString(
1563 MBMessage.class.getName(), "subject", subject);
1564
1565 subject = getSubject(subject, body);
1566 body = getBody(subject, body);
1567
1568 body = SanitizerUtil.sanitize(
1569 message.getCompanyId(), message.getGroupId(), userId,
1570 MBMessage.class.getName(), messageId, "text/" + message.getFormat(),
1571 body);
1572
1573 validate(subject, body);
1574
1575 message.setModifiedDate(modifiedDate);
1576 message.setSubject(subject);
1577 message.setBody(body);
1578 message.setAllowPingbacks(allowPingbacks);
1579
1580 if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
1581 message.setPriority(priority);
1582 }
1583
1584 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1585 message.getThreadId());
1586
1587 if (serviceContext.getWorkflowAction() ==
1588 WorkflowConstants.ACTION_SAVE_DRAFT) {
1589
1590 if (!message.isDraft() && !message.isPending()) {
1591 message.setStatus(WorkflowConstants.STATUS_DRAFT);
1592
1593
1594
1595 User user = userPersistence.findByPrimaryKey(userId);
1596
1597 updateThreadStatus(
1598 thread, message, user, oldStatus, modifiedDate);
1599
1600
1601
1602 assetEntryLocalService.updateVisible(
1603 message.getWorkflowClassName(), message.getMessageId(),
1604 false);
1605
1606 if (!message.isDiscussion()) {
1607
1608
1609
1610 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1611 MBMessage.class);
1612
1613 indexer.delete(message);
1614 }
1615 }
1616 }
1617
1618
1619
1620 if (!inputStreamOVPs.isEmpty() || !existingFiles.isEmpty()) {
1621 List<FileEntry> fileEntries = message.getAttachmentsFileEntries();
1622
1623 for (FileEntry fileEntry : fileEntries) {
1624 String fileEntryId = String.valueOf(fileEntry.getFileEntryId());
1625
1626 if (!existingFiles.contains(fileEntryId)) {
1627 if (!TrashUtil.isTrashEnabled(message.getGroupId())) {
1628 deleteMessageAttachment(
1629 messageId, fileEntry.getTitle());
1630 }
1631 else {
1632 moveMessageAttachmentToTrash(
1633 userId, messageId, fileEntry.getTitle());
1634 }
1635 }
1636 }
1637
1638 Folder folder = message.addAttachmentsFolder();
1639
1640 PortletFileRepositoryUtil.addPortletFileEntries(
1641 message.getGroupId(), userId, MBMessage.class.getName(),
1642 message.getMessageId(), PortletKeys.MESSAGE_BOARDS,
1643 folder.getFolderId(), inputStreamOVPs);
1644 }
1645 else {
1646 if (TrashUtil.isTrashEnabled(message.getGroupId())) {
1647 List<FileEntry> fileEntries =
1648 message.getAttachmentsFileEntries();
1649
1650 for (FileEntry fileEntry : fileEntries) {
1651 moveMessageAttachmentToTrash(
1652 userId, messageId, fileEntry.getTitle());
1653 }
1654 }
1655 else {
1656 deleteMessageAttachments(message.getMessageId());
1657 }
1658 }
1659
1660 message.setExpandoBridgeAttributes(serviceContext);
1661
1662 mbMessagePersistence.update(message);
1663
1664
1665
1666 if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
1667 (thread.getPriority() != priority)) {
1668
1669 thread.setPriority(priority);
1670
1671 mbThreadPersistence.update(thread);
1672
1673 updatePriorities(thread.getThreadId(), priority);
1674 }
1675
1676
1677
1678 updateAsset(
1679 userId, message, serviceContext.getAssetCategoryIds(),
1680 serviceContext.getAssetTagNames(),
1681 serviceContext.getAssetLinkEntryIds());
1682
1683
1684
1685 WorkflowHandlerRegistryUtil.startWorkflowInstance(
1686 message.getCompanyId(), message.getGroupId(), userId,
1687 message.getWorkflowClassName(), message.getMessageId(), message,
1688 serviceContext);
1689
1690 return message;
1691 }
1692
1693 @Override
1694 public MBMessage updateMessage(long messageId, String body)
1695 throws PortalException, SystemException {
1696
1697 MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
1698
1699 message.setBody(body);
1700
1701 mbMessagePersistence.update(message);
1702
1703 return message;
1704 }
1705
1706 @Override
1707 public MBMessage updateStatus(
1708 long userId, long messageId, int status,
1709 ServiceContext serviceContext)
1710 throws PortalException, SystemException {
1711
1712
1713
1714 MBMessage message = getMessage(messageId);
1715
1716 int oldStatus = message.getStatus();
1717
1718 User user = userPersistence.findByPrimaryKey(userId);
1719 Date now = new Date();
1720
1721 Date modifiedDate = serviceContext.getModifiedDate(now);
1722
1723 message.setStatus(status);
1724 message.setStatusByUserId(userId);
1725 message.setStatusByUserName(user.getFullName());
1726 message.setStatusDate(modifiedDate);
1727
1728 mbMessagePersistence.update(message);
1729
1730
1731
1732 MBThread thread = mbThreadPersistence.findByPrimaryKey(
1733 message.getThreadId());
1734
1735 updateThreadStatus(thread, message, user, oldStatus, modifiedDate);
1736
1737 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1738 MBMessage.class);
1739
1740 if (status == WorkflowConstants.STATUS_APPROVED) {
1741 if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
1742
1743
1744
1745 if (serviceContext.isAssetEntryVisible() &&
1746 ((message.getClassNameId() == 0) ||
1747 (message.getParentMessageId() != 0))) {
1748
1749 Date publishDate = null;
1750
1751 AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
1752 message.getWorkflowClassName(), message.getMessageId());
1753
1754 if ((assetEntry != null) &&
1755 (assetEntry.getPublishDate() != null)) {
1756
1757 publishDate = assetEntry.getPublishDate();
1758 }
1759 else {
1760 publishDate = now;
1761
1762 serviceContext.setCommand(Constants.ADD);
1763 }
1764
1765 assetEntryLocalService.updateEntry(
1766 message.getWorkflowClassName(), message.getMessageId(),
1767 publishDate, true);
1768 }
1769
1770 if (serviceContext.isCommandAdd()) {
1771
1772
1773
1774 JSONObject extraDataJSONObject =
1775 JSONFactoryUtil.createJSONObject();
1776
1777 extraDataJSONObject.put("title", message.getSubject());
1778
1779 if (!message.isDiscussion() ) {
1780 if (!message.isAnonymous() && !user.isDefaultUser()) {
1781 long receiverUserId = 0;
1782
1783 MBMessage parentMessage =
1784 mbMessagePersistence.fetchByPrimaryKey(
1785 message.getParentMessageId());
1786
1787 if (parentMessage != null) {
1788 receiverUserId = parentMessage.getUserId();
1789 }
1790
1791 socialActivityLocalService.addActivity(
1792 message.getUserId(), message.getGroupId(),
1793 MBMessage.class.getName(),
1794 message.getMessageId(),
1795 MBActivityKeys.ADD_MESSAGE,
1796 extraDataJSONObject.toString(), receiverUserId);
1797
1798 if ((parentMessage != null) &&
1799 (receiverUserId != message.getUserId())) {
1800
1801 socialActivityLocalService.addActivity(
1802 message.getUserId(),
1803 parentMessage.getGroupId(),
1804 MBMessage.class.getName(),
1805 parentMessage.getMessageId(),
1806 MBActivityKeys.REPLY_MESSAGE,
1807 extraDataJSONObject.toString(), 0);
1808 }
1809 }
1810 }
1811 else {
1812 String className = (String)serviceContext.getAttribute(
1813 "className");
1814 long classPK = ParamUtil.getLong(
1815 serviceContext, "classPK");
1816 long parentMessageId = message.getParentMessageId();
1817
1818 if (parentMessageId !=
1819 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
1820
1821 AssetEntry assetEntry =
1822 assetEntryLocalService.fetchEntry(
1823 className, classPK);
1824
1825 if (assetEntry != null) {
1826 extraDataJSONObject.put(
1827 "messageId", message.getMessageId());
1828
1829 socialActivityLocalService.addActivity(
1830 message.getUserId(),
1831 assetEntry.getGroupId(), className, classPK,
1832 SocialActivityConstants.TYPE_ADD_COMMENT,
1833 extraDataJSONObject.toString(),
1834 assetEntry.getUserId());
1835 }
1836 }
1837 }
1838 }
1839 }
1840
1841
1842
1843 notifySubscribers((MBMessage)message.clone(), serviceContext);
1844
1845
1846
1847 indexer.reindex(message);
1848
1849
1850
1851 pingPingback(message, serviceContext);
1852 }
1853 else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
1854
1855
1856
1857 assetEntryLocalService.updateVisible(
1858 message.getWorkflowClassName(), message.getMessageId(), false);
1859
1860
1861
1862 indexer.delete(message);
1863 }
1864
1865
1866
1867 if (!message.isDiscussion()) {
1868 mbStatsUserLocalService.updateStatsUser(
1869 message.getGroupId(), userId,
1870 serviceContext.getModifiedDate(now));
1871 }
1872
1873 return message;
1874 }
1875
1876 @Override
1877 public void updateUserName(long userId, String userName)
1878 throws SystemException {
1879
1880 List<MBMessage> messages = mbMessagePersistence.findByUserId(userId);
1881
1882 for (MBMessage message : messages) {
1883 message.setUserName(userName);
1884
1885 mbMessagePersistence.update(message);
1886 }
1887 }
1888
1889 protected void deleteDiscussionSocialActivities(
1890 String className, MBMessage message)
1891 throws PortalException, SystemException {
1892
1893 MBDiscussion discussion = mbDiscussionPersistence.findByThreadId(
1894 message.getThreadId());
1895
1896 long classNameId = PortalUtil.getClassNameId(className);
1897 long classPK = discussion.getClassPK();
1898
1899 if (discussion.getClassNameId() != classNameId) {
1900 return;
1901 }
1902
1903 List<SocialActivity> socialActivities =
1904 socialActivityLocalService.getActivities(
1905 0, className, classPK, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1906
1907 for (SocialActivity socialActivity : socialActivities) {
1908 if (Validator.isNull(socialActivity.getExtraData())) {
1909 continue;
1910 }
1911
1912 JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(
1913 socialActivity.getExtraData());
1914
1915 long extraDataMessageId = extraDataJSONObject.getLong("messageId");
1916
1917 if (message.getMessageId() == extraDataMessageId) {
1918 socialActivityLocalService.deleteActivity(
1919 socialActivity.getActivityId());
1920 }
1921 }
1922 }
1923
1924 protected String getBody(String subject, String body) {
1925 if (Validator.isNull(body)) {
1926 return subject;
1927 }
1928
1929 return body;
1930 }
1931
1932 protected String getMessageURL(
1933 MBMessage message, ServiceContext serviceContext)
1934 throws PortalException, SystemException {
1935
1936 HttpServletRequest request = serviceContext.getRequest();
1937
1938 ServletContext servletContext = null;
1939
1940 try {
1941 HttpSession session = request.getSession();
1942
1943 servletContext = session.getServletContext();
1944 }
1945 catch (Exception e) {
1946 }
1947
1948 if ((request == null) || (servletContext == null)) {
1949 if (Validator.isNull(serviceContext.getLayoutFullURL())) {
1950 return StringPool.BLANK;
1951 }
1952
1953 return serviceContext.getLayoutFullURL() +
1954 Portal.FRIENDLY_URL_SEPARATOR + "message_boards/view_message/" +
1955 message.getMessageId();
1956 }
1957
1958 String layoutURL = getLayoutURL(
1959 message.getGroupId(), PortletKeys.MESSAGE_BOARDS, serviceContext);
1960
1961 if (Validator.isNotNull(layoutURL)) {
1962 return layoutURL + Portal.FRIENDLY_URL_SEPARATOR +
1963 "message_boards/view_message/" + message.getMessageId();
1964 }
1965 else {
1966 long controlPanelPlid = PortalUtil.getControlPanelPlid(
1967 serviceContext.getCompanyId());
1968
1969 PortletURL portletURL = PortletURLFactoryUtil.create(
1970 request, PortletKeys.MESSAGE_BOARDS_ADMIN, controlPanelPlid,
1971 PortletRequest.RENDER_PHASE);
1972
1973 portletURL.setParameter(
1974 "struts_action", "/message_boards_admin/view_message");
1975 portletURL.setParameter(
1976 "messageId", String.valueOf(message.getMessageId()));
1977
1978 return portletURL.toString();
1979 }
1980 }
1981
1982 protected String getSubject(String subject, String body) {
1983 if (Validator.isNull(subject)) {
1984 return StringUtil.shorten(body);
1985 }
1986
1987 return subject;
1988 }
1989
1990 protected void notifyDiscussionSubscribers(
1991 MBMessage message, ServiceContext serviceContext)
1992 throws SystemException {
1993
1994 if (!PrefsPropsUtil.getBoolean(
1995 message.getCompanyId(),
1996 PropsKeys.DISCUSSION_EMAIL_COMMENTS_ADDED_ENABLED)) {
1997
1998 return;
1999 }
2000
2001 String contentURL = (String)serviceContext.getAttribute("contentURL");
2002
2003 String userAddress = StringPool.BLANK;
2004 String userName = (String)serviceContext.getAttribute(
2005 "pingbackUserName");
2006
2007 if (Validator.isNull(userName)) {
2008 userAddress = PortalUtil.getUserEmailAddress(message.getUserId());
2009 userName = PortalUtil.getUserName(
2010 message.getUserId(), StringPool.BLANK);
2011 }
2012
2013 String fromName = PrefsPropsUtil.getString(
2014 message.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_NAME);
2015 String fromAddress = PrefsPropsUtil.getString(
2016 message.getCompanyId(), PropsKeys.ADMIN_EMAIL_FROM_ADDRESS);
2017
2018 String subject = PrefsPropsUtil.getContent(
2019 message.getCompanyId(), PropsKeys.DISCUSSION_EMAIL_SUBJECT);
2020 String body = PrefsPropsUtil.getContent(
2021 message.getCompanyId(), PropsKeys.DISCUSSION_EMAIL_BODY);
2022
2023 SubscriptionSender subscriptionSender = new SubscriptionSender();
2024
2025 subscriptionSender.setBody(body);
2026 subscriptionSender.setCompanyId(message.getCompanyId());
2027 subscriptionSender.setContextAttribute(
2028 "[$COMMENTS_BODY$]", message.getBody(true), false);
2029 subscriptionSender.setContextAttributes(
2030 "[$COMMENTS_USER_ADDRESS$]", userAddress, "[$COMMENTS_USER_NAME$]",
2031 userName, "[$CONTENT_URL$]", contentURL);
2032 subscriptionSender.setFrom(fromAddress, fromName);
2033 subscriptionSender.setHtmlFormat(true);
2034
2035 Date modifiedDate = MBMessageDateDigesterUtil.digest(
2036 message.getModifiedDate());
2037
2038 subscriptionSender.setMailId(
2039 "mb_discussion", message.getCategoryId(), message.getMessageId(),
2040 modifiedDate.getTime());
2041
2042 subscriptionSender.setScopeGroupId(message.getGroupId());
2043 subscriptionSender.setServiceContext(serviceContext);
2044 subscriptionSender.setSubject(subject);
2045 subscriptionSender.setUniqueMailId(false);
2046 subscriptionSender.setUserId(message.getUserId());
2047
2048 String className = (String)serviceContext.getAttribute("className");
2049 long classPK = ParamUtil.getLong(serviceContext, "classPK");
2050
2051 subscriptionSender.addPersistedSubscribers(className, classPK);
2052
2053 subscriptionSender.flushNotificationsAsync();
2054 }
2055
2056 protected void notifySubscribers(
2057 MBMessage message, ServiceContext serviceContext)
2058 throws PortalException, SystemException {
2059
2060 String layoutFullURL = serviceContext.getLayoutFullURL();
2061
2062 if (!message.isApproved() || Validator.isNull(layoutFullURL)) {
2063 return;
2064 }
2065
2066 if (message.isDiscussion()) {
2067 try {
2068 notifyDiscussionSubscribers(message, serviceContext);
2069 }
2070 catch (Exception e) {
2071 _log.error(e, e);
2072 }
2073
2074 return;
2075 }
2076
2077 PortletPreferences preferences =
2078 portletPreferencesLocalService.getPreferences(
2079 message.getCompanyId(), message.getGroupId(),
2080 PortletKeys.PREFS_OWNER_TYPE_GROUP,
2081 PortletKeys.PREFS_PLID_SHARED, PortletKeys.MESSAGE_BOARDS,
2082 null);
2083
2084 if (serviceContext.isCommandAdd() &&
2085 MBUtil.getEmailMessageAddedEnabled(preferences)) {
2086 }
2087 else if (serviceContext.isCommandUpdate() &&
2088 MBUtil.getEmailMessageUpdatedEnabled(preferences)) {
2089 }
2090 else {
2091 return;
2092 }
2093
2094 Company company = companyPersistence.findByPrimaryKey(
2095 message.getCompanyId());
2096
2097 Group group = groupPersistence.findByPrimaryKey(message.getGroupId());
2098
2099 String emailAddress = PortalUtil.getUserEmailAddress(
2100 message.getUserId());
2101 String fullName = PortalUtil.getUserName(
2102 message.getUserId(), message.getUserName());
2103
2104 if (message.isAnonymous()) {
2105 emailAddress = StringPool.BLANK;
2106 fullName = serviceContext.translate("anonymous");
2107 }
2108
2109 MBCategory category = message.getCategory();
2110
2111 String categoryName = category.getName();
2112
2113 if (category.getCategoryId() ==
2114 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
2115
2116 categoryName = serviceContext.translate("message-boards-home");
2117
2118 categoryName += " - " + group.getDescriptiveName();
2119 }
2120
2121 List<Long> categoryIds = new ArrayList<Long>();
2122
2123 categoryIds.add(message.getCategoryId());
2124
2125 if (message.getCategoryId() !=
2126 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
2127
2128 categoryIds.addAll(category.getAncestorCategoryIds());
2129 }
2130
2131 String fromName = MBUtil.getEmailFromName(
2132 preferences, message.getCompanyId());
2133 String fromAddress = MBUtil.getEmailFromAddress(
2134 preferences, message.getCompanyId());
2135
2136 String replyToAddress = StringPool.BLANK;
2137
2138 if (PropsValues.POP_SERVER_NOTIFICATIONS_ENABLED) {
2139 replyToAddress = MBUtil.getReplyToAddress(
2140 message.getCategoryId(), message.getMessageId(),
2141 company.getMx(), fromAddress);
2142 }
2143
2144 String subject = null;
2145 String body = null;
2146 String signature = null;
2147
2148 if (serviceContext.isCommandUpdate()) {
2149 subject = MBUtil.getEmailMessageUpdatedSubject(preferences);
2150 body = MBUtil.getEmailMessageUpdatedBody(preferences);
2151 signature = MBUtil.getEmailMessageUpdatedSignature(preferences);
2152 }
2153 else {
2154 subject = MBUtil.getEmailMessageAddedSubject(preferences);
2155 body = MBUtil.getEmailMessageAddedBody(preferences);
2156 signature = MBUtil.getEmailMessageAddedSignature(preferences);
2157 }
2158
2159 boolean htmlFormat = MBUtil.getEmailHtmlFormat(preferences);
2160
2161 if (Validator.isNotNull(signature)) {
2162 String signatureSeparator = null;
2163
2164 if (htmlFormat) {
2165 signatureSeparator = "<br />--<br />";
2166 }
2167 else {
2168 signatureSeparator = "\n--\n";
2169 }
2170
2171 body += signatureSeparator + signature;
2172 }
2173
2174 String messageBody = message.getBody();
2175
2176 if (htmlFormat && message.isFormatBBCode()) {
2177 try {
2178 messageBody = BBCodeTranslatorUtil.getHTML(messageBody);
2179
2180 HttpServletRequest request = serviceContext.getRequest();
2181
2182 if (request != null) {
2183 ThemeDisplay themeDisplay =
2184 (ThemeDisplay)request.getAttribute(
2185 WebKeys.THEME_DISPLAY);
2186
2187 messageBody = MBUtil.replaceMessageBodyPaths(
2188 themeDisplay, messageBody);
2189 }
2190 }
2191 catch (Exception e) {
2192 _log.error(
2193 "Could not parse message " + message.getMessageId() +
2194 " " + e.getMessage());
2195 }
2196 }
2197
2198 String inReplyTo = null;
2199 String messageSubject = message.getSubject();
2200 String messageSubjectPrefix = StringPool.BLANK;
2201
2202 if (message.getParentMessageId() !=
2203 MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
2204
2205 MBMessage parentMessage = mbMessageLocalService.getMessage(
2206 message.getParentMessageId());
2207
2208 Date modifiedDate = MBMessageDateDigesterUtil.digest(
2209 parentMessage.getModifiedDate());
2210
2211 inReplyTo = PortalUtil.getMailId(
2212 company.getMx(), MBUtil.MESSAGE_POP_PORTLET_PREFIX,
2213 message.getCategoryId(), parentMessage.getMessageId(),
2214 modifiedDate.getTime());
2215
2216 if (messageSubject.startsWith(
2217 MBMessageConstants.MESSAGE_SUBJECT_PREFIX_RE)) {
2218
2219 messageSubjectPrefix =
2220 MBMessageConstants.MESSAGE_SUBJECT_PREFIX_RE;
2221
2222 messageSubject = messageSubject.substring(
2223 messageSubjectPrefix.length());
2224 }
2225 }
2226
2227 String entryURL = getMessageURL(message, serviceContext);
2228
2229 SubscriptionSender subscriptionSenderPrototype =
2230 new MBSubscriptionSender();
2231
2232 subscriptionSenderPrototype.setBody(body);
2233 subscriptionSenderPrototype.setBulk(
2234 PropsValues.MESSAGE_BOARDS_EMAIL_BULK);
2235 subscriptionSenderPrototype.setCompanyId(message.getCompanyId());
2236 subscriptionSenderPrototype.setContextAttribute(
2237 "[$MESSAGE_BODY$]", messageBody, false);
2238 subscriptionSenderPrototype.setContextAttributes(
2239 "[$CATEGORY_NAME$]", categoryName, "[$MAILING_LIST_ADDRESS$]",
2240 replyToAddress, "[$MESSAGE_ID$]", message.getMessageId(),
2241 "[$MESSAGE_SUBJECT$]", messageSubject, "[$MESSAGE_SUBJECT_PREFIX$]",
2242 messageSubjectPrefix, "[$MESSAGE_URL$]", entryURL,
2243 "[$MESSAGE_USER_ADDRESS$]", emailAddress, "[$MESSAGE_USER_NAME$]",
2244 fullName);
2245 subscriptionSenderPrototype.setFrom(fromAddress, fromName);
2246 subscriptionSenderPrototype.setHtmlFormat(htmlFormat);
2247 subscriptionSenderPrototype.setInReplyTo(inReplyTo);
2248
2249 Date modifiedDate = MBMessageDateDigesterUtil.digest(
2250 message.getModifiedDate());
2251
2252 subscriptionSenderPrototype.setMailId(
2253 MBUtil.MESSAGE_POP_PORTLET_PREFIX, message.getCategoryId(),
2254 message.getMessageId(), modifiedDate.getTime());
2255 subscriptionSenderPrototype.setPortletId(PortletKeys.MESSAGE_BOARDS);
2256 subscriptionSenderPrototype.setReplyToAddress(replyToAddress);
2257 subscriptionSenderPrototype.setScopeGroupId(message.getGroupId());
2258 subscriptionSenderPrototype.setServiceContext(serviceContext);
2259 subscriptionSenderPrototype.setSubject(subject);
2260 subscriptionSenderPrototype.setUniqueMailId(false);
2261 subscriptionSenderPrototype.setUserId(message.getUserId());
2262
2263 serviceContext.setAttribute("entryURL", entryURL);
2264
2265 SubscriptionSender subscriptionSender =
2266 (SubscriptionSender)SerializableUtil.clone(
2267 subscriptionSenderPrototype);
2268
2269 subscriptionSender.addPersistedSubscribers(
2270 MBCategory.class.getName(), message.getGroupId());
2271
2272 for (long categoryId : categoryIds) {
2273 if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
2274 subscriptionSender.addPersistedSubscribers(
2275 MBCategory.class.getName(), categoryId);
2276 }
2277 }
2278
2279 subscriptionSender.addPersistedSubscribers(
2280 MBThread.class.getName(), message.getThreadId());
2281
2282 subscriptionSender.flushNotificationsAsync();
2283
2284 if (!MailingListThreadLocal.isSourceMailingList()) {
2285 for (long categoryId : categoryIds) {
2286 MBSubscriptionSender sourceMailingListSubscriptionSender =
2287 (MBSubscriptionSender)SerializableUtil.clone(
2288 subscriptionSenderPrototype);
2289
2290 sourceMailingListSubscriptionSender.setBulk(false);
2291
2292 sourceMailingListSubscriptionSender.addMailingListSubscriber(
2293 message.getGroupId(), categoryId);
2294
2295 sourceMailingListSubscriptionSender.flushNotificationsAsync();
2296 }
2297 }
2298 }
2299
2300 protected void pingPingback(
2301 MBMessage message, ServiceContext serviceContext) {
2302
2303 if (!PropsValues.BLOGS_PINGBACK_ENABLED ||
2304 !message.isAllowPingbacks() || !message.isApproved()) {
2305
2306 return;
2307 }
2308
2309 String layoutFullURL = serviceContext.getLayoutFullURL();
2310
2311 if (Validator.isNull(layoutFullURL)) {
2312 return;
2313 }
2314
2315 String sourceUri =
2316 layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR +
2317 "message_boards/view_message/" + message.getMessageId();
2318
2319 Source source = new Source(message.getBody(true));
2320
2321 List<StartTag> startTags = source.getAllStartTags("a");
2322
2323 for (StartTag startTag : startTags) {
2324 String targetUri = startTag.getAttributeValue("href");
2325
2326 if (Validator.isNotNull(targetUri)) {
2327 try {
2328 LinkbackProducerUtil.sendPingback(sourceUri, targetUri);
2329 }
2330 catch (Exception e) {
2331 _log.error("Error while sending pingback " + targetUri, e);
2332 }
2333 }
2334 }
2335 }
2336
2337 protected void updateAsset(
2338 long userId, MBMessage message, long[] assetCategoryIds,
2339 String[] assetTagNames, long[] assetLinkEntryIds,
2340 boolean assetEntryVisible)
2341 throws PortalException, SystemException {
2342
2343 boolean visible = false;
2344
2345 if (assetEntryVisible && message.isApproved() &&
2346 ((message.getClassNameId() == 0) ||
2347 (message.getParentMessageId() != 0))) {
2348
2349 visible = true;
2350 }
2351
2352 AssetEntry assetEntry = assetEntryLocalService.updateEntry(
2353 userId, message.getGroupId(), message.getCreateDate(),
2354 message.getModifiedDate(), message.getWorkflowClassName(),
2355 message.getMessageId(), message.getUuid(), 0, assetCategoryIds,
2356 assetTagNames, visible, null, null, null, ContentTypes.TEXT_HTML,
2357 message.getSubject(), null, null, null, null, 0, 0,
2358 (int)message.getPriority(), false);
2359
2360 assetLinkLocalService.updateLinks(
2361 userId, assetEntry.getEntryId(), assetLinkEntryIds,
2362 AssetLinkConstants.TYPE_RELATED);
2363 }
2364
2365 protected void updatePriorities(long threadId, double priority)
2366 throws SystemException {
2367
2368 List<MBMessage> messages = mbMessagePersistence.findByThreadId(
2369 threadId);
2370
2371 for (MBMessage message : messages) {
2372 if (message.getPriority() != priority) {
2373 message.setPriority(priority);
2374
2375 mbMessagePersistence.update(message);
2376 }
2377 }
2378 }
2379
2380 protected void updateThreadStatus(
2381 MBThread thread, MBMessage message, User user, int oldStatus,
2382 Date modifiedDate)
2383 throws PortalException, SystemException {
2384
2385 MBCategory category = null;
2386
2387 int status = message.getStatus();
2388
2389 if ((thread.getCategoryId() !=
2390 MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
2391 (thread.getCategoryId() !=
2392 MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
2393
2394 category = mbCategoryPersistence.findByPrimaryKey(
2395 thread.getCategoryId());
2396 }
2397
2398 if ((thread.getRootMessageId() == message.getMessageId()) &&
2399 (oldStatus != status)) {
2400
2401 thread.setModifiedDate(modifiedDate);
2402 thread.setStatus(status);
2403 thread.setStatusByUserId(user.getUserId());
2404 thread.setStatusByUserName(user.getFullName());
2405 thread.setStatusDate(modifiedDate);
2406 }
2407
2408 if (status == oldStatus) {
2409 return;
2410 }
2411
2412 if (status == WorkflowConstants.STATUS_APPROVED) {
2413 if (message.isAnonymous()) {
2414 thread.setLastPostByUserId(0);
2415 }
2416 else {
2417 thread.setLastPostByUserId(message.getUserId());
2418 }
2419
2420 thread.setLastPostDate(modifiedDate);
2421
2422 if (category != null) {
2423 category.setLastPostDate(modifiedDate);
2424
2425 category = mbCategoryPersistence.update(category);
2426 }
2427 }
2428
2429 if ((oldStatus == WorkflowConstants.STATUS_APPROVED) ||
2430 (status == WorkflowConstants.STATUS_APPROVED)) {
2431
2432
2433
2434 MBUtil.updateThreadMessageCount(
2435 thread.getCompanyId(), thread.getThreadId());
2436
2437
2438
2439 if ((category != null) &&
2440 (thread.getRootMessageId() == message.getMessageId())) {
2441
2442 MBUtil.updateCategoryStatistics(
2443 category.getCompanyId(), category.getCategoryId());
2444 }
2445
2446 if ((category != null) &&
2447 !(thread.getRootMessageId() == message.getMessageId())) {
2448
2449 MBUtil.updateCategoryMessageCount(
2450 category.getCompanyId(), category.getCategoryId());
2451 }
2452 }
2453
2454
2455
2456 Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
2457 MBThread.class);
2458
2459 indexer.reindex(thread);
2460
2461 mbThreadPersistence.update(thread);
2462 }
2463
2464 protected void validate(String subject, String body)
2465 throws PortalException {
2466
2467 if (Validator.isNull(subject) && Validator.isNull(body)) {
2468 throw new MessageSubjectException();
2469 }
2470 }
2471
2472 private static Log _log = LogFactoryUtil.getLog(
2473 MBMessageLocalServiceImpl.class);
2474
2475 }