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