001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.bookmarks.service.impl;
016    
017    import com.liferay.portal.kernel.dao.orm.Session;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.json.JSONFactoryUtil;
021    import com.liferay.portal.kernel.json.JSONObject;
022    import com.liferay.portal.kernel.log.Log;
023    import com.liferay.portal.kernel.log.LogFactoryUtil;
024    import com.liferay.portal.kernel.search.Field;
025    import com.liferay.portal.kernel.search.Hits;
026    import com.liferay.portal.kernel.search.Indexable;
027    import com.liferay.portal.kernel.search.IndexableType;
028    import com.liferay.portal.kernel.search.Indexer;
029    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
030    import com.liferay.portal.kernel.search.SearchContext;
031    import com.liferay.portal.kernel.search.Sort;
032    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackRegistryUtil;
033    import com.liferay.portal.kernel.util.ArrayUtil;
034    import com.liferay.portal.kernel.util.ContentTypes;
035    import com.liferay.portal.kernel.util.OrderByComparator;
036    import com.liferay.portal.kernel.util.StringPool;
037    import com.liferay.portal.kernel.util.TreePathUtil;
038    import com.liferay.portal.kernel.util.Validator;
039    import com.liferay.portal.kernel.workflow.WorkflowConstants;
040    import com.liferay.portal.model.Group;
041    import com.liferay.portal.model.ResourceConstants;
042    import com.liferay.portal.model.User;
043    import com.liferay.portal.service.ServiceContext;
044    import com.liferay.portal.service.ServiceContextUtil;
045    import com.liferay.portal.util.Portal;
046    import com.liferay.portal.util.PortletKeys;
047    import com.liferay.portal.util.SubscriptionSender;
048    import com.liferay.portlet.asset.model.AssetEntry;
049    import com.liferay.portlet.asset.model.AssetLinkConstants;
050    import com.liferay.portlet.bookmarks.EntryURLException;
051    import com.liferay.portlet.bookmarks.model.BookmarksEntry;
052    import com.liferay.portlet.bookmarks.model.BookmarksFolder;
053    import com.liferay.portlet.bookmarks.model.BookmarksFolderConstants;
054    import com.liferay.portlet.bookmarks.model.impl.BookmarksEntryModelImpl;
055    import com.liferay.portlet.bookmarks.model.impl.BookmarksFolderModelImpl;
056    import com.liferay.portlet.bookmarks.service.base.BookmarksEntryLocalServiceBaseImpl;
057    import com.liferay.portlet.bookmarks.social.BookmarksActivityKeys;
058    import com.liferay.portlet.bookmarks.util.BookmarksUtil;
059    import com.liferay.portlet.bookmarks.util.comparator.EntryModifiedDateComparator;
060    import com.liferay.portlet.social.model.SocialActivityConstants;
061    import com.liferay.portlet.trash.model.TrashEntry;
062    import com.liferay.portlet.trash.model.TrashVersion;
063    
064    import java.util.ArrayList;
065    import java.util.Date;
066    import java.util.List;
067    import java.util.Locale;
068    import java.util.Map;
069    import java.util.concurrent.Callable;
070    
071    import javax.portlet.PortletPreferences;
072    
073    /**
074     * @author Brian Wing Shun Chan
075     * @author Raymond Aug??
076     * @author Levente Hud??k
077     */
078    public class BookmarksEntryLocalServiceImpl
079            extends BookmarksEntryLocalServiceBaseImpl {
080    
081            @Indexable(type = IndexableType.REINDEX)
082            @Override
083            public BookmarksEntry addEntry(
084                            long userId, long groupId, long folderId, String name, String url,
085                            String description, ServiceContext serviceContext)
086                    throws PortalException, SystemException {
087    
088                    // Entry
089    
090                    User user = userPersistence.findByPrimaryKey(userId);
091    
092                    if (Validator.isNull(name)) {
093                            name = url;
094                    }
095    
096                    Date now = new Date();
097    
098                    validate(url);
099    
100                    long entryId = counterLocalService.increment();
101    
102                    BookmarksEntry entry = bookmarksEntryPersistence.create(entryId);
103    
104                    entry.setUuid(serviceContext.getUuid());
105                    entry.setGroupId(groupId);
106                    entry.setCompanyId(user.getCompanyId());
107                    entry.setUserId(user.getUserId());
108                    entry.setUserName(user.getFullName());
109                    entry.setCreateDate(serviceContext.getCreateDate(now));
110                    entry.setModifiedDate(serviceContext.getModifiedDate(now));
111                    entry.setFolderId(folderId);
112                    entry.setTreePath(entry.buildTreePath());
113                    entry.setName(name);
114                    entry.setUrl(url);
115                    entry.setDescription(description);
116                    entry.setExpandoBridgeAttributes(serviceContext);
117    
118                    bookmarksEntryPersistence.update(entry);
119    
120                    // Resources
121    
122                    resourceLocalService.addModelResources(entry, serviceContext);
123    
124                    // Asset
125    
126                    updateAsset(
127                            userId, entry, serviceContext.getAssetCategoryIds(),
128                            serviceContext.getAssetTagNames(),
129                            serviceContext.getAssetLinkEntryIds());
130    
131                    // Social
132    
133                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
134    
135                    extraDataJSONObject.put("title", entry.getName());
136    
137                    socialActivityLocalService.addActivity(
138                            userId, groupId, BookmarksEntry.class.getName(), entryId,
139                            BookmarksActivityKeys.ADD_ENTRY, extraDataJSONObject.toString(), 0);
140    
141                    // Subscriptions
142    
143                    notifySubscribers(entry, serviceContext);
144    
145                    return entry;
146            }
147    
148            @Override
149            public void deleteEntries(long groupId, long folderId)
150                    throws PortalException, SystemException {
151    
152                    deleteEntries(groupId, folderId, true);
153            }
154    
155            @Override
156            public void deleteEntries(
157                            long groupId, long folderId, boolean includeTrashedEntries)
158                    throws PortalException, SystemException {
159    
160                    List<BookmarksEntry> entries = bookmarksEntryPersistence.findByG_F(
161                            groupId, folderId);
162    
163                    for (BookmarksEntry entry : entries) {
164                            if (includeTrashedEntries || !entry.isInTrashExplicitly()) {
165                                    bookmarksEntryLocalService.deleteEntry(entry);
166                            }
167                    }
168            }
169    
170            @Indexable(type = IndexableType.DELETE)
171            @Override
172            public BookmarksEntry deleteEntry(BookmarksEntry entry)
173                    throws PortalException, SystemException {
174    
175                    // Entry
176    
177                    bookmarksEntryPersistence.remove(entry);
178    
179                    // Resources
180    
181                    resourceLocalService.deleteResource(
182                            entry, ResourceConstants.SCOPE_INDIVIDUAL);
183    
184                    // Asset
185    
186                    assetEntryLocalService.deleteEntry(
187                            BookmarksEntry.class.getName(), entry.getEntryId());
188    
189                    // Expando
190    
191                    expandoRowLocalService.deleteRows(entry.getEntryId());
192    
193                    // Subscriptions
194    
195                    subscriptionLocalService.deleteSubscriptions(
196                            entry.getCompanyId(), BookmarksEntry.class.getName(),
197                            entry.getEntryId());
198    
199                    // Trash
200    
201                    trashEntryLocalService.deleteEntry(
202                            BookmarksEntry.class.getName(), entry.getEntryId());
203    
204                    return entry;
205            }
206    
207            @Indexable(type = IndexableType.DELETE)
208            @Override
209            public BookmarksEntry deleteEntry(long entryId)
210                    throws PortalException, SystemException {
211    
212                    BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
213                            entryId);
214    
215                    return deleteEntry(entry);
216            }
217    
218            @Override
219            public List<BookmarksEntry> getEntries(
220                            long groupId, long folderId, int start, int end)
221                    throws SystemException {
222    
223                    return getEntries(
224                            groupId, folderId, WorkflowConstants.STATUS_APPROVED, start, end);
225            }
226    
227            @Override
228            public List<BookmarksEntry> getEntries(
229                            long groupId, long folderId, int status, int start, int end)
230                    throws SystemException {
231    
232                    return getEntries(groupId, folderId, status, start, end, null);
233            }
234    
235            @Override
236            public List<BookmarksEntry> getEntries(
237                            long groupId, long folderId, int status, int start, int end,
238                            OrderByComparator orderByComparator)
239                    throws SystemException {
240    
241                    return bookmarksEntryPersistence.findByG_F_S(
242                            groupId, folderId, status, start, end, orderByComparator);
243            }
244    
245            @Override
246            public List<BookmarksEntry> getEntries(
247                            long groupId, long folderId, int start, int end,
248                            OrderByComparator orderByComparator)
249                    throws SystemException {
250    
251                    return getEntries(
252                            groupId, folderId, WorkflowConstants.STATUS_APPROVED, start, end,
253                            orderByComparator);
254            }
255    
256            @Override
257            public int getEntriesCount(long groupId, long folderId)
258                    throws SystemException {
259    
260                    return getEntriesCount(
261                            groupId, folderId, WorkflowConstants.STATUS_APPROVED);
262            }
263    
264            @Override
265            public int getEntriesCount(long groupId, long folderId, int status)
266                    throws SystemException {
267    
268                    return bookmarksEntryPersistence.countByG_F_S(
269                            groupId, folderId, status);
270            }
271    
272            @Override
273            public BookmarksEntry getEntry(long entryId)
274                    throws PortalException, SystemException {
275    
276                    return bookmarksEntryPersistence.findByPrimaryKey(entryId);
277            }
278    
279            @Override
280            public int getFoldersEntriesCount(long groupId, List<Long> folderIds)
281                    throws SystemException {
282    
283                    return bookmarksEntryPersistence.countByG_F_S(
284                            groupId,
285                            ArrayUtil.toArray(folderIds.toArray(new Long[folderIds.size()])),
286                            WorkflowConstants.STATUS_APPROVED);
287            }
288    
289            @Override
290            public List<BookmarksEntry> getGroupEntries(
291                            long groupId, int start, int end)
292                    throws SystemException {
293    
294                    return bookmarksEntryPersistence.findByG_S(
295                            groupId, WorkflowConstants.STATUS_APPROVED, start, end,
296                            new EntryModifiedDateComparator());
297            }
298    
299            @Override
300            public List<BookmarksEntry> getGroupEntries(
301                            long groupId, long userId, int start, int end)
302                    throws SystemException {
303    
304                    OrderByComparator orderByComparator = new EntryModifiedDateComparator();
305    
306                    if (userId <= 0) {
307                            return bookmarksEntryPersistence.findByG_S(
308                                    groupId, WorkflowConstants.STATUS_APPROVED, start, end,
309                                    orderByComparator);
310                    }
311                    else {
312                            return bookmarksEntryPersistence.findByG_U_S(
313                                    groupId, userId, WorkflowConstants.STATUS_APPROVED, start, end,
314                                    orderByComparator);
315                    }
316            }
317    
318            @Override
319            public int getGroupEntriesCount(long groupId) throws SystemException {
320                    return bookmarksEntryPersistence.countByG_S(
321                            groupId, WorkflowConstants.STATUS_APPROVED);
322            }
323    
324            @Override
325            public int getGroupEntriesCount(long groupId, long userId)
326                    throws SystemException {
327    
328                    if (userId <= 0) {
329                            return getGroupEntriesCount(groupId);
330                    }
331                    else {
332                            return bookmarksEntryPersistence.countByG_U_S(
333                                    groupId, userId, WorkflowConstants.STATUS_APPROVED);
334                    }
335            }
336    
337            @Override
338            public List<BookmarksEntry> getNoAssetEntries() throws SystemException {
339                    return bookmarksEntryFinder.findByNoAssets();
340            }
341    
342            @Indexable(type = IndexableType.REINDEX)
343            @Override
344            public BookmarksEntry moveEntry(long entryId, long parentFolderId)
345                    throws PortalException, SystemException {
346    
347                    BookmarksEntry entry = getBookmarksEntry(entryId);
348    
349                    entry.setFolderId(parentFolderId);
350                    entry.setTreePath(entry.buildTreePath());
351    
352                    bookmarksEntryPersistence.update(entry);
353    
354                    return entry;
355            }
356    
357            @Override
358            public BookmarksEntry moveEntryFromTrash(
359                            long userId, long entryId, long parentFolderId)
360                    throws PortalException, SystemException {
361    
362                    BookmarksEntry entry = getBookmarksEntry(entryId);
363    
364                    if (entry.isInTrashExplicitly()) {
365                            restoreEntryFromTrash(userId, entryId);
366                    }
367                    else {
368    
369                            // Entry
370    
371                            TrashEntry trashEntry = entry.getTrashEntry();
372    
373                            TrashVersion trashVersion =
374                                    trashVersionLocalService.fetchVersion(
375                                            trashEntry.getEntryId(), BookmarksEntry.class.getName(),
376                                            entryId);
377    
378                            int status = WorkflowConstants.STATUS_APPROVED;
379    
380                            if (trashVersion != null) {
381                                    status = trashVersion.getStatus();
382                            }
383    
384                            updateStatus(userId, entry, status);
385    
386                            // Trash
387    
388                            if (trashVersion != null) {
389                                    trashVersionLocalService.deleteTrashVersion(trashVersion);
390                            }
391                    }
392    
393                    return bookmarksEntryLocalService.moveEntry(entryId, parentFolderId);
394            }
395    
396            @Indexable(type = IndexableType.REINDEX)
397            @Override
398            public BookmarksEntry moveEntryToTrash(long userId, BookmarksEntry entry)
399                    throws PortalException, SystemException {
400    
401                    int oldStatus = entry.getStatus();
402    
403                    entry = updateStatus(userId, entry, WorkflowConstants.STATUS_IN_TRASH);
404    
405                    trashEntryLocalService.addTrashEntry(
406                            userId, entry.getGroupId(), BookmarksEntry.class.getName(),
407                            entry.getEntryId(), entry.getUuid(), null, oldStatus, null, null);
408    
409                    return entry;
410            }
411    
412            @Indexable(type = IndexableType.REINDEX)
413            @Override
414            public BookmarksEntry moveEntryToTrash(long userId, long entryId)
415                    throws PortalException, SystemException {
416    
417                    BookmarksEntry entry = getEntry(entryId);
418    
419                    return moveEntryToTrash(userId, entry);
420            }
421    
422            @Override
423            public BookmarksEntry openEntry(long userId, BookmarksEntry entry)
424                    throws SystemException {
425    
426                    entry.setVisits(entry.getVisits() + 1);
427    
428                    bookmarksEntryPersistence.update(entry);
429    
430                    assetEntryLocalService.incrementViewCounter(
431                            userId, BookmarksEntry.class.getName(), entry.getEntryId(), 1);
432    
433                    return entry;
434            }
435    
436            @Override
437            public BookmarksEntry openEntry(long userId, long entryId)
438                    throws PortalException, SystemException {
439    
440                    BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
441                            entryId);
442    
443                    return openEntry(userId, entry);
444            }
445    
446            @Override
447            public void rebuildTree(long companyId) throws SystemException {
448                    bookmarksFolderLocalService.rebuildTree(companyId);
449    
450                    Session session = bookmarksEntryPersistence.openSession();
451    
452                    try {
453                            TreePathUtil.rebuildTree(
454                                    session, companyId, BookmarksEntryModelImpl.TABLE_NAME,
455                                    BookmarksFolderModelImpl.TABLE_NAME, "folderId", true);
456                    }
457                    finally {
458                            bookmarksEntryPersistence.closeSession(session);
459    
460                            bookmarksEntryPersistence.clearCache();
461                    }
462            }
463    
464            @Indexable(type = IndexableType.REINDEX)
465            @Override
466            public BookmarksEntry restoreEntryFromTrash(long userId, long entryId)
467                    throws PortalException, SystemException {
468    
469                    BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
470                            entryId);
471    
472                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
473                            BookmarksEntry.class.getName(), entryId);
474    
475                    entry = updateStatus(userId, entry, trashEntry.getStatus());
476    
477                    trashEntryLocalService.deleteEntry(
478                            BookmarksEntry.class.getName(), entry.getEntryId());
479    
480                    return entry;
481            }
482    
483            @Override
484            public Hits search(
485                            long groupId, long userId, long creatorUserId, int status,
486                            int start, int end)
487                    throws PortalException, SystemException {
488    
489                    Indexer indexer = IndexerRegistryUtil.getIndexer(
490                            BookmarksEntry.class.getName());
491    
492                    SearchContext searchContext = new SearchContext();
493    
494                    searchContext.setAttribute(Field.STATUS, status);
495    
496                    if (creatorUserId > 0) {
497                            searchContext.setAttribute(
498                                    Field.USER_ID, String.valueOf(creatorUserId));
499                    }
500    
501                    searchContext.setAttribute("paginationType", "none");
502    
503                    Group group = groupLocalService.getGroup(groupId);
504    
505                    searchContext.setCompanyId(group.getCompanyId());
506    
507                    searchContext.setEnd(end);
508                    searchContext.setGroupIds(new long[] {groupId});
509                    searchContext.setSorts(new Sort(Field.MODIFIED_DATE, true));
510                    searchContext.setStart(start);
511                    searchContext.setUserId(userId);
512    
513                    return indexer.search(searchContext);
514            }
515    
516            @Override
517            public void subscribeEntry(long userId, long entryId)
518                    throws PortalException, SystemException {
519    
520                    BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
521                            entryId);
522    
523                    subscriptionLocalService.addSubscription(
524                            userId, entry.getGroupId(), BookmarksEntry.class.getName(),
525                            entryId);
526            }
527    
528            @Override
529            public void unsubscribeEntry(long userId, long entryId)
530                    throws PortalException, SystemException {
531    
532                    subscriptionLocalService.deleteSubscription(
533                            userId, BookmarksEntry.class.getName(), entryId);
534            }
535    
536            @Override
537            public void updateAsset(
538                            long userId, BookmarksEntry entry, long[] assetCategoryIds,
539                            String[] assetTagNames, long[] assetLinkEntryIds)
540                    throws PortalException, SystemException {
541    
542                    AssetEntry assetEntry = assetEntryLocalService.updateEntry(
543                            userId, entry.getGroupId(), entry.getCreateDate(),
544                            entry.getModifiedDate(), BookmarksEntry.class.getName(),
545                            entry.getEntryId(), entry.getUuid(), 0, assetCategoryIds,
546                            assetTagNames, true, null, null, null, ContentTypes.TEXT_PLAIN,
547                            entry.getName(), entry.getDescription(), null, entry.getUrl(), null,
548                            0, 0, null, false);
549    
550                    assetLinkLocalService.updateLinks(
551                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
552                            AssetLinkConstants.TYPE_RELATED);
553            }
554    
555            @Indexable(type = IndexableType.REINDEX)
556            @Override
557            public BookmarksEntry updateEntry(
558                            long userId, long entryId, long groupId, long folderId, String name,
559                            String url, String description, ServiceContext serviceContext)
560                    throws PortalException, SystemException {
561    
562                    // Entry
563    
564                    BookmarksEntry entry = bookmarksEntryPersistence.findByPrimaryKey(
565                            entryId);
566    
567                    if (Validator.isNull(name)) {
568                            name = url;
569                    }
570    
571                    validate(url);
572    
573                    entry.setModifiedDate(serviceContext.getModifiedDate(null));
574                    entry.setFolderId(folderId);
575                    entry.setTreePath(entry.buildTreePath());
576                    entry.setName(name);
577                    entry.setUrl(url);
578                    entry.setDescription(description);
579                    entry.setExpandoBridgeAttributes(serviceContext);
580    
581                    bookmarksEntryPersistence.update(entry);
582    
583                    // Asset
584    
585                    updateAsset(
586                            userId, entry, serviceContext.getAssetCategoryIds(),
587                            serviceContext.getAssetTagNames(),
588                            serviceContext.getAssetLinkEntryIds());
589    
590                    // Social
591    
592                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
593    
594                    extraDataJSONObject.put("title", entry.getName());
595    
596                    socialActivityLocalService.addActivity(
597                            userId, entry.getGroupId(), BookmarksEntry.class.getName(), entryId,
598                            BookmarksActivityKeys.UPDATE_ENTRY, extraDataJSONObject.toString(),
599                            0);
600    
601                    // Subscriptions
602    
603                    notifySubscribers(entry, serviceContext);
604    
605                    return entry;
606            }
607    
608            @Override
609            public BookmarksEntry updateStatus(
610                            long userId, BookmarksEntry entry, int status)
611                    throws PortalException, SystemException {
612    
613                    // Entry
614    
615                    User user = userPersistence.findByPrimaryKey(userId);
616    
617                    entry.setStatus(status);
618                    entry.setStatusByUserId(userId);
619                    entry.setStatusByUserName(user.getScreenName());
620                    entry.setStatusDate(new Date());
621    
622                    bookmarksEntryPersistence.update(entry);
623    
624                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
625    
626                    extraDataJSONObject.put("title", entry.getName());
627    
628                    if (status == WorkflowConstants.STATUS_APPROVED) {
629    
630                            // Asset
631    
632                            assetEntryLocalService.updateVisible(
633                                    BookmarksEntry.class.getName(), entry.getEntryId(), true);
634    
635                            // Social
636    
637                            socialActivityLocalService.addActivity(
638                                    userId, entry.getGroupId(), BookmarksEntry.class.getName(),
639                                    entry.getEntryId(),
640                                    SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
641                                    extraDataJSONObject.toString(), 0);
642                    }
643                    else if (status == WorkflowConstants.STATUS_IN_TRASH) {
644    
645                            // Asset
646    
647                            assetEntryLocalService.updateVisible(
648                                    BookmarksEntry.class.getName(), entry.getEntryId(), false);
649    
650                            // Social
651    
652                            socialActivityLocalService.addActivity(
653                                    userId, entry.getGroupId(), BookmarksEntry.class.getName(),
654                                    entry.getEntryId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
655                                    extraDataJSONObject.toString(), 0);
656                    }
657    
658                    return entry;
659            }
660    
661            protected long getFolder(BookmarksEntry entry, long folderId)
662                    throws SystemException {
663    
664                    if ((entry.getFolderId() != folderId) &&
665                            (folderId != BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID)) {
666    
667                            BookmarksFolder newFolder =
668                                    bookmarksFolderPersistence.fetchByPrimaryKey(folderId);
669    
670                            if ((newFolder == null) ||
671                                    (entry.getGroupId() != newFolder.getGroupId())) {
672    
673                                    folderId = entry.getFolderId();
674                            }
675                    }
676    
677                    return folderId;
678            }
679    
680            protected void notify(final SubscriptionSender subscriptionSender) {
681                    TransactionCommitCallbackRegistryUtil.registerCallback(
682                            new Callable<Void>() {
683    
684                                    @Override
685                                    public Void call() throws Exception {
686                                            subscriptionSender.flushNotificationsAsync();
687    
688                                            return null;
689                                    }
690    
691                            }
692                    );
693            }
694    
695            protected void notifySubscribers(
696                            BookmarksEntry entry, ServiceContext serviceContext)
697                    throws PortalException, SystemException {
698    
699                    String layoutFullURL = serviceContext.getLayoutFullURL();
700    
701                    if (Validator.isNull(layoutFullURL)) {
702                            return;
703                    }
704    
705                    PortletPreferences preferences =
706                            ServiceContextUtil.getPortletPreferences(serviceContext);
707    
708                    if (preferences == null) {
709                            long ownerId = entry.getGroupId();
710                            int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
711                            long plid = PortletKeys.PREFS_PLID_SHARED;
712                            String portletId = PortletKeys.BOOKMARKS;
713                            String defaultPreferences = null;
714    
715                            preferences = portletPreferencesLocalService.getPreferences(
716                                    entry.getCompanyId(), ownerId, ownerType, plid, portletId,
717                                    defaultPreferences);
718                    }
719    
720                    if ((serviceContext.isCommandAdd() &&
721                             !BookmarksUtil.getEmailEntryAddedEnabled(preferences)) ||
722                            (serviceContext.isCommandUpdate() &&
723                             !BookmarksUtil.getEmailEntryUpdatedEnabled(preferences))) {
724    
725                            return;
726                    }
727    
728                    String statusByUserName = StringPool.BLANK;
729    
730                    try {
731                            User user = userLocalService.getUserById(
732                                    serviceContext.getGuestOrUserId());
733    
734                            statusByUserName = user.getFullName();
735                    }
736                    catch (Exception e) {
737                            _log.error(e, e);
738                    }
739    
740                    String entryURL =
741                            layoutFullURL + Portal.FRIENDLY_URL_SEPARATOR + "bookmarks" +
742                                    StringPool.SLASH + entry.getEntryId();
743    
744                    String fromAddress = BookmarksUtil.getEmailFromAddress(
745                            preferences, entry.getCompanyId());
746                    String fromName = BookmarksUtil.getEmailFromName(
747                            preferences, entry.getCompanyId());
748    
749                    Map<Locale, String> localizedSubjectMap = null;
750                    Map<Locale, String> localizedBodyMap = null;
751    
752                    if (serviceContext.isCommandUpdate()) {
753                            localizedSubjectMap = BookmarksUtil.getEmailEntryUpdatedSubjectMap(
754                                    preferences);
755                            localizedBodyMap = BookmarksUtil.getEmailEntryUpdatedBodyMap(
756                                    preferences);
757                    }
758                    else {
759                            localizedSubjectMap = BookmarksUtil.getEmailEntryAddedSubjectMap(
760                                    preferences);
761                            localizedBodyMap = BookmarksUtil.getEmailEntryAddedBodyMap(
762                                    preferences);
763                    }
764    
765                    SubscriptionSender subscriptionSender = new SubscriptionSender();
766    
767                    subscriptionSender.setCompanyId(entry.getCompanyId());
768                    subscriptionSender.setContextAttributes(
769                            "[$BOOKMARKS_ENTRY_STATUS_BY_USER_NAME$]", statusByUserName,
770                            "[$BOOKMARKS_ENTRY_URL$]", entryURL);
771                    subscriptionSender.setContextUserPrefix("BOOKMARKS_ENTRY");
772                    subscriptionSender.setFrom(fromAddress, fromName);
773                    subscriptionSender.setHtmlFormat(true);
774                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
775                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
776                    subscriptionSender.setMailId("bookmarks_entry", entry.getEntryId());
777                    subscriptionSender.setPortletId(PortletKeys.BOOKMARKS);
778                    subscriptionSender.setReplyToAddress(fromAddress);
779                    subscriptionSender.setScopeGroupId(entry.getGroupId());
780                    subscriptionSender.setServiceContext(serviceContext);
781                    subscriptionSender.setUserId(entry.getUserId());
782    
783                    BookmarksFolder folder = entry.getFolder();
784    
785                    List<Long> folderIds = new ArrayList<Long>();
786    
787                    if (folder != null) {
788                            folderIds.add(folder.getFolderId());
789    
790                            folderIds.addAll(folder.getAncestorFolderIds());
791                    }
792    
793                    for (long curFolderId : folderIds) {
794                            subscriptionSender.addPersistedSubscribers(
795                                    BookmarksFolder.class.getName(), curFolderId);
796                    }
797    
798                    subscriptionSender.addPersistedSubscribers(
799                            BookmarksFolder.class.getName(), entry.getGroupId());
800    
801                    subscriptionSender.addPersistedSubscribers(
802                            BookmarksEntry.class.getName(), entry.getEntryId());
803    
804                    notify(subscriptionSender);
805            }
806    
807            protected void validate(String url) throws PortalException {
808                    if (!Validator.isUrl(url)) {
809                            throw new EntryURLException();
810                    }
811            }
812    
813            private static Log _log = LogFactoryUtil.getLog(
814                    BookmarksEntryLocalServiceImpl.class);
815    
816    }