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