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(), dlFileShortcut.getUuid(), null,
552                            oldStatus, null, null);
553    
554                    return dlFileShortcut;
555            }
556    
557            @Override
558            public void moveFolder(Folder folder) throws SystemException {
559                    if (!isStagingGroup(folder.getGroupId())) {
560                            registerDLSyncEventCallback(
561                                    DLSyncConstants.EVENT_MOVE, DLSyncConstants.TYPE_FOLDER,
562                                    folder.getFolderId());
563                    }
564            }
565    
566            @Override
567            public Folder moveFolderFromTrash(
568                            long userId, Folder folder, long parentFolderId,
569                            ServiceContext serviceContext)
570                    throws PortalException, SystemException {
571    
572                    boolean hasLock = dlFolderLocalService.hasFolderLock(
573                            userId, folder.getFolderId());
574    
575                    Lock lock = null;
576    
577                    if (!hasLock) {
578                            lock = dlFolderLocalService.lockFolder(
579                                    userId, folder.getFolderId());
580                    }
581    
582                    try {
583                            return doMoveFolderFromTrash(
584                                    userId, folder, parentFolderId, serviceContext);
585                    }
586                    finally {
587                            if (!hasLock) {
588                                    dlFolderLocalService.unlockFolder(
589                                            folder.getFolderId(), lock.getUuid());
590                            }
591                    }
592            }
593    
594            /**
595             * Moves the folder to the recycle bin.
596             *
597             * @param  userId the primary key of the user moving the folder
598             * @param  folder the folder to be moved
599             * @return the moved folder
600             * @throws PortalException if a user with the primary key could not be found
601             * @throws SystemException if a system exception occurred
602             */
603            @Override
604            public Folder moveFolderToTrash(long userId, Folder folder)
605                    throws PortalException, SystemException {
606    
607                    boolean hasLock = dlFolderLocalService.hasFolderLock(
608                            userId, folder.getFolderId());
609    
610                    Lock lock = null;
611    
612                    if (!hasLock) {
613                            lock = dlFolderLocalService.lockFolder(
614                                    userId, folder.getFolderId());
615                    }
616    
617                    try {
618                            return doMoveFolderToTrash(userId, folder);
619                    }
620                    finally {
621                            if (!hasLock) {
622                                    dlFolderLocalService.unlockFolder(
623                                            folder.getFolderId(), lock.getUuid());
624                            }
625                    }
626            }
627    
628            @Override
629            public void registerDLSyncEventCallback(
630                            final String event, final String type, final long typePK)
631                    throws SystemException {
632    
633                    DLSyncEvent dlSyncEvent = dlSyncEventLocalService.addDLSyncEvent(
634                            event, type, typePK);
635    
636                    final long modifiedTime = dlSyncEvent.getModifiedTime();
637    
638                    TransactionCommitCallbackRegistryUtil.registerCallback(
639                            new Callable<Void>() {
640    
641                                    @Override
642                                    public Void call() throws Exception {
643                                            Message message = new Message();
644    
645                                            Map<String, Object> values = new HashMap<String, Object>(4);
646    
647                                            values.put("event", event);
648                                            values.put("modifiedTime", modifiedTime);
649                                            values.put("type", type);
650                                            values.put("typePK", typePK);
651    
652                                            message.setValues(values);
653    
654                                            MessageBusUtil.sendMessage(
655                                                    DestinationNames.DOCUMENT_LIBRARY_SYNC_EVENT_PROCESSOR,
656                                                    message);
657    
658                                            return null;
659                                    }
660    
661                            });
662            }
663    
664            @Override
665            public void restoreFileEntryFromTrash(long userId, FileEntry fileEntry)
666                    throws PortalException, SystemException {
667    
668                    // File entry
669    
670                    DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
671    
672                    dlFileEntry.setTitle(
673                            TrashUtil.getOriginalTitle(dlFileEntry.getTitle()));
674    
675                    dlFileEntryPersistence.update(dlFileEntry);
676    
677                    FileVersion fileVersion = new LiferayFileVersion(
678                            dlFileEntry.getLatestFileVersion(true));
679    
680                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
681                            DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId());
682    
683                    // File version
684    
685                    Map<String, Serializable> workflowContext =
686                            new HashMap<String, Serializable>();
687    
688                    List<TrashVersion> trashVersions = trashVersionLocalService.getVersions(
689                            trashEntry.getEntryId());
690    
691                    workflowContext.put("trashVersions", (Serializable)trashVersions);
692    
693                    dlFileEntryLocalService.updateStatus(
694                            userId, fileVersion.getFileVersionId(), trashEntry.getStatus(),
695                            workflowContext, new ServiceContext());
696    
697                    if (!DLAppHelperThreadLocal.isEnabled()) {
698                            return;
699                    }
700    
701                    // File shortcut
702    
703                    dlFileShortcutLocalService.enableFileShortcuts(
704                            fileEntry.getFileEntryId());
705    
706                    // File rank
707    
708                    dlFileRankLocalService.enableFileRanks(fileEntry.getFileEntryId());
709    
710                    // Sync
711    
712                    registerDLSyncEventCallback(
713                            DLSyncConstants.EVENT_RESTORE, DLSyncConstants.TYPE_FILE,
714                            fileEntry.getFileEntryId());
715    
716                    // Social
717    
718                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
719    
720                    extraDataJSONObject.put("title", fileEntry.getTitle());
721    
722                    socialActivityLocalService.addActivity(
723                            userId, fileEntry.getGroupId(), DLFileEntryConstants.getClassName(),
724                            fileEntry.getFileEntryId(),
725                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
726                            extraDataJSONObject.toString(), 0);
727            }
728    
729            @Override
730            public void restoreFileShortcutFromTrash(
731                            long userId, DLFileShortcut dlFileShortcut)
732                    throws PortalException, SystemException {
733    
734                    // File shortcut
735    
736                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
737                            DLFileShortcut.class.getName(), dlFileShortcut.getFileShortcutId());
738    
739                    dlFileShortcutLocalService.updateStatus(
740                            userId, dlFileShortcut.getFileShortcutId(), trashEntry.getStatus(),
741                            new ServiceContext());
742    
743                    // Social
744    
745                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
746    
747                    extraDataJSONObject.put("title", dlFileShortcut.getToTitle());
748    
749                    socialActivityLocalService.addActivity(
750                            userId, dlFileShortcut.getGroupId(), DLFileShortcut.class.getName(),
751                            dlFileShortcut.getFileShortcutId(),
752                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
753                            extraDataJSONObject.toString(), 0);
754    
755                    // Trash
756    
757                    trashEntryLocalService.deleteEntry(trashEntry.getEntryId());
758            }
759    
760            @Override
761            public void restoreFolderFromTrash(long userId, Folder folder)
762                    throws PortalException, SystemException {
763    
764                    // Folder
765    
766                    DLFolder dlFolder = (DLFolder)folder.getModel();
767    
768                    dlFolder.setName(TrashUtil.getOriginalTitle(dlFolder.getName()));
769    
770                    dlFolderPersistence.update(dlFolder);
771    
772                    dlFolderLocalService.updateStatus(
773                            userId, folder.getFolderId(), WorkflowConstants.STATUS_APPROVED,
774                            new HashMap<String, Serializable>(), new ServiceContext());
775    
776                    // File rank
777    
778                    dlFileRankLocalService.enableFileRanksByFolderId(folder.getFolderId());
779    
780                    // Sync
781    
782                    registerDLSyncEventCallback(
783                            DLSyncConstants.EVENT_RESTORE, DLSyncConstants.TYPE_FOLDER,
784                            folder.getFolderId());
785    
786                    // Social
787    
788                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
789    
790                    extraDataJSONObject.put("title", folder.getName());
791    
792                    socialActivityLocalService.addActivity(
793                            userId, folder.getGroupId(), DLFolderConstants.getClassName(),
794                            folder.getFolderId(),
795                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
796                            extraDataJSONObject.toString(), 0);
797            }
798    
799            @Override
800            public AssetEntry updateAsset(
801                            long userId, FileEntry fileEntry, FileVersion fileVersion,
802                            long assetClassPk)
803                    throws PortalException, SystemException {
804    
805                    long[] assetCategoryIds = assetCategoryLocalService.getCategoryIds(
806                            DLFileEntryConstants.getClassName(), assetClassPk);
807                    String[] assetTagNames = assetTagLocalService.getTagNames(
808                            DLFileEntryConstants.getClassName(), assetClassPk);
809    
810                    AssetEntry assetEntry = assetEntryLocalService.getEntry(
811                            DLFileEntryConstants.getClassName(), assetClassPk);
812    
813                    List<AssetLink> assetLinks = assetLinkLocalService.getDirectLinks(
814                            assetEntry.getEntryId());
815    
816                    long[] assetLinkIds = StringUtil.split(
817                            ListUtil.toString(assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
818    
819                    return updateAsset(
820                            userId, fileEntry, fileVersion, assetCategoryIds, assetTagNames,
821                            assetLinkIds);
822            }
823    
824            @Override
825            public AssetEntry updateAsset(
826                            long userId, FileEntry fileEntry, FileVersion fileVersion,
827                            long[] assetCategoryIds, String[] assetTagNames,
828                            long[] assetLinkEntryIds)
829                    throws PortalException, SystemException {
830    
831                    AssetEntry assetEntry = null;
832    
833                    boolean visible = false;
834    
835                    boolean addDraftAssetEntry = false;
836    
837                    if (fileEntry instanceof LiferayFileEntry) {
838                            DLFileVersion dlFileVersion = (DLFileVersion)fileVersion.getModel();
839    
840                            if (dlFileVersion.isApproved()) {
841                                    visible = true;
842                            }
843                            else {
844                                    String version = dlFileVersion.getVersion();
845    
846                                    if (!version.equals(DLFileEntryConstants.VERSION_DEFAULT)) {
847                                            addDraftAssetEntry = true;
848                                    }
849                            }
850                    }
851                    else {
852                            visible = true;
853                    }
854    
855                    long fileEntryTypeId = getFileEntryTypeId(fileEntry);
856    
857                    if (addDraftAssetEntry) {
858                            if (assetCategoryIds == null) {
859                                    assetCategoryIds = assetCategoryLocalService.getCategoryIds(
860                                            DLFileEntryConstants.getClassName(),
861                                            fileEntry.getFileEntryId());
862                            }
863    
864                            if (assetTagNames == null) {
865                                    assetTagNames = assetTagLocalService.getTagNames(
866                                            DLFileEntryConstants.getClassName(),
867                                            fileEntry.getFileEntryId());
868                            }
869    
870                            if (assetLinkEntryIds == null) {
871                                    AssetEntry previousAssetEntry = assetEntryLocalService.getEntry(
872                                            DLFileEntryConstants.getClassName(),
873                                            fileEntry.getFileEntryId());
874    
875                                    List<AssetLink> assetLinks =
876                                            assetLinkLocalService.getDirectLinks(
877                                                    previousAssetEntry.getEntryId(),
878                                                    AssetLinkConstants.TYPE_RELATED);
879    
880                                    assetLinkEntryIds = StringUtil.split(
881                                            ListUtil.toString(
882                                                    assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
883                            }
884    
885                            assetEntry = assetEntryLocalService.updateEntry(
886                                    userId, fileEntry.getGroupId(), fileEntry.getCreateDate(),
887                                    fileEntry.getModifiedDate(),
888                                    DLFileEntryConstants.getClassName(),
889                                    fileVersion.getFileVersionId(), fileEntry.getUuid(),
890                                    fileEntryTypeId, assetCategoryIds, assetTagNames, false, null,
891                                    null, null, fileEntry.getMimeType(), fileEntry.getTitle(),
892                                    fileEntry.getDescription(), null, null, null, 0, 0, null,
893                                    false);
894                    }
895                    else {
896                            assetEntry = assetEntryLocalService.updateEntry(
897                                    userId, fileEntry.getGroupId(), fileEntry.getCreateDate(),
898                                    fileEntry.getModifiedDate(),
899                                    DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId(),
900                                    fileEntry.getUuid(), fileEntryTypeId, assetCategoryIds,
901                                    assetTagNames, visible, null, null, null,
902                                    fileEntry.getMimeType(), fileEntry.getTitle(),
903                                    fileEntry.getDescription(), null, null, null, 0, 0, null,
904                                    false);
905    
906                            List<DLFileShortcut> dlFileShortcuts =
907                                    dlFileShortcutPersistence.findByToFileEntryId(
908                                            fileEntry.getFileEntryId());
909    
910                            for (DLFileShortcut dlFileShortcut : dlFileShortcuts) {
911                                    assetEntryLocalService.updateEntry(
912                                            userId, dlFileShortcut.getGroupId(),
913                                            dlFileShortcut.getCreateDate(),
914                                            dlFileShortcut.getModifiedDate(),
915                                            DLFileShortcut.class.getName(),
916                                            dlFileShortcut.getFileShortcutId(),
917                                            dlFileShortcut.getUuid(), fileEntryTypeId, assetCategoryIds,
918                                            assetTagNames, true, null, null, null,
919                                            fileEntry.getMimeType(), fileEntry.getTitle(),
920                                            fileEntry.getDescription(), null, null, null, 0, 0, null,
921                                            false);
922                            }
923                    }
924    
925                    assetLinkLocalService.updateLinks(
926                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
927                            AssetLinkConstants.TYPE_RELATED);
928    
929                    return assetEntry;
930            }
931    
932            @Override
933            public AssetEntry updateAsset(
934                            long userId, Folder folder, long[] assetCategoryIds,
935                            String[] assetTagNames, long[] assetLinkEntryIds)
936                    throws PortalException, SystemException {
937    
938                    AssetEntry assetEntry = null;
939    
940                    boolean visible = false;
941    
942                    if (folder instanceof LiferayFolder) {
943                            DLFolder dlFolder = (DLFolder)folder.getModel();
944    
945                            if (dlFolder.isApproved() && !dlFolder.isHidden() &&
946                                    !dlFolder.isInHiddenFolder()) {
947    
948                                    visible = true;
949                            }
950                    }
951                    else {
952                            visible = true;
953                    }
954    
955                    assetEntry = assetEntryLocalService.updateEntry(
956                            userId, folder.getGroupId(), folder.getCreateDate(),
957                            folder.getModifiedDate(), DLFolderConstants.getClassName(),
958                            folder.getFolderId(), folder.getUuid(), 0, assetCategoryIds,
959                            assetTagNames, visible, null, null, null, null, folder.getName(),
960                            folder.getDescription(), null, null, null, 0, 0, null, false);
961    
962                    assetLinkLocalService.updateLinks(
963                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
964                            AssetLinkConstants.TYPE_RELATED);
965    
966                    return assetEntry;
967            }
968    
969            @Override
970            public void updateDependentStatus(
971                            User user, List<Object> dlFileEntriesAndDLFolders, int status)
972                    throws PortalException, SystemException {
973    
974                    for (Object object : dlFileEntriesAndDLFolders) {
975                            if (object instanceof DLFileEntry) {
976                                    DLFileEntry dlFileEntry = (DLFileEntry)object;
977    
978                                    List<DLFileVersion> dlFileVersions =
979                                            dlFileVersionLocalService.getFileVersions(
980                                                    dlFileEntry.getFileEntryId(),
981                                                    WorkflowConstants.STATUS_ANY);
982    
983                                    dlFileVersions = ListUtil.copy(dlFileVersions);
984    
985                                    Collections.sort(
986                                            dlFileVersions, new FileVersionVersionComparator());
987    
988                                    DLFileVersion latestDlFileVersion = dlFileVersions.get(0);
989    
990                                    if ((status == WorkflowConstants.STATUS_APPROVED) &&
991                                            (latestDlFileVersion.getStatus() ==
992                                                    WorkflowConstants.STATUS_IN_TRASH)) {
993    
994                                            continue;
995                                    }
996    
997                                    // File shortcut
998    
999                                    if (status == WorkflowConstants.STATUS_APPROVED) {
1000                                            dlFileShortcutLocalService.enableFileShortcuts(
1001                                                    dlFileEntry.getFileEntryId());
1002                                    }
1003                                    else {
1004                                            dlFileShortcutLocalService.disableFileShortcuts(
1005                                                    dlFileEntry.getFileEntryId());
1006                                    }
1007    
1008                                    // Asset
1009    
1010                                    if (status == WorkflowConstants.STATUS_APPROVED) {
1011                                            if (latestDlFileVersion.isApproved()) {
1012                                                    assetEntryLocalService.updateVisible(
1013                                                            DLFileEntryConstants.getClassName(),
1014                                                            dlFileEntry.getFileEntryId(), true);
1015                                            }
1016                                    }
1017                                    else {
1018                                            assetEntryLocalService.updateVisible(
1019                                                    DLFileEntryConstants.getClassName(),
1020                                                    dlFileEntry.getFileEntryId(), false);
1021                                    }
1022    
1023                                    // Index
1024    
1025                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1026                                            DLFileEntry.class);
1027    
1028                                    indexer.reindex(dlFileEntry);
1029    
1030                                    // Workflow
1031    
1032                                    if (status != WorkflowConstants.STATUS_APPROVED) {
1033                                            for (DLFileVersion dlFileVersion : dlFileVersions) {
1034                                                    if (!dlFileVersion.isPending()) {
1035                                                            continue;
1036                                                    }
1037    
1038                                                    dlFileVersion.setStatus(WorkflowConstants.STATUS_DRAFT);
1039    
1040                                                    dlFileVersionPersistence.update(dlFileVersion);
1041    
1042                                                    workflowInstanceLinkLocalService.
1043                                                            deleteWorkflowInstanceLink(
1044                                                                    dlFileVersion.getCompanyId(),
1045                                                                    dlFileVersion.getGroupId(),
1046                                                                    DLFileEntryConstants.getClassName(),
1047                                                                    dlFileVersion.getFileVersionId());
1048                                            }
1049                                    }
1050                            }
1051                            else if (object instanceof DLFolder) {
1052                                    DLFolder dlFolder = (DLFolder)object;
1053    
1054                                    if (dlFolder.isInTrash()) {
1055                                            continue;
1056                                    }
1057    
1058                                    // Folders, file entries, and file shortcuts
1059    
1060                                    QueryDefinition queryDefinition = new QueryDefinition(
1061                                            WorkflowConstants.STATUS_ANY);
1062    
1063                                    List<Object> foldersAndFileEntriesAndFileShortcuts =
1064                                            dlFolderLocalService.
1065                                                    getFoldersAndFileEntriesAndFileShortcuts(
1066                                                            dlFolder.getGroupId(), dlFolder.getFolderId(), null,
1067                                                            false, queryDefinition);
1068    
1069                                    updateDependentStatus(
1070                                            user, foldersAndFileEntriesAndFileShortcuts, status);
1071    
1072                                    if (status == WorkflowConstants.STATUS_IN_TRASH) {
1073    
1074                                            // Asset
1075    
1076                                            assetEntryLocalService.updateVisible(
1077                                                    DLFolderConstants.getClassName(),
1078                                                    dlFolder.getFolderId(), false);
1079                                    }
1080                                    else {
1081    
1082                                            // Asset
1083    
1084                                            assetEntryLocalService.updateVisible(
1085                                                    DLFolderConstants.getClassName(),
1086                                                    dlFolder.getFolderId(), true);
1087                                    }
1088    
1089                                    // Index
1090    
1091                                    Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1092                                            DLFolder.class);
1093    
1094                                    indexer.reindex(dlFolder);
1095                            }
1096                    }
1097            }
1098    
1099            @Override
1100            public void updateFileEntry(
1101                            long userId, FileEntry fileEntry, FileVersion sourceFileVersion,
1102                            FileVersion destinationFileVersion, long assetClassPk)
1103                    throws PortalException, SystemException {
1104    
1105                    if (!DLAppHelperThreadLocal.isEnabled()) {
1106                            return;
1107                    }
1108    
1109                    boolean updateAsset = true;
1110    
1111                    if (fileEntry instanceof LiferayFileEntry &&
1112                            fileEntry.getVersion().equals(
1113                                    destinationFileVersion.getVersion())) {
1114    
1115                            updateAsset = false;
1116                    }
1117    
1118                    if (updateAsset) {
1119                            updateAsset(
1120                                    userId, fileEntry, destinationFileVersion, assetClassPk);
1121                    }
1122    
1123                    registerDLProcessorCallback(fileEntry, sourceFileVersion);
1124    
1125                    registerDLSyncEventCallback(
1126                            DLSyncConstants.EVENT_UPDATE, DLSyncConstants.TYPE_FILE,
1127                            fileEntry.getFileEntryId());
1128            }
1129    
1130            @Override
1131            public void updateFileEntry(
1132                            long userId, FileEntry fileEntry, FileVersion sourceFileVersion,
1133                            FileVersion destinationFileVersion, ServiceContext serviceContext)
1134                    throws PortalException, SystemException {
1135    
1136                    if (!DLAppHelperThreadLocal.isEnabled()) {
1137                            return;
1138                    }
1139    
1140                    updateAsset(
1141                            userId, fileEntry, destinationFileVersion,
1142                            serviceContext.getAssetCategoryIds(),
1143                            serviceContext.getAssetTagNames(),
1144                            serviceContext.getAssetLinkEntryIds());
1145    
1146                    registerDLProcessorCallback(fileEntry, sourceFileVersion);
1147    
1148                    registerDLSyncEventCallback(
1149                            DLSyncConstants.EVENT_UPDATE, DLSyncConstants.TYPE_FILE,
1150                            fileEntry.getFileEntryId());
1151            }
1152    
1153            @Override
1154            public void updateFolder(
1155                            long userId, Folder folder, ServiceContext serviceContext)
1156                    throws PortalException, SystemException {
1157    
1158                    updateAsset(
1159                            userId, folder, serviceContext.getAssetCategoryIds(),
1160                            serviceContext.getAssetTagNames(),
1161                            serviceContext.getAssetLinkEntryIds());
1162    
1163                    if (!isStagingGroup(folder.getGroupId())) {
1164                            registerDLSyncEventCallback(
1165                                    DLSyncConstants.EVENT_UPDATE, DLSyncConstants.TYPE_FOLDER,
1166                                    folder.getFolderId());
1167                    }
1168            }
1169    
1170            @Override
1171            public void updateStatus(
1172                            long userId, FileEntry fileEntry, FileVersion latestFileVersion,
1173                            int oldStatus, int newStatus,
1174                            Map<String, Serializable> workflowContext,
1175                            ServiceContext serviceContext)
1176                    throws PortalException, SystemException {
1177    
1178                    if (!DLAppHelperThreadLocal.isEnabled()) {
1179                            return;
1180                    }
1181    
1182                    if (newStatus == WorkflowConstants.STATUS_APPROVED) {
1183    
1184                            // Asset
1185    
1186                            String latestFileVersionVersion = latestFileVersion.getVersion();
1187    
1188                            if (latestFileVersionVersion.equals(fileEntry.getVersion())) {
1189                                    if (!latestFileVersionVersion.equals(
1190                                                    DLFileEntryConstants.VERSION_DEFAULT)) {
1191    
1192                                            AssetEntry draftAssetEntry =
1193                                                    assetEntryLocalService.fetchEntry(
1194                                                            DLFileEntryConstants.getClassName(),
1195                                                            latestFileVersion.getPrimaryKey());
1196    
1197                                            if (draftAssetEntry != null) {
1198                                                    long fileEntryTypeId = getFileEntryTypeId(fileEntry);
1199    
1200                                                    long[] assetCategoryIds =
1201                                                            draftAssetEntry.getCategoryIds();
1202                                                    String[] assetTagNames = draftAssetEntry.getTagNames();
1203    
1204                                                    List<AssetLink> assetLinks =
1205                                                            assetLinkLocalService.getDirectLinks(
1206                                                                    draftAssetEntry.getEntryId(),
1207                                                                    AssetLinkConstants.TYPE_RELATED);
1208    
1209                                                    long[] assetLinkEntryIds = StringUtil.split(
1210                                                            ListUtil.toString(
1211                                                                    assetLinks, AssetLink.ENTRY_ID2_ACCESSOR), 0L);
1212    
1213                                                    AssetEntry assetEntry =
1214                                                            assetEntryLocalService.updateEntry(
1215                                                                    userId, fileEntry.getGroupId(),
1216                                                                    fileEntry.getCreateDate(),
1217                                                                    fileEntry.getModifiedDate(),
1218                                                                    DLFileEntryConstants.getClassName(),
1219                                                                    fileEntry.getFileEntryId(), fileEntry.getUuid(),
1220                                                                    fileEntryTypeId, assetCategoryIds,
1221                                                                    assetTagNames, true, null, null, null,
1222                                                                    draftAssetEntry.getMimeType(),
1223                                                                    fileEntry.getTitle(),
1224                                                                    fileEntry.getDescription(), null, null, null, 0,
1225                                                                    0, null, false);
1226    
1227                                                    assetLinkLocalService.updateLinks(
1228                                                            userId, assetEntry.getEntryId(), assetLinkEntryIds,
1229                                                            AssetLinkConstants.TYPE_RELATED);
1230    
1231                                                    assetEntryLocalService.deleteEntry(draftAssetEntry);
1232                                            }
1233                                    }
1234    
1235                                    assetEntryLocalService.updateVisible(
1236                                            DLFileEntryConstants.getClassName(),
1237                                            fileEntry.getFileEntryId(), true);
1238                            }
1239    
1240                            // Sync
1241    
1242                            String event = (String)workflowContext.get("event");
1243    
1244                            if (!isStagingGroup(fileEntry.getGroupId()) &&
1245                                    Validator.isNotNull(event)) {
1246    
1247                                    registerDLSyncEventCallback(
1248                                            event, DLSyncConstants.TYPE_FILE,
1249                                            fileEntry.getFileEntryId());
1250                            }
1251    
1252                            if ((oldStatus != WorkflowConstants.STATUS_IN_TRASH) &&
1253                                    !fileEntry.isInTrashContainer()) {
1254    
1255                                    // Social
1256    
1257                                    Date activityDate = latestFileVersion.getModifiedDate();
1258    
1259                                    int activityType = DLActivityKeys.UPDATE_FILE_ENTRY;
1260    
1261                                    if (event.equals(DLSyncConstants.EVENT_ADD)) {
1262                                            activityDate = latestFileVersion.getCreateDate();
1263    
1264                                            activityType = DLActivityKeys.ADD_FILE_ENTRY;
1265                                    }
1266    
1267                                    JSONObject extraDataJSONObject =
1268                                            JSONFactoryUtil.createJSONObject();
1269    
1270                                    extraDataJSONObject.put("title", fileEntry.getTitle());
1271    
1272                                    socialActivityLocalService.addUniqueActivity(
1273                                            latestFileVersion.getStatusByUserId(),
1274                                            fileEntry.getGroupId(), activityDate,
1275                                            DLFileEntryConstants.getClassName(),
1276                                            fileEntry.getFileEntryId(), activityType,
1277                                            extraDataJSONObject.toString(), 0);
1278    
1279                                    // Subscriptions
1280    
1281                                    notifySubscribers(latestFileVersion, serviceContext);
1282                            }
1283                    }
1284                    else {
1285    
1286                            // Asset
1287    
1288                            boolean visible = false;
1289    
1290                            if (newStatus != WorkflowConstants.STATUS_IN_TRASH) {
1291                                    List<DLFileVersion> approvedFileVersions =
1292                                            dlFileVersionPersistence.findByF_S(
1293                                                    fileEntry.getFileEntryId(),
1294                                                    WorkflowConstants.STATUS_APPROVED);
1295    
1296                                    if (!approvedFileVersions.isEmpty()) {
1297                                            visible = true;
1298                                    }
1299                            }
1300    
1301                            assetEntryLocalService.updateVisible(
1302                                    DLFileEntryConstants.getClassName(), fileEntry.getFileEntryId(),
1303                                    visible);
1304                    }
1305            }
1306    
1307            protected FileEntry doMoveFileEntryFromTrash(
1308                            long userId, FileEntry fileEntry, long newFolderId,
1309                            ServiceContext serviceContext)
1310                    throws PortalException, SystemException {
1311    
1312                    // File entry
1313    
1314                    List<DLFileVersion> dlFileVersions =
1315                            dlFileVersionLocalService.getFileVersions(
1316                                    fileEntry.getFileEntryId(), WorkflowConstants.STATUS_ANY);
1317    
1318                    dlFileVersions = ListUtil.sort(
1319                            dlFileVersions, new FileVersionVersionComparator());
1320    
1321                    if (fileEntry.isInTrash()) {
1322                            restoreFileEntryFromTrash(userId, fileEntry);
1323    
1324                            fileEntry = dlAppLocalService.moveFileEntry(
1325                                    userId, fileEntry.getFileEntryId(), newFolderId,
1326                                    serviceContext);
1327    
1328                            if (DLAppHelperThreadLocal.isEnabled()) {
1329                                    dlFileRankLocalService.enableFileRanks(
1330                                            fileEntry.getFileEntryId());
1331                            }
1332    
1333                            return fileEntry;
1334                    }
1335    
1336                    FileVersion fileVersion = new LiferayFileVersion(dlFileVersions.get(0));
1337    
1338                    dlFileEntryLocalService.updateStatus(
1339                            userId, fileVersion.getFileVersionId(), fileVersion.getStatus(),
1340                            new HashMap<String, Serializable>(), serviceContext);
1341    
1342                    if (DLAppHelperThreadLocal.isEnabled()) {
1343    
1344                            // File rank
1345    
1346                            dlFileRankLocalService.enableFileRanks(fileEntry.getFileEntryId());
1347    
1348                            // File shortcut
1349    
1350                            dlFileShortcutLocalService.enableFileShortcuts(
1351                                    fileEntry.getFileEntryId());
1352                    }
1353    
1354                    // App helper
1355    
1356                    fileEntry = dlAppService.moveFileEntry(
1357                            fileEntry.getFileEntryId(), newFolderId, serviceContext);
1358    
1359                    // Sync
1360    
1361                    registerDLSyncEventCallback(
1362                            DLSyncConstants.EVENT_RESTORE, DLSyncConstants.TYPE_FILE,
1363                            fileEntry.getFileEntryId());
1364    
1365                    // Social
1366    
1367                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1368    
1369                    extraDataJSONObject.put("title", fileEntry.getTitle());
1370    
1371                    socialActivityLocalService.addActivity(
1372                            userId, fileEntry.getGroupId(), DLFileEntryConstants.getClassName(),
1373                            fileEntry.getFileEntryId(),
1374                            SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
1375                            extraDataJSONObject.toString(), 0);
1376    
1377                    return fileEntry;
1378            }
1379    
1380            protected FileEntry doMoveFileEntryToTrash(long userId, FileEntry fileEntry)
1381                    throws PortalException, SystemException {
1382    
1383                    // File versions
1384    
1385                    List<DLFileVersion> dlFileVersions =
1386                            dlFileVersionLocalService.getFileVersions(
1387                                    fileEntry.getFileEntryId(), WorkflowConstants.STATUS_ANY);
1388    
1389                    dlFileVersions = ListUtil.sort(
1390                            dlFileVersions, new FileVersionVersionComparator());
1391    
1392                    FileVersion fileVersion = new LiferayFileVersion(dlFileVersions.get(0));
1393    
1394                    Map<String, Serializable> workflowContext =
1395                            new HashMap<String, Serializable>();
1396    
1397                    workflowContext.put("dlFileVersions", (Serializable)dlFileVersions);
1398    
1399                    int oldStatus = fileVersion.getStatus();
1400    
1401                    dlFileEntryLocalService.updateStatus(
1402                            userId, fileVersion.getFileVersionId(),
1403                            WorkflowConstants.STATUS_IN_TRASH, workflowContext,
1404                            new ServiceContext());
1405    
1406                    // File entry
1407    
1408                    DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
1409    
1410                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
1411                            DLFileEntryConstants.getClassName(), dlFileEntry.getFileEntryId());
1412    
1413                    String trashTitle = TrashUtil.getTrashTitle(trashEntry.getEntryId());
1414    
1415                    dlFileEntry.setTitle(trashTitle);
1416    
1417                    dlFileEntryPersistence.update(dlFileEntry);
1418    
1419                    if (!DLAppHelperThreadLocal.isEnabled()) {
1420                            return fileEntry;
1421                    }
1422    
1423                    // File shortcut
1424    
1425                    dlFileShortcutLocalService.disableFileShortcuts(
1426                            fileEntry.getFileEntryId());
1427    
1428                    // File rank
1429    
1430                    dlFileRankLocalService.disableFileRanks(fileEntry.getFileEntryId());
1431    
1432                    // Sync
1433    
1434                    registerDLSyncEventCallback(
1435                            DLSyncConstants.EVENT_DELETE, DLSyncConstants.TYPE_FILE,
1436                            fileEntry.getFileEntryId());
1437    
1438                    // Social
1439    
1440                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1441    
1442                    extraDataJSONObject.put(
1443                            "title", TrashUtil.getOriginalTitle(fileEntry.getTitle()));
1444    
1445                    socialActivityLocalService.addActivity(
1446                            userId, fileEntry.getGroupId(), DLFileEntryConstants.getClassName(),
1447                            fileEntry.getFileEntryId(),
1448                            SocialActivityConstants.TYPE_MOVE_TO_TRASH,
1449                            extraDataJSONObject.toString(), 0);
1450    
1451                    // Workflow
1452    
1453                    if (oldStatus == WorkflowConstants.STATUS_PENDING) {
1454                            workflowInstanceLinkLocalService.deleteWorkflowInstanceLink(
1455                                    fileVersion.getCompanyId(), fileVersion.getGroupId(),
1456                                    DLFileEntryConstants.getClassName(),
1457                                    fileVersion.getFileVersionId());
1458                    }
1459    
1460                    return fileEntry;
1461            }
1462    
1463            protected Folder doMoveFolderFromTrash(
1464                            long userId, Folder folder, long parentFolderId,
1465                            ServiceContext serviceContext)
1466                    throws PortalException, SystemException {
1467    
1468                    DLFolder dlFolder = (DLFolder)folder.getModel();
1469    
1470                    if (dlFolder.isInTrash()) {
1471                            restoreFolderFromTrash(userId, folder);
1472                    }
1473                    else {
1474    
1475                            // Folder
1476    
1477                            dlFolderLocalService.updateStatus(
1478                                    userId, folder.getFolderId(), WorkflowConstants.STATUS_APPROVED,
1479                                    new HashMap<String, Serializable>(), new ServiceContext());
1480    
1481                            // File rank
1482    
1483                            dlFileRankLocalService.enableFileRanksByFolderId(
1484                                    folder.getFolderId());
1485    
1486                            // Sync
1487    
1488                            registerDLSyncEventCallback(
1489                                    DLSyncConstants.EVENT_RESTORE, DLSyncConstants.TYPE_FOLDER,
1490                                    folder.getFolderId());
1491    
1492                            // Social
1493    
1494                            JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1495    
1496                            extraDataJSONObject.put("title", folder.getName());
1497    
1498                            socialActivityLocalService.addActivity(
1499                                    userId, folder.getGroupId(), DLFolderConstants.class.getName(),
1500                                    folder.getFolderId(),
1501                                    SocialActivityConstants.TYPE_RESTORE_FROM_TRASH,
1502                                    extraDataJSONObject.toString(), 0);
1503                    }
1504    
1505                    return dlAppLocalService.moveFolder(
1506                            userId, folder.getFolderId(), parentFolderId, serviceContext);
1507            }
1508    
1509            protected Folder doMoveFolderToTrash(long userId, Folder folder)
1510                    throws PortalException, SystemException {
1511    
1512                    // Folder
1513    
1514                    DLFolder dlFolder = dlFolderLocalService.updateStatus(
1515                            userId, folder.getFolderId(), WorkflowConstants.STATUS_IN_TRASH,
1516                            new HashMap<String, Serializable>(), new ServiceContext());
1517    
1518                    TrashEntry trashEntry = trashEntryLocalService.getEntry(
1519                            DLFolderConstants.getClassName(), dlFolder.getFolderId());
1520    
1521                    String trashTitle = TrashUtil.getTrashTitle(trashEntry.getEntryId());
1522    
1523                    dlFolder.setName(trashTitle);
1524    
1525                    dlFolderPersistence.update(dlFolder);
1526    
1527                    // File rank
1528    
1529                    dlFileRankLocalService.disableFileRanksByFolderId(folder.getFolderId());
1530    
1531                    // Sync
1532    
1533                    registerDLSyncEventCallback(
1534                            DLSyncConstants.EVENT_DELETE, DLSyncConstants.TYPE_FOLDER,
1535                            folder.getFolderId());
1536    
1537                    // Social
1538    
1539                    JSONObject extraDataJSONObject = JSONFactoryUtil.createJSONObject();
1540    
1541                    extraDataJSONObject.put("title", folder.getName());
1542    
1543                    socialActivityLocalService.addActivity(
1544                            userId, folder.getGroupId(), DLFolderConstants.getClassName(),
1545                            folder.getFolderId(), SocialActivityConstants.TYPE_MOVE_TO_TRASH,
1546                            extraDataJSONObject.toString(), 0);
1547    
1548                    return new LiferayFolder(dlFolder);
1549            }
1550    
1551            protected long getFileEntryTypeId(FileEntry fileEntry) {
1552                    if (fileEntry instanceof LiferayFileEntry) {
1553                            DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
1554    
1555                            return dlFileEntry.getFileEntryTypeId();
1556                    }
1557                    else {
1558                            return 0;
1559                    }
1560            }
1561    
1562            protected boolean isStagingGroup(long groupId) {
1563                    try {
1564                            Group group = groupLocalService.getGroup(groupId);
1565    
1566                            return group.isStagingGroup();
1567                    }
1568                    catch (Exception e) {
1569                            return false;
1570                    }
1571            }
1572    
1573            protected boolean isUpdateSync(FileEntry fileEntry)
1574                    throws PortalException, SystemException {
1575    
1576                    if (isStagingGroup(fileEntry.getGroupId())) {
1577                            return false;
1578                    }
1579    
1580                    FileVersion fileVersion = fileEntry.getFileVersion();
1581    
1582                    if (!fileVersion.isApproved()) {
1583                            return false;
1584                    }
1585    
1586                    return true;
1587            }
1588    
1589            protected void notifySubscribers(
1590                            FileVersion fileVersion, ServiceContext serviceContext)
1591                    throws PortalException, SystemException {
1592    
1593                    if (!fileVersion.isApproved()) {
1594                            return;
1595                    }
1596    
1597                    PortletPreferences preferences =
1598                            ServiceContextUtil.getPortletPreferences(serviceContext);
1599    
1600                    if (preferences == null) {
1601                            long ownerId = fileVersion.getGroupId();
1602                            int ownerType = PortletKeys.PREFS_OWNER_TYPE_GROUP;
1603                            long plid = PortletKeys.PREFS_PLID_SHARED;
1604                            String portletId = PortletKeys.DOCUMENT_LIBRARY;
1605                            String defaultPreferences = null;
1606    
1607                            preferences = portletPreferencesLocalService.getPreferences(
1608                                    fileVersion.getCompanyId(), ownerId, ownerType, plid, portletId,
1609                                    defaultPreferences);
1610                    }
1611    
1612                    if (serviceContext.isCommandAdd() &&
1613                            DLUtil.getEmailFileEntryAddedEnabled(preferences)) {
1614                    }
1615                    else if (serviceContext.isCommandUpdate() &&
1616                                     DLUtil.getEmailFileEntryUpdatedEnabled(preferences)) {
1617                    }
1618                    else {
1619                            return;
1620                    }
1621    
1622                    String fromName = DLUtil.getEmailFromName(
1623                            preferences, fileVersion.getCompanyId());
1624                    String fromAddress = DLUtil.getEmailFromAddress(
1625                            preferences, fileVersion.getCompanyId());
1626    
1627                    Map<Locale, String> localizedSubjectMap = null;
1628                    Map<Locale, String> localizedBodyMap = null;
1629    
1630                    if (serviceContext.isCommandUpdate()) {
1631                            localizedSubjectMap = DLUtil.getEmailFileEntryUpdatedSubjectMap(
1632                                    preferences);
1633                            localizedBodyMap = DLUtil.getEmailFileEntryUpdatedBodyMap(
1634                                    preferences);
1635                    }
1636                    else {
1637                            localizedSubjectMap = DLUtil.getEmailFileEntryAddedSubjectMap(
1638                                    preferences);
1639                            localizedBodyMap = DLUtil.getEmailFileEntryAddedBodyMap(
1640                                    preferences);
1641                    }
1642    
1643                    FileEntry fileEntry = fileVersion.getFileEntry();
1644    
1645                    Folder folder = null;
1646    
1647                    long folderId = fileEntry.getFolderId();
1648    
1649                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1650                            folder = dlAppLocalService.getFolder(folderId);
1651                    }
1652    
1653                    String folderName = LanguageUtil.get(
1654                            serviceContext.getLocale(), "home");
1655    
1656                    if (folder != null) {
1657                            folderName = folder.getName();
1658                    }
1659    
1660                    SubscriptionSender subscriptionSender = new SubscriptionSender();
1661    
1662                    DLFileEntry dlFileEntry = (DLFileEntry)fileEntry.getModel();
1663    
1664                    DLFileEntryType dlFileEntryType =
1665                            dlFileEntryTypeLocalService.getDLFileEntryType(
1666                                    dlFileEntry.getFileEntryTypeId());
1667    
1668                    subscriptionSender.setCompanyId(fileVersion.getCompanyId());
1669                    subscriptionSender.setContextAttributes(
1670                            "[$DOCUMENT_STATUS_BY_USER_NAME$]",
1671                            fileVersion.getStatusByUserName(), "[$DOCUMENT_TITLE$]",
1672                            fileVersion.getTitle(), "[$DOCUMENT_TYPE$]",
1673                            dlFileEntryType.getName(serviceContext.getLocale()),
1674                            "[$FOLDER_NAME$]", folderName);
1675                    subscriptionSender.setContextUserPrefix("DOCUMENT");
1676                    subscriptionSender.setFrom(fromAddress, fromName);
1677                    subscriptionSender.setHtmlFormat(true);
1678                    subscriptionSender.setLocalizedBodyMap(localizedBodyMap);
1679                    subscriptionSender.setLocalizedSubjectMap(localizedSubjectMap);
1680                    subscriptionSender.setMailId(
1681                            "file_entry", fileVersion.getFileEntryId());
1682                    subscriptionSender.setPortletId(PortletKeys.DOCUMENT_LIBRARY);
1683                    subscriptionSender.setReplyToAddress(fromAddress);
1684                    subscriptionSender.setScopeGroupId(fileVersion.getGroupId());
1685                    subscriptionSender.setServiceContext(serviceContext);
1686                    subscriptionSender.setUserId(fileVersion.getUserId());
1687    
1688                    subscriptionSender.addPersistedSubscribers(
1689                            Folder.class.getName(), fileVersion.getGroupId());
1690    
1691                    List<Long> folderIds = new ArrayList<Long>();
1692    
1693                    if (folder != null) {
1694                            folderIds.add(folder.getFolderId());
1695    
1696                            folderIds.addAll(folder.getAncestorFolderIds());
1697                    }
1698    
1699                    for (long curFolderId : folderIds) {
1700                            subscriptionSender.addPersistedSubscribers(
1701                                    Folder.class.getName(), curFolderId);
1702                    }
1703    
1704                    if (dlFileEntryType.getFileEntryTypeId() ==
1705                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT) {
1706    
1707                            subscriptionSender.addPersistedSubscribers(
1708                                    DLFileEntryType.class.getName(), fileVersion.getGroupId());
1709                    }
1710                    else {
1711                            subscriptionSender.addPersistedSubscribers(
1712                                    DLFileEntryType.class.getName(),
1713                                    dlFileEntryType.getFileEntryTypeId());
1714                    }
1715    
1716                    subscriptionSender.addPersistedSubscribers(
1717                            DLFileEntry.class.getName(), fileEntry.getFileEntryId());
1718    
1719                    subscriptionSender.flushNotificationsAsync();
1720            }
1721    
1722            protected void registerDLProcessorCallback(
1723                    final FileEntry fileEntry, final FileVersion fileVersion) {
1724    
1725                    TransactionCommitCallbackRegistryUtil.registerCallback(
1726                            new Callable<Void>() {
1727    
1728                                    @Override
1729                                    public Void call() throws Exception {
1730                                            DLProcessorRegistryUtil.trigger(
1731                                                    fileEntry, fileVersion, true);
1732    
1733                                            return null;
1734                                    }
1735    
1736                            });
1737            }
1738    
1739    }