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