/**
* 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.content.targeting.service.impl;
import com.liferay.content.targeting.InvalidNameException;
import com.liferay.content.targeting.UsedUserSegmentException;
import com.liferay.content.targeting.model.Campaign;
import com.liferay.content.targeting.model.ReportInstance;
import com.liferay.content.targeting.model.RuleInstance;
import com.liferay.content.targeting.model.UserSegment;
import com.liferay.content.targeting.service.base.UserSegmentLocalServiceBaseImpl;
import com.liferay.content.targeting.util.BaseModelSearchResult;
import com.liferay.content.targeting.util.ContentTargetingUtil;
import com.liferay.content.targeting.util.PortletKeys;
import com.liferay.content.targeting.util.UserSegmentUtil;
import com.liferay.counter.service.CounterLocalServiceUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.search.Hits;
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.search.SearchContext;
import com.liferay.portal.kernel.search.SearchException;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.OrderByComparator;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.Validator;
import com.liferay.portal.model.Group;
import com.liferay.portal.model.ResourceConstants;
import com.liferay.portal.model.SystemEventConstants;
import com.liferay.portal.model.User;
import com.liferay.portal.service.GroupLocalServiceUtil;
import com.liferay.portal.service.ServiceContext;
import com.liferay.portal.service.UserLocalServiceUtil;
import com.liferay.portlet.asset.DuplicateCategoryException;
import com.liferay.portlet.asset.NoSuchCategoryException;
import com.liferay.portlet.asset.model.AssetCategory;
import com.liferay.portlet.asset.model.AssetCategoryConstants;
import com.liferay.portlet.asset.service.AssetCategoryLocalServiceUtil;
import com.liferay.portlet.asset.service.AssetVocabularyLocalServiceUtil;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Map;
/**
* The implementation of the user segment local service.
*
* <p>
* All custom service methods should be put in this class. Whenever methods are added, rerun ServiceBuilder to copy their definitions into the {@link com.liferay.content.targeting.service.UserSegmentLocalService} interface.
*
* <p>
* This is a local service. Methods of this service will not have security checks based on the propagated JAAS credentials because this service can only be accessed from within the same VM.
* </p>
*
* @author Eudaldo Alonso
* @author Julio Camarero
* @see com.liferay.content.targeting.service.base.UserSegmentLocalServiceBaseImpl
* @see com.liferay.content.targeting.service.UserSegmentLocalServiceUtil
*/
public class UserSegmentLocalServiceImpl
extends UserSegmentLocalServiceBaseImpl {
@Indexable(type = IndexableType.REINDEX)
@Override
public UserSegment addUserSegment(
long userId, Map<Locale, String> nameMap,
Map<Locale, String> descriptionMap, ServiceContext serviceContext)
throws PortalException, SystemException {
User user = UserLocalServiceUtil.getUser(userId);
Date now = new Date();
long userSegmentId = CounterLocalServiceUtil.increment();
UserSegment userSegment = userSegmentPersistence.create(userSegmentId);
userSegment.setUuid(serviceContext.getUuid());
userSegment.setGroupId(serviceContext.getScopeGroupId());
// Category
AssetCategory assetCategory = null;
long assetCategoryId = GetterUtil.getLong(
serviceContext.getAttribute("userSegmentAssetCategoryId"));
if (assetCategoryId > 0) {
assetCategory = AssetCategoryLocalServiceUtil.getAssetCategory(
assetCategoryId);
}
else {
assetCategory = addUserSegmentCategory(
userId, nameMap, descriptionMap, serviceContext);
}
userSegment.setAssetCategoryId(assetCategory.getCategoryId());
userSegment.setCompanyId(user.getCompanyId());
userSegment.setUserId(user.getUserId());
userSegment.setUserName(user.getFullName());
userSegment.setCreateDate(serviceContext.getCreateDate(now));
userSegment.setModifiedDate(serviceContext.getModifiedDate(now));
userSegment.setNameMap(nameMap);
userSegment.setDescriptionMap(descriptionMap);
validateUserSegment(userSegment);
userSegmentPersistence.update(userSegment);
// Resources
if (serviceContext.isAddGroupPermissions() ||
serviceContext.isAddGuestPermissions()) {
addUserSegmentResources(
userSegment, serviceContext.isAddGroupPermissions(),
serviceContext.isAddGuestPermissions());
}
else {
addUserSegmentResources(
userSegment, serviceContext.getGroupPermissions(),
serviceContext.getGuestPermissions());
}
// Local Live Category
Group scopeGroup = serviceContext.getScopeGroup();
if (scopeGroup.hasStagingGroup() &&
!ContentTargetingUtil.isStaged(
scopeGroup.getGroupId(), PortletKeys.CT_ADMIN)) {
Group stagingGroup = scopeGroup.getStagingGroup();
ServiceContext serviceContextStaging =
(ServiceContext)serviceContext.clone();
serviceContextStaging.setScopeGroupId(stagingGroup.getGroupId());
serviceContextStaging.setUuid(assetCategory.getUuid());
addUserSegmentCategory(
userId, nameMap, descriptionMap, serviceContextStaging);
}
return userSegment;
}
@Override
public void addUserSegmentResources(
UserSegment userSegment, boolean addGroupPermissions,
boolean addGuestPermissions)
throws PortalException, SystemException {
resourceLocalService.addResources(
userSegment.getCompanyId(), userSegment.getGroupId(),
userSegment.getUserId(), UserSegment.class.getName(),
userSegment.getUserSegmentId(), false, addGroupPermissions,
addGuestPermissions);
}
@Override
public void addUserSegmentResources(
UserSegment userSegment, String[] groupPermissions,
String[] guestPermissions)
throws PortalException, SystemException {
resourceLocalService.addModelResources(
userSegment.getCompanyId(), userSegment.getGroupId(),
userSegment.getUserId(), UserSegment.class.getName(),
userSegment.getUserSegmentId(), groupPermissions, guestPermissions);
}
@Indexable(type = IndexableType.DELETE)
@Override
public UserSegment deleteUserSegment(long userSegmentId)
throws PortalException, SystemException {
List<Campaign> campaigns = userSegmentPersistence.getCampaigns(
userSegmentId);
if (!campaigns.isEmpty()) {
throw new UsedUserSegmentException(campaigns);
}
UserSegment userSegment = userSegmentPersistence.findByPrimaryKey(
userSegmentId);
return deleteUserSegment(userSegment);
}
@Indexable(type = IndexableType.DELETE)
@Override
public UserSegment deleteUserSegment(UserSegment userSegment)
throws PortalException, SystemException {
userSegmentPersistence.remove(userSegment);
// System event
systemEventLocalService.addSystemEvent(
0, userSegment.getGroupId(), UserSegment.class.getName(),
userSegment.getUserSegmentId(), userSegment.getUuid(), null,
SystemEventConstants.TYPE_DELETE, StringPool.BLANK);
// Resources
resourceLocalService.deleteResource(
userSegment.getCompanyId(), UserSegment.class.getName(),
ResourceConstants.SCOPE_INDIVIDUAL, userSegment.getUserSegmentId());
// Reports
for (ReportInstance reportInstance :
reportInstanceLocalService.getReportInstances(
UserSegment.class.getName(),
userSegment.getUserSegmentId())) {
reportInstanceLocalService.deleteReportInstance(
reportInstance.getReportInstanceId());
}
// Rules
for (RuleInstance ruleInstance :
ruleInstanceLocalService.getRuleInstances(
userSegment.getUserSegmentId())) {
ruleInstanceLocalService.deleteRuleInstance(
ruleInstance.getRuleInstanceId());
}
// Categories
Group group = GroupLocalServiceUtil.fetchGroup(
userSegment.getGroupId());
AssetCategory stagingAssetCategory = getStagingAssetCategory(
group, userSegment.getAssetCategoryId());
if (stagingAssetCategory != null) {
removeUserSegmentCategory(stagingAssetCategory.getCategoryId());
}
removeUserSegmentCategory(userSegment.getAssetCategoryId());
return userSegment;
}
@Override
public void deleteUserSegments(long groupId)
throws PortalException, SystemException {
for (UserSegment userSegment :
userSegmentPersistence.findByGroupId(groupId)) {
userSegmentLocalService.deleteUserSegment(
userSegment.getUserSegmentId());
}
}
@Override
public UserSegment fetchUserSegmentByAssetCategoryId(long assetCategoryId)
throws PortalException, SystemException {
return userSegmentPersistence.fetchByAssetCategoryId(assetCategoryId);
}
@Override
public List<UserSegment> getUserSegments(long groupId)
throws PortalException, SystemException {
return getUserSegments(new long[]{groupId});
}
@Override
public List<UserSegment> getUserSegments(
long groupId, int start, int end, OrderByComparator obc)
throws PortalException, SystemException {
return getUserSegments(new long[]{groupId}, start, end, obc);
}
@Override
public List<UserSegment> getUserSegments(long[] groupIds)
throws PortalException, SystemException {
return userSegmentPersistence.findByGroupId(groupIds);
}
@Override
public List<UserSegment> getUserSegments(
long[] groupIds, int start, int end, OrderByComparator obc)
throws PortalException, SystemException {
return userSegmentPersistence.findByGroupId(groupIds, start, end, obc);
}
@Override
public int getUserSegmentsCount(long groupId)
throws PortalException, SystemException {
return userSegmentPersistence.countByGroupId(groupId);
}
@Override
public int getUserSegmentsCount(long[] groupIds)
throws PortalException, SystemException {
return userSegmentPersistence.countByGroupId(groupIds);
}
@Override
public Hits search(long groupId, String keywords, int start, int end)
throws PortalException, SystemException {
Indexer indexer = IndexerRegistryUtil.getIndexer(
UserSegment.class.getName());
SearchContext searchContext = buildSearchContext(
groupId, keywords, start, end);
return indexer.search(searchContext);
}
@Override
public BaseModelSearchResult<UserSegment> searchUserSegments(
long groupId, String keywords, int start, int end)
throws PortalException, SystemException {
SearchContext searchContext = buildSearchContext(
groupId, keywords, start, end);
return searchUserSegments(searchContext);
}
@Indexable(type = IndexableType.REINDEX)
@Override
public UserSegment updateUserSegment(
long userSegmentId, Map<Locale, String> nameMap,
Map<Locale, String> descriptionMap, ServiceContext serviceContext)
throws PortalException, SystemException {
Date now = new Date();
UserSegment userSegment = userSegmentPersistence.findByPrimaryKey(
userSegmentId);
userSegment.setModifiedDate(serviceContext.getModifiedDate(now));
userSegment.setNameMap(nameMap);
userSegment.setDescriptionMap(descriptionMap);
validateUserSegment(userSegment);
userSegmentPersistence.update(userSegment);
// Resources
if ((serviceContext.getGroupPermissions() != null) ||
(serviceContext.getGuestPermissions() != null)) {
updateUserSegmentResources(
userSegment, serviceContext.getGroupPermissions(),
serviceContext.getGuestPermissions());
}
// Categories
updateUserSegmentCategory(
userSegment.getUserId(), userSegment.getAssetCategoryId(), nameMap,
descriptionMap, serviceContext);
AssetCategory stagingAssetCategory = getStagingAssetCategory(
serviceContext.getScopeGroup(), userSegment.getAssetCategoryId());
if (stagingAssetCategory != null) {
ServiceContext serviceContextStaging =
(ServiceContext)serviceContext.clone();
serviceContextStaging.setScopeGroupId(
stagingAssetCategory.getGroupId());
updateUserSegmentCategory(
userSegment.getUserId(), stagingAssetCategory.getCategoryId(),
nameMap, descriptionMap, serviceContextStaging);
}
return userSegment;
}
@Override
public void updateUserSegmentResources(
UserSegment userSegment, String[] groupPermissions,
String[] guestPermissions)
throws PortalException, SystemException {
resourceLocalService.updateResources(
userSegment.getCompanyId(), userSegment.getGroupId(),
UserSegment.class.getName(), userSegment.getUserSegmentId(),
groupPermissions, guestPermissions);
}
protected AssetCategory addUserSegmentCategory(
long userId, Map<Locale, String> titleMap,
Map<Locale, String> descriptionMap, ServiceContext serviceContext)
throws PortalException, SystemException {
long vocabularyId = UserSegmentUtil.getAssetVocabularyId(
userId, serviceContext);
serviceContext.setAddGroupPermissions(true);
serviceContext.setAddGuestPermissions(true);
AssetCategory assetCategory = null;
try {
assetCategory = AssetCategoryLocalServiceUtil.addCategory(
userId, AssetCategoryConstants.DEFAULT_PARENT_CATEGORY_ID,
titleMap, descriptionMap, vocabularyId, null, serviceContext);
}
catch (DuplicateCategoryException dce) {
throw new InvalidNameException(InvalidNameException.DUPLICATED);
}
return assetCategory;
}
protected SearchContext buildSearchContext(
long groupId, String keywords, int start, int end)
throws PortalException, SystemException {
SearchContext searchContext = new SearchContext();
Group group = GroupLocalServiceUtil.getGroup(groupId);
searchContext.setCompanyId(group.getCompanyId());
searchContext.setEnd(end);
searchContext.setGroupIds(new long[]{groupId});
searchContext.setKeywords(keywords);
searchContext.setStart(start);
return searchContext;
}
protected AssetCategory getStagingAssetCategory(
Group scopeGroup, long assetCategoryId)
throws SystemException {
if (!scopeGroup.hasStagingGroup()) {
return null;
}
Group stagingGroup = scopeGroup.getStagingGroup();
AssetCategory assetCategory =
AssetCategoryLocalServiceUtil.fetchAssetCategory(assetCategoryId);
return AssetCategoryLocalServiceUtil.fetchAssetCategoryByUuidAndGroupId(
assetCategory.getUuid(), stagingGroup.getGroupId());
}
protected void removeUserSegmentCategory(long assetCategoryId)
throws PortalException, SystemException {
AssetCategory assetCategory =
AssetCategoryLocalServiceUtil.fetchAssetCategory(assetCategoryId);
try {
AssetCategoryLocalServiceUtil.deleteCategory(assetCategory);
}
catch (NoSuchCategoryException nsace) {
if (_log.isDebugEnabled()) {
_log.debug(
"Category " + assetCategoryId + "could not be deleted");
}
}
int categoriesCount =
AssetCategoryLocalServiceUtil.getVocabularyRootCategoriesCount(
assetCategory.getVocabularyId());
if (categoriesCount > 0) {
return;
}
AssetVocabularyLocalServiceUtil.deleteAssetVocabulary(
assetCategory.getVocabularyId());
}
protected BaseModelSearchResult<UserSegment> searchUserSegments(
SearchContext searchContext)
throws PortalException, SystemException {
Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
UserSegment.class);
for (int i = 0; i < 10; i++) {
Hits hits = indexer.search(searchContext);
List<UserSegment> userSegments = UserSegmentUtil.getUserSegments(
hits);
if (userSegments != null) {
return new BaseModelSearchResult<UserSegment>(
userSegments, hits.getLength());
}
}
throw new SearchException(
"Unable to fix the search index after 10 attempts");
}
protected AssetCategory updateUserSegmentCategory(
long userId, long assetCategoryId, Map<Locale, String> titleMap,
Map<Locale, String> descriptionMap, ServiceContext serviceContext)
throws PortalException, SystemException {
long vocabularyId = UserSegmentUtil.getAssetVocabularyId(
userId, serviceContext);
AssetCategory assetCategory = AssetCategoryLocalServiceUtil.getCategory(
assetCategoryId);
AssetCategoryLocalServiceUtil.updateCategory(
userId, assetCategoryId, assetCategory.getParentCategoryId(),
titleMap, descriptionMap, vocabularyId, null, serviceContext);
return assetCategory;
}
protected void validateUserSegment(UserSegment userSegment)
throws PortalException {
if (Validator.isNull(userSegment.getName(LocaleUtil.getDefault()))) {
throw new InvalidNameException(InvalidNameException.EMPTY);
}
}
private static Log _log = LogFactoryUtil.getLog(
UserSegmentLocalServiceImpl.class);
}