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.QueryDefinition;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.json.JSONFactoryUtil;
021    import com.liferay.portal.kernel.json.JSONObject;
022    import com.liferay.portal.kernel.search.Indexable;
023    import com.liferay.portal.kernel.search.IndexableType;
024    import com.liferay.portal.kernel.search.Indexer;
025    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
026    import com.liferay.portal.kernel.systemevent.SystemEvent;
027    import com.liferay.portal.kernel.util.ContentTypes;
028    import com.liferay.portal.kernel.util.StringPool;
029    import com.liferay.portal.kernel.util.TreeModelTasksAdapter;
030    import com.liferay.portal.kernel.util.TreePathUtil;
031    import com.liferay.portal.kernel.util.Validator;
032    import com.liferay.portal.kernel.workflow.WorkflowConstants;
033    import com.liferay.portal.model.ResourceConstants;
034    import com.liferay.portal.model.SystemEventConstants;
035    import com.liferay.portal.model.TreeModel;
036    import com.liferay.portal.model.User;
037    import com.liferay.portal.service.ServiceContext;
038    import com.liferay.portlet.asset.model.AssetEntry;
039    import com.liferay.portlet.asset.model.AssetLinkConstants;
040    import com.liferay.portlet.bookmarks.FolderNameException;
041    import com.liferay.portlet.bookmarks.model.BookmarksEntry;
042    import com.liferay.portlet.bookmarks.model.BookmarksFolder;
043    import com.liferay.portlet.bookmarks.model.BookmarksFolderConstants;
044    import com.liferay.portlet.bookmarks.service.base.BookmarksFolderLocalServiceBaseImpl;
045    import com.liferay.portlet.bookmarks.util.comparator.FolderIdComparator;
046    import com.liferay.portlet.social.model.SocialActivityConstants;
047    import com.liferay.portlet.trash.model.TrashEntry;
048    import com.liferay.portlet.trash.model.TrashVersion;
049    
050    import java.util.ArrayList;
051    import java.util.Date;
052    import java.util.List;
053    
054    /**
055     * @author Brian Wing Shun Chan
056     * @author Wesley Gong
057     */
058    public class BookmarksFolderLocalServiceImpl
059            extends BookmarksFolderLocalServiceBaseImpl {
060    
061            @Override
062            public BookmarksFolder addFolder(
063                            long userId, long parentFolderId, String name, String description,
064                            ServiceContext serviceContext)
065                    throws PortalException {
066    
067                    // Folder
068    
069                    User user = userPersistence.findByPrimaryKey(userId);
070                    long groupId = serviceContext.getScopeGroupId();
071                    parentFolderId = getParentFolderId(groupId, parentFolderId);
072                    Date now = new Date();
073    
074                    validate(name);
075    
076                    long folderId = counterLocalService.increment();
077    
078                    BookmarksFolder folder = bookmarksFolderPersistence.create(folderId);
079    
080                    folder.setUuid(serviceContext.getUuid());
081                    folder.setGroupId(groupId);
082                    folder.setCompanyId(user.getCompanyId());
083                    folder.setUserId(user.getUserId());
084                    folder.setUserName(user.getFullName());
085                    folder.setCreateDate(serviceContext.getCreateDate(now));
086                    folder.setModifiedDate(serviceContext.getModifiedDate(now));
087                    folder.setParentFolderId(parentFolderId);
088                    folder.setTreePath(folder.buildTreePath());
089                    folder.setName(name);
090                    folder.setDescription(description);
091                    folder.setExpandoBridgeAttributes(serviceContext);
092    
093                    bookmarksFolderPersistence.update(folder);
094    
095                    // Resources
096    
097                    resourceLocalService.addModelResources(folder, serviceContext);
098    
099                    // Asset
100    
101                    updateAsset(
102                            userId, folder, serviceContext.getAssetCategoryIds(),
103                            serviceContext.getAssetTagNames(),
104                            serviceContext.getAssetLinkEntryIds());
105    
106                    return folder;
107            }
108    
109            @Indexable(type = IndexableType.DELETE)
110            @Override
111            @SystemEvent(
112                    action = SystemEventConstants.ACTION_SKIP,
113                    type = SystemEventConstants.TYPE_DELETE)
114            public BookmarksFolder deleteFolder(BookmarksFolder folder)
115                    throws PortalException {
116    
117                    return bookmarksFolderLocalService.deleteFolder(folder, true);
118            }
119    
120            @Indexable(type = IndexableType.DELETE)
121            @Override
122            @SystemEvent(
123                    action = SystemEventConstants.ACTION_SKIP,
124                    type = SystemEventConstants.TYPE_DELETE)
125            public BookmarksFolder deleteFolder(
126                            BookmarksFolder folder, boolean includeTrashedEntries)
127                    throws PortalException {
128    
129                    List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
130                            folder.getGroupId(), folder.getFolderId());
131    
132                    for (BookmarksFolder curFolder : folders) {
133                            if (includeTrashedEntries || !curFolder.isInTrashExplicitly()) {
134                                    bookmarksFolderLocalService.deleteFolder(curFolder);
135                            }
136                    }
137    
138                    // Folder
139    
140                    bookmarksFolderPersistence.remove(folder);
141    
142                    // Resources
143    
144                    resourceLocalService.deleteResource(
145                            folder, ResourceConstants.SCOPE_INDIVIDUAL);
146    
147                    // Entries
148    
149                    bookmarksEntryLocalService.deleteEntries(
150                            folder.getGroupId(), folder.getFolderId(), includeTrashedEntries);
151    
152                    // Asset
153    
154                    assetEntryLocalService.deleteEntry(
155                            BookmarksFolder.class.getName(), folder.getFolderId());
156    
157                    // Expando
158    
159                    expandoRowLocalService.deleteRows(folder.getFolderId());
160    
161                    // Subscriptions
162    
163                    subscriptionLocalService.deleteSubscriptions(
164                            folder.getCompanyId(), BookmarksFolder.class.getName(),
165                            folder.getFolderId());
166    
167                    // Trash
168    
169                    if (folder.isInTrashExplicitly()) {
170                            trashEntryLocalService.deleteEntry(
171                                    BookmarksFolder.class.getName(), folder.getFolderId());
172                    }
173                    else {
174                            trashVersionLocalService.deleteTrashVersion(
175                                    BookmarksFolder.class.getName(), folder.getFolderId());
176                    }
177    
178                    return folder;
179            }
180    
181            @Indexable(type = IndexableType.DELETE)
182            @Override
183            public BookmarksFolder deleteFolder(long folderId) throws PortalException {
184                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
185                            folderId);
186    
187                    return bookmarksFolderLocalService.deleteFolder(folder);
188            }
189    
190            @Indexable(type = IndexableType.DELETE)
191            @Override
192            public BookmarksFolder deleteFolder(
193                            long folderId, boolean includeTrashedEntries)
194                    throws PortalException {
195    
196                    BookmarksFolder folder = bookmarksFolderLocalService.getFolder(
197                            folderId);
198    
199                    return bookmarksFolderLocalService.deleteFolder(
200                            folder, includeTrashedEntries);
201            }
202    
203            @Override
204            public void deleteFolders(long groupId) throws PortalException {
205                    List<BookmarksFolder> folders =
206                            bookmarksFolderPersistence.findByGroupId(groupId);
207    
208                    for (BookmarksFolder folder : folders) {
209                            bookmarksFolderLocalService.deleteFolder(folder);
210                    }
211            }
212    
213            @Override
214            public List<BookmarksFolder> getCompanyFolders(
215                    long companyId, int start, int end) {
216    
217                    return bookmarksFolderPersistence.findByCompanyId(
218                            companyId, start, end);
219            }
220    
221            @Override
222            public int getCompanyFoldersCount(long companyId) {
223                    return bookmarksFolderPersistence.countByCompanyId(companyId);
224            }
225    
226            @Override
227            public BookmarksFolder getFolder(long folderId) throws PortalException {
228                    return bookmarksFolderPersistence.findByPrimaryKey(folderId);
229            }
230    
231            @Override
232            public List<BookmarksFolder> getFolders(long groupId) {
233                    return bookmarksFolderPersistence.findByGroupId(groupId);
234            }
235    
236            @Override
237            public List<BookmarksFolder> getFolders(long groupId, long parentFolderId) {
238                    return bookmarksFolderPersistence.findByG_P(groupId, parentFolderId);
239            }
240    
241            @Override
242            public List<BookmarksFolder> getFolders(
243                    long groupId, long parentFolderId, int start, int end) {
244    
245                    return getFolders(
246                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED, start,
247                            end);
248            }
249    
250            @Override
251            public List<BookmarksFolder> getFolders(
252                    long groupId, long parentFolderId, int status, int start, int end) {
253    
254                    return bookmarksFolderPersistence.findByG_P_S(
255                            groupId, parentFolderId, status, start, end);
256            }
257    
258            @Override
259            public List<Object> getFoldersAndEntries(long groupId, long folderId) {
260                    return getFoldersAndEntries(
261                            groupId, folderId, WorkflowConstants.STATUS_ANY);
262            }
263    
264            @Override
265            public List<Object> getFoldersAndEntries(
266                    long groupId, long folderId, int status) {
267    
268                    QueryDefinition<?> queryDefinition = new QueryDefinition<Object>(
269                            status);
270    
271                    return bookmarksFolderFinder.findF_E_ByG_F(
272                            groupId, folderId, queryDefinition);
273            }
274    
275            @Override
276            public List<Object> getFoldersAndEntries(
277                    long groupId, long folderId, int status, int start, int end) {
278    
279                    QueryDefinition<?> queryDefinition = new QueryDefinition<Object>(
280                            status, start, end, null);
281    
282                    return bookmarksFolderFinder.findF_E_ByG_F(
283                            groupId, folderId, queryDefinition);
284            }
285    
286            @Override
287            public int getFoldersAndEntriesCount(
288                    long groupId, long folderId, int status) {
289    
290                    QueryDefinition<?> queryDefinition = new QueryDefinition<Object>(
291                            status);
292    
293                    return bookmarksFolderFinder.countF_E_ByG_F(
294                            groupId, folderId, queryDefinition);
295            }
296    
297            @Override
298            public int getFoldersCount(long groupId, long parentFolderId) {
299                    return getFoldersCount(
300                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED);
301            }
302    
303            @Override
304            public int getFoldersCount(long groupId, long parentFolderId, int status) {
305                    return bookmarksFolderPersistence.countByG_P_S(
306                            groupId, parentFolderId, status);
307            }
308    
309            @Override
310            public List<BookmarksFolder> getNoAssetFolders() {
311                    return bookmarksFolderFinder.findByNoAssets();
312            }
313    
314            @Override
315            public void getSubfolderIds(
316                    List<Long> folderIds, long groupId, long folderId) {
317    
318                    List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
319                            groupId, folderId);
320    
321                    for (BookmarksFolder folder : folders) {
322                            folderIds.add(folder.getFolderId());
323    
324                            getSubfolderIds(
325                                    folderIds, folder.getGroupId(), folder.getFolderId());
326                    }
327            }
328    
329            @Indexable(type = IndexableType.REINDEX)
330            @Override
331            public BookmarksFolder moveFolder(long folderId, long parentFolderId)
332                    throws PortalException {
333    
334                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
335                            folderId);
336    
337                    folder.setParentFolderId(parentFolderId);
338                    folder.setTreePath(folder.buildTreePath());
339    
340                    bookmarksFolderPersistence.update(folder);
341    
342                    rebuildTree(
343                            folder.getCompanyId(), folderId, folder.getTreePath(), true);
344    
345                    return folder;
346            }
347    
348            @Override
349            public BookmarksFolder moveFolderFromTrash(
350                            long userId, long folderId, long parentFolderId)
351                    throws PortalException {
352    
353                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
354                            folderId);
355    
356                    if (folder.isInTrashExplicitly()) {
357                            restoreFolderFromTrash(userId, folderId);
358                    }
359                    else {
360    
361                            // Folder
362    
363                            TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
364                                    BookmarksFolder.class.getName(), folderId);
365    
366                            int status = WorkflowConstants.STATUS_APPROVED;
367    
368                            if (trashVersion != null) {
369                                    status = trashVersion.getStatus();
370                            }
371    
372                            updateStatus(userId, folder, status);
373    
374                            // Trash
375    
376                            if (trashVersion != null) {
377                                    trashVersionLocalService.deleteTrashVersion(trashVersion);
378                            }
379    
380                            // Folders and entries
381    
382                            List<Object> foldersAndEntries =
383                                    bookmarksFolderLocalService.getFoldersAndEntries(
384                                            folder.getGroupId(), folder.getFolderId(),
385                                            WorkflowConstants.STATUS_IN_TRASH);
386    
387                            restoreDependentsFromTrash(foldersAndEntries);
388                    }
389    
390                    return bookmarksFolderLocalService.moveFolder(folderId, parentFolderId);
391            }
392    
393            @Indexable(type = IndexableType.REINDEX)
394            @Override
395            public BookmarksFolder moveFolderToTrash(long userId, long folderId)
396                    throws PortalException {
397    
398                    // Folder
399    
400                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
401                            folderId);
402    
403                    int oldStatus = folder.getStatus();
404    
405                    folder = updateStatus(
406                            userId, folder, WorkflowConstants.STATUS_IN_TRASH);
407    
408                    // Trash
409    
410                    TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
411                            userId, folder.getGroupId(), BookmarksFolder.class.getName(),
412                            folder.getFolderId(), folder.getUuid(), null, oldStatus, null,
413                            null);
414    
415                    // Folders and entries
416    
417                    List<Object> foldersAndEntries =
418                            bookmarksFolderLocalService.getFoldersAndEntries(
419                                    folder.getGroupId(), folder.getFolderId());
420    
421                    moveDependentsToTrash(foldersAndEntries, trashEntry.getEntryId());
422    
423                    // Social
424    
425                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
426    
427                    extraDataJSONObject.put("title", folder.getName());
428    
429                    socialActivityLocalService.addActivity(
430                            userId, folder.getGroupId(), BookmarksFolder.class.getName(),
431                            folder.getFolderId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
432                            extraDataJSONObject.toString(), 0);
433    
434                    return folder;
435            }
436    
437            @Override
438            public void rebuildTree(long companyId) throws PortalException {
439                    rebuildTree(
440                            companyId, BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID,
441                            StringPool.SLASH, false);
442            }
443    
444            @Override
445            public void rebuildTree(
446                            long companyId, long parentFolderId, String parentTreePath,
447                            final boolean reindex)
448                    throws PortalException {
449    
450                    TreePathUtil.rebuildTree(
451                            companyId, parentFolderId, parentTreePath,
452                            new TreeModelTasksAdapter<BookmarksFolder>() {
453    
454                                    @Override
455                                    public List<BookmarksFolder> findTreeModels(
456                                            long previousId, long companyId, long parentPrimaryKey,
457                                            int size) {
458    
459                                            return bookmarksFolderPersistence.findByF_C_P_NotS(
460                                                    previousId, companyId, parentPrimaryKey,
461                                                    WorkflowConstants.STATUS_IN_TRASH, QueryUtil.ALL_POS,
462                                                    size, new FolderIdComparator(true));
463                                    }
464    
465                                    @Override
466                                    public void rebuildDependentModelsTreePaths(
467                                                    long parentPrimaryKey, String treePath)
468                                            throws PortalException {
469    
470                                            bookmarksEntryLocalService.setTreePaths(
471                                                    parentPrimaryKey, treePath, false);
472                                    }
473    
474                                    @Override
475                                    public void reindexTreeModels(List<TreeModel> treeModels)
476                                            throws PortalException {
477    
478                                            if (!reindex) {
479                                                    return;
480                                            }
481    
482                                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
483                                                    BookmarksFolder.class);
484    
485                                            for (TreeModel treeModel : treeModels) {
486                                                    indexer.reindex(treeModel);
487                                            }
488                                    }
489    
490                            }
491                    );
492            }
493    
494            @Indexable(type = IndexableType.REINDEX)
495            @Override
496            public void restoreFolderFromTrash(long userId, long folderId)
497                    throws PortalException {
498    
499                    // Folder
500    
501                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
502                            folderId);
503    
504                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
505                            BookmarksFolder.class.getName(), folderId);
506    
507                    updateStatus(userId, folder, trashEntry.getStatus());
508    
509                    // Folders and entries
510    
511                    List<Object> foldersAndEntries =
512                            bookmarksFolderLocalService.getFoldersAndEntries(
513                                    folder.getGroupId(), folder.getFolderId(),
514                                    WorkflowConstants.STATUS_IN_TRASH);
515    
516                    restoreDependentsFromTrash(foldersAndEntries);
517    
518                    // Trash
519    
520                    trashEntryLocalService.deleteEntry(trashEntry.getEntryId());
521    
522                    // Social
523    
524                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
525    
526                    extraDataJSONObject.put("title", folder.getName());
527    
528                    socialActivityLocalService.addActivity(
529                            userId, folder.getGroupId(), BookmarksFolder.class.getName(),
530                            folder.getFolderId(),
531                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
532                            extraDataJSONObject.toString(), 0);
533            }
534    
535            @Override
536            public void subscribeFolder(long userId, long groupId, long folderId)
537                    throws PortalException {
538    
539                    if (folderId == BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
540                            folderId = groupId;
541                    }
542    
543                    subscriptionLocalService.addSubscription(
544                            userId, groupId, BookmarksFolder.class.getName(), folderId);
545            }
546    
547            @Override
548            public void unsubscribeFolder(long userId, long groupId, long folderId)
549                    throws PortalException {
550    
551                    if (folderId == BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
552                            folderId = groupId;
553                    }
554    
555                    subscriptionLocalService.deleteSubscription(
556                            userId, BookmarksFolder.class.getName(), folderId);
557            }
558    
559            @Override
560            public void updateAsset(
561                            long userId, BookmarksFolder folder, long[] assetCategoryIds,
562                            String[] assetTagNames, long[] assetLinkEntryIds)
563                    throws PortalException {
564    
565                    AssetEntry assetEntry = assetEntryLocalService.updateEntry(
566                            userId, folder.getGroupId(), folder.getCreateDate(),
567                            folder.getModifiedDate(), BookmarksFolder.class.getName(),
568                            folder.getFolderId(), folder.getUuid(), 0, assetCategoryIds,
569                            assetTagNames, true, null, null, null, ContentTypes.TEXT_PLAIN,
570                            folder.getName(), folder.getDescription(), null, null, null, 0, 0,
571                            null, false);
572    
573                    assetLinkLocalService.updateLinks(
574                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
575                            AssetLinkConstants.TYPE_RELATED);
576            }
577    
578            @Indexable(type = IndexableType.REINDEX)
579            @Override
580            public BookmarksFolder updateFolder(
581                            long userId, long folderId, long parentFolderId, String name,
582                            String description, boolean mergeWithParentFolder,
583                            ServiceContext serviceContext)
584                    throws PortalException {
585    
586                    // Merge folders
587    
588                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
589                            folderId);
590    
591                    parentFolderId = getParentFolderId(folder, parentFolderId);
592    
593                    if (mergeWithParentFolder && (folderId != parentFolderId)) {
594                            mergeFolders(folder, parentFolderId);
595    
596                            return folder;
597                    }
598    
599                    // Folder
600    
601                    validate(name);
602    
603                    folder.setModifiedDate(serviceContext.getModifiedDate(null));
604                    folder.setParentFolderId(parentFolderId);
605                    folder.setTreePath(folder.buildTreePath());
606                    folder.setName(name);
607                    folder.setDescription(description);
608                    folder.setExpandoBridgeAttributes(serviceContext);
609    
610                    bookmarksFolderPersistence.update(folder);
611    
612                    // Asset
613    
614                    updateAsset(
615                            userId, folder, serviceContext.getAssetCategoryIds(),
616                            serviceContext.getAssetTagNames(),
617                            serviceContext.getAssetLinkEntryIds());
618    
619                    return folder;
620            }
621    
622            @Override
623            public BookmarksFolder updateStatus(
624                            long userId, BookmarksFolder folder, int status)
625                    throws PortalException {
626    
627                    // Folder
628    
629                    User user = userPersistence.findByPrimaryKey(userId);
630    
631                    folder.setStatus(status);
632                    folder.setStatusByUserId(userId);
633                    folder.setStatusByUserName(user.getFullName());
634                    folder.setStatusDate(new Date());
635    
636                    bookmarksFolderPersistence.update(folder);
637    
638                    // Asset
639    
640                    if (status == WorkflowConstants.STATUS_APPROVED) {
641                            assetEntryLocalService.updateVisible(
642                                    BookmarksFolder.class.getName(), folder.getFolderId(), true);
643                    }
644                    else if (status == WorkflowConstants.STATUS_IN_TRASH) {
645                            assetEntryLocalService.updateVisible(
646                                    BookmarksFolder.class.getName(), folder.getFolderId(), false);
647                    }
648    
649                    // Index
650    
651                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
652                            BookmarksFolder.class);
653    
654                    indexer.reindex(folder);
655    
656                    return folder;
657            }
658    
659            protected long getParentFolderId(
660                    BookmarksFolder folder, long parentFolderId) {
661    
662                    if (parentFolderId ==
663                                    BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
664    
665                            return parentFolderId;
666                    }
667    
668                    if (folder.getFolderId() == parentFolderId) {
669                            return folder.getParentFolderId();
670                    }
671    
672                    BookmarksFolder parentFolder =
673                            bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
674    
675                    if ((parentFolder == null) ||
676                            (folder.getGroupId() != parentFolder.getGroupId())) {
677    
678                            return folder.getParentFolderId();
679                    }
680    
681                    List<Long> subfolderIds = new ArrayList<Long>();
682    
683                    getSubfolderIds(
684                            subfolderIds, folder.getGroupId(), folder.getFolderId());
685    
686                    if (subfolderIds.contains(parentFolderId)) {
687                            return folder.getParentFolderId();
688                    }
689    
690                    return parentFolderId;
691            }
692    
693            protected long getParentFolderId(long groupId, long parentFolderId) {
694                    if (parentFolderId !=
695                                    BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
696    
697                            BookmarksFolder parentFolder =
698                                    bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
699    
700                            if ((parentFolder == null) ||
701                                    (groupId != parentFolder.getGroupId())) {
702    
703                                    parentFolderId =
704                                            BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID;
705                            }
706                    }
707    
708                    return parentFolderId;
709            }
710    
711            protected void mergeFolders(BookmarksFolder fromFolder, long toFolderId)
712                    throws PortalException {
713    
714                    List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
715                            fromFolder.getGroupId(), fromFolder.getFolderId());
716    
717                    for (BookmarksFolder folder : folders) {
718                            mergeFolders(folder, toFolderId);
719                    }
720    
721                    List<BookmarksEntry> entries = bookmarksEntryPersistence.findByG_F(
722                            fromFolder.getGroupId(), fromFolder.getFolderId());
723    
724                    for (BookmarksEntry entry : entries) {
725                            entry.setFolderId(toFolderId);
726    
727                            bookmarksEntryPersistence.update(entry);
728    
729                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
730                                    BookmarksEntry.class);
731    
732                            indexer.reindex(entry);
733                    }
734    
735                    bookmarksFolderLocalService.deleteFolder(fromFolder);
736            }
737    
738            protected void moveDependentsToTrash(
739                            List<Object> foldersAndEntries, long trashEntryId)
740                    throws PortalException {
741    
742                    for (Object object : foldersAndEntries) {
743                            if (object instanceof BookmarksEntry) {
744    
745                                    // Entry
746    
747                                    BookmarksEntry entry = (BookmarksEntry)object;
748    
749                                    if (entry.isInTrash()) {
750                                            continue;
751                                    }
752    
753                                    int oldStatus = entry.getStatus();
754    
755                                    entry.setStatus(WorkflowConstants.STATUS_IN_TRASH);
756    
757                                    bookmarksEntryPersistence.update(entry);
758    
759                                    // Trash
760    
761                                    int status = oldStatus;
762    
763                                    if (oldStatus == WorkflowConstants.STATUS_PENDING) {
764                                            status = WorkflowConstants.STATUS_DRAFT;
765                                    }
766    
767                                    if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
768                                            trashVersionLocalService.addTrashVersion(
769                                                    trashEntryId, BookmarksEntry.class.getName(),
770                                                    entry.getEntryId(), status, null);
771                                    }
772    
773                                    // Asset
774    
775                                    assetEntryLocalService.updateVisible(
776                                            BookmarksEntry.class.getName(), entry.getEntryId(), false);
777    
778                                    // Indexer
779    
780                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
781                                            BookmarksEntry.class);
782    
783                                    indexer.reindex(entry);
784                            }
785                            else if (object instanceof BookmarksFolder) {
786    
787                                    // Folder
788    
789                                    BookmarksFolder folder = (BookmarksFolder)object;
790    
791                                    if (folder.isInTrash()) {
792                                            continue;
793                                    }
794    
795                                    int oldStatus = folder.getStatus();
796    
797                                    folder.setStatus(WorkflowConstants.STATUS_IN_TRASH);
798    
799                                    bookmarksFolderPersistence.update(folder);
800    
801                                    // Trash
802    
803                                    if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
804                                            trashVersionLocalService.addTrashVersion(
805                                                    trashEntryId, BookmarksFolder.class.getName(),
806                                                    folder.getFolderId(), oldStatus, null);
807                                    }
808    
809                                    // Folders and entries
810    
811                                    List<Object> curFoldersAndEntries = getFoldersAndEntries(
812                                            folder.getGroupId(), folder.getFolderId());
813    
814                                    moveDependentsToTrash(curFoldersAndEntries, trashEntryId);
815    
816                                    // Asset
817    
818                                    assetEntryLocalService.updateVisible(
819                                            BookmarksFolder.class.getName(), folder.getFolderId(),
820                                            false);
821    
822                                    // Index
823    
824                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
825                                            BookmarksFolder.class);
826    
827                                    indexer.reindex(folder);
828                            }
829                    }
830            }
831    
832            protected void restoreDependentsFromTrash(List<Object> foldersAndEntries)
833                    throws PortalException {
834    
835                    for (Object object : foldersAndEntries) {
836                            if (object instanceof BookmarksEntry) {
837    
838                                    // Entry
839    
840                                    BookmarksEntry entry = (BookmarksEntry)object;
841    
842                                    if (!entry.isInTrashImplicitly()) {
843                                            continue;
844                                    }
845    
846                                    TrashVersion trashVersion =
847                                            trashVersionLocalService.fetchVersion(
848                                                    BookmarksEntry.class.getName(), entry.getEntryId());
849    
850                                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
851    
852                                    if (trashVersion != null) {
853                                            oldStatus = trashVersion.getStatus();
854                                    }
855    
856                                    entry.setStatus(oldStatus);
857    
858                                    bookmarksEntryPersistence.update(entry);
859    
860                                    // Trash
861    
862                                    if (trashVersion != null) {
863                                            trashVersionLocalService.deleteTrashVersion(trashVersion);
864                                    }
865    
866                                    // Asset
867    
868                                    if (oldStatus == WorkflowConstants.STATUS_APPROVED) {
869                                            assetEntryLocalService.updateVisible(
870                                                    BookmarksEntry.class.getName(), entry.getEntryId(),
871                                                    true);
872                                    }
873    
874                                    // Indexer
875    
876                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
877                                            BookmarksEntry.class);
878    
879                                    indexer.reindex(entry);
880                            }
881                            else if (object instanceof BookmarksFolder) {
882    
883                                    // Folder
884    
885                                    BookmarksFolder folder = (BookmarksFolder)object;
886    
887                                    if (!folder.isInTrashImplicitly()) {
888                                            continue;
889                                    }
890    
891                                    TrashVersion trashVersion =
892                                            trashVersionLocalService.fetchVersion(
893                                                    BookmarksFolder.class.getName(), folder.getFolderId());
894    
895                                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
896    
897                                    if (trashVersion != null) {
898                                            oldStatus = trashVersion.getStatus();
899                                    }
900    
901                                    folder.setStatus(oldStatus);
902    
903                                    bookmarksFolderPersistence.update(folder);
904    
905                                    // Folders and entries
906    
907                                    List<Object> curFoldersAndEntries = getFoldersAndEntries(
908                                            folder.getGroupId(), folder.getFolderId(),
909                                            WorkflowConstants.STATUS_IN_TRASH);
910    
911                                    restoreDependentsFromTrash(curFoldersAndEntries);
912    
913                                    // Trash
914    
915                                    if (trashVersion != null) {
916                                            trashVersionLocalService.deleteTrashVersion(trashVersion);
917                                    }
918    
919                                    // Asset
920    
921                                    assetEntryLocalService.updateVisible(
922                                            BookmarksFolder.class.getName(), folder.getFolderId(),
923                                            true);
924    
925                                    // Index
926    
927                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
928                                            BookmarksFolder.class);
929    
930                                    indexer.reindex(folder);
931                            }
932                    }
933            }
934    
935            protected void validate(String name) throws PortalException {
936                    if (Validator.isNull(name) || name.contains("\\\\") ||
937                            name.contains("//")) {
938    
939                            throw new FolderNameException();
940                    }
941            }
942    
943    }