001    /**
002     * Copyright (c) 2000-2012 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.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.search.Indexable;
021    import com.liferay.portal.kernel.search.IndexableType;
022    import com.liferay.portal.kernel.search.Indexer;
023    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
024    import com.liferay.portal.kernel.util.ContentTypes;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.kernel.workflow.WorkflowConstants;
027    import com.liferay.portal.model.ResourceConstants;
028    import com.liferay.portal.model.User;
029    import com.liferay.portal.service.ServiceContext;
030    import com.liferay.portlet.asset.model.AssetEntry;
031    import com.liferay.portlet.asset.model.AssetLinkConstants;
032    import com.liferay.portlet.bookmarks.FolderNameException;
033    import com.liferay.portlet.bookmarks.model.BookmarksEntry;
034    import com.liferay.portlet.bookmarks.model.BookmarksFolder;
035    import com.liferay.portlet.bookmarks.model.BookmarksFolderConstants;
036    import com.liferay.portlet.bookmarks.service.base.BookmarksFolderLocalServiceBaseImpl;
037    import com.liferay.portlet.trash.model.TrashEntry;
038    
039    import java.util.ArrayList;
040    import java.util.Date;
041    import java.util.List;
042    
043    /**
044     * @author Brian Wing Shun Chan
045     * @author Wesley Gong
046     */
047    public class BookmarksFolderLocalServiceImpl
048            extends BookmarksFolderLocalServiceBaseImpl {
049    
050            public BookmarksFolder addFolder(
051                            long userId, long parentFolderId, String name, String description,
052                            ServiceContext serviceContext)
053                    throws PortalException, SystemException {
054    
055                    // Folder
056    
057                    User user = userPersistence.findByPrimaryKey(userId);
058                    long groupId = serviceContext.getScopeGroupId();
059                    parentFolderId = getParentFolderId(groupId, parentFolderId);
060                    Date now = new Date();
061    
062                    validate(name);
063    
064                    long folderId = counterLocalService.increment();
065    
066                    BookmarksFolder folder = bookmarksFolderPersistence.create(folderId);
067    
068                    folder.setUuid(serviceContext.getUuid());
069                    folder.setGroupId(groupId);
070                    folder.setCompanyId(user.getCompanyId());
071                    folder.setUserId(user.getUserId());
072                    folder.setUserName(user.getFullName());
073                    folder.setCreateDate(serviceContext.getCreateDate(now));
074                    folder.setModifiedDate(serviceContext.getModifiedDate(now));
075                    folder.setParentFolderId(parentFolderId);
076                    folder.setName(name);
077                    folder.setDescription(description);
078                    folder.setExpandoBridgeAttributes(serviceContext);
079    
080                    bookmarksFolderPersistence.update(folder);
081    
082                    // Resources
083    
084                    resourceLocalService.addModelResources(folder, serviceContext);
085    
086                    // Asset
087    
088                    updateAsset(
089                            userId, folder, serviceContext.getAssetCategoryIds(),
090                            serviceContext.getAssetTagNames(),
091                            serviceContext.getAssetLinkEntryIds());
092    
093                    return folder;
094            }
095    
096            @Indexable(type = IndexableType.DELETE)
097            public BookmarksFolder deleteFolder(BookmarksFolder folder)
098                    throws PortalException, SystemException {
099    
100                    return deleteFolder(folder, true);
101            }
102    
103            @Indexable(type = IndexableType.DELETE)
104            public BookmarksFolder deleteFolder(
105                            BookmarksFolder folder, boolean includeTrashedEntries)
106                    throws PortalException, SystemException {
107    
108                    // Folders
109    
110                    List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P_S(
111                            folder.getGroupId(), folder.getFolderId(),
112                            WorkflowConstants.STATUS_ANY);
113    
114                    for (BookmarksFolder curFolder : folders) {
115                            if (includeTrashedEntries || !curFolder.isInTrash()) {
116                                    deleteFolder(curFolder);
117                            }
118                    }
119    
120                    // Folder
121    
122                    bookmarksFolderPersistence.remove(folder);
123    
124                    // Resources
125    
126                    resourceLocalService.deleteResource(
127                            folder, ResourceConstants.SCOPE_INDIVIDUAL);
128    
129                    // Entries
130    
131                    bookmarksEntryLocalService.deleteEntries(
132                            folder.getGroupId(), folder.getFolderId(), includeTrashedEntries);
133    
134                    // Asset
135    
136                    assetEntryLocalService.deleteEntry(
137                            BookmarksFolder.class.getName(), folder.getFolderId());
138    
139                    // Expando
140    
141                    expandoValueLocalService.deleteValues(
142                            BookmarksFolder.class.getName(), folder.getFolderId());
143    
144                    // Subscriptions
145    
146                    subscriptionLocalService.deleteSubscriptions(
147                            folder.getCompanyId(), BookmarksFolder.class.getName(),
148                            folder.getFolderId());
149    
150                    // Trash
151    
152                    trashEntryLocalService.deleteEntry(
153                            BookmarksFolder.class.getName(), folder.getFolderId());
154    
155                    return folder;
156            }
157    
158            @Indexable(type = IndexableType.DELETE)
159            public BookmarksFolder deleteFolder(long folderId)
160                    throws PortalException, SystemException {
161    
162                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
163                            folderId);
164    
165                    return deleteFolder(folder);
166            }
167    
168            @Indexable(type = IndexableType.DELETE)
169            public BookmarksFolder deleteFolder(
170                            long folderId, boolean includeTrashedEntries)
171                    throws PortalException, SystemException {
172    
173                    BookmarksFolder folder = bookmarksFolderLocalService.getFolder(
174                            folderId);
175    
176                    return deleteFolder(folder, includeTrashedEntries);
177            }
178    
179            public void deleteFolders(long groupId)
180                    throws PortalException, SystemException {
181    
182                    List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
183                            groupId, BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID);
184    
185                    for (BookmarksFolder folder : folders) {
186                            bookmarksFolderLocalService.deleteFolder(folder);
187                    }
188            }
189    
190            public List<BookmarksFolder> getCompanyFolders(
191                            long companyId, int start, int end)
192                    throws SystemException {
193    
194                    return bookmarksFolderPersistence.findByCompanyId(
195                            companyId, start, end);
196            }
197    
198            public int getCompanyFoldersCount(long companyId) throws SystemException {
199                    return bookmarksFolderPersistence.countByCompanyId(companyId);
200            }
201    
202            public BookmarksFolder getFolder(long folderId)
203                    throws PortalException, SystemException {
204    
205                    return bookmarksFolderPersistence.findByPrimaryKey(folderId);
206            }
207    
208            public List<BookmarksFolder> getFolders(long groupId)
209                    throws SystemException {
210    
211                    return bookmarksFolderPersistence.findByGroupId(groupId);
212            }
213    
214            public List<BookmarksFolder> getFolders(long groupId, long parentFolderId)
215                    throws SystemException {
216    
217                    return bookmarksFolderPersistence.findByG_P(groupId, parentFolderId);
218            }
219    
220            public List<BookmarksFolder> getFolders(
221                            long groupId, long parentFolderId, int start, int end)
222                    throws SystemException {
223    
224                    return getFolders(
225                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED, start,
226                            end);
227            }
228    
229            public List<BookmarksFolder> getFolders(
230                            long groupId, long parentFolderId, int status, int start, int end)
231                    throws SystemException {
232    
233                    return bookmarksFolderPersistence.findByG_P_S(
234                            groupId, parentFolderId, status, start, end);
235            }
236    
237            public List<Object> getFoldersAndEntries(long groupId, long folderId)
238                    throws SystemException {
239    
240                    return getFoldersAndEntries(
241                            groupId, folderId, WorkflowConstants.STATUS_ANY);
242            }
243    
244            public List<Object> getFoldersAndEntries(
245                            long groupId, long folderId, int status)
246                    throws SystemException {
247    
248                    QueryDefinition queryDefinition = new QueryDefinition(status);
249    
250                    return bookmarksFolderFinder.findF_E_ByG_F(
251                            groupId, folderId, queryDefinition);
252            }
253    
254            public List<Object> getFoldersAndEntries(
255                            long groupId, long folderId, int status, int start, int end)
256                    throws SystemException {
257    
258                    QueryDefinition queryDefinition = new QueryDefinition(
259                            status, start, end, null);
260    
261                    return bookmarksFolderFinder.findF_E_ByG_F(
262                            groupId, folderId, queryDefinition);
263            }
264    
265            public int getFoldersAndEntriesCount(
266                            long groupId, long folderId, int status)
267                    throws SystemException {
268    
269                    QueryDefinition queryDefinition = new QueryDefinition(status);
270    
271                    return bookmarksFolderFinder.countF_E_ByG_F(
272                            groupId, folderId, queryDefinition);
273            }
274    
275            public int getFoldersCount(long groupId, long parentFolderId)
276                    throws SystemException {
277    
278                    return getFoldersCount(
279                            groupId, parentFolderId, WorkflowConstants.STATUS_APPROVED);
280            }
281    
282            public int getFoldersCount(long groupId, long parentFolderId, int status)
283                    throws SystemException {
284    
285                    return bookmarksFolderPersistence.countByG_P_S(
286                            groupId, parentFolderId, status);
287            }
288    
289            public List<BookmarksFolder> getNoAssetFolders() throws SystemException {
290                    return bookmarksFolderFinder.findByNoAssets();
291            }
292    
293            public void getSubfolderIds(
294                            List<Long> folderIds, long groupId, long folderId)
295                    throws SystemException {
296    
297                    List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
298                            groupId, folderId);
299    
300                    for (BookmarksFolder folder : folders) {
301                            folderIds.add(folder.getFolderId());
302    
303                            getSubfolderIds(
304                                    folderIds, folder.getGroupId(), folder.getFolderId());
305                    }
306            }
307    
308            @Indexable(type = IndexableType.REINDEX)
309            public BookmarksFolder moveFolder(long folderId, long parentFolderId)
310                    throws PortalException, SystemException {
311    
312                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
313                            folderId);
314    
315                    folder.setParentFolderId(parentFolderId);
316    
317                    bookmarksFolderPersistence.update(folder);
318    
319                    return folder;
320            }
321    
322            public BookmarksFolder moveFolderFromTrash(
323                            long userId, long folderId, long parentFolderId)
324                    throws PortalException, SystemException {
325    
326                    restoreFolderFromTrash(userId, folderId);
327    
328                    return moveFolder(folderId, parentFolderId);
329            }
330    
331            @Indexable(type = IndexableType.REINDEX)
332            public void moveFolderToTrash(long userId, long folderId)
333                    throws PortalException, SystemException {
334    
335                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
336                            folderId);
337    
338                    updateStatus(userId, folder, WorkflowConstants.STATUS_IN_TRASH);
339            }
340    
341            @Indexable(type = IndexableType.REINDEX)
342            public void restoreFolderFromTrash(long userId, long folderId)
343                    throws PortalException, SystemException {
344    
345                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
346                            folderId);
347    
348                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
349                            BookmarksFolder.class.getName(), folderId);
350    
351                    updateStatus(userId, folder, trashEntry.getStatus());
352            }
353    
354            public void subscribeFolder(long userId, long groupId, long folderId)
355                    throws PortalException, SystemException {
356    
357                    if (folderId == BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
358                            folderId = groupId;
359                    }
360    
361                    subscriptionLocalService.addSubscription(
362                            userId, groupId, BookmarksFolder.class.getName(), folderId);
363            }
364    
365            public void unsubscribeFolder(long userId, long groupId, long folderId)
366                    throws PortalException, SystemException {
367    
368                    if (folderId == BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
369                            folderId = groupId;
370                    }
371    
372                    subscriptionLocalService.deleteSubscription(
373                            userId, BookmarksFolder.class.getName(), folderId);
374            }
375    
376            public void updateAsset(
377                            long userId, BookmarksFolder folder, long[] assetCategoryIds,
378                            String[] assetTagNames, long[] assetLinkEntryIds)
379                    throws PortalException, SystemException {
380    
381                    AssetEntry assetEntry = assetEntryLocalService.updateEntry(
382                            userId, folder.getGroupId(), folder.getCreateDate(),
383                            folder.getModifiedDate(), BookmarksFolder.class.getName(),
384                            folder.getFolderId(), folder.getUuid(), 0, assetCategoryIds,
385                            assetTagNames, true, null, null, null, ContentTypes.TEXT_PLAIN,
386                            folder.getName(), folder.getDescription(), null, null, null, 0, 0,
387                            null, false);
388    
389                    assetLinkLocalService.updateLinks(
390                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
391                            AssetLinkConstants.TYPE_RELATED);
392            }
393    
394            @Indexable(type = IndexableType.REINDEX)
395            public BookmarksFolder updateFolder(
396                            long userId, long folderId, long parentFolderId, String name,
397                            String description, boolean mergeWithParentFolder,
398                            ServiceContext serviceContext)
399                    throws PortalException, SystemException {
400    
401                    // Merge folders
402    
403                    BookmarksFolder folder = bookmarksFolderPersistence.findByPrimaryKey(
404                            folderId);
405    
406                    parentFolderId = getParentFolderId(folder, parentFolderId);
407    
408                    if (mergeWithParentFolder && (folderId != parentFolderId)) {
409                            mergeFolders(folder, parentFolderId);
410    
411                            return folder;
412                    }
413    
414                    // Folder
415    
416                    validate(name);
417    
418                    folder.setModifiedDate(serviceContext.getModifiedDate(null));
419                    folder.setParentFolderId(parentFolderId);
420                    folder.setName(name);
421                    folder.setDescription(description);
422                    folder.setExpandoBridgeAttributes(serviceContext);
423    
424                    bookmarksFolderPersistence.update(folder);
425    
426                    // Asset
427    
428                    updateAsset(
429                            userId, folder, serviceContext.getAssetCategoryIds(),
430                            serviceContext.getAssetTagNames(),
431                            serviceContext.getAssetLinkEntryIds());
432    
433                    return folder;
434            }
435    
436            public BookmarksFolder updateStatus(
437                            long userId, BookmarksFolder folder, int status)
438                    throws PortalException, SystemException {
439    
440                    // Folder
441    
442                    User user = userPersistence.findByPrimaryKey(userId);
443    
444                    int oldStatus = folder.getStatus();
445    
446                    folder.setStatus(status);
447                    folder.setStatusByUserId(userId);
448                    folder.setStatusByUserName(user.getFullName());
449                    folder.setStatusDate(new Date());
450    
451                    bookmarksFolderPersistence.update(folder);
452    
453                    // Folders and entries
454    
455                    List<Object> foldersAndEntries =
456                            bookmarksFolderLocalService.getFoldersAndEntries(
457                                    folder.getGroupId(), folder.getFolderId());
458    
459                    updateDependentStatus(foldersAndEntries, status);
460    
461                    // Asset
462    
463                    if (status == WorkflowConstants.STATUS_APPROVED) {
464                            assetEntryLocalService.updateVisible(
465                                    BookmarksFolder.class.getName(), folder.getFolderId(), true);
466                    }
467                    else if (status == WorkflowConstants.STATUS_IN_TRASH) {
468                            assetEntryLocalService.updateVisible(
469                                    BookmarksFolder.class.getName(), folder.getFolderId(), false);
470                    }
471    
472                    // Trash
473    
474                    if (oldStatus == WorkflowConstants.STATUS_IN_TRASH) {
475                            trashEntryLocalService.deleteEntry(
476                                    BookmarksFolder.class.getName(), folder.getFolderId());
477                    }
478                    else if (status == WorkflowConstants.STATUS_IN_TRASH) {
479                            trashEntryLocalService.addTrashEntry(
480                                    userId, folder.getGroupId(), BookmarksFolder.class.getName(),
481                                    folder.getFolderId(), oldStatus, null, null);
482                    }
483    
484                    // Index
485    
486                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
487                            BookmarksFolder.class);
488    
489                    indexer.reindex(folder);
490    
491                    return folder;
492            }
493    
494            protected long getParentFolderId(
495                            BookmarksFolder folder, long parentFolderId)
496                    throws SystemException {
497    
498                    if (parentFolderId ==
499                                    BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
500    
501                            return parentFolderId;
502                    }
503    
504                    if (folder.getFolderId() == parentFolderId) {
505                            return folder.getParentFolderId();
506                    }
507                    else {
508                            BookmarksFolder parentFolder =
509                                    bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
510    
511                            if ((parentFolder == null) ||
512                                    (folder.getGroupId() != parentFolder.getGroupId())) {
513    
514                                    return folder.getParentFolderId();
515                            }
516    
517                            List<Long> subfolderIds = new ArrayList<Long>();
518    
519                            getSubfolderIds(
520                                    subfolderIds, folder.getGroupId(), folder.getFolderId());
521    
522                            if (subfolderIds.contains(parentFolderId)) {
523                                    return folder.getParentFolderId();
524                            }
525    
526                            return parentFolderId;
527                    }
528            }
529    
530            protected long getParentFolderId(long groupId, long parentFolderId)
531                    throws SystemException {
532    
533                    if (parentFolderId !=
534                                    BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
535    
536                            BookmarksFolder parentFolder =
537                                    bookmarksFolderPersistence.fetchByPrimaryKey(parentFolderId);
538    
539                            if ((parentFolder == null) ||
540                                    (groupId != parentFolder.getGroupId())) {
541    
542                                    parentFolderId =
543                                            BookmarksFolderConstants.DEFAULT_PARENT_FOLDER_ID;
544                            }
545                    }
546    
547                    return parentFolderId;
548            }
549    
550            protected void mergeFolders(BookmarksFolder fromFolder, long toFolderId)
551                    throws PortalException, SystemException {
552    
553                    List<BookmarksFolder> folders = bookmarksFolderPersistence.findByG_P(
554                            fromFolder.getGroupId(), fromFolder.getFolderId());
555    
556                    for (BookmarksFolder folder : folders) {
557                            mergeFolders(folder, toFolderId);
558                    }
559    
560                    List<BookmarksEntry> entries = bookmarksEntryPersistence.findByG_F(
561                            fromFolder.getGroupId(), fromFolder.getFolderId());
562    
563                    for (BookmarksEntry entry : entries) {
564                            entry.setFolderId(toFolderId);
565    
566                            bookmarksEntryPersistence.update(entry);
567    
568                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
569                                    BookmarksEntry.class);
570    
571                            indexer.reindex(entry);
572                    }
573    
574                    bookmarksFolderLocalService.deleteFolder(fromFolder);
575            }
576    
577            protected void updateDependentStatus(
578                            List<Object> foldersAndEntries, int status)
579                    throws PortalException, SystemException {
580    
581                    for (Object object : foldersAndEntries) {
582                            if (object instanceof BookmarksEntry) {
583                                    BookmarksEntry entry = (BookmarksEntry)object;
584    
585                                    if (status == WorkflowConstants.STATUS_IN_TRASH) {
586    
587                                            // Asset
588    
589                                            if (entry.getStatus() ==
590                                                            WorkflowConstants.STATUS_APPROVED) {
591    
592                                                    assetEntryLocalService.updateVisible(
593                                                            BookmarksEntry.class.getName(), entry.getEntryId(),
594                                                            false);
595                                            }
596    
597                                            // Social
598    
599                                            socialActivityCounterLocalService.disableActivityCounters(
600                                                    BookmarksEntry.class.getName(), entry.getEntryId());
601    
602                                            if (entry.getStatus() == WorkflowConstants.STATUS_PENDING) {
603                                                    entry.setStatus(WorkflowConstants.STATUS_DRAFT);
604    
605                                                    bookmarksEntryPersistence.update(entry);
606                                            }
607                                    }
608                                    else {
609    
610                                            // Asset
611    
612                                            if (entry.getStatus() ==
613                                                            WorkflowConstants.STATUS_APPROVED) {
614    
615                                                    assetEntryLocalService.updateVisible(
616                                                            BookmarksEntry.class.getName(), entry.getEntryId(),
617                                                            true);
618                                            }
619    
620                                            // Social
621    
622                                            socialActivityCounterLocalService.enableActivityCounters(
623                                                    BookmarksEntry.class.getName(), entry.getEntryId());
624                                    }
625    
626                                    // Indexer
627    
628                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
629                                            BookmarksEntry.class);
630    
631                                    indexer.reindex(entry);
632                            }
633                            else if (object instanceof BookmarksFolder) {
634                                    BookmarksFolder folder = (BookmarksFolder)object;
635    
636                                    if (folder.isInTrash()) {
637                                            continue;
638                                    }
639    
640                                    List<Object> curFoldersAndEntries =
641                                            bookmarksFolderLocalService.getFoldersAndEntries(
642                                                    folder.getGroupId(), folder.getFolderId());
643    
644                                    updateDependentStatus(curFoldersAndEntries, status);
645                            }
646                    }
647            }
648    
649            protected void validate(String name) throws PortalException {
650                    if (Validator.isNull(name) || name.contains("\\\\") ||
651                            name.contains("//")) {
652    
653                            throw new FolderNameException();
654                    }
655            }
656    
657    }