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