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