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