Java tutorial
/** * 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.bookmarks.service.impl; import aQute.bnd.annotation.ProviderType; import com.liferay.asset.kernel.model.AssetEntry; import com.liferay.asset.kernel.model.AssetLinkConstants; import com.liferay.bookmarks.configuration.BookmarksGroupServiceOverriddenConfiguration; import com.liferay.bookmarks.constants.BookmarksConstants; import com.liferay.bookmarks.constants.BookmarksPortletKeys; import com.liferay.bookmarks.exception.EntryURLException; import com.liferay.bookmarks.model.BookmarksEntry; import com.liferay.bookmarks.model.BookmarksFolder; import com.liferay.bookmarks.model.BookmarksFolderConstants; import com.liferay.bookmarks.service.base.BookmarksEntryLocalServiceBaseImpl; import com.liferay.bookmarks.service.permission.BookmarksResourcePermissionChecker; import com.liferay.bookmarks.social.BookmarksActivityKeys; import com.liferay.bookmarks.util.comparator.EntryModifiedDateComparator; import com.liferay.portal.kernel.dao.orm.ActionableDynamicQuery; import com.liferay.portal.kernel.dao.orm.DynamicQuery; import com.liferay.portal.kernel.dao.orm.IndexableActionableDynamicQuery; import com.liferay.portal.kernel.dao.orm.Property; import com.liferay.portal.kernel.dao.orm.PropertyFactoryUtil; import com.liferay.portal.kernel.dao.orm.RestrictionsFactoryUtil; import com.liferay.portal.kernel.exception.PortalException; import com.liferay.portal.kernel.json.JSONFactoryUtil; import com.liferay.portal.kernel.json.JSONObject; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.model.Group; 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.ConfigurationProvider; import com.liferay.portal.kernel.notifications.UserNotificationDefinition; import com.liferay.portal.kernel.search.Document; import com.liferay.portal.kernel.search.Field; 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.QueryConfig; import com.liferay.portal.kernel.search.SearchContext; import com.liferay.portal.kernel.search.Sort; import com.liferay.portal.kernel.service.ServiceContext; import com.liferay.portal.kernel.settings.GroupServiceSettingsLocator; import com.liferay.portal.kernel.settings.LocalizedValuesMap; import com.liferay.portal.kernel.systemevent.SystemEvent; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.ContentTypes; import com.liferay.portal.kernel.util.GroupSubscriptionCheckSubscriptionSender; import com.liferay.portal.kernel.util.LocalizationUtil; import com.liferay.portal.kernel.util.OrderByComparator; import com.liferay.portal.kernel.util.Portal; import com.liferay.portal.kernel.util.StringBundler; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.SubscriptionSender; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.workflow.WorkflowConstants; import com.liferay.portal.spring.extender.service.ServiceReference; import com.liferay.social.kernel.model.SocialActivityConstants; import com.liferay.trash.kernel.exception.RestoreEntryException; import com.liferay.trash.kernel.exception.TrashEntryException; import com.liferay.trash.kernel.model.TrashEntry; import com.liferay.trash.kernel.model.TrashVersion; import java.util.Date; import java.util.List; /** * @author Brian Wing Shun Chan * @author Raymond Aug * @author Levente Hudk */ @ProviderType public class BookmarksEntryLocalServiceImpl extends BookmarksEntryLocalServiceBaseImpl { @Indexable(type = IndexableType.REINDEX) @Override public BookmarksEntry addEntry(long userId, long groupId, long folderId, String name, String url, String description, ServiceContext serviceContext) throws PortalException { // Entry User user = userPersistence.findByPrimaryKey(userId); if (Validator.isNull(name)) { name = url; } validate(url); long entryId = counterLocalService.increment(); BookmarksEntry entry = bookmarksEntryPersistence.create(entryId); entry.setUuid(serviceContext.getUuid()); entry.setGroupId(groupId); entry.setCompanyId(user.getCompanyId()); entry.setUserId(user.getUserId()); entry.setUserName(user.getFullName()); entry.setFolderId(folderId); entry.setTreePath(entry.buildTreePath()); entry.setName(name); entry.setUrl(url); entry.setDescription(description); entry.setExpandoBridgeAttributes(serviceContext); bookmarksEntryPersistence.update(entry); // Resources resourceLocalService.addModelResources(entry, serviceContext); // Asset updateAsset(userId, entry, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames(), serviceContext.getAssetLinkEntryIds(), serviceContext.getAssetPriority()); // Social JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(); extraDataJSONObject.put("title", entry.getName()); socialActivityLocalService.addActivity(userId, groupId, BookmarksEntry.class.getName(), entryId, BookmarksActivityKeys.ADD_ENTRY, extraDataJSONObject.toString(), 0); // Subscriptions notifySubscribers(userId, entry, serviceContext); return entry; } @Override public void deleteEntries(long groupId, long folderId) throws PortalException { deleteEntries(groupId, folderId, true); } @Override public void deleteEntries(long groupId, long folderId, boolean includeTrashedEntries) throws PortalException { List<BookmarksEntry> entries = bookmarksEntryPersistence.findByG_F(groupId, folderId); for (BookmarksEntry entry : entries) { if (includeTrashedEntries || !entry.isInTrashExplicitly()) { bookmarksEntryLocalService.deleteEntry(entry); } } } @Indexable(type = IndexableType.DELETE) @Override @SystemEvent(type = SystemEventConstants.TYPE_DELETE) public BookmarksEntry deleteEntry(BookmarksEntry entry) throws PortalException { // Entry bookmarksEntryPersistence.remove(entry); // Resources resourceLocalService.deleteResource(entry, ResourceConstants.SCOPE_INDIVIDUAL); // Asset assetEntryLocalService.deleteEntry(BookmarksEntry.class.getName(), entry.getEntryId()); // Expando expandoRowLocalService.deleteRows(entry.getEntryId()); // Ratings ratingsStatsLocalService.deleteStats(BookmarksEntry.class.getName(), entry.getEntryId()); // Subscriptions subscriptionLocalService.deleteSubscriptions(entry.getCompanyId(), BookmarksEntry.class.getName(), entry.getEntryId()); // Trash if (entry.isInTrashExplicitly()) { trashEntryLocalService.deleteEntry(BookmarksEntry.class.getName(), entry.getEntryId()); } else { trashVersionLocalService.deleteTrashVersion(BookmarksEntry.class.getName(), entry.getEntryId()); } return entry; } @Indexable(type = IndexableType.DELETE) @Override public BookmarksEntry deleteEntry(long entryId) throws PortalException { BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(entryId); return bookmarksEntryLocalService.deleteEntry(entry); } @Override public List<BookmarksEntry> getEntries(long groupId, long folderId, int start, int end) { return getEntries(groupId, folderId, WorkflowConstants.STATUS_APPROVED, start, end); } @Override public List<BookmarksEntry> getEntries(long groupId, long folderId, int status, int start, int end) { return getEntries(groupId, folderId, status, start, end, null); } @Override public List<BookmarksEntry> getEntries(long groupId, long folderId, int status, int start, int end, OrderByComparator<BookmarksEntry> orderByComparator) { return bookmarksEntryPersistence.findByG_F_S(groupId, folderId, status, start, end, orderByComparator); } @Override public List<BookmarksEntry> getEntries(long groupId, long folderId, int start, int end, OrderByComparator<BookmarksEntry> orderByComparator) { return getEntries(groupId, folderId, WorkflowConstants.STATUS_APPROVED, start, end, orderByComparator); } @Override public int getEntriesCount(long groupId, long folderId) { return getEntriesCount(groupId, folderId, WorkflowConstants.STATUS_APPROVED); } @Override public int getEntriesCount(long groupId, long folderId, int status) { return bookmarksEntryPersistence.countByG_F_S(groupId, folderId, status); } @Override public BookmarksEntry getEntry(long entryId) throws PortalException { return bookmarksEntryPersistence.findByPrimaryKey(entryId); } @Override public int getFoldersEntriesCount(long groupId, List<Long> folderIds) { return bookmarksEntryPersistence.countByG_F_S(groupId, ArrayUtil.toArray(folderIds.toArray(new Long[folderIds.size()])), WorkflowConstants.STATUS_APPROVED); } @Override public List<BookmarksEntry> getGroupEntries(long groupId, int start, int end) { return bookmarksEntryPersistence.findByG_S(groupId, WorkflowConstants.STATUS_APPROVED, start, end, new EntryModifiedDateComparator()); } @Override public List<BookmarksEntry> getGroupEntries(long groupId, long userId, int start, int end) { OrderByComparator<BookmarksEntry> orderByComparator = new EntryModifiedDateComparator(); if (userId <= 0) { return bookmarksEntryPersistence.findByG_S(groupId, WorkflowConstants.STATUS_APPROVED, start, end, orderByComparator); } else { return bookmarksEntryPersistence.findByG_U_S(groupId, userId, WorkflowConstants.STATUS_APPROVED, start, end, orderByComparator); } } @Override public int getGroupEntriesCount(long groupId) { return bookmarksEntryPersistence.countByG_S(groupId, WorkflowConstants.STATUS_APPROVED); } @Override public int getGroupEntriesCount(long groupId, long userId) { if (userId <= 0) { return getGroupEntriesCount(groupId); } else { return bookmarksEntryPersistence.countByG_U_S(groupId, userId, WorkflowConstants.STATUS_APPROVED); } } @Override public List<BookmarksEntry> getNoAssetEntries() { return bookmarksEntryFinder.findByNoAssets(); } @Indexable(type = IndexableType.REINDEX) @Override public BookmarksEntry moveEntry(long entryId, long parentFolderId) throws PortalException { BookmarksEntry entry = getBookmarksEntry(entryId); entry.setFolderId(parentFolderId); entry.setTreePath(entry.buildTreePath()); bookmarksEntryPersistence.update(entry); return entry; } @Override public BookmarksEntry moveEntryFromTrash(long userId, long entryId, long parentFolderId) throws PortalException { BookmarksEntry entry = getBookmarksEntry(entryId); if (!entry.isInTrash()) { throw new RestoreEntryException(RestoreEntryException.INVALID_STATUS); } if (entry.isInTrashExplicitly()) { restoreEntryFromTrash(userId, entryId); } else { // Entry TrashVersion trashVersion = trashVersionLocalService.fetchVersion(BookmarksEntry.class.getName(), entryId); int status = WorkflowConstants.STATUS_APPROVED; if (trashVersion != null) { status = trashVersion.getStatus(); } updateStatus(userId, entry, status); // Trash if (trashVersion != null) { trashVersionLocalService.deleteTrashVersion(trashVersion); } } return bookmarksEntryLocalService.moveEntry(entryId, parentFolderId); } @Indexable(type = IndexableType.REINDEX) @Override public BookmarksEntry moveEntryToTrash(long userId, BookmarksEntry entry) throws PortalException { if (entry.isInTrash()) { throw new TrashEntryException(); } int oldStatus = entry.getStatus(); entry = updateStatus(userId, entry, WorkflowConstants.STATUS_IN_TRASH); trashEntryLocalService.addTrashEntry(userId, entry.getGroupId(), BookmarksEntry.class.getName(), entry.getEntryId(), entry.getUuid(), null, oldStatus, null, null); return entry; } @Indexable(type = IndexableType.REINDEX) @Override public BookmarksEntry moveEntryToTrash(long userId, long entryId) throws PortalException { BookmarksEntry entry = getEntry(entryId); return moveEntryToTrash(userId, entry); } @Override public BookmarksEntry openEntry(long userId, BookmarksEntry entry) { entry.setVisits(entry.getVisits() + 1); bookmarksEntryPersistence.update(entry); assetEntryLocalService.incrementViewCounter(userId, BookmarksEntry.class.getName(), entry.getEntryId(), 1); return entry; } @Override public BookmarksEntry openEntry(long userId, long entryId) throws PortalException { BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(entryId); return openEntry(userId, entry); } @Override public void rebuildTree(long companyId) throws PortalException { bookmarksFolderLocalService.rebuildTree(companyId); } @Indexable(type = IndexableType.REINDEX) @Override public BookmarksEntry restoreEntryFromTrash(long userId, long entryId) throws PortalException { BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(entryId); if (!entry.isInTrash()) { throw new RestoreEntryException(RestoreEntryException.INVALID_STATUS); } TrashEntry trashEntry = trashEntryLocalService.getEntry(BookmarksEntry.class.getName(), entryId); entry = updateStatus(userId, entry, trashEntry.getStatus()); trashEntryLocalService.deleteEntry(BookmarksEntry.class.getName(), entry.getEntryId()); return entry; } @Override public Hits search(long groupId, long userId, long creatorUserId, int status, int start, int end) throws PortalException { Indexer<BookmarksEntry> indexer = IndexerRegistryUtil.getIndexer(BookmarksEntry.class.getName()); SearchContext searchContext = new SearchContext(); searchContext.setAttribute(Field.STATUS, status); if (creatorUserId > 0) { searchContext.setAttribute(Field.USER_ID, String.valueOf(creatorUserId)); } searchContext.setAttribute("paginationType", "none"); Group group = groupLocalService.getGroup(groupId); searchContext.setCompanyId(group.getCompanyId()); searchContext.setEnd(end); searchContext.setGroupIds(new long[] { groupId }); searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true)); searchContext.setStart(start); searchContext.setUserId(userId); QueryConfig queryConfig = searchContext.getQueryConfig(); queryConfig.setHighlightEnabled(false); queryConfig.setScoreEnabled(false); return indexer.search(searchContext); } @Override public void setTreePaths(final long folderId, final String treePath, final boolean reindex) throws PortalException { if (treePath == null) { throw new IllegalArgumentException("Tree path is null"); } final IndexableActionableDynamicQuery indexableActionableDynamicQuery = getIndexableActionableDynamicQuery(); indexableActionableDynamicQuery.setAddCriteriaMethod(new ActionableDynamicQuery.AddCriteriaMethod() { @Override public void addCriteria(DynamicQuery dynamicQuery) { Property folderIdProperty = PropertyFactoryUtil.forName("folderId"); dynamicQuery.add(folderIdProperty.eq(folderId)); Property treePathProperty = PropertyFactoryUtil.forName("treePath"); dynamicQuery .add(RestrictionsFactoryUtil.or(treePathProperty.isNull(), treePathProperty.ne(treePath))); } }); final Indexer<BookmarksEntry> indexer = IndexerRegistryUtil.getIndexer(BookmarksEntry.class); indexableActionableDynamicQuery .setPerformActionMethod(new ActionableDynamicQuery.PerformActionMethod<BookmarksEntry>() { @Override public void performAction(BookmarksEntry entry) throws PortalException { entry.setTreePath(treePath); updateBookmarksEntry(entry); if (!reindex) { return; } Document document = indexer.getDocument(entry); indexableActionableDynamicQuery.addDocuments(document); } }); indexableActionableDynamicQuery.performActions(); } @Override public void subscribeEntry(long userId, long entryId) throws PortalException { BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(entryId); subscriptionLocalService.addSubscription(userId, entry.getGroupId(), BookmarksEntry.class.getName(), entryId); } @Override public void unsubscribeEntry(long userId, long entryId) throws PortalException { subscriptionLocalService.deleteSubscription(userId, BookmarksEntry.class.getName(), entryId); } @Override public void updateAsset(long userId, BookmarksEntry entry, long[] assetCategoryIds, String[] assetTagNames, long[] assetLinkEntryIds, Double priority) throws PortalException { AssetEntry assetEntry = assetEntryLocalService.updateEntry(userId, entry.getGroupId(), entry.getCreateDate(), entry.getModifiedDate(), BookmarksEntry.class.getName(), entry.getEntryId(), entry.getUuid(), 0, assetCategoryIds, assetTagNames, true, true, null, null, entry.getCreateDate(), null, ContentTypes.TEXT_PLAIN, entry.getName(), entry.getDescription(), null, entry.getUrl(), null, 0, 0, priority); assetLinkLocalService.updateLinks(userId, assetEntry.getEntryId(), assetLinkEntryIds, AssetLinkConstants.TYPE_RELATED); } @Indexable(type = IndexableType.REINDEX) @Override public BookmarksEntry updateEntry(long userId, long entryId, long groupId, long folderId, String name, String url, String description, ServiceContext serviceContext) throws PortalException { // Entry BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(entryId); if (Validator.isNull(name)) { name = url; } validate(url); entry.setFolderId(folderId); entry.setTreePath(entry.buildTreePath()); entry.setName(name); entry.setUrl(url); entry.setDescription(description); entry.setExpandoBridgeAttributes(serviceContext); bookmarksEntryPersistence.update(entry); // Asset updateAsset(userId, entry, serviceContext.getAssetCategoryIds(), serviceContext.getAssetTagNames(), serviceContext.getAssetLinkEntryIds(), serviceContext.getAssetPriority()); // Social JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(); extraDataJSONObject.put("title", entry.getName()); socialActivityLocalService.addActivity(userId, entry.getGroupId(), BookmarksEntry.class.getName(), entryId, BookmarksActivityKeys.UPDATE_ENTRY, extraDataJSONObject.toString(), 0); // Subscriptions notifySubscribers(userId, entry, serviceContext); return entry; } @Override public BookmarksEntry updateStatus(long userId, BookmarksEntry entry, int status) throws PortalException { // Entry User user = userPersistence.findByPrimaryKey(userId); entry.setStatus(status); entry.setStatusByUserId(userId); entry.setStatusByUserName(user.getScreenName()); entry.setStatusDate(new Date()); bookmarksEntryPersistence.update(entry); JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject(); extraDataJSONObject.put("title", entry.getName()); if (status == WorkflowConstants.STATUS_APPROVED) { // Asset assetEntryLocalService.updateVisible(BookmarksEntry.class.getName(), entry.getEntryId(), true); // Social socialActivityLocalService.addActivity(userId, entry.getGroupId(), BookmarksEntry.class.getName(), entry.getEntryId(), SocialActivityConstants.TYPE_RESTORE_FROM_TRASH, extraDataJSONObject.toString(), 0); } else if (status == WorkflowConstants.STATUS_IN_TRASH) { // Asset assetEntryLocalService.updateVisible(BookmarksEntry.class.getName(), entry.getEntryId(), false); // Social socialActivityLocalService.addActivity(userId, entry.getGroupId(), BookmarksEntry.class.getName(), entry.getEntryId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH, extraDataJSONObject.toString(), 0); } return entry; } protected long getFolder(BookmarksEntry entry, long folderId) { if ((entry.getFolderId() != folderId) && (folderId != BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID)) { BookmarksFolder newFolder = bookmarksFolderPersistence.fetchByPrimaryKey(folderId); if ((newFolder == null) || (entry.getGroupId() != newFolder.getGroupId())) { folderId = entry.getFolderId(); } } return folderId; } protected void notifySubscribers(long userId, BookmarksEntry entry, ServiceContext serviceContext) throws PortalException { String layoutFullURL = serviceContext.getLayoutFullURL(); if (!entry.isApproved() || Validator.isNull(layoutFullURL)) { return; } BookmarksGroupServiceOverriddenConfiguration bookmarksGroupServiceOverriddenConfiguration = configurationProvider .getConfiguration(BookmarksGroupServiceOverriddenConfiguration.class, new GroupServiceSettingsLocator(entry.getGroupId(), BookmarksConstants.SERVICE_NAME)); if ((serviceContext.isCommandAdd() && !bookmarksGroupServiceOverriddenConfiguration.emailEntryAddedEnabled()) || (serviceContext.isCommandUpdate() && !bookmarksGroupServiceOverriddenConfiguration.emailEntryUpdatedEnabled())) { return; } String statusByUserName = StringPool.BLANK; try { User user = userLocalService.getUserById(serviceContext.getGuestOrUserId()); statusByUserName = user.getFullName(); } catch (Exception e) { _log.error(e, e); } String entryTitle = entry.getName(); StringBundler sb = new StringBundler(7); sb.append(layoutFullURL); sb.append(Portal.FRIENDLY_URL_SEPARATOR); sb.append("bookmarks"); sb.append(StringPool.SLASH); sb.append("folder"); sb.append(StringPool.SLASH); sb.append(entry.getFolderId()); String entryURL = sb.toString(); String fromName = bookmarksGroupServiceOverriddenConfiguration.emailFromName(); String fromAddress = bookmarksGroupServiceOverriddenConfiguration.emailFromAddress(); LocalizedValuesMap subjectLocalizedValuesMap = null; LocalizedValuesMap bodyLocalizedValuesMap = null; if (serviceContext.isCommandUpdate()) { subjectLocalizedValuesMap = bookmarksGroupServiceOverriddenConfiguration.emailEntryUpdatedSubject(); bodyLocalizedValuesMap = bookmarksGroupServiceOverriddenConfiguration.emailEntryUpdatedBody(); } else { subjectLocalizedValuesMap = bookmarksGroupServiceOverriddenConfiguration.emailEntryAddedSubject(); bodyLocalizedValuesMap = bookmarksGroupServiceOverriddenConfiguration.emailEntryAddedBody(); } SubscriptionSender subscriptionSender = new GroupSubscriptionCheckSubscriptionSender( BookmarksResourcePermissionChecker.RESOURCE_NAME); subscriptionSender.setClassName(entry.getModelClassName()); subscriptionSender.setClassPK(entry.getEntryId()); subscriptionSender.setCompanyId(entry.getCompanyId()); subscriptionSender.setContextAttributes("[$BOOKMARKS_ENTRY_STATUS_BY_USER_NAME$]", statusByUserName, "[$BOOKMARKS_ENTRY_URL$]", entryURL); subscriptionSender.setContextCreatorUserPrefix("BOOKMARKS_ENTRY"); subscriptionSender.setCreatorUserId(entry.getUserId()); subscriptionSender.setCurrentUserId(userId); subscriptionSender.setEntryTitle(entryTitle); subscriptionSender.setEntryURL(entryURL); subscriptionSender.setFrom(fromAddress, fromName); subscriptionSender.setHtmlFormat(true); if (bodyLocalizedValuesMap != null) { subscriptionSender.setLocalizedBodyMap(LocalizationUtil.getMap(bodyLocalizedValuesMap)); } if (subjectLocalizedValuesMap != null) { subscriptionSender.setLocalizedSubjectMap(LocalizationUtil.getMap(subjectLocalizedValuesMap)); } subscriptionSender.setMailId("bookmarks_entry", entry.getEntryId()); int notificationType = UserNotificationDefinition.NOTIFICATION_TYPE_ADD_ENTRY; if (serviceContext.isCommandUpdate()) { notificationType = UserNotificationDefinition.NOTIFICATION_TYPE_UPDATE_ENTRY; } subscriptionSender.setNotificationType(notificationType); subscriptionSender.setPortletId(BookmarksPortletKeys.BOOKMARKS); subscriptionSender.setReplyToAddress(fromAddress); subscriptionSender.setScopeGroupId(entry.getGroupId()); subscriptionSender.setServiceContext(serviceContext); BookmarksFolder folder = entry.getFolder(); if (folder != null) { subscriptionSender.addPersistedSubscribers(BookmarksFolder.class.getName(), folder.getFolderId()); for (Long ancestorFolderId : folder.getAncestorFolderIds()) { subscriptionSender.addPersistedSubscribers(BookmarksFolder.class.getName(), ancestorFolderId); } } subscriptionSender.addPersistedSubscribers(BookmarksFolder.class.getName(), entry.getGroupId()); subscriptionSender.addPersistedSubscribers(BookmarksEntry.class.getName(), entry.getEntryId()); subscriptionSender.flushNotificationsAsync(); } protected void validate(String url) throws PortalException { if (!Validator.isUrl(url)) { throw new EntryURLException(); } } @ServiceReference(type = ConfigurationProvider.class) protected ConfigurationProvider configurationProvider; private static final Log _log = LogFactoryUtil.getLog(BookmarksEntryLocalServiceImpl.class); }