001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.service.impl;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryDefinition;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.json.JSONFactoryUtil;
021    import com.liferay.portal.kernel.json.JSONObject;
022    import com.liferay.portal.kernel.language.LanguageUtil;
023    import com.liferay.portal.kernel.lock.Lock;
024    import com.liferay.portal.kernel.notifications.UserNotificationDefinition;
025    import com.liferay.portal.kernel.repository.LocalRepository;
026    import com.liferay.portal.kernel.repository.Repository;
027    import com.liferay.portal.kernel.repository.RepositoryProviderUtil;
028    import com.liferay.portal.kernel.repository.capabilities.RepositoryEventTriggerCapability;
029    import com.liferay.portal.kernel.repository.event.RepositoryEventType;
030    import com.liferay.portal.kernel.repository.event.TrashRepositoryEventType;
031    import com.liferay.portal.kernel.repository.event.WorkflowRepositoryEventType;
032    import com.liferay.portal.kernel.repository.model.FileEntry;
033    import com.liferay.portal.kernel.repository.model.FileShortcut;
034    import com.liferay.portal.kernel.repository.model.FileVersion;
035    import com.liferay.portal.kernel.repository.model.Folder;
036    import com.liferay.portal.kernel.repository.model.RepositoryModel;
037    import com.liferay.portal.kernel.search.Indexer;
038    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
039    import com.liferay.portal.kernel.settings.LocalizedValuesMap;
040    import com.liferay.portal.kernel.util.GetterUtil;
041    import com.liferay.portal.kernel.util.ListUtil;
042    import com.liferay.portal.kernel.util.LocalizationUtil;
043    import com.liferay.portal.kernel.util.ObjectValuePair;
044    import com.liferay.portal.kernel.util.UnicodeProperties;
045    import com.liferay.portal.kernel.util.Validator;
046    import com.liferay.portal.kernel.workflow.WorkflowConstants;
047    import com.liferay.portal.model.UserConstants;
048    import com.liferay.portal.repository.liferayrepository.model.LiferayFileEntry;
049    import com.liferay.portal.repository.liferayrepository.model.LiferayFileVersion;
050    import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
051    import com.liferay.portal.service.ServiceContext;
052    import com.liferay.portal.util.GroupSubscriptionCheckSubscriptionSender;
053    import com.liferay.portal.util.PortletKeys;
054    import com.liferay.portal.util.SubscriptionSender;
055    import com.liferay.portlet.asset.model.AssetEntry;
056    import com.liferay.portlet.asset.model.AssetLink;
057    import com.liferay.portlet.asset.model.AssetLinkConstants;
058    import com.liferay.portlet.documentlibrary.DLGroupServiceSettings;
059    import com.liferay.portlet.documentlibrary.model.DLFileEntry;
060    import com.liferay.portlet.documentlibrary.model.DLFileEntryConstants;
061    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
062    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
063    import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
064    import com.liferay.portlet.documentlibrary.model.DLFileShortcutConstants;
065    import com.liferay.portlet.documentlibrary.model.DLFileVersion;
066    import com.liferay.portlet.documentlibrary.model.DLFolder;
067    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
068    import com.liferay.portlet.documentlibrary.model.DLSyncConstants;
069    import com.liferay.portlet.documentlibrary.service.base.DLAppHelperLocalServiceBaseImpl;
070    import com.liferay.portlet.documentlibrary.service.permission.DLPermission;
071    import com.liferay.portlet.documentlibrary.social.DLActivityKeys;
072    import com.liferay.portlet.documentlibrary.util.DLAppHelperThreadLocal;
073    import com.liferay.portlet.documentlibrary.util.comparator.DLFileVersionVersionComparator;
074    import com.liferay.portlet.social.model.SocialActivityConstants;
075    import com.liferay.portlet.trash.model.TrashEntry;
076    import com.liferay.portlet.trash.model.TrashVersion;
077    import com.liferay.portlet.trash.util.TrashUtil;
078    
079    import java.io.Serializable;
080    
081    import java.util.ArrayList;
082    import java.util.Date;
083    import java.util.HashMap;
084    import java.util.List;
085    import java.util.Map;
086    
087    /**
088     * Provides the local service helper for the document library application.
089     *
090     * @author Alexander Chow
091     */
092    public class DLAppHelperLocalServiceImpl
093            extends DLAppHelperLocalServiceBaseImpl {
094    
095            @Override
096            public void addFolder(
097                            long userId, Folder folder, ServiceContext serviceContext)
098                    throws PortalException {
099    
100                    if (!DLAppHelperThreadLocal.isEnabled()) {
101                            return;
102                    }
103    
104                    updateAsset(
105                            userId, folder, serviceContext.getAssetCategoryIds(),
106                            serviceContext.getAssetTagNames(),
107                            serviceContext.getAssetLinkEntryIds());
108            }
109    
110            @Override
111            public void cancelCheckOut(
112                            long userId, FileEntry fileEntry, FileVersion sourceFileVersion,
113                            FileVersion destinationFileVersion, FileVersion draftFileVersion,
114                            ServiceContext serviceContext)
115                    throws PortalException {
116    
117                    if (draftFileVersion == null) {
118                            return;
119                    }
120    
121                    AssetEntry draftAssetEntry = assetEntryLocalService.fetchEntry(
122                            DLFileEntryConstants.getClassName(),
123                            draftFileVersion.getPrimaryKey());
124    
125                    if (draftAssetEntry != null) {
126                            assetEntryLocalService.deleteEntry(draftAssetEntry);
127                    }
128            }
129    
130            @Override
131            public void checkAssetEntry(
132                            long userId, FileEntry fileEntry, FileVersion fileVersion)
133                    throws PortalException {
134    
135                    AssetEntry fileEntryAssetEntry = assetEntryLocalService.fetchEntry(
136                            DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId());
137    
138                    long[] assetCategoryIds = new long[0];
139                    String[] assetTagNames = new String[0];
140    
141                    long fileEntryTypeId = getFileEntryTypeId(fileEntry);
142    
143                    if (fileEntryAssetEntry == null) {
144                            fileEntryAssetEntry = assetEntryLocalService.updateEntry(
145                                    userId, fileEntry.getGroupId(), fileEntry.getCreateDate(),
146                                    fileEntry.getModifiedDate(),
147                                    DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId(),
148                                    fileEntry.getUuid(), fileEntryTypeId, assetCategoryIds,
149                                    assetTagNames, false, null, null, null, fileEntry.getMimeType(),
150                                    fileEntry.getTitle(), fileEntry.getDescription(), null, null,
151                                    null, 0, 0, null);
152                    }
153    
154                    AssetEntry fileVersionAssetEntry = assetEntryLocalService.fetchEntry(
155                            DLFileEntryConstants.getClassName(),
156                            fileVersion.getFileVersionId());
157    
158                    if ((fileVersionAssetEntry == null) && !fileVersion.isApproved() &&
159                            !fileVersion.getVersion().equals(
160                                    DLFileEntryConstants.VERSION_DEFAULT)) {
161    
162                            assetCategoryIds = assetCategoryLocalService.getCategoryIds(
163                                    DLFileEntryConstants.getClassName(),
164                                    fileEntry.getFileEntryId());
165                            assetTagNames = assetTagLocalService.getTagNames(
166                                    DLFileEntryConstants.getClassName(),
167                                    fileEntry.getFileEntryId());
168    
169                            fileVersionAssetEntry = assetEntryLocalService.updateEntry(
170                                    userId, fileEntry.getGroupId(), fileEntry.getCreateDate(),
171                                    fileEntry.getModifiedDate(),
172                                    DLFileEntryConstants.getClassName(),
173                                    fileVersion.getFileVersionId(), fileEntry.getUuid(),
174                                    fileEntryTypeId, assetCategoryIds, assetTagNames, false, null,
175                                    null, null, fileEntry.getMimeType(), fileEntry.getTitle(),
176                                    fileEntry.getDescription(), null, null, null, 0, 0, null);
177    
178                            List<AssetLink> assetLinks = assetLinkLocalService.getDirectLinks(
179                                    fileEntryAssetEntry.getEntryId());
180    
181                            long[] assetLinkIds = ListUtil.toLongArray(
182                                    assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
183    
184                            assetLinkLocalService.updateLinks(
185                                    userId, fileVersionAssetEntry.getEntryId(), assetLinkIds,
186                                    AssetLinkConstants.TYPE_RELATED);
187                    }
188            }
189    
190            @Override
191            public void deleteFileEntry(FileEntry fileEntry) throws PortalException {
192                    if (!DLAppHelperThreadLocal.isEnabled()) {
193                            return;
194                    }
195    
196                    // Subscriptions
197    
198                    subscriptionLocalService.deleteSubscriptions(
199                            fileEntry.getCompanyId(), DLFileEntryConstants.getClassName(),
200                            fileEntry.getFileEntryId());
201    
202                    // File ranks
203    
204                    dlFileRankLocalService.deleteFileRanksByFileEntryId(
205                            fileEntry.getFileEntryId());
206    
207                    // File shortcuts
208    
209                    dlFileShortcutLocalService.deleteFileShortcuts(
210                            fileEntry.getFileEntryId());
211    
212                    // Asset
213    
214                    assetEntryLocalService.deleteEntry(
215                            DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId());
216    
217                    // Ratings
218    
219                    ratingsStatsLocalService.deleteStats(
220                            DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId());
221            }
222    
223            @Override
224            public void deleteFolder(Folder folder) throws PortalException {
225                    if (!DLAppHelperThreadLocal.isEnabled()) {
226                            return;
227                    }
228    
229                    // Asset
230    
231                    assetEntryLocalService.deleteEntry(
232                            DLFolderConstants.getClassName(), folder.getFolderId());
233            }
234    
235            @Override
236            public void deleteRepositoryFileEntries(long repositoryId)
237                    throws PortalException {
238    
239                    LocalRepository localRepository =
240                            RepositoryProviderUtil.getLocalRepository(repositoryId);
241    
242                    List<FileEntry> fileEntries = localRepository.getRepositoryFileEntries(
243                            UserConstants.USER_ID_DEFAULT,
244                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, QueryUtil.ALL_POS,
245                            QueryUtil.ALL_POS, null);
246    
247                    for (FileEntry fileEntry : fileEntries) {
248                            deleteFileEntry(fileEntry);
249                    }
250            }
251    
252            @Override
253            public void getFileAsStream(
254                    long userId, FileEntry fileEntry, boolean incrementCounter) {
255    
256                    if (!incrementCounter) {
257                            return;
258                    }
259    
260                    // File rank
261    
262                    if (userId > 0) {
263                            dlFileRankLocalService.updateFileRank(
264                                    fileEntry.getGroupId(), fileEntry.getCompanyId(), userId,
265                                    fileEntry.getFileEntryId(), new ServiceContext());
266                    }
267    
268                    // File read count
269    
270                    assetEntryLocalService.incrementViewCounter(
271                            userId, DLFileEntryConstants.getClassName(),
272                            fileEntry.getFileEntryId(), 1);
273    
274                    List<DLFileShortcut> fileShortcuts =
275                            dlFileShortcutPersistence.findByToFileEntryId(
276                                    fileEntry.getFileEntryId());
277    
278                    for (DLFileShortcut fileShortcut : fileShortcuts) {
279                            assetEntryLocalService.incrementViewCounter(
280                                    userId, DLFileShortcutConstants.getClassName(),
281                                    fileShortcut.getFileShortcutId(), 1);
282                    }
283            }
284    
285            @Override
286            public List<DLFileShortcut> getFileShortcuts(
287                    long groupId, long folderId, boolean active, int status) {
288    
289                    return dlFileShortcutPersistence.findByG_F_A_S(
290                            groupId, folderId, active, status);
291            }
292    
293            /**
294             * @deprecated As of 6.2.0, replaced by {@link #getFileShortcuts(long, long,
295             *             boolean, int)}
296             */
297            @Deprecated
298            @Override
299            public List<DLFileShortcut> getFileShortcuts(
300                    long groupId, long folderId, int status) {
301    
302                    return getFileShortcuts(groupId, folderId, true, status);
303            }
304    
305            @Override
306            public int getFileShortcutsCount(
307                    long groupId, long folderId, boolean active, int status) {
308    
309                    return dlFileShortcutPersistence.countByG_F_A_S(
310                            groupId, folderId, active, status);
311            }
312    
313            /**
314             * @deprecated As of 6.2.0, replaced by {@link #getFileShortcutsCount(long,
315             *             long, boolean, int)}
316             */
317            @Deprecated
318            @Override
319            public int getFileShortcutsCount(long groupId, long folderId, int status) {
320                    return getFileShortcutsCount(groupId, folderId, true, status);
321            }
322    
323            @Override
324            public List<FileEntry> getNoAssetFileEntries() {
325                    return null;
326            }
327    
328            @Override
329            public void moveDependentsToTrash(
330                            List<Object> dlFileEntriesAndDLFolders, long trashEntryId)
331                    throws PortalException {
332    
333                    for (Object object : dlFileEntriesAndDLFolders) {
334                            if (object instanceof DLFileEntry) {
335    
336                                    // File entry
337    
338                                    DLFileEntry dlFileEntry = (DLFileEntry)object;
339    
340                                    if (dlFileEntry.isInTrashExplicitly()) {
341                                            continue;
342                                    }
343    
344                                    // File shortcut
345    
346                                    dlFileShortcutLocalService.disableFileShortcuts(
347                                            dlFileEntry.getFileEntryId());
348    
349                                    // File versions
350    
351                                    List<DLFileVersion> dlFileVersions =
352                                            dlFileVersionLocalService.getFileVersions(
353                                                    dlFileEntry.getFileEntryId(),
354                                                    WorkflowConstants.STATUS_ANY);
355    
356                                    for (DLFileVersion dlFileVersion : dlFileVersions) {
357    
358                                            // File version
359    
360                                            int oldStatus = dlFileVersion.getStatus();
361    
362                                            dlFileVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
363    
364                                            dlFileVersionPersistence.update(dlFileVersion);
365    
366                                            // Trash
367    
368                                            int status = oldStatus;
369    
370                                            if (oldStatus == WorkflowConstants.STATUS_PENDING) {
371                                                    status = WorkflowConstants.STATUS_DRAFT;
372                                            }
373    
374                                            if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
375                                                    trashVersionLocalService.addTrashVersion(
376                                                            trashEntryId, DLFileVersion.class.getName(),
377                                                            dlFileVersion.getFileVersionId(), status, null);
378                                            }
379    
380                                            // Workflow
381    
382                                            if (oldStatus == WorkflowConstants.STATUS_PENDING) {
383                                                    workflowInstanceLinkLocalService.
384                                                            deleteWorkflowInstanceLink(
385                                                                    dlFileVersion.getCompanyId(),
386                                                                    dlFileVersion.getGroupId(),
387                                                                    DLFileEntryConstants.getClassName(),
388                                                                    dlFileVersion.getFileVersionId());
389                                            }
390                                    }
391    
392                                    // Asset
393    
394                                    assetEntryLocalService.updateVisible(
395                                            DLFileEntryConstants.getClassName(),
396                                            dlFileEntry.getFileEntryId(), false);
397    
398                                    // Index
399    
400                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
401                                            DLFileEntry.class);
402    
403                                    indexer.reindex(dlFileEntry);
404                            }
405                            else if (object instanceof DLFileShortcut) {
406    
407                                    // File shortcut
408    
409                                    DLFileShortcut dlFileShortcut = (DLFileShortcut)object;
410    
411                                    if (dlFileShortcut.isInTrash()) {
412                                            continue;
413                                    }
414    
415                                    int oldStatus = dlFileShortcut.getStatus();
416    
417                                    dlFileShortcut.setStatus(WorkflowConstants.STATUS_IN_TRASH);
418    
419                                    dlFileShortcutPersistence.update(dlFileShortcut);
420    
421                                    // Trash
422    
423                                    if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
424                                            trashVersionLocalService.addTrashVersion(
425                                                    trashEntryId, DLFileShortcutConstants.getClassName(),
426                                                    dlFileShortcut.getFileShortcutId(), oldStatus, null);
427                                    }
428                            }
429                            else if (object instanceof DLFolder) {
430    
431                                    // Folder
432    
433                                    DLFolder dlFolder = (DLFolder)object;
434    
435                                    if (dlFolder.isInTrashExplicitly()) {
436                                            continue;
437                                    }
438    
439                                    int oldStatus = dlFolder.getStatus();
440    
441                                    dlFolder.setStatus(WorkflowConstants.STATUS_IN_TRASH);
442    
443                                    dlFolderPersistence.update(dlFolder);
444    
445                                    // Trash
446    
447                                    if (oldStatus != WorkflowConstants.STATUS_APPROVED) {
448                                            trashVersionLocalService.addTrashVersion(
449                                                    trashEntryId, DLFolder.class.getName(),
450                                                    dlFolder.getFolderId(), oldStatus, null);
451                                    }
452    
453                                    // Folders, file entries, and file shortcuts
454    
455                                    QueryDefinition<?> queryDefinition = new QueryDefinition<>(
456                                            WorkflowConstants.STATUS_ANY);
457    
458                                    List<Object> foldersAndFileEntriesAndFileShortcuts =
459                                            dlFolderLocalService.
460                                                    getFoldersAndFileEntriesAndFileShortcuts(
461                                                            dlFolder.getGroupId(), dlFolder.getFolderId(), null,
462                                                            false, queryDefinition);
463    
464                                    moveDependentsToTrash(
465                                            foldersAndFileEntriesAndFileShortcuts, trashEntryId);
466    
467                                    // Asset
468    
469                                    assetEntryLocalService.updateVisible(
470                                            DLFolderConstants.getClassName(), dlFolder.getFolderId(),
471                                            false);
472    
473                                    // Index
474    
475                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
476                                            DLFolder.class);
477    
478                                    indexer.reindex(dlFolder);
479                            }
480                    }
481            }
482    
483            @Override
484            public FileEntry moveFileEntryFromTrash(
485                            long userId, FileEntry fileEntry, long newFolderId,
486                            ServiceContext serviceContext)
487                    throws PortalException {
488    
489                    boolean hasLock = dlFileEntryLocalService.hasFileEntryLock(
490                            userId, fileEntry.getFileEntryId());
491    
492                    if (!hasLock) {
493                            dlFileEntryLocalService.lockFileEntry(
494                                    userId, fileEntry.getFileEntryId());
495                    }
496    
497                    try {
498                            return doMoveFileEntryFromTrash(
499                                    userId, fileEntry, newFolderId, serviceContext);
500                    }
501                    finally {
502                            if (!hasLock) {
503                                    dlFileEntryLocalService.unlockFileEntry(
504                                            fileEntry.getFileEntryId());
505                            }
506                    }
507            }
508    
509            /**
510             * Moves the file entry to the recycle bin.
511             *
512             * @param  userId the primary key of the user moving the file entry
513             * @param  fileEntry the file entry to be moved
514             * @return the moved file entry
515             * @throws PortalException if a user with the primary key could not be found
516             */
517            @Override
518            public FileEntry moveFileEntryToTrash(long userId, FileEntry fileEntry)
519                    throws PortalException {
520    
521                    boolean hasLock = dlFileEntryLocalService.hasFileEntryLock(
522                            userId, fileEntry.getFileEntryId());
523    
524                    if (!hasLock) {
525                            dlFileEntryLocalService.lockFileEntry(
526                                    userId, fileEntry.getFileEntryId());
527                    }
528    
529                    try {
530                            return doMoveFileEntryToTrash(userId, fileEntry);
531                    }
532                    finally {
533                            if (!hasLock) {
534                                    dlFileEntryLocalService.unlockFileEntry(
535                                            fileEntry.getFileEntryId());
536                            }
537                    }
538            }
539    
540            @Override
541            public FileShortcut moveFileShortcutFromTrash(
542                            long userId, FileShortcut fileShortcut, long newFolderId,
543                            ServiceContext serviceContext)
544                    throws PortalException {
545    
546                    DLFileShortcut dlFileShortcut = (DLFileShortcut)fileShortcut.getModel();
547    
548                    if (dlFileShortcut.isInTrashExplicitly()) {
549                            restoreFileShortcutFromTrash(userId, fileShortcut);
550                    }
551                    else {
552    
553                            // File shortcut
554    
555                            TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
556                                    DLFileShortcutConstants.getClassName(),
557                                    fileShortcut.getFileShortcutId());
558    
559                            int status = WorkflowConstants.STATUS_APPROVED;
560    
561                            if (trashVersion != null) {
562                                    status = trashVersion.getStatus();
563                            }
564    
565                            dlFileShortcutLocalService.updateStatus(
566                                    userId, fileShortcut.getFileShortcutId(), status,
567                                    new ServiceContext());
568    
569                            // Trash
570    
571                            if (trashVersion != null) {
572                                    trashVersionLocalService.deleteTrashVersion(trashVersion);
573                            }
574    
575                            // Social
576    
577                            JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
578    
579                            extraDataJSONObject.put("title", fileShortcut.getToTitle());
580    
581                            socialActivityLocalService.addActivity(
582                                    userId, fileShortcut.getGroupId(),
583                                    DLFileShortcutConstants.getClassName(),
584                                    fileShortcut.getFileShortcutId(),
585                                    SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
586                                    extraDataJSONObject.toString(), 0);
587                    }
588    
589                    return dlAppService.updateFileShortcut(
590                            fileShortcut.getFileShortcutId(), newFolderId,
591                            fileShortcut.getToFileEntryId(), serviceContext);
592            }
593    
594            /**
595             * Moves the file shortcut to the recycle bin.
596             *
597             * @param  userId the primary key of the user moving the file shortcut
598             * @param  fileShortcut the file shortcut to be moved
599             * @return the moved file shortcut
600             * @throws PortalException if a user with the primary key could not be found
601             */
602            @Override
603            public FileShortcut moveFileShortcutToTrash(
604                            long userId, FileShortcut fileShortcut)
605                    throws PortalException {
606    
607                    // File shortcut
608    
609                    DLFileShortcut dlFileShortcut = (DLFileShortcut)fileShortcut.getModel();
610    
611                    int oldStatus = dlFileShortcut.getStatus();
612    
613                    dlFileShortcutLocalService.updateStatus(
614                            userId, fileShortcut.getFileShortcutId(),
615                            WorkflowConstants.STATUS_IN_TRASH, new ServiceContext());
616    
617                    // Social
618    
619                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
620    
621                    extraDataJSONObject.put(
622                            "title", TrashUtil.getOriginalTitle(fileShortcut.getToTitle()));
623    
624                    socialActivityLocalService.addActivity(
625                            userId, fileShortcut.getGroupId(),
626                            DLFileShortcutConstants.getClassName(),
627                            fileShortcut.getFileShortcutId(),
628                            SocialActivityConstants.TYPE_MOVE_TO_TRASH,
629                            extraDataJSONObject.toString(), 0);
630    
631                    // Trash
632    
633                    trashEntryLocalService.addTrashEntry(
634                            userId, fileShortcut.getGroupId(),
635                            DLFileShortcutConstants.getClassName(),
636                            fileShortcut.getFileShortcutId(), fileShortcut.getUuid(), null,
637                            oldStatus, null, null);
638    
639                    return fileShortcut;
640            }
641    
642            @Override
643            public Folder moveFolderFromTrash(
644                            long userId, Folder folder, long parentFolderId,
645                            ServiceContext serviceContext)
646                    throws PortalException {
647    
648                    boolean hasLock = dlFolderLocalService.hasFolderLock(
649                            userId, folder.getFolderId());
650    
651                    Lock lock = null;
652    
653                    if (!hasLock) {
654                            lock = dlFolderLocalService.lockFolder(
655                                    userId, folder.getFolderId());
656                    }
657    
658                    try {
659                            return doMoveFolderFromTrash(
660                                    userId, folder, parentFolderId, serviceContext);
661                    }
662                    finally {
663                            if (!hasLock) {
664                                    dlFolderLocalService.unlockFolder(
665                                            folder.getFolderId(), lock.getUuid());
666                            }
667                    }
668            }
669    
670            /**
671             * Moves the folder to the recycle bin.
672             *
673             * @param  userId the primary key of the user moving the folder
674             * @param  folder the folder to be moved
675             * @return the moved folder
676             * @throws PortalException if a user with the primary key could not be found
677             */
678            @Override
679            public Folder moveFolderToTrash(long userId, Folder folder)
680                    throws PortalException {
681    
682                    boolean hasLock = dlFolderLocalService.hasFolderLock(
683                            userId, folder.getFolderId());
684    
685                    Lock lock = null;
686    
687                    if (!hasLock) {
688                            lock = dlFolderLocalService.lockFolder(
689                                    userId, folder.getFolderId());
690                    }
691    
692                    try {
693                            return doMoveFolderToTrash(userId, folder);
694                    }
695                    finally {
696                            if (!hasLock) {
697                                    dlFolderLocalService.unlockFolder(
698                                            folder.getFolderId(), lock.getUuid());
699                            }
700                    }
701            }
702    
703            @Override
704            public void restoreDependentsFromTrash(
705                            List<Object> dlFileEntriesAndDLFolders)
706                    throws PortalException {
707    
708                    for (Object object : dlFileEntriesAndDLFolders) {
709                            if (object instanceof DLFileEntry) {
710    
711                                    // File entry
712    
713                                    DLFileEntry dlFileEntry = (DLFileEntry)object;
714    
715                                    if (!dlFileEntry.isInTrashImplicitly()) {
716                                            continue;
717                                    }
718    
719                                    // File shortcut
720    
721                                    dlFileShortcutLocalService.enableFileShortcuts(
722                                            dlFileEntry.getFileEntryId());
723    
724                                    // File versions
725    
726                                    List<DLFileVersion> dlFileVersions =
727                                            dlFileVersionLocalService.getFileVersions(
728                                                    dlFileEntry.getFileEntryId(),
729                                                    WorkflowConstants.STATUS_IN_TRASH);
730    
731                                    for (DLFileVersion dlFileVersion : dlFileVersions) {
732    
733                                            // File version
734    
735                                            TrashVersion trashVersion =
736                                                    trashVersionLocalService.fetchVersion(
737                                                            DLFileVersion.class.getName(),
738                                                            dlFileVersion.getFileVersionId());
739    
740                                            int oldStatus = WorkflowConstants.STATUS_APPROVED;
741    
742                                            if (trashVersion != null) {
743                                                    oldStatus = trashVersion.getStatus();
744                                            }
745    
746                                            dlFileVersion.setStatus(oldStatus);
747    
748                                            dlFileVersionPersistence.update(dlFileVersion);
749    
750                                            // Trash
751    
752                                            if (trashVersion != null) {
753                                                    trashVersionLocalService.deleteTrashVersion(
754                                                            trashVersion);
755                                            }
756                                    }
757    
758                                    // Asset
759    
760                                    DLFileVersion latestDlFileVersion =
761                                            dlFileEntry.getLatestFileVersion(false);
762    
763                                    if (latestDlFileVersion.isApproved()) {
764                                            assetEntryLocalService.updateVisible(
765                                                    DLFileEntryConstants.getClassName(),
766                                                    dlFileEntry.getFileEntryId(), true);
767                                    }
768    
769                                    // Index
770    
771                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
772                                            DLFileEntry.class);
773    
774                                    indexer.reindex(dlFileEntry);
775                            }
776                            else if (object instanceof DLFileShortcut) {
777    
778                                    // Folder
779    
780                                    DLFileShortcut dlFileShortcut = (DLFileShortcut)object;
781    
782                                    if (!dlFileShortcut.isInTrashImplicitly()) {
783                                            continue;
784                                    }
785    
786                                    TrashVersion trashVersion =
787                                            trashVersionLocalService.fetchVersion(
788                                                    DLFileShortcutConstants.getClassName(),
789                                                    dlFileShortcut.getFileShortcutId());
790    
791                                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
792    
793                                    if (trashVersion != null) {
794                                            oldStatus = trashVersion.getStatus();
795                                    }
796    
797                                    dlFileShortcut.setStatus(oldStatus);
798    
799                                    dlFileShortcutPersistence.update(dlFileShortcut);
800    
801                                    if (trashVersion != null) {
802                                            trashVersionLocalService.deleteTrashVersion(trashVersion);
803                                    }
804                            }
805                            else if (object instanceof DLFolder) {
806    
807                                    // Folder
808    
809                                    DLFolder dlFolder = (DLFolder)object;
810    
811                                    if (!dlFolder.isInTrashImplicitly()) {
812                                            continue;
813                                    }
814    
815                                    TrashVersion trashVersion =
816                                            trashVersionLocalService.fetchVersion(
817                                                    DLFolder.class.getName(), dlFolder.getFolderId());
818    
819                                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
820    
821                                    if (trashVersion != null) {
822                                            oldStatus = trashVersion.getStatus();
823                                    }
824    
825                                    dlFolder.setStatus(oldStatus);
826    
827                                    dlFolderPersistence.update(dlFolder);
828    
829                                    // Folders, file entries, and file shortcuts
830    
831                                    QueryDefinition<?> queryDefinition = new QueryDefinition<>(
832                                            WorkflowConstants.STATUS_IN_TRASH);
833    
834                                    List<Object> foldersAndFileEntriesAndFileShortcuts =
835                                            dlFolderLocalService.
836                                                    getFoldersAndFileEntriesAndFileShortcuts(
837                                                            dlFolder.getGroupId(), dlFolder.getFolderId(), null,
838                                                            false, queryDefinition);
839    
840                                    restoreDependentsFromTrash(
841                                            foldersAndFileEntriesAndFileShortcuts);
842    
843                                    // Trash
844    
845                                    if (trashVersion != null) {
846                                            trashVersionLocalService.deleteTrashVersion(trashVersion);
847                                    }
848    
849                                    // Asset
850    
851                                    assetEntryLocalService.updateVisible(
852                                            DLFolderConstants.getClassName(), dlFolder.getFolderId(),
853                                            true);
854    
855                                    // Index
856    
857                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
858                                            DLFolder.class);
859    
860                                    indexer.reindex(dlFolder);
861                            }
862                    }
863            }
864    
865            /**
866             * @deprecated As of 7.0.0, replaced by {@link
867             *             #restoreDependentsFromTrash(List)}
868             */
869            @Deprecated
870            @Override
871            public void restoreDependentsFromTrash(
872                            List<Object> dlFileEntriesAndDLFolders, long trashEntryId)
873                    throws PortalException {
874    
875                    restoreDependentsFromTrash(dlFileEntriesAndDLFolders);
876            }
877    
878            @Override
879            public void restoreFileEntryFromTrash(long userId, FileEntry fileEntry)
880                    throws PortalException {
881    
882                    // File entry
883    
884                    DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
885    
886                    dlFileEntry.setFileName(
887                            TrashUtil.getOriginalTitle(dlFileEntry.getTitle(), "fileName"));
888                    dlFileEntry.setTitle(
889                            TrashUtil.getOriginalTitle(dlFileEntry.getTitle()));
890    
891                    dlFileEntryPersistence.update(dlFileEntry);
892    
893                    FileVersion fileVersion = fileEntry.getFileVersion();
894    
895                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
896                            DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId());
897    
898                    dlFileEntryLocalService.updateStatus(
899                            userId, fileVersion.getFileVersionId(), trashEntry.getStatus(),
900                            new ServiceContext(), new HashMap<String, Serializable>());
901    
902                    if (DLAppHelperThreadLocal.isEnabled()) {
903    
904                            // File rank
905    
906                            dlFileRankLocalService.enableFileRanks(fileEntry.getFileEntryId());
907    
908                            // File shortcut
909    
910                            dlFileShortcutLocalService.enableFileShortcuts(
911                                    fileEntry.getFileEntryId());
912    
913                            // Sync
914    
915                            triggerRepositoryEvent(
916                                    fileEntry.getRepositoryId(),
917                                    TrashRepositoryEventType.EntryRestored.class, FileEntry.class,
918                                    fileEntry);
919                    }
920    
921                    // Trash
922    
923                    List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
924                            trashEntry.getEntryId());
925    
926                    for (TrashVersion trashVersion : trashVersions) {
927                            DLFileVersion trashDLFileVersion =
928                                    dlFileVersionPersistence.findByPrimaryKey(
929                                            trashVersion.getClassPK());
930    
931                            trashDLFileVersion.setStatus(trashVersion.getStatus());
932    
933                            dlFileVersionPersistence.update(trashDLFileVersion);
934                    }
935    
936                    trashEntryLocalService.deleteEntry(trashEntry.getEntryId());
937    
938                    if (!DLAppHelperThreadLocal.isEnabled()) {
939                            return;
940                    }
941    
942                    // Social
943    
944                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
945    
946                    extraDataJSONObject.put("title", fileEntry.getTitle());
947    
948                    socialActivityLocalService.addActivity(
949                            userId, fileEntry.getGroupId(), DLFileEntryConstants.getClassName(),
950                            fileEntry.getFileEntryId(),
951                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
952                            extraDataJSONObject.toString(), 0);
953            }
954    
955            @Override
956            public void restoreFileShortcutFromTrash(
957                            long userId, FileShortcut fileShortcut)
958                    throws PortalException {
959    
960                    // File shortcut
961    
962                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
963                            DLFileShortcutConstants.getClassName(),
964                            fileShortcut.getFileShortcutId());
965    
966                    dlFileShortcutLocalService.updateStatus(
967                            userId, fileShortcut.getFileShortcutId(), trashEntry.getStatus(),
968                            new ServiceContext());
969    
970                    // Social
971    
972                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
973    
974                    extraDataJSONObject.put("title", fileShortcut.getToTitle());
975    
976                    socialActivityLocalService.addActivity(
977                            userId, fileShortcut.getGroupId(),
978                            DLFileShortcutConstants.getClassName(),
979                            fileShortcut.getFileShortcutId(),
980                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
981                            extraDataJSONObject.toString(), 0);
982    
983                    // Trash
984    
985                    trashEntryLocalService.deleteEntry(trashEntry.getEntryId());
986            }
987    
988            @Override
989            public void restoreFolderFromTrash(long userId, Folder folder)
990                    throws PortalException {
991    
992                    // Folder
993    
994                    DLFolder dlFolder = (DLFolder)folder.getModel();
995    
996                    dlFolder.setName(TrashUtil.getOriginalTitle(dlFolder.getName()));
997    
998                    dlFolderPersistence.update(dlFolder);
999    
1000                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
1001                            DLFolder.class.getName(), dlFolder.getFolderId());
1002    
1003                    dlFolderLocalService.updateStatus(
1004                            userId, folder.getFolderId(), trashEntry.getStatus(),
1005                            new HashMap<String, Serializable>(), new ServiceContext());
1006    
1007                    // File rank
1008    
1009                    dlFileRankLocalService.enableFileRanksByFolderId(folder.getFolderId());
1010    
1011                    // Folders, file entries, and file shortcuts
1012    
1013                    QueryDefinition<?> queryDefinition = new QueryDefinition<>(
1014                            WorkflowConstants.STATUS_IN_TRASH);
1015    
1016                    List<Object> foldersAndFileEntriesAndFileShortcuts =
1017                            dlFolderLocalService.getFoldersAndFileEntriesAndFileShortcuts(
1018                                    dlFolder.getGroupId(), dlFolder.getFolderId(), null, false,
1019                                    queryDefinition);
1020    
1021                    dlAppHelperLocalService.restoreDependentsFromTrash(
1022                            foldersAndFileEntriesAndFileShortcuts);
1023    
1024                    // Sync
1025    
1026                    triggerRepositoryEvent(
1027                            folder.getRepositoryId(),
1028                            TrashRepositoryEventType.EntryRestored.class, Folder.class, folder);
1029    
1030                    // Trash
1031    
1032                    trashEntryLocalService.deleteEntry(trashEntry.getEntryId());
1033    
1034                    // Social
1035    
1036                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1037    
1038                    extraDataJSONObject.put("title", folder.getName());
1039    
1040                    socialActivityLocalService.addActivity(
1041                            userId, folder.getGroupId(), DLFolderConstants.getClassName(),
1042                            folder.getFolderId(),
1043                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
1044                            extraDataJSONObject.toString(), 0);
1045            }
1046    
1047            @Override
1048            public AssetEntry updateAsset(
1049                            long userId, FileEntry fileEntry, FileVersion fileVersion,
1050                            long assetClassPk)
1051                    throws PortalException {
1052    
1053                    long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
1054                            DLFileEntryConstants.getClassName(), assetClassPk);
1055                    String[] assetTagNames = assetTagLocalService.getTagNames(
1056                            DLFileEntryConstants.getClassName(), assetClassPk);
1057    
1058                    AssetEntry assetEntry = assetEntryLocalService.getEntry(
1059                            DLFileEntryConstants.getClassName(), assetClassPk);
1060    
1061                    List<AssetLink> assetLinks = assetLinkLocalService.getDirectLinks(
1062                            assetEntry.getEntryId());
1063    
1064                    long[] assetLinkIds = ListUtil.toLongArray(
1065                            assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
1066    
1067                    return updateAsset(
1068                            userId, fileEntry, fileVersion, assetCategoryIds, assetTagNames,
1069                            assetLinkIds);
1070            }
1071    
1072            @Override
1073            public AssetEntry updateAsset(
1074                            long userId, FileEntry fileEntry, FileVersion fileVersion,
1075                            long[] assetCategoryIds, String[] assetTagNames,
1076                            long[] assetLinkEntryIds)
1077                    throws PortalException {
1078    
1079                    AssetEntry assetEntry = null;
1080    
1081                    boolean visible = false;
1082    
1083                    boolean addDraftAssetEntry = false;
1084    
1085                    if (fileEntry instanceof LiferayFileEntry) {
1086                            DLFileVersion dlFileVersion = (DLFileVersion)fileVersion.getModel();
1087    
1088                            if (dlFileVersion.isApproved()) {
1089                                    visible = true;
1090                            }
1091                            else {
1092                                    String version = dlFileVersion.getVersion();
1093    
1094                                    if (!version.equals(DLFileEntryConstants.VERSION_DEFAULT)) {
1095                                            addDraftAssetEntry = true;
1096                                    }
1097                            }
1098                    }
1099                    else {
1100                            visible = true;
1101                    }
1102    
1103                    long fileEntryTypeId = getFileEntryTypeId(fileEntry);
1104    
1105                    if (addDraftAssetEntry) {
1106                            if (assetCategoryIds == null) {
1107                                    assetCategoryIds = assetCategoryLocalService.getCategoryIds(
1108                                            DLFileEntryConstants.getClassName(),
1109                                            fileEntry.getFileEntryId());
1110                            }
1111    
1112                            if (assetTagNames == null) {
1113                                    assetTagNames = assetTagLocalService.getTagNames(
1114                                            DLFileEntryConstants.getClassName(),
1115                                            fileEntry.getFileEntryId());
1116                            }
1117    
1118                            if (assetLinkEntryIds == null) {
1119                                    AssetEntry previousAssetEntry = assetEntryLocalService.getEntry(
1120                                            DLFileEntryConstants.getClassName(),
1121                                            fileEntry.getFileEntryId());
1122    
1123                                    List<AssetLink> assetLinks =
1124                                            assetLinkLocalService.getDirectLinks(
1125                                                    previousAssetEntry.getEntryId(),
1126                                                    AssetLinkConstants.TYPE_RELATED);
1127    
1128                                    assetLinkEntryIds = ListUtil.toLongArray(
1129                                            assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
1130                            }
1131    
1132                            assetEntry = assetEntryLocalService.updateEntry(
1133                                    userId, fileEntry.getGroupId(), fileEntry.getCreateDate(),
1134                                    fileEntry.getModifiedDate(),
1135                                    DLFileEntryConstants.getClassName(),
1136                                    fileVersion.getFileVersionId(), fileEntry.getUuid(),
1137                                    fileEntryTypeId, assetCategoryIds, assetTagNames, false, null,
1138                                    null, null, fileEntry.getMimeType(), fileEntry.getTitle(),
1139                                    fileEntry.getDescription(), null, null, null, 0, 0, null);
1140                    }
1141                    else {
1142                            assetEntry = assetEntryLocalService.updateEntry(
1143                                    userId, fileEntry.getGroupId(), fileEntry.getCreateDate(),
1144                                    fileEntry.getModifiedDate(),
1145                                    DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId(),
1146                                    fileEntry.getUuid(), fileEntryTypeId, assetCategoryIds,
1147                                    assetTagNames, visible, null, null, null,
1148                                    fileEntry.getMimeType(), fileEntry.getTitle(),
1149                                    fileEntry.getDescription(), null, null, null, 0, 0, null);
1150    
1151                            List<DLFileShortcut> dlFileShortcuts =
1152                                    dlFileShortcutPersistence.findByToFileEntryId(
1153                                            fileEntry.getFileEntryId());
1154    
1155                            for (DLFileShortcut dlFileShortcut : dlFileShortcuts) {
1156                                    assetEntryLocalService.updateEntry(
1157                                            userId, dlFileShortcut.getGroupId(),
1158                                            dlFileShortcut.getCreateDate(),
1159                                            dlFileShortcut.getModifiedDate(),
1160                                            DLFileShortcutConstants.getClassName(),
1161                                            dlFileShortcut.getFileShortcutId(),
1162                                            dlFileShortcut.getUuid(), fileEntryTypeId, assetCategoryIds,
1163                                            assetTagNames, true, null, null, null,
1164                                            fileEntry.getMimeType(), fileEntry.getTitle(),
1165                                            fileEntry.getDescription(), null, null, null, 0, 0, null);
1166                            }
1167                    }
1168    
1169                    assetLinkLocalService.updateLinks(
1170                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
1171                            AssetLinkConstants.TYPE_RELATED);
1172    
1173                    return assetEntry;
1174            }
1175    
1176            @Override
1177            public AssetEntry updateAsset(
1178                            long userId, Folder folder, long[] assetCategoryIds,
1179                            String[] assetTagNames, long[] assetLinkEntryIds)
1180                    throws PortalException {
1181    
1182                    AssetEntry assetEntry = null;
1183    
1184                    boolean visible = false;
1185    
1186                    if (folder instanceof LiferayFolder) {
1187                            DLFolder dlFolder = (DLFolder)folder.getModel();
1188    
1189                            if (dlFolder.isApproved() && !dlFolder.isHidden() &&
1190                                    !dlFolder.isInHiddenFolder()) {
1191    
1192                                    visible = true;
1193                            }
1194                    }
1195                    else {
1196                            visible = true;
1197                    }
1198    
1199                    assetEntry = assetEntryLocalService.updateEntry(
1200                            userId, folder.getGroupId(), folder.getCreateDate(),
1201                            folder.getModifiedDate(), DLFolderConstants.getClassName(),
1202                            folder.getFolderId(), folder.getUuid(), 0, assetCategoryIds,
1203                            assetTagNames, visible, null, null, null, null, folder.getName(),
1204                            folder.getDescription(), null, null, null, 0, 0, null);
1205    
1206                    assetLinkLocalService.updateLinks(
1207                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
1208                            AssetLinkConstants.TYPE_RELATED);
1209    
1210                    return assetEntry;
1211            }
1212    
1213            @Override
1214            public void updateFileEntry(
1215                            long userId, FileEntry fileEntry, FileVersion sourceFileVersion,
1216                            FileVersion destinationFileVersion, long assetClassPk)
1217                    throws PortalException {
1218    
1219                    if (!DLAppHelperThreadLocal.isEnabled()) {
1220                            return;
1221                    }
1222    
1223                    boolean updateAsset = true;
1224    
1225                    if (fileEntry instanceof LiferayFileEntry &&
1226                            fileEntry.getVersion().equals(
1227                                    destinationFileVersion.getVersion())) {
1228    
1229                            updateAsset = false;
1230                    }
1231    
1232                    if (updateAsset) {
1233                            updateAsset(
1234                                    userId, fileEntry, destinationFileVersion, assetClassPk);
1235                    }
1236            }
1237    
1238            @Override
1239            public void updateFileEntry(
1240                            long userId, FileEntry fileEntry, FileVersion sourceFileVersion,
1241                            FileVersion destinationFileVersion, ServiceContext serviceContext)
1242                    throws PortalException {
1243    
1244                    if (!DLAppHelperThreadLocal.isEnabled()) {
1245                            return;
1246                    }
1247    
1248                    updateAsset(
1249                            userId, fileEntry, destinationFileVersion,
1250                            serviceContext.getAssetCategoryIds(),
1251                            serviceContext.getAssetTagNames(),
1252                            serviceContext.getAssetLinkEntryIds());
1253            }
1254    
1255            @Override
1256            public void updateFolder(
1257                            long userId, Folder folder, ServiceContext serviceContext)
1258                    throws PortalException {
1259    
1260                    updateAsset(
1261                            userId, folder, serviceContext.getAssetCategoryIds(),
1262                            serviceContext.getAssetTagNames(),
1263                            serviceContext.getAssetLinkEntryIds());
1264            }
1265    
1266            @Override
1267            public void updateStatus(
1268                            long userId, FileEntry fileEntry, FileVersion latestFileVersion,
1269                            int oldStatus, int newStatus, ServiceContext serviceContext,
1270                            Map<String, Serializable> workflowContext)
1271                    throws PortalException {
1272    
1273                    if (!DLAppHelperThreadLocal.isEnabled()) {
1274                            return;
1275                    }
1276    
1277                    if (newStatus == WorkflowConstants.STATUS_APPROVED) {
1278    
1279                            // Asset
1280    
1281                            String latestFileVersionVersion = latestFileVersion.getVersion();
1282    
1283                            if (latestFileVersionVersion.equals(fileEntry.getVersion())) {
1284                                    if (!latestFileVersionVersion.equals(
1285                                                    DLFileEntryConstants.VERSION_DEFAULT)) {
1286    
1287                                            AssetEntry draftAssetEntry =
1288                                                    assetEntryLocalService.fetchEntry(
1289                                                            DLFileEntryConstants.getClassName(),
1290                                                            latestFileVersion.getPrimaryKey());
1291    
1292                                            if (draftAssetEntry != null) {
1293                                                    long fileEntryTypeId = getFileEntryTypeId(fileEntry);
1294    
1295                                                    long[] assetCategoryIds =
1296                                                            draftAssetEntry.getCategoryIds();
1297                                                    String[] assetTagNames = draftAssetEntry.getTagNames();
1298    
1299                                                    List<AssetLink> assetLinks =
1300                                                            assetLinkLocalService.getDirectLinks(
1301                                                                    draftAssetEntry.getEntryId(),
1302                                                                    AssetLinkConstants.TYPE_RELATED);
1303    
1304                                                    long[] assetLinkEntryIds = ListUtil.toLongArray(
1305                                                            assetLinks, AssetLink.ENTRY_ID2_ACCESSOR);
1306    
1307                                                    AssetEntry assetEntry =
1308                                                            assetEntryLocalService.updateEntry(
1309                                                                    userId, fileEntry.getGroupId(),
1310                                                                    fileEntry.getCreateDate(),
1311                                                                    fileEntry.getModifiedDate(),
1312                                                                    DLFileEntryConstants.getClassName(),
1313                                                                    fileEntry.getFileEntryId(), fileEntry.getUuid(),
1314                                                                    fileEntryTypeId, assetCategoryIds,
1315                                                                    assetTagNames, true, null, null, null,
1316                                                                    draftAssetEntry.getMimeType(),
1317                                                                    fileEntry.getTitle(),
1318                                                                    fileEntry.getDescription(), null, null, null, 0,
1319                                                                    0, null);
1320    
1321                                                    assetLinkLocalService.updateLinks(
1322                                                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
1323                                                            AssetLinkConstants.TYPE_RELATED);
1324    
1325                                                    assetEntryLocalService.deleteEntry(draftAssetEntry);
1326                                            }
1327                                    }
1328    
1329                                    AssetEntry assetEntry = assetEntryLocalService.fetchEntry(
1330                                            DLFileEntryConstants.getClassName(),
1331                                            fileEntry.getFileEntryId());
1332    
1333                                    if (assetEntry != null) {
1334                                            assetEntryLocalService.updateVisible(
1335                                                    DLFileEntryConstants.getClassName(),
1336                                                    fileEntry.getFileEntryId(), true);
1337                                    }
1338                            }
1339    
1340                            // Sync
1341    
1342                            String event = GetterUtil.getString(workflowContext.get("event"));
1343    
1344                            if (Validator.isNotNull(event)) {
1345                                    triggerRepositoryEvent(
1346                                            fileEntry.getRepositoryId(),
1347                                            getWorkflowRepositoryEventTypeClass(event), FileEntry.class,
1348                                            fileEntry);
1349                            }
1350    
1351                            if ((oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
1352                                    !fileEntry.isInTrash()) {
1353    
1354                                    // Social
1355    
1356                                    Date activityCreateDate = latestFileVersion.getModifiedDate();
1357                                    int activityType = DLActivityKeys.UPDATE_FILE_ENTRY;
1358    
1359                                    if (event.equals(DLSyncConstants.EVENT_ADD)) {
1360                                            activityCreateDate = latestFileVersion.getCreateDate();
1361                                            activityType = DLActivityKeys.ADD_FILE_ENTRY;
1362                                    }
1363    
1364                                    JSONObject extraDataJSONObject =
1365                                            JSONFactoryUtil.createJSONObject();
1366    
1367                                    extraDataJSONObject.put("title", fileEntry.getTitle());
1368    
1369                                    socialActivityLocalService.addUniqueActivity(
1370                                            latestFileVersion.getStatusByUserId(),
1371                                            fileEntry.getGroupId(), activityCreateDate,
1372                                            DLFileEntryConstants.getClassName(),
1373                                            fileEntry.getFileEntryId(), activityType,
1374                                            extraDataJSONObject.toString(), 0);
1375    
1376                                    // Subscriptions
1377    
1378                                    notifySubscribers(
1379                                            userId, latestFileVersion,
1380                                            (String)workflowContext.get(WorkflowConstants.CONTEXT_URL),
1381                                            serviceContext);
1382                            }
1383                    }
1384                    else {
1385    
1386                            // Asset
1387    
1388                            boolean visible = false;
1389    
1390                            if (newStatus != WorkflowConstants.STATUS_IN_TRASH) {
1391                                    List<DLFileVersion> approvedFileVersions =
1392                                            dlFileVersionPersistence.findByF_S(
1393                                                    fileEntry.getFileEntryId(),
1394                                                    WorkflowConstants.STATUS_APPROVED);
1395    
1396                                    if (!approvedFileVersions.isEmpty()) {
1397                                            visible = true;
1398                                    }
1399                            }
1400    
1401                            assetEntryLocalService.updateVisible(
1402                                    DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId(),
1403                                    visible);
1404                    }
1405            }
1406    
1407            protected FileEntry doMoveFileEntryFromTrash(
1408                            long userId, FileEntry fileEntry, long newFolderId,
1409                            ServiceContext serviceContext)
1410                    throws PortalException {
1411    
1412                    // File entry
1413    
1414                    DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
1415    
1416                    if (dlFileEntry.isInTrashExplicitly()) {
1417                            restoreFileEntryFromTrash(userId, fileEntry);
1418    
1419                            fileEntry = dlAppLocalService.moveFileEntry(
1420                                    userId, fileEntry.getFileEntryId(), newFolderId,
1421                                    serviceContext);
1422    
1423                            if (DLAppHelperThreadLocal.isEnabled()) {
1424                                    dlFileRankLocalService.enableFileRanks(
1425                                            fileEntry.getFileEntryId());
1426                            }
1427    
1428                            return fileEntry;
1429                    }
1430    
1431                    List<DLFileVersion> dlFileVersions =
1432                            dlFileVersionLocalService.getFileVersions(
1433                                    fileEntry.getFileEntryId(), WorkflowConstants.STATUS_IN_TRASH);
1434    
1435                    dlFileVersions = ListUtil.sort(
1436                            dlFileVersions, new DLFileVersionVersionComparator());
1437    
1438                    FileVersion fileVersion = new LiferayFileVersion(dlFileVersions.get(0));
1439    
1440                    TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
1441                            DLFileVersion.class.getName(), fileVersion.getFileVersionId());
1442    
1443                    int oldStatus = WorkflowConstants.STATUS_APPROVED;
1444    
1445                    if (trashVersion != null) {
1446                            oldStatus = trashVersion.getStatus();
1447                    }
1448    
1449                    dlFileEntryLocalService.updateStatus(
1450                            userId, fileVersion.getFileVersionId(), oldStatus, serviceContext,
1451                            new HashMap<String, Serializable>());
1452    
1453                    // File versions
1454    
1455                    for (DLFileVersion dlFileVersion : dlFileVersions) {
1456    
1457                            // File version
1458    
1459                            trashVersion = trashVersionLocalService.fetchVersion(
1460                                    DLFileVersion.class.getName(),
1461                                    dlFileVersion.getFileVersionId());
1462    
1463                            oldStatus = WorkflowConstants.STATUS_APPROVED;
1464    
1465                            if (trashVersion != null) {
1466                                    oldStatus = trashVersion.getStatus();
1467                            }
1468    
1469                            dlFileVersion.setStatus(oldStatus);
1470    
1471                            dlFileVersionPersistence.update(dlFileVersion);
1472    
1473                            // Trash
1474    
1475                            if (trashVersion != null) {
1476                                    trashVersionLocalService.deleteTrashVersion(trashVersion);
1477                            }
1478                    }
1479    
1480                    if (DLAppHelperThreadLocal.isEnabled()) {
1481    
1482                            // File rank
1483    
1484                            dlFileRankLocalService.enableFileRanks(fileEntry.getFileEntryId());
1485    
1486                            // File shortcut
1487    
1488                            dlFileShortcutLocalService.enableFileShortcuts(
1489                                    fileEntry.getFileEntryId());
1490                    }
1491    
1492                    // App helper
1493    
1494                    fileEntry = dlAppService.moveFileEntry(
1495                            fileEntry.getFileEntryId(), newFolderId, serviceContext);
1496    
1497                    // Sync
1498    
1499                    triggerRepositoryEvent(
1500                            fileEntry.getRepositoryId(),
1501                            TrashRepositoryEventType.EntryRestored.class, FileEntry.class,
1502                            fileEntry);
1503    
1504                    // Social
1505    
1506                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1507    
1508                    extraDataJSONObject.put("title", fileEntry.getTitle());
1509    
1510                    socialActivityLocalService.addActivity(
1511                            userId, fileEntry.getGroupId(), DLFileEntryConstants.getClassName(),
1512                            fileEntry.getFileEntryId(),
1513                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
1514                            extraDataJSONObject.toString(), 0);
1515    
1516                    return fileEntry;
1517            }
1518    
1519            protected FileEntry doMoveFileEntryToTrash(long userId, FileEntry fileEntry)
1520                    throws PortalException {
1521    
1522                    // File versions
1523    
1524                    List<DLFileVersion> dlFileVersions =
1525                            dlFileVersionLocalService.getFileVersions(
1526                                    fileEntry.getFileEntryId(), WorkflowConstants.STATUS_ANY);
1527    
1528                    dlFileVersions = ListUtil.sort(
1529                            dlFileVersions, new DLFileVersionVersionComparator());
1530    
1531                    List<ObjectValuePair<Long, Integer>> dlFileVersionStatusOVPs =
1532                            new ArrayList<>();
1533    
1534                    if ((dlFileVersions != null) && !dlFileVersions.isEmpty()) {
1535                            dlFileVersionStatusOVPs = getDlFileVersionStatuses(dlFileVersions);
1536                    }
1537    
1538                    FileVersion fileVersion = fileEntry.getFileVersion();
1539    
1540                    int oldStatus = fileVersion.getStatus();
1541    
1542                    dlFileEntryLocalService.updateStatus(
1543                            userId, fileVersion.getFileVersionId(),
1544                            WorkflowConstants.STATUS_IN_TRASH, new ServiceContext(),
1545                            new HashMap<String, Serializable>());
1546    
1547                    if (DLAppHelperThreadLocal.isEnabled()) {
1548    
1549                            // File shortcut
1550    
1551                            dlFileShortcutLocalService.disableFileShortcuts(
1552                                    fileEntry.getFileEntryId());
1553    
1554                            // File rank
1555    
1556                            dlFileRankLocalService.disableFileRanks(fileEntry.getFileEntryId());
1557    
1558                            // Sync
1559    
1560                            triggerRepositoryEvent(
1561                                    fileEntry.getRepositoryId(),
1562                                    TrashRepositoryEventType.EntryTrashed.class, FileEntry.class,
1563                                    fileEntry);
1564                    }
1565    
1566                    // Trash
1567    
1568                    DLFileVersion oldDLFileVersion = (DLFileVersion)fileVersion.getModel();
1569    
1570                    int oldDLFileVersionStatus = oldDLFileVersion.getStatus();
1571    
1572                    for (DLFileVersion curDLFileVersion : dlFileVersions) {
1573                            curDLFileVersion.setStatus(WorkflowConstants.STATUS_IN_TRASH);
1574    
1575                            dlFileVersionPersistence.update(curDLFileVersion);
1576                    }
1577    
1578                    DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
1579    
1580                    UnicodeProperties typeSettingsProperties = new UnicodeProperties();
1581    
1582                    typeSettingsProperties.put("fileName", dlFileEntry.getFileName());
1583                    typeSettingsProperties.put("title", dlFileEntry.getTitle());
1584    
1585                    TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
1586                            userId, dlFileEntry.getGroupId(),
1587                            DLFileEntryConstants.getClassName(), dlFileEntry.getFileEntryId(),
1588                            dlFileEntry.getUuid(), dlFileEntry.getClassName(),
1589                            oldDLFileVersionStatus, dlFileVersionStatusOVPs,
1590                            typeSettingsProperties);
1591    
1592                    String trashTitle = TrashUtil.getTrashTitle(trashEntry.getEntryId());
1593    
1594                    dlFileEntry.setFileName(trashTitle);
1595                    dlFileEntry.setTitle(trashTitle);
1596    
1597                    dlFileEntryPersistence.update(dlFileEntry);
1598    
1599                    if (!DLAppHelperThreadLocal.isEnabled()) {
1600                            return fileEntry;
1601                    }
1602    
1603                    // Social
1604    
1605                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1606    
1607                    extraDataJSONObject.put(
1608                            "title", TrashUtil.getOriginalTitle(fileEntry.getTitle()));
1609    
1610                    socialActivityLocalService.addActivity(
1611                            userId, fileEntry.getGroupId(), DLFileEntryConstants.getClassName(),
1612                            fileEntry.getFileEntryId(),
1613                            SocialActivityConstants.TYPE_MOVE_TO_TRASH,
1614                            extraDataJSONObject.toString(), 0);
1615    
1616                    // Workflow
1617    
1618                    if (oldStatus == WorkflowConstants.STATUS_PENDING) {
1619                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
1620                                    fileVersion.getCompanyId(), fileVersion.getGroupId(),
1621                                    DLFileEntryConstants.getClassName(),
1622                                    fileVersion.getFileVersionId());
1623                    }
1624    
1625                    return fileEntry;
1626            }
1627    
1628            protected Folder doMoveFolderFromTrash(
1629                            long userId, Folder folder, long parentFolderId,
1630                            ServiceContext serviceContext)
1631                    throws PortalException {
1632    
1633                    DLFolder dlFolder = (DLFolder)folder.getModel();
1634    
1635                    if (dlFolder.isInTrashExplicitly()) {
1636                            restoreFolderFromTrash(userId, folder);
1637                    }
1638                    else {
1639    
1640                            // Folder
1641    
1642                            TrashVersion trashVersion = trashVersionLocalService.fetchVersion(
1643                                    DLFolder.class.getName(), dlFolder.getFolderId());
1644    
1645                            int status = WorkflowConstants.STATUS_APPROVED;
1646    
1647                            if (trashVersion != null) {
1648                                    status = trashVersion.getStatus();
1649                            }
1650    
1651                            dlFolderLocalService.updateStatus(
1652                                    userId, folder.getFolderId(), status,
1653                                    new HashMap<String, Serializable>(), new ServiceContext());
1654    
1655                            // File rank
1656    
1657                            dlFileRankLocalService.enableFileRanksByFolderId(
1658                                    folder.getFolderId());
1659    
1660                            // Trash
1661    
1662                            if (trashVersion != null) {
1663                                    trashVersionLocalService.deleteTrashVersion(trashVersion);
1664                            }
1665    
1666                            // Folders, file entries, and file shortcuts
1667    
1668                            QueryDefinition<?> queryDefinition = new QueryDefinition<>(
1669                                    WorkflowConstants.STATUS_IN_TRASH);
1670    
1671                            List<Object> foldersAndFileEntriesAndFileShortcuts =
1672                                    dlFolderLocalService.getFoldersAndFileEntriesAndFileShortcuts(
1673                                            dlFolder.getGroupId(), dlFolder.getFolderId(), null, false,
1674                                            queryDefinition);
1675    
1676                            dlAppHelperLocalService.restoreDependentsFromTrash(
1677                                    foldersAndFileEntriesAndFileShortcuts);
1678    
1679                            // Sync
1680    
1681                            triggerRepositoryEvent(
1682                                    folder.getRepositoryId(),
1683                                    TrashRepositoryEventType.EntryRestored.class, Folder.class,
1684                                    folder);
1685    
1686                            // Social
1687    
1688                            JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1689    
1690                            extraDataJSONObject.put("title", folder.getName());
1691    
1692                            socialActivityLocalService.addActivity(
1693                                    userId, folder.getGroupId(), DLFolderConstants.class.getName(),
1694                                    folder.getFolderId(),
1695                                    SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
1696                                    extraDataJSONObject.toString(), 0);
1697                    }
1698    
1699                    return dlAppLocalService.moveFolder(
1700                            userId, folder.getFolderId(), parentFolderId, serviceContext);
1701            }
1702    
1703            protected Folder doMoveFolderToTrash(long userId, Folder folder)
1704                    throws PortalException {
1705    
1706                    // Folder
1707    
1708                    DLFolder dlFolder = dlFolderLocalService.updateStatus(
1709                            userId, folder.getFolderId(), WorkflowConstants.STATUS_IN_TRASH,
1710                            new HashMap<String, Serializable>(), new ServiceContext());
1711    
1712                    // File rank
1713    
1714                    dlFileRankLocalService.disableFileRanksByFolderId(folder.getFolderId());
1715    
1716                    // Trash
1717    
1718                    UnicodeProperties typeSettingsProperties = new UnicodeProperties();
1719    
1720                    typeSettingsProperties.put("title", dlFolder.getName());
1721    
1722                    TrashEntry trashEntry = trashEntryLocalService.addTrashEntry(
1723                            userId, dlFolder.getGroupId(), DLFolderConstants.getClassName(),
1724                            dlFolder.getFolderId(), dlFolder.getUuid(), null,
1725                            WorkflowConstants.STATUS_APPROVED, null, typeSettingsProperties);
1726    
1727                    dlFolder.setName(TrashUtil.getTrashTitle(trashEntry.getEntryId()));
1728    
1729                    dlFolderPersistence.update(dlFolder);
1730    
1731                    // Folders, file entries, and file shortcuts
1732    
1733                    QueryDefinition<?> queryDefinition = new QueryDefinition<>(
1734                            WorkflowConstants.STATUS_ANY);
1735    
1736                    List<Object> foldersAndFileEntriesAndFileShortcuts =
1737                            dlFolderLocalService.getFoldersAndFileEntriesAndFileShortcuts(
1738                                    dlFolder.getGroupId(), dlFolder.getFolderId(), null, false,
1739                                    queryDefinition);
1740    
1741                    dlAppHelperLocalService.moveDependentsToTrash(
1742                            foldersAndFileEntriesAndFileShortcuts, trashEntry.getEntryId());
1743    
1744                    // Sync
1745    
1746                    triggerRepositoryEvent(
1747                            folder.getRepositoryId(),
1748                            TrashRepositoryEventType.EntryTrashed.class, Folder.class, folder);
1749    
1750                    // Social
1751    
1752                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1753    
1754                    extraDataJSONObject.put("title", folder.getName());
1755    
1756                    socialActivityLocalService.addActivity(
1757                            userId, folder.getGroupId(), DLFolderConstants.getClassName(),
1758                            folder.getFolderId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
1759                            extraDataJSONObject.toString(), 0);
1760    
1761                    return new LiferayFolder(dlFolder);
1762            }
1763    
1764            protected List<ObjectValuePair<Long, Integer>> getDlFileVersionStatuses(
1765                    List<DLFileVersion> dlFileVersions) {
1766    
1767                    List<ObjectValuePair<Long, Integer>> dlFileVersionStatusOVPs =
1768                            new ArrayList<>(dlFileVersions.size());
1769    
1770                    for (DLFileVersion dlFileVersion : dlFileVersions) {
1771                            int status = dlFileVersion.getStatus();
1772    
1773                            if (status == WorkflowConstants.STATUS_PENDING) {
1774                                    status = WorkflowConstants.STATUS_DRAFT;
1775                            }
1776    
1777                            ObjectValuePair<Long, Integer> dlFileVersionStatusOVP =
1778                                    new ObjectValuePair<>(dlFileVersion.getFileVersionId(), status);
1779    
1780                            dlFileVersionStatusOVPs.add(dlFileVersionStatusOVP);
1781                    }
1782    
1783                    return dlFileVersionStatusOVPs;
1784            }
1785    
1786            protected long getFileEntryTypeId(FileEntry fileEntry) {
1787                    if (fileEntry instanceof LiferayFileEntry) {
1788                            DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
1789    
1790                            return dlFileEntry.getFileEntryTypeId();
1791                    }
1792    
1793                    return 0;
1794            }
1795    
1796            protected Class<? extends WorkflowRepositoryEventType>
1797                    getWorkflowRepositoryEventTypeClass(
1798                            String syncEvent) {
1799    
1800                    if (syncEvent.equals(DLSyncConstants.EVENT_ADD)) {
1801                            return WorkflowRepositoryEventType.Add.class;
1802                    }
1803                    else if (syncEvent.equals(DLSyncConstants.EVENT_UPDATE)) {
1804                            return WorkflowRepositoryEventType.Update.class;
1805                    }
1806                    else {
1807                            throw new IllegalArgumentException(
1808                                    String.format("Unsupported sync event %s", syncEvent));
1809                    }
1810            }
1811    
1812            protected void notifySubscribers(
1813                            long userId, FileVersion fileVersion, String entryURL,
1814                            ServiceContext serviceContext)
1815                    throws PortalException {
1816    
1817                    if (!fileVersion.isApproved() || Validator.isNull(entryURL)) {
1818                            return;
1819                    }
1820    
1821                    DLGroupServiceSettings dlGroupServiceSettings =
1822                            DLGroupServiceSettings.getInstance(fileVersion.getGroupId());
1823    
1824                    if (serviceContext.isCommandAdd() &&
1825                            dlGroupServiceSettings.isEmailFileEntryAddedEnabled()) {
1826                    }
1827                    else if (serviceContext.isCommandUpdate() &&
1828                                     dlGroupServiceSettings.isEmailFileEntryUpdatedEnabled()) {
1829                    }
1830                    else {
1831                            return;
1832                    }
1833    
1834                    String entryTitle = fileVersion.getTitle();
1835    
1836                    String fromName = dlGroupServiceSettings.getEmailFromName();
1837                    String fromAddress = dlGroupServiceSettings.getEmailFromAddress();
1838    
1839                    LocalizedValuesMap subjectLocalizedValuesMap = null;
1840                    LocalizedValuesMap bodyLocalizedValuesMap = null;
1841    
1842                    if (serviceContext.isCommandUpdate()) {
1843                            subjectLocalizedValuesMap =
1844                                    dlGroupServiceSettings.getEmailFileEntryUpdatedSubject();
1845                            bodyLocalizedValuesMap =
1846                                    dlGroupServiceSettings.getEmailFileEntryUpdatedBody();
1847                    }
1848                    else {
1849                            subjectLocalizedValuesMap =
1850                                    dlGroupServiceSettings.getEmailFileEntryAddedSubject();
1851                            bodyLocalizedValuesMap =
1852                                    dlGroupServiceSettings.getEmailFileEntryAddedBody();
1853                    }
1854    
1855                    FileEntry fileEntry = fileVersion.getFileEntry();
1856    
1857                    Folder folder = null;
1858    
1859                    long folderId = fileEntry.getFolderId();
1860    
1861                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1862                            folder = dlAppLocalService.getFolder(folderId);
1863                    }
1864    
1865                    String folderName = LanguageUtil.get(
1866                            serviceContext.getLocale(), "home");
1867    
1868                    if (folder != null) {
1869                            folderName = folder.getName();
1870                    }
1871    
1872                    SubscriptionSender subscriptionSender =
1873                            new GroupSubscriptionCheckSubscriptionSender(
1874                                    DLPermission.RESOURCE_NAME);
1875    
1876                    DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
1877    
1878                    DLFileEntryType dlFileEntryType =
1879                            dlFileEntryTypeLocalService.getDLFileEntryType(
1880                                    dlFileEntry.getFileEntryTypeId());
1881    
1882                    subscriptionSender.setClassPK(fileVersion.getFileEntryId());
1883                    subscriptionSender.setClassName(DLFileEntryConstants.getClassName());
1884                    subscriptionSender.setCompanyId(fileVersion.getCompanyId());
1885                    subscriptionSender.setContextAttributes(
1886                            "[$DOCUMENT_STATUS_BY_USER_NAME$]",
1887                            fileVersion.getStatusByUserName(), "[$DOCUMENT_TITLE$]", entryTitle,
1888                            "[$DOCUMENT_TYPE$]",
1889                            dlFileEntryType.getName(serviceContext.getLocale()),
1890                            "[$DOCUMENT_URL$]", entryURL, "[$FOLDER_NAME$]", folderName);
1891                    subscriptionSender.setContextCreatorUserPrefix("DOCUMENT");
1892                    subscriptionSender.setCreatorUserId(fileVersion.getUserId());
1893                    subscriptionSender.setCurrentUserId(userId);
1894                    subscriptionSender.setEntryTitle(entryTitle);
1895                    subscriptionSender.setEntryURL(entryURL);
1896                    subscriptionSender.setFrom(fromAddress, fromName);
1897                    subscriptionSender.setHtmlFormat(true);
1898                    subscriptionSender.setLocalizedBodyMap(
1899                            LocalizationUtil.getMap(bodyLocalizedValuesMap));
1900                    subscriptionSender.setLocalizedSubjectMap(
1901                            LocalizationUtil.getMap(subjectLocalizedValuesMap));
1902                    subscriptionSender.setMailId(
1903                            "file_entry", fileVersion.getFileEntryId());
1904    
1905                    int notificationType =
1906                            UserNotificationDefinition.NOTIFICATION_TYPE_ADD_ENTRY;
1907    
1908                    if (serviceContext.isCommandUpdate()) {
1909                            notificationType =
1910                                    UserNotificationDefinition.NOTIFICATION_TYPE_UPDATE_ENTRY;
1911                    }
1912    
1913                    subscriptionSender.setNotificationType(notificationType);
1914    
1915                    subscriptionSender.setPortletId(PortletKeys.DOCUMENT_LIBRARY);
1916                    subscriptionSender.setReplyToAddress(fromAddress);
1917                    subscriptionSender.setScopeGroupId(fileVersion.getGroupId());
1918                    subscriptionSender.setServiceContext(serviceContext);
1919    
1920                    subscriptionSender.addPersistedSubscribers(
1921                            DLFolder.class.getName(), fileVersion.getGroupId());
1922    
1923                    if (folder != null) {
1924                            subscriptionSender.addPersistedSubscribers(
1925                                    DLFolder.class.getName(), folder.getFolderId());
1926    
1927                            for (Long ancestorFolderId : folder.getAncestorFolderIds()) {
1928                                    subscriptionSender.addPersistedSubscribers(
1929                                            DLFolder.class.getName(), ancestorFolderId);
1930                            }
1931                    }
1932    
1933                    if (dlFileEntryType.getFileEntryTypeId() ==
1934                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT) {
1935    
1936                            subscriptionSender.addPersistedSubscribers(
1937                                    DLFileEntryType.class.getName(), fileVersion.getGroupId());
1938                    }
1939                    else {
1940                            subscriptionSender.addPersistedSubscribers(
1941                                    DLFileEntryType.class.getName(),
1942                                    dlFileEntryType.getFileEntryTypeId());
1943                    }
1944    
1945                    subscriptionSender.addPersistedSubscribers(
1946                            DLFileEntry.class.getName(), fileEntry.getFileEntryId());
1947    
1948                    subscriptionSender.flushNotificationsAsync();
1949            }
1950    
1951            protected <T extends RepositoryModel<T>> void triggerRepositoryEvent(
1952                            long repositoryId,
1953                            Class<? extends RepositoryEventType> repositoryEventType,
1954                            Class<T> modelClass, T target)
1955                    throws PortalException {
1956    
1957                    Repository repository = RepositoryProviderUtil.getRepository(
1958                            repositoryId);
1959    
1960                    if (repository.isCapabilityProvided(
1961                                    RepositoryEventTriggerCapability.class)) {
1962    
1963                            RepositoryEventTriggerCapability repositoryEventTriggerCapability =
1964                                    repository.getCapability(
1965                                            RepositoryEventTriggerCapability.class);
1966    
1967                            repositoryEventTriggerCapability.trigger(
1968                                    repositoryEventType, modelClass, target);
1969                    }
1970            }
1971    
1972    }