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