com.liferay.message.boards.service.impl.MBMessageLocalServiceImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.message.boards.service
Show all versions of com.liferay.message.boards.service
Liferay Message Boards Service
/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.message.boards.service.impl;
import com.liferay.asset.kernel.model.AssetEntry;
import com.liferay.asset.kernel.model.AssetLinkConstants;
import com.liferay.asset.kernel.service.AssetEntryLocalService;
import com.liferay.asset.kernel.service.AssetLinkLocalService;
import com.liferay.change.tracking.service.CTEntryLocalService;
import com.liferay.comment.configuration.CommentGroupServiceConfiguration;
import com.liferay.comment.constants.CommentConstants;
import com.liferay.document.library.kernel.model.DLFileEntry;
import com.liferay.document.library.kernel.model.DLFolder;
import com.liferay.document.library.kernel.model.DLFolderConstants;
import com.liferay.document.library.kernel.service.DLFileEntryLocalService;
import com.liferay.expando.kernel.service.ExpandoRowLocalService;
import com.liferay.message.boards.constants.MBCategoryConstants;
import com.liferay.message.boards.constants.MBConstants;
import com.liferay.message.boards.constants.MBMessageConstants;
import com.liferay.message.boards.constants.MBThreadConstants;
import com.liferay.message.boards.exception.DiscussionMaxCommentsException;
import com.liferay.message.boards.exception.MessageBodyException;
import com.liferay.message.boards.exception.MessageSubjectException;
import com.liferay.message.boards.exception.NoSuchThreadException;
import com.liferay.message.boards.exception.RequiredMessageException;
import com.liferay.message.boards.internal.helper.MBMessageNotificationTemplateHelper;
import com.liferay.message.boards.internal.util.MBDiscussionSubscriptionSender;
import com.liferay.message.boards.internal.util.MBMailUtil;
import com.liferay.message.boards.internal.util.MBMessageUtil;
import com.liferay.message.boards.internal.util.MBSubscriptionSender;
import com.liferay.message.boards.internal.util.MBUtil;
import com.liferay.message.boards.internal.util.MailingListThreadLocal;
import com.liferay.message.boards.model.MBCategory;
import com.liferay.message.boards.model.MBDiscussion;
import com.liferay.message.boards.model.MBMessage;
import com.liferay.message.boards.model.MBMessageDisplay;
import com.liferay.message.boards.model.MBThread;
import com.liferay.message.boards.model.impl.MBCategoryImpl;
import com.liferay.message.boards.model.impl.MBMessageDisplayImpl;
import com.liferay.message.boards.service.MBDiscussionLocalService;
import com.liferay.message.boards.service.MBThreadLocalService;
import com.liferay.message.boards.service.base.MBMessageLocalServiceBaseImpl;
import com.liferay.message.boards.service.persistence.MBCategoryPersistence;
import com.liferay.message.boards.service.persistence.MBThreadPersistence;
import com.liferay.message.boards.settings.MBGroupServiceSettings;
import com.liferay.message.boards.social.MBActivityKeys;
import com.liferay.message.boards.util.comparator.MessageCreateDateComparator;
import com.liferay.message.boards.util.comparator.MessageThreadComparator;
import com.liferay.petra.lang.SafeCloseable;
import com.liferay.petra.string.StringBundler;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.aop.AopService;
import com.liferay.portal.json.jabsorb.serializer.LiferayJSONDeserializationWhitelist;
import com.liferay.portal.kernel.change.tracking.CTCollectionThreadLocal;
import com.liferay.portal.kernel.comment.Comment;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.json.JSONObject;
import com.liferay.portal.kernel.json.JSONUtil;
import com.liferay.portal.kernel.language.Language;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.Layout;
import com.liferay.portal.kernel.model.ModelHintsUtil;
import com.liferay.portal.kernel.model.PortletPreferences;
import com.liferay.portal.kernel.model.ResourceConstants;
import com.liferay.portal.kernel.model.SystemEventConstants;
import com.liferay.portal.kernel.model.User;
import com.liferay.portal.kernel.module.configuration.ConfigurationException;
import com.liferay.portal.kernel.module.configuration.ConfigurationProvider;
import com.liferay.portal.kernel.notifications.UserNotificationDefinition;
import com.liferay.portal.kernel.portlet.PortletProvider;
import com.liferay.portal.kernel.portlet.PortletProviderUtil;
import com.liferay.portal.kernel.portlet.url.builder.PortletURLBuilder;
import com.liferay.portal.kernel.portletfilerepository.PortletFileRepository;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.repository.model.Folder;
import com.liferay.portal.kernel.sanitizer.Sanitizer;
import com.liferay.portal.kernel.sanitizer.SanitizerUtil;
import com.liferay.portal.kernel.search.Indexable;
import com.liferay.portal.kernel.search.IndexableType;
import com.liferay.portal.kernel.search.Indexer;
import com.liferay.portal.kernel.search.IndexerRegistryUtil;
import com.liferay.portal.kernel.security.auth.PrincipalException;
import com.liferay.portal.kernel.security.permission.ActionKeys;
import com.liferay.portal.kernel.service.ClassNameLocalService;
import com.liferay.portal.kernel.service.CompanyLocalService;
import com.liferay.portal.kernel.service.GroupLocalService;
import com.liferay.portal.kernel.service.LayoutLocalService;
import com.liferay.portal.kernel.service.PortletPreferencesLocalService;
import com.liferay.portal.kernel.service.ResourceLocalService;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.UserLocalService;
import com.liferay.portal.kernel.service.WorkflowInstanceLinkLocalService;
import com.liferay.portal.kernel.service.permission.ModelPermissions;
import com.liferay.portal.kernel.settings.GroupServiceSettingsLocator;
import com.liferay.portal.kernel.settings.LocalizedValuesMap;
import com.liferay.portal.kernel.social.SocialActivityManagerUtil;
import com.liferay.portal.kernel.systemevent.SystemEvent;
import com.liferay.portal.kernel.theme.ThemeDisplay;
import com.liferay.portal.kernel.util.Constants;
import com.liferay.portal.kernel.util.ContentTypes;
import com.liferay.portal.kernel.util.CopyLayoutThreadLocal;
import com.liferay.portal.kernel.util.EscapableLocalizableFunction;
import com.liferay.portal.kernel.util.FriendlyURLNormalizer;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HashMapBuilder;
import com.liferay.portal.kernel.util.HtmlParser;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.HttpComponentsUtil;
import com.liferay.portal.kernel.util.ListUtil;
import com.liferay.portal.kernel.util.Localization;
import com.liferay.portal.kernel.util.ObjectValuePair;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.PortletKeys;
import com.liferay.portal.kernel.util.PrefsPropsUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.util.SubscriptionSender;
import com.liferay.portal.kernel.util.TempFileEntryUtil;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import com.liferay.portal.kernel.workflow.WorkflowHandlerRegistryUtil;
import com.liferay.portal.kernel.workflow.WorkflowThreadLocal;
import com.liferay.portal.linkback.LinkbackProducerUtil;
import com.liferay.portal.util.PropsValues;
import com.liferay.ratings.kernel.service.RatingsStatsLocalService;
import com.liferay.social.kernel.model.SocialActivityConstants;
import com.liferay.subscription.service.SubscriptionLocalService;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import javax.portlet.PortletRequest;
import javax.servlet.http.HttpServletRequest;
import net.htmlparser.jericho.Source;
import net.htmlparser.jericho.StartTag;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
/**
* @author Brian Wing Shun Chan
* @author Raymond Augé
* @author Mika Koivisto
* @author Jorge Ferrer
* @author Juan Fernández
* @author Shuyang Zhou
*/
@Component(
property = "model.class.name=com.liferay.message.boards.model.MBMessage",
service = AopService.class
)
public class MBMessageLocalServiceImpl extends MBMessageLocalServiceBaseImpl {
@Override
public MBMessage addDiscussionMessage(
long userId, String userName, long groupId, String className,
long classPK, int workflowAction)
throws PortalException {
long threadId = 0;
long parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
String subject = String.valueOf(classPK);
String body = subject;
ServiceContext serviceContext = new ServiceContext();
serviceContext.setWorkflowAction(workflowAction);
boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
WorkflowThreadLocal.setEnabled(false);
try {
return addDiscussionMessage(
null, userId, userName, groupId, className, classPK, threadId,
parentMessageId, subject, body, serviceContext);
}
finally {
WorkflowThreadLocal.setEnabled(workflowEnabled);
}
}
@Override
public MBMessage addDiscussionMessage(
String externalReferenceCode, long userId, String userName,
long groupId, String className, long classPK, long threadId,
long parentMessageId, String subject, String body,
ServiceContext serviceContext)
throws PortalException {
// Message
_validateDiscussionMaxComments(className, classPK);
long categoryId = MBCategoryConstants.DISCUSSION_CATEGORY_ID;
subject = _getDiscussionMessageSubject(subject, body);
List> inputStreamOVPs =
Collections.emptyList();
boolean anonymous = false;
double priority = 0.0;
boolean allowPingbacks = false;
serviceContext.setAddGroupPermissions(true);
serviceContext.setAddGuestPermissions(true);
serviceContext.setAttribute("className", className);
serviceContext.setAttribute("classPK", String.valueOf(classPK));
Date date = new Date();
if (serviceContext.getCreateDate() == null) {
serviceContext.setCreateDate(date);
}
if (serviceContext.getModifiedDate() == null) {
serviceContext.setModifiedDate(date);
}
MBMessage message = addMessage(
externalReferenceCode, userId, userName, groupId, categoryId,
threadId, parentMessageId, subject, body,
PropsValues.DISCUSSION_COMMENTS_FORMAT, inputStreamOVPs, anonymous,
priority, allowPingbacks, serviceContext);
// Discussion
if (parentMessageId == MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
long classNameId = _classNameLocalService.getClassNameId(className);
MBDiscussion discussion = _mbDiscussionLocalService.fetchDiscussion(
classNameId, classPK);
if (discussion == null) {
_mbDiscussionLocalService.addDiscussion(
userId, groupId, classNameId, classPK,
message.getThreadId(), serviceContext);
}
}
return message;
}
/**
* @deprecated As of Cavanaugh (7.4.x), replaced by {@link
* #addMessage(String, long, String, long, long, long, long,
* String, String, String, List, boolean, double, boolean,
* ServiceContext)}
*/
@Deprecated
@Override
public MBMessage addMessage(
long userId, String userName, long groupId, long categoryId,
long threadId, long parentMessageId, String subject, String body,
String format,
List> inputStreamOVPs,
boolean anonymous, double priority, boolean allowPingbacks,
ServiceContext serviceContext)
throws PortalException {
return addMessage(
null, userId, userName, groupId, categoryId, threadId,
parentMessageId, subject, body, format, inputStreamOVPs, anonymous,
priority, allowPingbacks, serviceContext);
}
/**
* @deprecated As of Cavanaugh (7.4.x), replaced by {@link
* #addMessage(String, long, String, long, long, long, long,
* String, String, String, List, boolean, double, boolean,
* ServiceContext)}
*/
@Deprecated
@Override
public MBMessage addMessage(
long userId, String userName, long groupId, long categoryId,
String subject, String body, ServiceContext serviceContext)
throws PortalException {
List> inputStreamOVPs =
Collections.emptyList();
return addMessage(
userId, userName, groupId, categoryId, 0, 0, subject, body,
MBMessageConstants.DEFAULT_FORMAT, inputStreamOVPs, false, 0.0,
false, serviceContext);
}
/**
* @deprecated As of Cavanaugh (7.4.x), replaced by {@link
* #addMessage(String, long, String, long, long, long, long,
* String, String, String, List, boolean, double, boolean,
* ServiceContext)}
*/
@Deprecated
@Override
public MBMessage addMessage(
long userId, String userName, long groupId, long categoryId,
String subject, String body, String format,
List> inputStreamOVPs,
boolean anonymous, double priority, boolean allowPingbacks,
ServiceContext serviceContext)
throws PortalException {
long threadId = 0;
long parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
return addMessage(
userId, userName, groupId, categoryId, threadId, parentMessageId,
subject, body, format, inputStreamOVPs, anonymous, priority,
allowPingbacks, serviceContext);
}
/**
* @deprecated As of Cavanaugh (7.4.x), replaced by {@link
* #addMessage(String, long, String, long, long, long, long,
* String, String, String, List, boolean, double, boolean,
* ServiceContext)}
*/
@Deprecated
@Override
public MBMessage addMessage(
long userId, String userName, long groupId, long categoryId,
String subject, String body, String format, String fileName,
File file, boolean anonymous, double priority,
boolean allowPingbacks, ServiceContext serviceContext)
throws FileNotFoundException, PortalException {
List> inputStreamOVPs =
new ArrayList<>(1);
InputStream inputStream = new FileInputStream(file);
ObjectValuePair inputStreamOVP =
new ObjectValuePair<>(fileName, inputStream);
inputStreamOVPs.add(inputStreamOVP);
return addMessage(
userId, userName, groupId, categoryId, 0, 0, subject, body, format,
inputStreamOVPs, anonymous, priority, allowPingbacks,
serviceContext);
}
@Override
public MBMessage addMessage(
String externalReferenceCode, long userId, String userName,
long groupId, long categoryId, long threadId, long parentMessageId,
String subject, String body, String format,
List> inputStreamOVPs,
boolean anonymous, double priority, boolean allowPingbacks,
ServiceContext serviceContext)
throws PortalException {
MBMessage parentMBMessage = fetchMBMessage(parentMessageId);
if ((parentMBMessage != null) && !parentMBMessage.isApproved()) {
throw new PortalException("Parent message is not approved");
}
// Message
Group group = _groupLocalService.getGroup(groupId);
User user = _userLocalService.fetchUser(
_portal.getValidUserId(group.getCompanyId(), userId));
userName = user.isGuestUser() ? userName : user.getFullName();
subject = ModelHintsUtil.trimString(
MBMessage.class.getName(), "subject", subject);
if (!com.liferay.message.boards.util.MBUtil.isValidMessageFormat(
format)) {
format = "html";
}
if (anonymous || user.isGuestUser()) {
MBGroupServiceSettings mbGroupServiceSettings =
MBGroupServiceSettings.getInstance(groupId);
if ((mbGroupServiceSettings != null) &&
!mbGroupServiceSettings.isAllowAnonymousPosting()) {
throw new PrincipalException.MustHavePermission(
userId, ActionKeys.ADD_MESSAGE);
}
}
if (user.isGuestUser()) {
anonymous = true;
}
Date date = new Date();
Date modifiedDate = serviceContext.getModifiedDate(date);
long messageId = counterLocalService.increment();
subject = _getSubject(subject, body);
body = _getBody(subject, body, format);
body = SanitizerUtil.sanitize(
user.getCompanyId(), groupId, userId, MBMessage.class.getName(),
messageId, "text/" + format, Sanitizer.MODE_ALL, body,
HashMapBuilder.put(
"discussion",
() -> {
if (categoryId ==
MBCategoryConstants.DISCUSSION_CATEGORY_ID) {
return true;
}
return false;
}
).build());
_validate(subject, body);
MBMessage message = mbMessagePersistence.create(messageId);
message.setUuid(serviceContext.getUuid());
message.setExternalReferenceCode(externalReferenceCode);
message.setGroupId(groupId);
message.setCompanyId(user.getCompanyId());
message.setUserId(user.getUserId());
message.setUserName(userName);
message.setCreateDate(serviceContext.getCreateDate(date));
message.setModifiedDate(modifiedDate);
if (threadId > 0) {
message.setThreadId(threadId);
}
if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
message.setPriority(priority);
}
message.setSubject(subject);
message.setUrlSubject(
_getUniqueUrlSubject(groupId, messageId, subject));
message.setAllowPingbacks(allowPingbacks);
message.setStatus(WorkflowConstants.STATUS_DRAFT);
message.setStatusByUserId(user.getUserId());
message.setStatusByUserName(userName);
message.setStatusDate(modifiedDate);
// Thread
if (parentMessageId != MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
MBMessage parentMessage = mbMessagePersistence.fetchByPrimaryKey(
parentMessageId);
if (parentMessage == null) {
parentMessageId = MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
}
}
MBThread thread = null;
if (threadId > 0) {
thread = _mbThreadPersistence.fetchByPrimaryKey(threadId);
}
if (thread == null) {
if (parentMessageId ==
MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
thread = _mbThreadLocalService.addThread(
categoryId, message, serviceContext);
}
else {
throw new NoSuchThreadException("{threadId=" + threadId + "}");
}
}
if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
(thread.getPriority() != priority)) {
thread.setPriority(priority);
thread = _mbThreadLocalService.updateMBThread(thread);
_updatePriorities(thread.getThreadId(), priority);
}
// Message
message.setCategoryId(categoryId);
message.setThreadId(thread.getThreadId());
message.setRootMessageId(thread.getRootMessageId());
message.setParentMessageId(parentMessageId);
message.setTreePath(message.buildTreePath());
message.setBody(body);
message.setFormat(format);
message.setAnonymous(anonymous);
if (message.isDiscussion()) {
message.setClassNameId(
_classNameLocalService.getClassNameId(
(String)serviceContext.getAttribute("className")));
message.setClassPK(ParamUtil.getLong(serviceContext, "classPK"));
}
message.setExpandoBridgeAttributes(serviceContext);
message = mbMessagePersistence.update(message);
// Resources
if ((parentMessageId != MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) &&
GetterUtil.getBoolean(
serviceContext.getAttribute("propagatePermissions"))) {
MBUtil.propagatePermissions(
message.getCompanyId(), groupId, parentMessageId,
serviceContext);
}
if (!message.isDiscussion()) {
if (user.isGuestUser()) {
addMessageResources(message, true, true);
}
else if (serviceContext.isAddGroupPermissions() ||
serviceContext.isAddGuestPermissions()) {
addMessageResources(
message, serviceContext.isAddGroupPermissions(),
serviceContext.isAddGuestPermissions());
}
else {
addMessageResources(
message, serviceContext.getModelPermissions());
}
}
// Attachments
if (ListUtil.isNotEmpty(inputStreamOVPs)) {
Folder folder = message.addAttachmentsFolder();
_portletFileRepository.addPortletFileEntries(
message.getGroupId(), userId, MBMessage.class.getName(),
message.getMessageId(), MBConstants.SERVICE_NAME,
folder.getFolderId(), inputStreamOVPs);
}
// Asset
_updateAsset(
userId, message, serviceContext.getAssetCategoryIds(),
serviceContext.getAssetTagNames(),
serviceContext.getAssetLinkEntryIds(),
serviceContext.isAssetEntryVisible());
// Workflow
return _startWorkflowInstance(userId, message, serviceContext);
}
@Override
public void addMessageAttachment(
long userId, long messageId, String fileName, File file,
String mimeType)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
Folder folder = message.addAttachmentsFolder();
_portletFileRepository.addPortletFileEntry(
null, message.getGroupId(), userId, MBMessage.class.getName(),
message.getMessageId(), MBConstants.SERVICE_NAME,
folder.getFolderId(), file, fileName, mimeType, true);
}
@Override
public void addMessageResources(
long messageId, boolean addGroupPermissions,
boolean addGuestPermissions)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
addMessageResources(message, addGroupPermissions, addGuestPermissions);
}
@Override
public void addMessageResources(
long messageId, ModelPermissions modelPermissions)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
addMessageResources(message, modelPermissions);
}
@Override
public void addMessageResources(
MBMessage message, boolean addGroupPermissions,
boolean addGuestPermissions)
throws PortalException {
_resourceLocalService.addResources(
message.getCompanyId(), message.getGroupId(), message.getUserId(),
MBMessage.class.getName(), message.getMessageId(), false,
addGroupPermissions, addGuestPermissions);
}
@Override
public void addMessageResources(
MBMessage message, ModelPermissions modelPermissions)
throws PortalException {
_resourceLocalService.addModelResources(
message.getCompanyId(), message.getGroupId(), message.getUserId(),
MBMessage.class.getName(), message.getMessageId(),
modelPermissions);
}
@Override
public FileEntry addTempAttachment(
long groupId, long userId, String folderName, String fileName,
InputStream inputStream, String mimeType)
throws PortalException {
return TempFileEntryUtil.addTempFileEntry(
groupId, userId, folderName, fileName, inputStream, mimeType);
}
@Indexable(type = IndexableType.DELETE)
@Override
public MBMessage deleteDiscussionMessage(long messageId)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
SocialActivityManagerUtil.deleteActivities(message);
return mbMessageLocalService.deleteMessage(messageId);
}
@Override
public void deleteDiscussionMessages(String className, long classPK)
throws PortalException {
MBDiscussion discussion = _mbDiscussionLocalService.fetchDiscussion(
_classNameLocalService.getClassNameId(className), classPK);
if (discussion == null) {
if (_log.isInfoEnabled()) {
_log.info(
StringBundler.concat(
"Unable to delete discussion message for class name ",
className, " and class PK ", classPK,
" because it does not exist"));
}
return;
}
List messages = mbMessagePersistence.findByT_P(
discussion.getThreadId(),
MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, 0, 1);
if (!messages.isEmpty()) {
MBMessage message = messages.get(0);
SocialActivityManagerUtil.deleteActivities(message);
MBThread thread = _mbThreadPersistence.findByPrimaryKey(
message.getThreadId());
_mbThreadLocalService.deleteThread(thread);
}
_mbDiscussionLocalService.deleteMBDiscussion(discussion);
}
@Indexable(type = IndexableType.DELETE)
@Override
public MBMessage deleteMessage(long messageId) throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
return mbMessageLocalService.deleteMessage(message);
}
@Indexable(type = IndexableType.DELETE)
@Override
@SystemEvent(type = SystemEventConstants.TYPE_DELETE)
public MBMessage deleteMessage(MBMessage message) throws PortalException {
// Attachments
long folderId = message.getAttachmentsFolderId();
if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
_portletFileRepository.deletePortletFolder(folderId);
}
// Thread
int count = mbMessagePersistence.countByThreadId(message.getThreadId());
if (count == 1) {
// Attachments
long threadAttachmentsFolderId =
message.getThreadAttachmentsFolderId();
if (threadAttachmentsFolderId !=
DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
_portletFileRepository.deletePortletFolder(
threadAttachmentsFolderId);
}
// Subscriptions
_subscriptionLocalService.deleteSubscriptions(
message.getCompanyId(), MBThread.class.getName(),
message.getThreadId());
// Thread
MBThread thread = _mbThreadPersistence.findByPrimaryKey(
message.getThreadId());
_mbThreadLocalService.deleteMBThread(thread);
// Indexer
Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
MBThread.class);
indexer.delete(thread);
}
else {
MBThread thread = _mbThreadPersistence.findByPrimaryKey(
message.getThreadId());
// Message is a root message
if (thread.getRootMessageId() == message.getMessageId()) {
List childrenMessages =
mbMessagePersistence.findByT_P(
message.getThreadId(), message.getMessageId());
if (childrenMessages.size() > 1) {
throw new RequiredMessageException(
String.valueOf(message.getMessageId()));
}
else if (childrenMessages.size() == 1) {
MBMessage childMessage = childrenMessages.get(0);
long defaultParentMessageId =
MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID;
childMessage.setRootMessageId(childMessage.getMessageId());
childMessage.setParentMessageId(defaultParentMessageId);
childMessage.setTreePath(childMessage.buildTreePath());
childMessage = mbMessagePersistence.update(childMessage);
List repliesMessages =
mbMessagePersistence.findByThreadIdReplies(
message.getThreadId());
for (MBMessage repliesMessage : repliesMessages) {
repliesMessage.setRootMessageId(
childMessage.getMessageId());
mbMessagePersistence.update(repliesMessage);
}
thread.setRootMessageId(childMessage.getMessageId());
thread.setRootMessageUserId(childMessage.getUserId());
thread = _mbThreadLocalService.updateMBThread(thread);
}
}
else {
// Message is a child message
List childrenMessages =
mbMessagePersistence.findByT_P(
message.getThreadId(), message.getMessageId());
// Message has children messages
if (!childrenMessages.isEmpty()) {
for (MBMessage childMessage : childrenMessages) {
childMessage.setParentMessageId(
message.getParentMessageId());
childMessage.setTreePath(childMessage.buildTreePath());
mbMessagePersistence.update(childMessage);
}
Indexer indexer =
IndexerRegistryUtil.nullSafeGetIndexer(MBMessage.class);
indexer.reindex(childrenMessages);
}
else if (message.getStatus() ==
WorkflowConstants.STATUS_APPROVED) {
MessageCreateDateComparator comparator =
new MessageCreateDateComparator(true);
MBMessage[] prevAndNextMessages =
mbMessagePersistence.findByT_S_PrevAndNext(
message.getMessageId(), thread.getThreadId(),
WorkflowConstants.STATUS_APPROVED, comparator);
if (prevAndNextMessages[2] == null) {
_mbThreadLocalService.updateLastPostDate(
thread.getThreadId(),
prevAndNextMessages[0].getModifiedDate());
}
}
}
// Indexer
Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
MBThread.class);
indexer.reindex(thread);
Indexer mbMessageIndexer =
IndexerRegistryUtil.nullSafeGetIndexer(MBMessage.class);
mbMessageIndexer.reindex(
mbMessageLocalService.getMBMessage(thread.getRootMessageId()));
}
// Asset
_assetEntryLocalService.deleteEntry(
message.getWorkflowClassName(), message.getMessageId());
// Expando
_expandoRowLocalService.deleteRows(message.getMessageId());
// Ratings
_ratingsStatsLocalService.deleteStats(
message.getWorkflowClassName(), message.getMessageId());
// Resources
if (!message.isDiscussion()) {
_resourceLocalService.deleteResource(
message.getCompanyId(), message.getWorkflowClassName(),
ResourceConstants.SCOPE_INDIVIDUAL, message.getMessageId());
}
// Message
mbMessagePersistence.remove(message);
// Workflow
_workflowInstanceLinkLocalService.deleteWorkflowInstanceLinks(
message.getCompanyId(), message.getGroupId(),
message.getWorkflowClassName(), message.getMessageId());
return message;
}
@Override
public void deleteMessageAttachment(long messageId, String fileName)
throws PortalException {
MBMessage message = getMessage(messageId);
long folderId = message.getAttachmentsFolderId();
if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
return;
}
_portletFileRepository.deletePortletFileEntry(
message.getGroupId(), folderId, fileName);
}
@Override
public void deleteMessageAttachments(long messageId)
throws PortalException {
MBMessage message = getMessage(messageId);
long folderId = message.getAttachmentsFolderId();
if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
return;
}
_portletFileRepository.deletePortletFileEntries(
message.getGroupId(), folderId);
}
@Override
public void deleteTempAttachment(
long groupId, long userId, String folderName, String fileName)
throws PortalException {
TempFileEntryUtil.deleteTempFileEntry(
groupId, userId, folderName, fileName);
}
@Override
public void emptyMessageAttachments(long messageId) throws PortalException {
MBMessage message = getMessage(messageId);
long folderId = message.getAttachmentsFolderId();
if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
return;
}
_portletFileRepository.deletePortletFileEntries(
message.getGroupId(), folderId, WorkflowConstants.STATUS_IN_TRASH);
}
@Override
public MBMessage fetchFileEntryMessage(long fileEntryId)
throws PortalException {
return mbMessagePersistence.fetchByPrimaryKey(
_getFileEntryMessageId(fileEntryId));
}
@Override
public MBMessage fetchFirstMessage(long threadId, long parentMessageId)
throws PortalException {
return mbMessagePersistence.fetchByT_P_First(
threadId, parentMessageId, null);
}
@Override
public MBMessage fetchMBMessageByUrlSubject(
long groupId, String urlSubject) {
return mbMessagePersistence.fetchByG_US(groupId, urlSubject);
}
@Override
public List getCategoryMessages(
long groupId, long categoryId, int status, int start, int end) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByG_C(
groupId, categoryId, start, end);
}
return mbMessagePersistence.findByG_C_S(
groupId, categoryId, status, start, end);
}
@Override
public List getCategoryMessages(
long groupId, long categoryId, int status, int start, int end,
OrderByComparator orderByComparator) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByG_C(
groupId, categoryId, start, end, orderByComparator);
}
return mbMessagePersistence.findByG_C_S(
groupId, categoryId, status, start, end, orderByComparator);
}
@Override
public List getCategoryMessages(
long groupId, long categoryId, long threadId) {
return mbMessagePersistence.findByG_C_T(groupId, categoryId, threadId);
}
@Override
public int getCategoryMessagesCount(
long groupId, long categoryId, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.countByG_C(groupId, categoryId);
}
return mbMessagePersistence.countByG_C_S(groupId, categoryId, status);
}
@Override
public List getChildMessages(long parentMessageId, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByParentMessageId(parentMessageId);
}
return mbMessagePersistence.findByP_S(parentMessageId, status);
}
@Override
public List getChildMessages(
long parentMessageId, int status, int start, int end) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByParentMessageId(
parentMessageId, start, end);
}
return mbMessagePersistence.findByP_S(
parentMessageId, status, start, end);
}
@Override
public int getChildMessagesCount(long parentMessageId, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.countByParentMessageId(parentMessageId);
}
return mbMessagePersistence.countByP_S(parentMessageId, status);
}
@Override
public List getCompanyMessages(
long companyId, int status, int start, int end) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByCompanyId(companyId, start, end);
}
return mbMessagePersistence.findByC_S(companyId, status, start, end);
}
@Override
public List getCompanyMessages(
long companyId, int status, int start, int end,
OrderByComparator orderByComparator) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByCompanyId(
companyId, start, end, orderByComparator);
}
return mbMessagePersistence.findByC_S(
companyId, status, start, end, orderByComparator);
}
@Override
public int getCompanyMessagesCount(long companyId, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.countByCompanyId(companyId);
}
return mbMessagePersistence.countByC_S(companyId, status);
}
@Override
public MBMessageDisplay getDiscussionMessageDisplay(
long userId, long groupId, String className, long classPK,
int status)
throws PortalException {
return getDiscussionMessageDisplay(
userId, groupId, className, classPK, status,
new MessageThreadComparator());
}
@Override
public MBMessageDisplay getDiscussionMessageDisplay(
long userId, long groupId, String className, long classPK,
int status, Comparator comparator)
throws PortalException {
long classNameId = _classNameLocalService.getClassNameId(className);
MBMessage message = null;
MBDiscussion discussion = _mbDiscussionLocalService.fetchDiscussion(
classNameId, classPK);
if (discussion != null) {
MBThread mbThread = _mbThreadPersistence.findByPrimaryKey(
discussion.getThreadId());
message = mbMessagePersistence.findByPrimaryKey(
mbThread.getRootMessageId());
}
else {
boolean workflowEnabled = WorkflowThreadLocal.isEnabled();
WorkflowThreadLocal.setEnabled(false);
try {
String subject = String.valueOf(classPK);
//String body = subject;
if (CTCollectionThreadLocal.isProductionMode() ||
_ctEntryLocalService.hasCTEntry(
CTCollectionThreadLocal.getCTCollectionId(),
classNameId, classPK)) {
message = mbMessageLocalService.addDiscussionMessage(
null, userId, null, groupId, className, classPK, 0,
MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, subject,
subject, new ServiceContext());
}
else {
try (SafeCloseable safeCloseable =
CTCollectionThreadLocal.
setProductionModeWithSafeCloseable()) {
message = mbMessageLocalService.addDiscussionMessage(
null, userId, null, groupId, className, classPK, 0,
MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID,
subject, subject, new ServiceContext());
}
}
}
catch (SystemException systemException) {
if (_log.isWarnEnabled()) {
_log.warn(
"Add failed, fetch {threadId=0, parentMessageId=" +
MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID + "}");
}
message = mbMessagePersistence.fetchByT_P_First(
0, MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID, null);
if (message == null) {
throw systemException;
}
}
finally {
WorkflowThreadLocal.setEnabled(workflowEnabled);
}
}
return getMessageDisplay(userId, message, status, comparator);
}
@Override
public int getDiscussionMessagesCount(
long classNameId, long classPK, int status) {
MBDiscussion discussion = _mbDiscussionLocalService.fetchDiscussion(
classNameId, classPK);
if (discussion == null) {
return 0;
}
int count = 0;
if (status == WorkflowConstants.STATUS_ANY) {
count = mbMessagePersistence.countByThreadId(
discussion.getThreadId());
}
else {
count = mbMessagePersistence.countByT_S(
discussion.getThreadId(), status);
}
if (count >= 1) {
return count - 1;
}
return 0;
}
@Override
public int getDiscussionMessagesCount(
String className, long classPK, int status) {
return getDiscussionMessagesCount(
_classNameLocalService.getClassNameId(className), classPK, status);
}
@Override
public List getDiscussions(String className) {
return _mbDiscussionLocalService.getDiscussions(className);
}
@Override
public MBMessage getFileEntryMessage(long fileEntryId)
throws PortalException {
return mbMessagePersistence.findByPrimaryKey(
_getFileEntryMessageId(fileEntryId));
}
@Override
public MBMessage getFirstMessage(long threadId, long parentMessageId)
throws PortalException {
return mbMessagePersistence.findByT_P_First(
threadId, parentMessageId, null);
}
@Override
public List getGroupMessages(
long groupId, int status, int start, int end) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByGroupId(groupId, start, end);
}
return mbMessagePersistence.findByG_S(groupId, status, start, end);
}
@Override
public List getGroupMessages(
long groupId, int status, int start, int end,
OrderByComparator orderByComparator) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByGroupId(
groupId, start, end, orderByComparator);
}
return mbMessagePersistence.findByG_S(
groupId, status, start, end, orderByComparator);
}
@Override
public List getGroupMessages(
long groupId, long userId, int status, int start, int end) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByG_U(groupId, userId, start, end);
}
return mbMessagePersistence.findByG_U_S(
groupId, userId, status, start, end);
}
@Override
public List getGroupMessages(
long groupId, long userId, int status, int start, int end,
OrderByComparator orderByComparator) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByG_U(
groupId, userId, start, end, orderByComparator);
}
return mbMessagePersistence.findByG_U_S(
groupId, userId, status, start, end, orderByComparator);
}
@Override
public int getGroupMessagesCount(long groupId, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.countByGroupId(groupId);
}
return mbMessagePersistence.countByG_S(groupId, status);
}
@Override
public int getGroupMessagesCount(long groupId, long userId, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.countByG_U(groupId, userId);
}
return mbMessagePersistence.countByG_U_S(groupId, userId, status);
}
@Override
public MBMessage getLastThreadMessage(long threadId, int status)
throws PortalException {
return mbMessagePersistence.findByT_S_Last(threadId, status, null);
}
@Override
public MBMessage getMessage(long messageId) throws PortalException {
return mbMessagePersistence.findByPrimaryKey(messageId);
}
@Override
public MBMessageDisplay getMessageDisplay(
long userId, long messageId, int status)
throws PortalException {
return getMessageDisplay(userId, getMessage(messageId), status);
}
@Override
public MBMessageDisplay getMessageDisplay(
long userId, MBMessage message, int status)
throws PortalException {
return getMessageDisplay(
userId, message, status, new MessageThreadComparator());
}
@Override
public MBMessageDisplay getMessageDisplay(
long userId, MBMessage message, int status,
Comparator comparator)
throws PortalException {
MBCategory category = null;
if ((message.getCategoryId() !=
MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) &&
(message.getCategoryId() !=
MBCategoryConstants.DISCUSSION_CATEGORY_ID)) {
category = _mbCategoryPersistence.findByPrimaryKey(
message.getCategoryId());
}
else {
category = new MBCategoryImpl();
category.setCategoryId(message.getCategoryId());
category.setDisplayStyle(MBCategoryConstants.DEFAULT_DISPLAY_STYLE);
}
MBMessage parentMessage = null;
if (message.isReply()) {
parentMessage = mbMessagePersistence.findByPrimaryKey(
message.getParentMessageId());
}
MBThread thread = _mbThreadPersistence.findByPrimaryKey(
message.getThreadId());
if (message.isApproved() && !message.isDiscussion()) {
_mbThreadLocalService.incrementViewCounter(thread.getThreadId(), 1);
SocialActivityManagerUtil.addActivity(
userId, thread, SocialActivityConstants.TYPE_VIEW,
StringPool.BLANK, 0);
}
List messages = null;
if (userId > 0) {
messages = getThreadMessages(
userId, message.getThreadId(), status, QueryUtil.ALL_POS,
QueryUtil.ALL_POS, comparator);
}
else {
messages = getThreadMessages(
message.getThreadId(), status, comparator);
}
int discussionMessagesCount = 0;
if (message.isDiscussion() &&
(PropsValues.DISCUSSION_MAX_COMMENTS > 0)) {
discussionMessagesCount = getDiscussionMessagesCount(
message.getClassName(), message.getClassPK(),
WorkflowConstants.STATUS_APPROVED);
}
return new MBMessageDisplayImpl(
message, parentMessage, messages, category, thread,
discussionMessagesCount);
}
@Override
public List getMessages(
String className, long classPK, int status) {
long classNameId = _classNameLocalService.getClassNameId(className);
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByC_C(classNameId, classPK);
}
return mbMessagePersistence.findByC_C_S(classNameId, classPK, status);
}
@Override
public int getPositionInThread(long messageId) throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
return mbMessageFinder.countByC_T(
message.getCreateDate(), message.getThreadId());
}
@Override
public List getRootDiscussionMessages(
String className, long classPK, int status)
throws PortalException {
return getRootDiscussionMessages(
className, classPK, status, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
}
@Override
public List getRootDiscussionMessages(
String className, long classPK, int status, int start, int end)
throws PortalException {
return getChildMessages(
_getRootDiscussionMessageId(className, classPK), status, start,
end);
}
@Override
public int getRootDiscussionMessagesCount(
String className, long classPK, int status) {
int count = 0;
try {
count = getChildMessagesCount(
_getRootDiscussionMessageId(className, classPK), status);
}
catch (PortalException portalException) {
if (_log.isWarnEnabled()) {
_log.warn(
StringBundler.concat(
"Unable to obtain root discussion message id for ",
"class name ", className, " and class PK ", classPK),
portalException);
}
}
return count;
}
@Override
public String[] getTempAttachmentNames(
long groupId, long userId, String folderName)
throws PortalException {
return TempFileEntryUtil.getTempFileNames(groupId, userId, folderName);
}
@Override
public List getThreadMessages(long threadId, int status) {
return getThreadMessages(
threadId, status, new MessageThreadComparator());
}
@Override
public List getThreadMessages(
long threadId, int status, Comparator comparator) {
List messages = null;
if (status == WorkflowConstants.STATUS_ANY) {
messages = mbMessagePersistence.findByThreadId(threadId);
}
else {
messages = mbMessagePersistence.findByT_S(threadId, status);
}
return ListUtil.sort(messages, comparator);
}
@Override
public List getThreadMessages(
long threadId, int status, int start, int end) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByThreadId(threadId, start, end);
}
return mbMessagePersistence.findByT_S(threadId, status, start, end);
}
@Override
public List getThreadMessages(
long threadId, long parentMessageId) {
return mbMessagePersistence.findByT_P(threadId, parentMessageId);
}
@Override
public List getThreadMessages(
long userId, long threadId, int status, int start, int end,
Comparator comparator) {
return MBMessageUtil.getThreadMessages(
mbMessagePersistence, mbMessageFinder, userId, threadId, status,
start, end, comparator);
}
@Override
public int getThreadMessagesCount(long threadId, boolean answer) {
return mbMessagePersistence.countByT_A(threadId, answer);
}
@Override
public int getThreadMessagesCount(long threadId, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.countByThreadId(threadId);
}
return mbMessagePersistence.countByT_S(threadId, status);
}
@Override
public List getThreadRepliesMessages(
long threadId, int status, int start, int end) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByThreadIdReplies(
threadId, start, end);
}
return mbMessagePersistence.findByTR_S(threadId, status, start, end);
}
@Override
public List getUserDiscussionMessages(
long userId, long classNameId, long classPK, int status, int start,
int end, OrderByComparator orderByComparator) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByU_C_C(
userId, classNameId, classPK, start, end, orderByComparator);
}
return mbMessagePersistence.findByU_C_C_S(
userId, classNameId, classPK, status, start, end,
orderByComparator);
}
@Override
public List getUserDiscussionMessages(
long userId, long[] classNameIds, int status, int start, int end,
OrderByComparator orderByComparator) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.findByU_C(
userId, classNameIds, start, end, orderByComparator);
}
return mbMessagePersistence.findByU_C_S(
userId, classNameIds, status, start, end, orderByComparator);
}
@Override
public List getUserDiscussionMessages(
long userId, String className, long classPK, int status, int start,
int end, OrderByComparator orderByComparator) {
return getUserDiscussionMessages(
userId, _classNameLocalService.getClassNameId(className), classPK,
status, start, end, orderByComparator);
}
@Override
public int getUserDiscussionMessagesCount(
long userId, long classNameId, long classPK, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.countByU_C_C(
userId, classNameId, classPK);
}
return mbMessagePersistence.countByU_C_C_S(
userId, classNameId, classPK, status);
}
@Override
public int getUserDiscussionMessagesCount(
long userId, long[] classNameIds, int status) {
if (status == WorkflowConstants.STATUS_ANY) {
return mbMessagePersistence.countByU_C(userId, classNameIds);
}
return mbMessagePersistence.countByU_C_S(userId, classNameIds, status);
}
@Override
public int getUserDiscussionMessagesCount(
long userId, String className, long classPK, int status) {
return getUserDiscussionMessagesCount(
userId, _classNameLocalService.getClassNameId(className), classPK,
status);
}
@Override
public long moveMessageAttachmentToTrash(
long userId, long messageId, String fileName)
throws PortalException {
MBMessage message = getMessage(messageId);
long folderId = message.getAttachmentsFolderId();
FileEntry fileEntry = _portletFileRepository.getPortletFileEntry(
message.getGroupId(), folderId, fileName);
_portletFileRepository.movePortletFileEntryToTrash(
userId, fileEntry.getFileEntryId());
return fileEntry.getFileEntryId();
}
@Override
public void restoreMessageAttachmentFromTrash(
long userId, long messageId, String deletedFileName)
throws PortalException {
MBMessage message = getMessage(messageId);
Folder folder = message.addAttachmentsFolder();
_portletFileRepository.restorePortletFileEntryFromTrash(
message.getGroupId(), userId, folder.getFolderId(),
deletedFileName);
}
@Override
public void subscribeMessage(long userId, long messageId)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
_subscriptionLocalService.addSubscription(
userId, message.getGroupId(), MBThread.class.getName(),
message.getThreadId());
}
@Override
public void unsubscribeMessage(long userId, long messageId)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
_subscriptionLocalService.deleteSubscription(
userId, MBThread.class.getName(), message.getThreadId());
}
@Indexable(type = IndexableType.REINDEX)
@Override
public MBMessage updateAnswer(
long messageId, boolean answer, boolean cascade)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
return updateAnswer(message, answer, cascade);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public MBMessage updateAnswer(
MBMessage message, boolean answer, boolean cascade)
throws PortalException {
return MBMessageUtil.updateAnswer(
mbMessagePersistence, message, answer, cascade);
}
@Override
public void updateAsset(
long userId, MBMessage message, long[] assetCategoryIds,
String[] assetTagNames, long[] assetLinkEntryIds)
throws PortalException {
_updateAsset(
userId, message, assetCategoryIds, assetTagNames, assetLinkEntryIds,
true);
}
@Override
public MBMessage updateDiscussionMessage(
long userId, long messageId, String className, long classPK,
String subject, String body, ServiceContext serviceContext)
throws PortalException {
subject = _getDiscussionMessageSubject(subject, body);
List> inputStreamOVPs = null;
double priority = 0.0;
boolean allowPingbacks = false;
serviceContext.setAttribute("className", className);
serviceContext.setAttribute("classPK", String.valueOf(classPK));
return mbMessageLocalService.updateMessage(
userId, messageId, subject, body, inputStreamOVPs, priority,
allowPingbacks, serviceContext);
}
@Override
public MBMessage updateMessage(
long userId, long messageId, String body,
ServiceContext serviceContext)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
return mbMessageLocalService.updateMessage(
userId, messageId, message.getSubject(), body, null,
message.getPriority(), message.isAllowPingbacks(), serviceContext);
}
@Override
public MBMessage updateMessage(
long userId, long messageId, String subject, String body,
List> inputStreamOVPs,
double priority, boolean allowPingbacks,
ServiceContext serviceContext)
throws PortalException {
// Message
MBMessage message = _updateMessage(
userId, messageId, subject, body, priority, allowPingbacks,
serviceContext);
// Attachments
if (ListUtil.isNotEmpty(inputStreamOVPs)) {
Folder folder = message.addAttachmentsFolder();
_portletFileRepository.addPortletFileEntries(
message.getGroupId(), userId, MBMessage.class.getName(),
message.getMessageId(), MBConstants.SERVICE_NAME,
folder.getFolderId(), inputStreamOVPs);
}
return message;
}
@Override
public MBMessage updateStatus(
long userId, long messageId, int status,
ServiceContext serviceContext,
Map workflowContext)
throws PortalException {
// Message
MBMessage message = getMessage(messageId);
int oldStatus = message.getStatus();
User user = _userLocalService.getUser(userId);
Date modifiedDate = serviceContext.getModifiedDate(new Date());
message.setStatus(status);
message.setStatusByUserId(userId);
message.setStatusByUserName(user.getFullName());
message.setStatusDate(modifiedDate);
message = mbMessagePersistence.update(message);
// Thread
MBThread thread = _mbThreadPersistence.findByPrimaryKey(
message.getThreadId());
_updateThreadStatus(thread, message, user, oldStatus, modifiedDate);
Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
MBMessage.class);
if (status == WorkflowConstants.STATUS_APPROVED) {
long notifySubscribersUserId = userId;
if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
notifySubscribersUserId = message.getUserId();
// Asset
if (serviceContext.isAssetEntryVisible() &&
((message.getClassNameId() == 0) ||
(message.getParentMessageId() != 0))) {
Date publishDate = null;
AssetEntry assetEntry = _assetEntryLocalService.fetchEntry(
message.getWorkflowClassName(), message.getMessageId());
if ((assetEntry != null) &&
(assetEntry.getPublishDate() != null)) {
publishDate = assetEntry.getPublishDate();
}
else {
publishDate = modifiedDate;
serviceContext.setCommand(Constants.ADD);
}
_assetEntryLocalService.updateEntry(
message.getWorkflowClassName(), message.getMessageId(),
publishDate, null, true, true);
}
}
// Social
_updateSocialActivity(user, message, serviceContext);
// Subscriptions
_notifySubscribers(
notifySubscribersUserId, (MBMessage)message.clone(),
(String)workflowContext.get(WorkflowConstants.CONTEXT_URL),
serviceContext);
// Indexer
indexer.reindex(message);
// Ping
_pingPingback(message, serviceContext);
}
else if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
// Asset
_assetEntryLocalService.updateVisible(
message.getWorkflowClassName(), message.getMessageId(), false);
// Indexer
indexer.delete(message);
}
return message;
}
@Override
public void updateUserName(long userId, String userName) {
List messages = mbMessagePersistence.findByUserId(userId);
for (MBMessage message : messages) {
message.setUserName(userName);
mbMessagePersistence.update(message);
}
}
@Activate
protected void activate() {
_closeable = _liferayJSONDeserializationWhitelist.register(
MBDiscussionSubscriptionSender.class.getName(),
MBSubscriptionSender.class.getName());
}
@Deactivate
@Override
protected void deactivate() {
super.deactivate();
try {
_closeable.close();
}
catch (Exception exception) {
throw new RuntimeException(exception);
}
}
private String _getBody(String subject, String body, String format) {
if (!Validator.isBlank(body)) {
return body;
}
if (StringUtil.equals(format, "html")) {
return HtmlUtil.escape(subject);
}
return subject;
}
private CommentGroupServiceConfiguration
_getCommentGroupServiceConfiguration(long groupId)
throws ConfigurationException {
return _configurationProvider.getConfiguration(
CommentGroupServiceConfiguration.class,
new GroupServiceSettingsLocator(
groupId, CommentConstants.SERVICE_NAME,
CommentGroupServiceConfiguration.class.getName()));
}
private String _getDiscussionMessageSubject(String subject, String body)
throws MessageBodyException {
if (Validator.isNotNull(subject)) {
return subject;
}
if (Validator.isNull(body)) {
throw new MessageBodyException("Body is null");
}
subject = _htmlParser.extractText(body);
if (subject.length() <= MBMessageConstants.MESSAGE_SUBJECT_MAX_LENGTH) {
return subject;
}
String subjectSubstring = subject.substring(
0, MBMessageConstants.MESSAGE_SUBJECT_MAX_LENGTH);
return subjectSubstring + StringPool.TRIPLE_PERIOD;
}
private long _getFileEntryMessageId(long fileEntryId)
throws PortalException {
// See LPS-110554
DLFileEntry dlFileEntry = _dlFileEntryLocalService.fetchDLFileEntry(
fileEntryId);
if (dlFileEntry != null) {
DLFolder dlFolder = dlFileEntry.getFolder();
return GetterUtil.getLong(dlFolder.getName());
}
FileEntry fileEntry = _portletFileRepository.getPortletFileEntry(
fileEntryId);
Folder folder = _portletFileRepository.getPortletFolder(
fileEntry.getFolderId());
return GetterUtil.getLong(folder.getName());
}
private String _getGroupDescriptiveName(Group group, Locale locale) {
try {
return group.getDescriptiveName(locale);
}
catch (PortalException portalException) {
_log.error(
"Unable to get descriptive name for group " +
group.getGroupId(),
portalException);
}
return StringPool.BLANK;
}
private String _getLayoutFullURL(
MBMessage message, String portletId, ServiceContext serviceContext)
throws PortalException {
List layouts = _layoutLocalService.getPublishedLayouts(
message.getGroupId(), QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
for (Layout curLayout : layouts) {
PortletPreferences portletPreferences =
_portletPreferencesLocalService.fetchPortletPreferences(
PortletKeys.PREFS_OWNER_ID_DEFAULT,
PortletKeys.PREFS_OWNER_TYPE_LAYOUT, curLayout.getPlid(),
portletId);
if (portletPreferences != null) {
return _portal.getLayoutFullURL(
curLayout, serviceContext.getThemeDisplay(), false);
}
}
String layoutFullURL = StringPool.BLANK;
Layout layout = _layoutLocalService.fetchLayout(
_portal.getPlidFromPortletId(
message.getGroupId(), false, portletId));
ThemeDisplay themeDisplay = serviceContext.getThemeDisplay();
if ((layout != null) && (themeDisplay != null)) {
layoutFullURL = _portal.getLayoutFullURL(layout, themeDisplay);
}
else {
layoutFullURL = _portal.getLayoutFullURL(
message.getGroupId(), portletId);
}
if (Validator.isNotNull(layoutFullURL)) {
return layoutFullURL;
}
return null;
}
private String _getLocalizedRootCategoryName(Group group, Locale locale) {
try {
return _language.get(locale, "home") + " - " +
group.getDescriptiveName(locale);
}
catch (PortalException portalException) {
_log.error(
"Unable to get descriptive name for group " +
group.getGroupId(),
portalException);
return _language.get(locale, "home");
}
}
private String _getMessageURL(
MBMessage message, ServiceContext serviceContext)
throws PortalException {
String entryURL = GetterUtil.getString(
serviceContext.getAttribute("entryURL"));
if (Validator.isNotNull(entryURL)) {
return entryURL;
}
String link = GetterUtil.getString(serviceContext.getAttribute("link"));
if (Validator.isNotNull(link)) {
return link + message.getUrlSubject();
}
HttpServletRequest httpServletRequest = serviceContext.getRequest();
if (httpServletRequest == null) {
if (Validator.isNull(serviceContext.getLayoutFullURL())) {
return StringPool.BLANK;
}
return StringBundler.concat(
serviceContext.getLayoutFullURL(),
Portal.FRIENDLY_URL_SEPARATOR, "message_boards/view_message/",
message.getMessageId());
}
String layoutURL = _getLayoutFullURL(
message,
PortletProviderUtil.getPortletId(
MBMessage.class.getName(), PortletProvider.Action.VIEW),
serviceContext);
if (Validator.isNotNull(layoutURL)) {
return StringBundler.concat(
layoutURL, Portal.FRIENDLY_URL_SEPARATOR,
"message_boards/view_message/", message.getMessageId());
}
Group group = _groupLocalService.fetchGroup(message.getGroupId());
return PortletURLBuilder.create(
_portal.getControlPanelPortletURL(
httpServletRequest, group,
PortletProviderUtil.getPortletId(
MBMessage.class.getName(), PortletProvider.Action.MANAGE),
0, 0, PortletRequest.RENDER_PHASE)
).setMVCRenderCommandName(
"/message_boards/view_message"
).setParameter(
"messageId", message.getMessageId()
).buildString();
}
private long _getRootDiscussionMessageId(String className, long classPK)
throws PortalException {
MBMessage message = mbMessagePersistence.findByC_C_First(
_classNameLocalService.getClassNameId(className), classPK,
new MessageCreateDateComparator(true));
return message.getMessageId();
}
private String _getSubject(String subject, String body) {
if (Validator.isNull(subject)) {
return StringUtil.shorten(body);
}
return subject;
}
private MBSubscriptionSender _getSubscriptionSender(
long userId, MBCategory category, MBMessage message,
String messageURL, String entryTitle, boolean htmlFormat,
String messageBody, String messageSubject,
String messageSubjectPrefix, String inReplyTo, String fromName,
String fromAddress, String replyToAddress, String emailAddress,
String fullName, String messageParentMessageContent,
String messageSiblingMessagesContent, String rootMessageBody,
LocalizedValuesMap subjectLocalizedValuesMap,
LocalizedValuesMap bodyLocalizedValuesMap,
ServiceContext serviceContext)
throws PortalException {
MBSubscriptionSender subscriptionSender = new MBSubscriptionSender(
MBConstants.RESOURCE_NAME);
subscriptionSender.setAnonymous(message.isAnonymous());
subscriptionSender.setBulk(PropsValues.MESSAGE_BOARDS_EMAIL_BULK);
subscriptionSender.setClassName(message.getModelClassName());
subscriptionSender.setClassPK(message.getMessageId());
subscriptionSender.setCompanyId(message.getCompanyId());
subscriptionSender.setContextAttribute(
"[$MESSAGE_BODY$]", messageBody, false);
subscriptionSender.setContextAttribute(
"[$MESSAGE_PARENT$]", messageParentMessageContent, false);
subscriptionSender.setContextAttribute(
"[$MESSAGE_SIBLINGS$]", messageSiblingMessagesContent, false);
subscriptionSender.setContextAttribute(
"[$ROOT_MESSAGE_BODY$]", rootMessageBody, false);
long groupId = message.getGroupId();
Group group = _groupLocalService.getGroup(groupId);
if (category.getCategoryId() !=
MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
subscriptionSender.setContextAttribute(
"[$CATEGORY_NAME$]", category.getName(), true);
}
else {
subscriptionSender.setLocalizedContextAttribute(
"[$CATEGORY_NAME$]",
new EscapableLocalizableFunction(
locale -> _getLocalizedRootCategoryName(group, locale)));
}
subscriptionSender.setContextAttributes(
"[$MAILING_LIST_ADDRESS$]", replyToAddress, "[$MESSAGE_ID$]",
message.getMessageId(), "[$MESSAGE_SUBJECT$]", messageSubject,
"[$MESSAGE_SUBJECT_PREFIX$]", messageSubjectPrefix,
"[$MESSAGE_URL$]", messageURL, "[$MESSAGE_USER_ADDRESS$]",
emailAddress, "[$MESSAGE_USER_NAME$]", fullName);
subscriptionSender.setCreatorUserId(message.getUserId());
subscriptionSender.setCurrentUserId(userId);
subscriptionSender.setEntryTitle(entryTitle);
subscriptionSender.setEntryURL(messageURL);
subscriptionSender.setFrom(fromAddress, fromName);
subscriptionSender.setFullName(fullName);
subscriptionSender.setHtmlFormat(htmlFormat);
subscriptionSender.setInReplyTo(inReplyTo);
subscriptionSender.setLocalizedContextAttribute(
"[$SITE_NAME$]",
new EscapableLocalizableFunction(
locale -> _getGroupDescriptiveName(group, locale)));
if (bodyLocalizedValuesMap != null) {
subscriptionSender.setLocalizedBodyMap(
_localization.getMap(bodyLocalizedValuesMap));
}
if (subjectLocalizedValuesMap != null) {
subscriptionSender.setLocalizedSubjectMap(
_localization.getMap(subjectLocalizedValuesMap));
}
Date modifiedDate = message.getModifiedDate();
subscriptionSender.setMailId(
MBMailUtil.MESSAGE_POP_PORTLET_PREFIX, message.getCategoryId(),
message.getMessageId(), modifiedDate.getTime());
int notificationType =
UserNotificationDefinition.NOTIFICATION_TYPE_ADD_ENTRY;
if (serviceContext.isCommandUpdate()) {
notificationType =
UserNotificationDefinition.NOTIFICATION_TYPE_UPDATE_ENTRY;
}
subscriptionSender.setNotificationType(notificationType);
subscriptionSender.setPortletId(
PortletProviderUtil.getPortletId(
MBMessage.class.getName(), PortletProvider.Action.VIEW));
subscriptionSender.setReplyToAddress(replyToAddress);
subscriptionSender.setScopeGroupId(groupId);
subscriptionSender.setServiceContext(serviceContext);
subscriptionSender.setUniqueMailId(false);
return subscriptionSender;
}
private String _getUniqueUrlSubject(
long groupId, long mbMessageId, String subject) {
String urlSubject = _getUrlSubject(mbMessageId, subject);
String uniqueUrlSubject = urlSubject;
MBMessage mbMessage = mbMessagePersistence.fetchByG_US(
groupId, uniqueUrlSubject);
for (int i = 1; mbMessage != null; i++) {
uniqueUrlSubject = urlSubject + StringPool.DASH + i;
mbMessage = mbMessagePersistence.fetchByG_US(
groupId, uniqueUrlSubject);
}
return uniqueUrlSubject;
}
private String _getUrlSubject(long id, String subject) {
if (subject == null) {
return String.valueOf(id);
}
subject = StringUtil.toLowerCase(subject.trim());
if (Validator.isNull(subject) || Validator.isNumber(subject) ||
subject.equals("rss")) {
subject = String.valueOf(id);
}
else {
subject = _friendlyURLNormalizer.normalizeWithPeriodsAndSlashes(
subject);
}
return ModelHintsUtil.trimString(
MBMessage.class.getName(), "urlSubject", subject);
}
private void _notifyDiscussionSubscribers(
long userId, MBMessage message, ServiceContext serviceContext)
throws PortalException {
CommentGroupServiceConfiguration commentGroupServiceConfiguration =
_getCommentGroupServiceConfiguration(message.getGroupId());
MBDiscussion mbDiscussion =
_mbDiscussionLocalService.getThreadDiscussion(
message.getThreadId());
String contentURL = (String)serviceContext.getAttribute("contentURL");
contentURL = HttpComponentsUtil.addParameter(
contentURL, serviceContext.getAttribute("namespace") + "messageId",
message.getMessageId());
String userAddress = StringPool.BLANK;
String userName = (String)serviceContext.getAttribute(
"pingbackUserName");
if (Validator.isNull(userName)) {
userAddress = _portal.getUserEmailAddress(message.getUserId());
userName = _portal.getUserName(
message.getUserId(), StringPool.BLANK);
}
SubscriptionSender subscriptionSender =
new MBDiscussionSubscriptionSender(
commentGroupServiceConfiguration);
subscriptionSender.setCompanyId(message.getCompanyId());
subscriptionSender.setClassName(MBDiscussion.class.getName());
subscriptionSender.setClassPK(mbDiscussion.getDiscussionId());
subscriptionSender.setContextAttribute(
"[$COMMENTS_BODY$]", message.getBody(message.isFormatBBCode()),
false);
subscriptionSender.setContextAttributes(
"[$COMMENTS_USER_ADDRESS$]", userAddress, "[$COMMENTS_USER_NAME$]",
userName, "[$CONTENT_URL$]", contentURL);
subscriptionSender.setCurrentUserId(userId);
subscriptionSender.setEntryTitle(message.getBody());
subscriptionSender.setEntryURL(contentURL);
subscriptionSender.setFrom(
commentGroupServiceConfiguration.emailFromAddress(),
commentGroupServiceConfiguration.emailFromName());
subscriptionSender.setHtmlFormat(true);
Map localizedBodyMap = null;
Map localizedSubjectMap = null;
if (serviceContext.isCommandUpdate()) {
localizedBodyMap = _localization.getMap(
commentGroupServiceConfiguration.discussionEmailUpdatedBody());
localizedSubjectMap = _localization.getMap(
commentGroupServiceConfiguration.
discussionEmailUpdatedSubject());
}
else {
localizedBodyMap = _localization.getMap(
commentGroupServiceConfiguration.discussionEmailBody());
localizedSubjectMap = _localization.getMap(
commentGroupServiceConfiguration.discussionEmailSubject());
}
if (localizedBodyMap != null) {
subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
}
if (localizedSubjectMap != null) {
subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
}
Date modifiedDate = message.getModifiedDate();
subscriptionSender.setMailId(
"mb_discussion", message.getCategoryId(), message.getMessageId(),
modifiedDate.getTime());
int notificationType =
UserNotificationDefinition.NOTIFICATION_TYPE_ADD_ENTRY;
if (serviceContext.isCommandUpdate()) {
notificationType =
UserNotificationDefinition.NOTIFICATION_TYPE_UPDATE_ENTRY;
}
subscriptionSender.setNotificationType(notificationType);
subscriptionSender.setPortletId(
PortletProviderUtil.getPortletId(
Comment.class.getName(), PortletProvider.Action.VIEW));
subscriptionSender.setScopeGroupId(message.getGroupId());
subscriptionSender.setServiceContext(serviceContext);
subscriptionSender.setUniqueMailId(false);
String className = (String)serviceContext.getAttribute("className");
long classPK = ParamUtil.getLong(serviceContext, "classPK");
subscriptionSender.addPersistedSubscribers(
com.liferay.message.boards.util.MBUtil.getSubscriptionClassName(
className),
classPK);
subscriptionSender.flushNotificationsAsync();
}
private void _notifySubscribers(
long userId, MBMessage message, String messageURL,
ServiceContext serviceContext)
throws PortalException {
if (!message.isApproved() || Validator.isNull(messageURL)) {
return;
}
if (message.isDiscussion()) {
if (CopyLayoutThreadLocal.isCopyLayout()) {
return;
}
try {
_notifyDiscussionSubscribers(userId, message, serviceContext);
}
catch (Exception exception) {
_log.error(exception);
}
return;
}
MBGroupServiceSettings mbGroupServiceSettings =
MBGroupServiceSettings.getInstance(message.getGroupId());
if (serviceContext.isCommandAdd() &&
mbGroupServiceSettings.isEmailMessageAddedEnabled()) {
}
else if (serviceContext.isCommandUpdate() &&
mbGroupServiceSettings.isEmailMessageUpdatedEnabled()) {
}
else {
return;
}
Company company = _companyLocalService.getCompany(
message.getCompanyId());
User user = _userLocalService.getUser(userId);
String emailAddress = user.getEmailAddress();
String fullName = user.getFullName();
if (message.isAnonymous()) {
emailAddress = StringPool.BLANK;
fullName = serviceContext.translate("anonymous");
}
MBCategory category = message.getCategory();
List categoryIds = new ArrayList<>();
categoryIds.add(message.getCategoryId());
if (message.getCategoryId() !=
MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
categoryIds.addAll(category.getAncestorCategoryIds());
}
String entryTitle = message.getSubject();
String fromName = mbGroupServiceSettings.getEmailFromName();
String fromAddress = mbGroupServiceSettings.getEmailFromAddress();
String replyToAddress = StringPool.BLANK;
if (PrefsPropsUtil.getBoolean(
company.getCompanyId(),
PropsKeys.POP_SERVER_NOTIFICATIONS_ENABLED,
PropsValues.POP_SERVER_NOTIFICATIONS_ENABLED)) {
replyToAddress = MBMailUtil.getReplyToAddress(
message.getCategoryId(), message.getMessageId(),
company.getMx(), fromAddress);
}
LocalizedValuesMap subjectLocalizedValuesMap = null;
LocalizedValuesMap bodyLocalizedValuesMap = null;
if (serviceContext.isCommandUpdate()) {
subjectLocalizedValuesMap =
mbGroupServiceSettings.getEmailMessageUpdatedSubject();
bodyLocalizedValuesMap =
mbGroupServiceSettings.getEmailMessageUpdatedBody();
}
else {
subjectLocalizedValuesMap =
mbGroupServiceSettings.getEmailMessageAddedSubject();
bodyLocalizedValuesMap =
mbGroupServiceSettings.getEmailMessageAddedBody();
}
boolean htmlFormat = mbGroupServiceSettings.isEmailHtmlFormat();
int maxNumberOfMessages = 3;
int maxNumberOfParentMessages = 1;
MBMessageNotificationTemplateHelper
mbMessageNotificationTemplateHelper =
new MBMessageNotificationTemplateHelper(
htmlFormat, maxNumberOfMessages, maxNumberOfParentMessages,
mbMessageLocalService, serviceContext);
String messageBody = mbMessageNotificationTemplateHelper.getMessageBody(
message, StringPool.BLANK);
String inReplyTo = null;
String messageSubject = message.getSubject();
String messageSubjectPrefix = StringPool.BLANK;
String messageParentMessageContent = StringPool.BLANK;
String messageSiblingMessagesContent = StringPool.BLANK;
if (message.getParentMessageId() !=
MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
MBMessage parentMessage = mbMessageLocalService.getMessage(
message.getParentMessageId());
Date modifiedDate = parentMessage.getModifiedDate();
inReplyTo = _portal.getMailId(
company.getMx(), MBMailUtil.MESSAGE_POP_PORTLET_PREFIX,
message.getCategoryId(), parentMessage.getMessageId(),
modifiedDate.getTime());
if (messageSubject.startsWith(
MBMessageConstants.MESSAGE_SUBJECT_PREFIX_RE)) {
messageSubjectPrefix =
MBMessageConstants.MESSAGE_SUBJECT_PREFIX_RE;
messageSubject = messageSubject.substring(
messageSubjectPrefix.length());
}
messageParentMessageContent =
mbMessageNotificationTemplateHelper.
renderMessageParentMessageContent(parentMessage);
messageSiblingMessagesContent =
mbMessageNotificationTemplateHelper.
renderMessageSiblingMessagesContent(message);
}
String rootMessageBody =
mbMessageNotificationTemplateHelper.renderRootMessage(message);
SubscriptionSender subscriptionSender = _getSubscriptionSender(
userId, category, message, messageURL, entryTitle, htmlFormat,
messageBody, messageSubject, messageSubjectPrefix, inReplyTo,
fromName, fromAddress, replyToAddress, emailAddress, fullName,
messageParentMessageContent, messageSiblingMessagesContent,
rootMessageBody, subjectLocalizedValuesMap, bodyLocalizedValuesMap,
serviceContext);
subscriptionSender.addAssetEntryPersistedSubscribers(
MBMessage.class.getName(), message.getMessageId());
subscriptionSender.addPersistedSubscribers(
MBCategory.class.getName(), message.getGroupId());
for (long categoryId : categoryIds) {
if (categoryId != MBCategoryConstants.DEFAULT_PARENT_CATEGORY_ID) {
subscriptionSender.addPersistedSubscribers(
MBCategory.class.getName(), categoryId);
}
}
subscriptionSender.addPersistedSubscribers(
MBThread.class.getName(), message.getThreadId());
subscriptionSender.flushNotificationsAsync();
if (!MailingListThreadLocal.isSourceMailingList()) {
for (long categoryId : categoryIds) {
MBSubscriptionSender sourceMailingListSubscriptionSender =
_getSubscriptionSender(
userId, category, message, messageURL, entryTitle,
htmlFormat, messageBody, messageSubject,
messageSubjectPrefix, inReplyTo, fromName, fromAddress,
replyToAddress, emailAddress, fullName,
messageParentMessageContent,
messageSiblingMessagesContent, rootMessageBody,
subjectLocalizedValuesMap, bodyLocalizedValuesMap,
serviceContext);
sourceMailingListSubscriptionSender.setBulk(false);
sourceMailingListSubscriptionSender.addMailingListSubscriber(
message.getGroupId(), categoryId);
sourceMailingListSubscriptionSender.flushNotificationsAsync();
}
}
}
private void _pingPingback(
MBMessage message, ServiceContext serviceContext) {
if (!PropsValues.BLOGS_PINGBACK_ENABLED ||
!message.isAllowPingbacks() || !message.isApproved()) {
return;
}
String layoutFullURL = serviceContext.getLayoutFullURL();
if (Validator.isNull(layoutFullURL)) {
return;
}
String sourceUri = StringBundler.concat(
layoutFullURL, Portal.FRIENDLY_URL_SEPARATOR,
"message_boards/view_message/", message.getMessageId());
Source source = new Source(message.getBody(message.isFormatBBCode()));
List startTags = source.getAllStartTags("a");
for (StartTag startTag : startTags) {
String targetUri = startTag.getAttributeValue("href");
if (Validator.isNotNull(targetUri)) {
try {
LinkbackProducerUtil.sendPingback(sourceUri, targetUri);
}
catch (Exception exception) {
_log.error(
"Error while sending pingback " + targetUri, exception);
}
}
}
}
private MBMessage _startWorkflowInstance(
long userId, MBMessage message, ServiceContext serviceContext)
throws PortalException {
Map workflowContext =
HashMapBuilder.put(
WorkflowConstants.CONTEXT_URL,
_getMessageURL(message, serviceContext)
).build();
return WorkflowHandlerRegistryUtil.startWorkflowInstance(
message.getCompanyId(), message.getGroupId(), userId,
message.getWorkflowClassName(), message.getMessageId(), message,
serviceContext, workflowContext);
}
private void _updateAsset(
long userId, MBMessage message, long[] assetCategoryIds,
String[] assetTagNames, long[] assetLinkEntryIds,
boolean assetEntryVisible)
throws PortalException {
boolean visible = false;
Date publishDate = null;
if (assetEntryVisible && message.isApproved() &&
((message.getClassNameId() == 0) ||
(message.getParentMessageId() != 0))) {
visible = true;
publishDate = message.getModifiedDate();
}
AssetEntry assetEntry = _assetEntryLocalService.updateEntry(
userId, message.getGroupId(), message.getCreateDate(),
message.getModifiedDate(), message.getWorkflowClassName(),
message.getMessageId(), message.getUuid(), 0, assetCategoryIds,
assetTagNames, true, visible, null, null, publishDate, null,
ContentTypes.TEXT_HTML, message.getSubject(), null, null, null,
null, 0, 0, message.getPriority());
_assetLinkLocalService.updateLinks(
userId, assetEntry.getEntryId(), assetLinkEntryIds,
AssetLinkConstants.TYPE_RELATED);
}
private MBMessage _updateMessage(
long userId, long messageId, String subject, String body,
double priority, boolean allowPingbacks,
ServiceContext serviceContext)
throws PortalException {
MBMessage message = mbMessagePersistence.findByPrimaryKey(messageId);
int oldStatus = message.getStatus();
String oldSubject = message.getSubject();
Date modifiedDate = serviceContext.getModifiedDate(null);
subject = ModelHintsUtil.trimString(
MBMessage.class.getName(), "subject", subject);
subject = _getSubject(subject, body);
body = _getBody(subject, body, message.getFormat());
body = SanitizerUtil.sanitize(
message.getCompanyId(), message.getGroupId(), userId,
MBMessage.class.getName(), messageId, "text/" + message.getFormat(),
Sanitizer.MODE_ALL, body,
HashMapBuilder.put(
"discussion", message.isDiscussion()
).build());
_validate(subject, body);
message.setModifiedDate(modifiedDate);
message.setSubject(subject);
message.setBody(body);
message.setAllowPingbacks(allowPingbacks);
if (priority != MBThreadConstants.PRIORITY_NOT_GIVEN) {
message.setPriority(priority);
}
MBThread thread = _mbThreadPersistence.findByPrimaryKey(
message.getThreadId());
if ((serviceContext.getWorkflowAction() ==
WorkflowConstants.ACTION_SAVE_DRAFT) &&
!message.isDraft() && !message.isPending()) {
message.setStatus(WorkflowConstants.STATUS_DRAFT);
// Thread
thread = _updateThreadStatus(
thread, message, _userLocalService.getUser(userId), oldStatus,
modifiedDate);
// Asset
_assetEntryLocalService.updateVisible(
message.getWorkflowClassName(), message.getMessageId(), false);
if (!message.isDiscussion()) {
// Indexer
Indexer indexer =
IndexerRegistryUtil.nullSafeGetIndexer(MBMessage.class);
indexer.delete(message);
}
}
message.setExpandoBridgeAttributes(serviceContext);
message = mbMessagePersistence.update(message);
// Thread
if ((priority != MBThreadConstants.PRIORITY_NOT_GIVEN) &&
(thread.getPriority() != priority)) {
thread.setPriority(priority);
thread = _mbThreadLocalService.updateMBThread(thread);
_updatePriorities(thread.getThreadId(), priority);
}
if (message.isRoot()) {
if (!Objects.equals(subject, oldSubject)) {
thread.setTitle(subject);
}
_mbThreadLocalService.updateMBThread(thread);
}
// Asset
updateAsset(
userId, message, serviceContext.getAssetCategoryIds(),
serviceContext.getAssetTagNames(),
serviceContext.getAssetLinkEntryIds());
// Workflow
return _startWorkflowInstance(userId, message, serviceContext);
}
private void _updatePriorities(long threadId, double priority) {
List messages = mbMessagePersistence.findByThreadId(
threadId);
for (MBMessage message : messages) {
if (message.getPriority() != priority) {
message.setPriority(priority);
mbMessagePersistence.update(message);
}
}
}
private void _updateSocialActivity(
User user, MBMessage message, ServiceContext serviceContext)
throws PortalException {
String title = message.getSubject();
if (message.isDiscussion()) {
title = HtmlUtil.stripHtml(title);
}
JSONObject extraDataJSONObject = JSONUtil.put("title", title);
if (!message.isDiscussion()) {
if (!message.isAnonymous() && !user.isGuestUser()) {
long receiverUserId = 0;
MBMessage parentMessage =
mbMessagePersistence.fetchByPrimaryKey(
message.getParentMessageId());
if (parentMessage != null) {
receiverUserId = parentMessage.getUserId();
}
int activityKey = MBActivityKeys.UPDATE_MESSAGE;
if (serviceContext.isCommandAdd()) {
activityKey = MBActivityKeys.ADD_MESSAGE;
}
SocialActivityManagerUtil.addActivity(
message.getUserId(), message, activityKey,
extraDataJSONObject.toString(), receiverUserId);
if ((parentMessage != null) &&
(receiverUserId != message.getUserId())) {
SocialActivityManagerUtil.addActivity(
message.getUserId(), parentMessage,
MBActivityKeys.REPLY_MESSAGE,
extraDataJSONObject.toString(), 0);
}
}
}
else if (serviceContext.isCommandAdd()) {
long parentMessageId = message.getParentMessageId();
if (parentMessageId !=
MBMessageConstants.DEFAULT_PARENT_MESSAGE_ID) {
String className = (String)serviceContext.getAttribute(
"className");
long classPK = ParamUtil.getLong(serviceContext, "classPK");
AssetEntry assetEntry = _assetEntryLocalService.fetchEntry(
className, classPK);
if (assetEntry != null) {
extraDataJSONObject.put(
"messageId", message.getMessageId());
SocialActivityManagerUtil.addActivity(
message.getUserId(), assetEntry,
SocialActivityConstants.TYPE_ADD_COMMENT,
extraDataJSONObject.toString(), assetEntry.getUserId());
}
}
}
}
private MBThread _updateThreadStatus(
MBThread thread, MBMessage message, User user, int oldStatus,
Date modifiedDate)
throws PortalException {
int status = message.getStatus();
if (status == oldStatus) {
return thread;
}
if (thread.getRootMessageId() == message.getMessageId()) {
thread.setModifiedDate(modifiedDate);
thread.setStatus(status);
thread.setStatusByUserId(user.getUserId());
thread.setStatusByUserName(user.getFullName());
thread.setStatusDate(modifiedDate);
if (status == WorkflowConstants.STATUS_APPROVED) {
if (message.isAnonymous()) {
thread.setLastPostByUserId(0);
}
else {
thread.setLastPostByUserId(message.getUserId());
}
thread.setLastPostDate(modifiedDate);
}
thread = _mbThreadPersistence.update(thread);
Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
MBThread.class);
indexer.reindex(thread);
}
else if (status == WorkflowConstants.STATUS_APPROVED) {
_mbThreadLocalService.updateLastPostDate(
thread.getThreadId(), modifiedDate);
}
return thread;
}
private void _validate(String subject, String body) throws PortalException {
if (Validator.isNull(subject) && Validator.isNull(body)) {
throw new MessageSubjectException("Subject and body are null");
}
}
private void _validateDiscussionMaxComments(String className, long classPK)
throws PortalException {
if (PropsValues.DISCUSSION_MAX_COMMENTS <= 0) {
return;
}
int count = mbMessageLocalService.getDiscussionMessagesCount(
className, classPK, WorkflowConstants.STATUS_APPROVED);
if (count >= PropsValues.DISCUSSION_MAX_COMMENTS) {
int max = PropsValues.DISCUSSION_MAX_COMMENTS - 1;
throw new DiscussionMaxCommentsException(count + " exceeds " + max);
}
}
private static final Log _log = LogFactoryUtil.getLog(
MBMessageLocalServiceImpl.class);
@Reference
private AssetEntryLocalService _assetEntryLocalService;
@Reference
private AssetLinkLocalService _assetLinkLocalService;
@Reference
private ClassNameLocalService _classNameLocalService;
private Closeable _closeable;
@Reference
private CompanyLocalService _companyLocalService;
@Reference
private ConfigurationProvider _configurationProvider;
@Reference
private CTEntryLocalService _ctEntryLocalService;
@Reference
private DLFileEntryLocalService _dlFileEntryLocalService;
@Reference
private ExpandoRowLocalService _expandoRowLocalService;
@Reference
private FriendlyURLNormalizer _friendlyURLNormalizer;
@Reference
private GroupLocalService _groupLocalService;
@Reference
private HtmlParser _htmlParser;
@Reference
private Language _language;
@Reference
private LayoutLocalService _layoutLocalService;
@Reference
private LiferayJSONDeserializationWhitelist
_liferayJSONDeserializationWhitelist;
@Reference
private Localization _localization;
@Reference
private MBCategoryPersistence _mbCategoryPersistence;
@Reference
private MBDiscussionLocalService _mbDiscussionLocalService;
@Reference
private MBThreadLocalService _mbThreadLocalService;
@Reference
private MBThreadPersistence _mbThreadPersistence;
@Reference
private Portal _portal;
@Reference
private PortletFileRepository _portletFileRepository;
@Reference
private PortletPreferencesLocalService _portletPreferencesLocalService;
@Reference
private RatingsStatsLocalService _ratingsStatsLocalService;
@Reference
private ResourceLocalService _resourceLocalService;
@Reference
private SubscriptionLocalService _subscriptionLocalService;
@Reference
private UserLocalService _userLocalService;
@Reference
private WorkflowInstanceLinkLocalService _workflowInstanceLinkLocalService;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy