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