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