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.ExpiredLockException;
018    import com.liferay.portal.InvalidLockException;
019    import com.liferay.portal.NoSuchLockException;
020    import com.liferay.portal.NoSuchWorkflowDefinitionLinkException;
021    import com.liferay.portal.kernel.dao.orm.QueryDefinition;
022    import com.liferay.portal.kernel.exception.PortalException;
023    import com.liferay.portal.kernel.exception.SystemException;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.search.Indexable;
027    import com.liferay.portal.kernel.search.IndexableType;
028    import com.liferay.portal.kernel.search.Indexer;
029    import com.liferay.portal.kernel.search.IndexerRegistryUtil;
030    import com.liferay.portal.kernel.systemevent.SystemEvent;
031    import com.liferay.portal.kernel.util.ObjectValuePair;
032    import com.liferay.portal.kernel.util.OrderByComparator;
033    import com.liferay.portal.kernel.util.ParamUtil;
034    import com.liferay.portal.kernel.util.StringPool;
035    import com.liferay.portal.kernel.util.UnicodeProperties;
036    import com.liferay.portal.kernel.util.Validator;
037    import com.liferay.portal.kernel.workflow.WorkflowConstants;
038    import com.liferay.portal.model.Group;
039    import com.liferay.portal.model.Lock;
040    import com.liferay.portal.model.ResourceConstants;
041    import com.liferay.portal.model.SystemEventConstants;
042    import com.liferay.portal.model.User;
043    import com.liferay.portal.model.WorkflowDefinitionLink;
044    import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
045    import com.liferay.portal.service.ServiceContext;
046    import com.liferay.portlet.asset.util.AssetUtil;
047    import com.liferay.portlet.documentlibrary.DuplicateFileException;
048    import com.liferay.portlet.documentlibrary.DuplicateFolderNameException;
049    import com.liferay.portlet.documentlibrary.FolderNameException;
050    import com.liferay.portlet.documentlibrary.NoSuchDirectoryException;
051    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
052    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
053    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
054    import com.liferay.portlet.documentlibrary.model.DLFolder;
055    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
056    import com.liferay.portlet.documentlibrary.model.impl.DLFolderImpl;
057    import com.liferay.portlet.documentlibrary.service.base.DLFolderLocalServiceBaseImpl;
058    import com.liferay.portlet.documentlibrary.store.DLStoreUtil;
059    
060    import java.io.Serializable;
061    
062    import java.util.ArrayList;
063    import java.util.Collections;
064    import java.util.Date;
065    import java.util.List;
066    import java.util.Map;
067    
068    /**
069     * @author Brian Wing Shun Chan
070     * @author Alexander Chow
071     */
072    public class DLFolderLocalServiceImpl extends DLFolderLocalServiceBaseImpl {
073    
074            @Override
075            public DLFolder addFolder(
076                            long userId, long groupId, long repositoryId, boolean mountPoint,
077                            long parentFolderId, String name, String description,
078                            boolean hidden, ServiceContext serviceContext)
079                    throws PortalException, SystemException {
080    
081                    // Folder
082    
083                    User user = userPersistence.findByPrimaryKey(userId);
084                    parentFolderId = getParentFolderId(groupId, parentFolderId);
085                    Date now = new Date();
086    
087                    validateFolder(groupId, parentFolderId, name);
088    
089                    long folderId = counterLocalService.increment();
090    
091                    DLFolder dlFolder = dlFolderPersistence.create(folderId);
092    
093                    dlFolder.setUuid(serviceContext.getUuid());
094                    dlFolder.setGroupId(groupId);
095                    dlFolder.setCompanyId(user.getCompanyId());
096                    dlFolder.setUserId(user.getUserId());
097                    dlFolder.setUserName(user.getFullName());
098                    dlFolder.setCreateDate(serviceContext.getCreateDate(now));
099                    dlFolder.setModifiedDate(serviceContext.getModifiedDate(now));
100                    dlFolder.setRepositoryId(repositoryId);
101                    dlFolder.setMountPoint(mountPoint);
102                    dlFolder.setParentFolderId(parentFolderId);
103                    dlFolder.setTreePath(dlFolder.buildTreePath());
104                    dlFolder.setName(name);
105                    dlFolder.setDescription(description);
106                    dlFolder.setLastPostDate(now);
107                    dlFolder.setHidden(hidden);
108                    dlFolder.setOverrideFileEntryTypes(false);
109                    dlFolder.setExpandoBridgeAttributes(serviceContext);
110    
111                    dlFolderPersistence.update(dlFolder);
112    
113                    // Resources
114    
115                    if (serviceContext.isAddGroupPermissions() ||
116                            serviceContext.isAddGuestPermissions()) {
117    
118                            addFolderResources(
119                                    dlFolder, serviceContext.isAddGroupPermissions(),
120                                    serviceContext.isAddGuestPermissions());
121                    }
122                    else {
123                            if (serviceContext.isDeriveDefaultPermissions()) {
124                                    serviceContext.deriveDefaultPermissions(
125                                            repositoryId, DLFolderConstants.getClassName());
126                            }
127    
128                            addFolderResources(
129                                    dlFolder, serviceContext.getGroupPermissions(),
130                                    serviceContext.getGuestPermissions());
131                    }
132    
133                    // Parent folder
134    
135                    if (parentFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
136                            DLFolder parentDLFolder = dlFolderPersistence.findByPrimaryKey(
137                                    parentFolderId);
138    
139                            parentDLFolder.setLastPostDate(now);
140    
141                            dlFolderPersistence.update(parentDLFolder);
142                    }
143    
144                    // App helper
145    
146                    dlAppHelperLocalService.addFolder(
147                            userId, new LiferayFolder(dlFolder), serviceContext);
148    
149                    return dlFolder;
150            }
151    
152            /**
153             * @deprecated As of 6.2.0, replaced by more general {@link #addFolder(long,
154             *             long, long, boolean, long, String, String, boolean,
155             *             ServiceContext)}
156             */
157            @Override
158            public DLFolder addFolder(
159                            long userId, long groupId, long repositoryId, boolean mountPoint,
160                            long parentFolderId, String name, String description,
161                            ServiceContext serviceContext)
162                    throws PortalException, SystemException {
163    
164                    return addFolder(
165                            userId, groupId, repositoryId, mountPoint, parentFolderId, name,
166                            description, false, serviceContext);
167            }
168    
169            @Override
170            public void deleteAll(long groupId)
171                    throws PortalException, SystemException {
172    
173                    Group group = groupLocalService.getGroup(groupId);
174    
175                    List<DLFolder> dlFolders = dlFolderPersistence.findByGroupId(groupId);
176    
177                    for (DLFolder dlFolder : dlFolders) {
178                            dlFolderLocalService.deleteFolder(dlFolder);
179                    }
180    
181                    dlFileEntryLocalService.deleteFileEntries(
182                            groupId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID);
183    
184                    dlFileEntryTypeLocalService.deleteFileEntryTypes(groupId);
185    
186                    dlFileShortcutLocalService.deleteFileShortcuts(
187                            groupId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID);
188    
189                    try {
190                            DLStoreUtil.deleteDirectory(
191                                    group.getCompanyId(), groupId, StringPool.BLANK);
192                    }
193                    catch (NoSuchDirectoryException nsde) {
194                            if (_log.isDebugEnabled()) {
195                                    _log.debug(nsde.getMessage());
196                            }
197                    }
198            }
199    
200            @Indexable(type = IndexableType.DELETE)
201            @Override
202            @SystemEvent(
203                    action = SystemEventConstants.ACTION_SKIP,
204                    type = SystemEventConstants.TYPE_DELETE)
205            public DLFolder deleteFolder(DLFolder dlFolder)
206                    throws PortalException, SystemException {
207    
208                    return deleteFolder(dlFolder, true);
209            }
210    
211            @Indexable(type = IndexableType.DELETE)
212            @Override
213            @SystemEvent(
214                    action = SystemEventConstants.ACTION_SKIP,
215                    type = SystemEventConstants.TYPE_DELETE)
216            public DLFolder deleteFolder(
217                            DLFolder dlFolder, boolean includeTrashedEntries)
218                    throws PortalException, SystemException {
219    
220                    // Folders
221    
222                    List<DLFolder> dlFolders = dlFolderPersistence.findByG_P(
223                            dlFolder.getGroupId(), dlFolder.getFolderId());
224    
225                    for (DLFolder curDLFolder : dlFolders) {
226                            if (includeTrashedEntries || !curDLFolder.isInTrash()) {
227                                    dlFolderLocalService.deleteFolder(
228                                            curDLFolder, includeTrashedEntries);
229                            }
230                    }
231    
232                    // Resources
233    
234                    resourceLocalService.deleteResource(
235                            dlFolder.getCompanyId(), DLFolder.class.getName(),
236                            ResourceConstants.SCOPE_INDIVIDUAL, dlFolder.getFolderId());
237    
238                    // WebDAVProps
239    
240                    webDAVPropsLocalService.deleteWebDAVProps(
241                            DLFolder.class.getName(), dlFolder.getFolderId());
242    
243                    // File entries
244    
245                    dlFileEntryLocalService.deleteFileEntries(
246                            dlFolder.getGroupId(), dlFolder.getFolderId(),
247                            includeTrashedEntries);
248    
249                    // File entry types
250    
251                    List<Long> fileEntryTypeIds = new ArrayList<Long>();
252    
253                    for (DLFileEntryType dlFileEntryType :
254                                    dlFileEntryTypeLocalService.getDLFolderDLFileEntryTypes(
255                                            dlFolder.getFolderId())) {
256    
257                            fileEntryTypeIds.add(dlFileEntryType.getFileEntryTypeId());
258                    }
259    
260                    if (fileEntryTypeIds.isEmpty()) {
261                            fileEntryTypeIds.add(
262                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_ALL);
263                    }
264    
265                    dlFileEntryTypeLocalService.unsetFolderFileEntryTypes(
266                            dlFolder.getFolderId());
267    
268                    // File shortcuts
269    
270                    dlFileShortcutLocalService.deleteFileShortcuts(
271                            dlFolder.getGroupId(), dlFolder.getFolderId(),
272                            includeTrashedEntries);
273    
274                    // Expando
275    
276                    expandoRowLocalService.deleteRows(dlFolder.getFolderId());
277    
278                    // App helper
279    
280                    dlAppHelperLocalService.deleteFolder(new LiferayFolder(dlFolder));
281    
282                    // Folder
283    
284                    dlFolderPersistence.remove(dlFolder);
285    
286                    // Directory
287    
288                    try {
289                            if (includeTrashedEntries) {
290                                    DLStoreUtil.deleteDirectory(
291                                            dlFolder.getCompanyId(), dlFolder.getFolderId(),
292                                            StringPool.BLANK);
293                            }
294                    }
295                    catch (NoSuchDirectoryException nsde) {
296                            if (_log.isDebugEnabled()) {
297                                    _log.debug(nsde.getMessage());
298                            }
299                    }
300    
301                    // Workflow
302    
303                    for (long fileEntryTypeId : fileEntryTypeIds) {
304                            WorkflowDefinitionLink workflowDefinitionLink = null;
305    
306                            try {
307                                    workflowDefinitionLink =
308                                            workflowDefinitionLinkLocalService.
309                                                    getWorkflowDefinitionLink(
310                                                            dlFolder.getCompanyId(), dlFolder.getGroupId(),
311                                                            DLFolder.class.getName(), dlFolder.getFolderId(),
312                                                            fileEntryTypeId);
313                            }
314                            catch (NoSuchWorkflowDefinitionLinkException nswdle) {
315                                    continue;
316                            }
317    
318                            workflowDefinitionLinkLocalService.deleteWorkflowDefinitionLink(
319                                    workflowDefinitionLink);
320                    }
321    
322                    return dlFolder;
323            }
324    
325            @Indexable(type = IndexableType.DELETE)
326            @Override
327            public DLFolder deleteFolder(long folderId)
328                    throws PortalException, SystemException {
329    
330                    return dlFolderLocalService.deleteFolder(folderId, true);
331            }
332    
333            @Indexable(type = IndexableType.DELETE)
334            @Override
335            public DLFolder deleteFolder(long folderId, boolean includeTrashedEntries)
336                    throws PortalException, SystemException {
337    
338                    DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
339    
340                    return dlFolderLocalService.deleteFolder(
341                            dlFolder, includeTrashedEntries);
342            }
343    
344            @Indexable(type = IndexableType.DELETE)
345            @Override
346            public DLFolder deleteFolder(
347                            long userId, long folderId, boolean includeTrashedEntries)
348                    throws PortalException, SystemException {
349    
350                    boolean hasLock = hasFolderLock(userId, folderId);
351    
352                    Lock lock = null;
353    
354                    if (!hasLock) {
355    
356                            // Lock
357    
358                            lock = lockFolder(
359                                    userId, folderId, null, false,
360                                    DLFolderImpl.LOCK_EXPIRATION_TIME);
361                    }
362    
363                    try {
364                            return deleteFolder(folderId, includeTrashedEntries);
365                    }
366                    finally {
367                            if (!hasLock) {
368    
369                                    // Unlock
370    
371                                    unlockFolder(folderId, lock.getUuid());
372                            }
373                    }
374            }
375    
376            @Override
377            public DLFolder fetchFolder(long folderId) throws SystemException {
378                    return dlFolderPersistence.fetchByPrimaryKey(folderId);
379            }
380    
381            @Override
382            public DLFolder fetchFolder(long groupId, long parentFolderId, String name)
383                    throws SystemException {
384    
385                    return dlFolderPersistence.fetchByG_P_N(groupId, parentFolderId, name);
386            }
387    
388            @Override
389            public List<DLFolder> getCompanyFolders(long companyId, int start, int end)
390                    throws SystemException {
391    
392                    return dlFolderPersistence.findByCompanyId(companyId, start, end);
393            }
394    
395            @Override
396            public int getCompanyFoldersCount(long companyId) throws SystemException {
397                    return dlFolderPersistence.countByCompanyId(companyId);
398            }
399    
400            /**
401             * @deprecated As of 6.2.0, replaced by {@link
402             *             #getFileEntriesAndFileShortcuts(long, long, QueryDefinition)}
403             */
404            @Override
405            public List<Object> getFileEntriesAndFileShortcuts(
406                            long groupId, long folderId, int status, int start, int end)
407                    throws SystemException {
408    
409                    QueryDefinition queryDefinition = new QueryDefinition(
410                            status, start, end, null);
411    
412                    return getFileEntriesAndFileShortcuts(
413                            groupId, folderId, queryDefinition);
414            }
415    
416            @Override
417            public List<Object> getFileEntriesAndFileShortcuts(
418                            long groupId, long folderId, QueryDefinition queryDefinition)
419                    throws SystemException {
420    
421                    return dlFolderFinder.findFE_FS_ByG_F(
422                            groupId, folderId, queryDefinition);
423            }
424    
425            /**
426             * @deprecated As of 6.2.0, replaced by {@link
427             *             #getFileEntriesAndFileShortcutsCount(long, long,
428             *             QueryDefinition)}
429             */
430            @Override
431            public int getFileEntriesAndFileShortcutsCount(
432                            long groupId, long folderId, int status)
433                    throws SystemException {
434    
435                    QueryDefinition queryDefinition = new QueryDefinition(status);
436    
437                    return getFileEntriesAndFileShortcutsCount(
438                            groupId, folderId, queryDefinition);
439            }
440    
441            @Override
442            public int getFileEntriesAndFileShortcutsCount(
443                            long groupId, long folderId, QueryDefinition queryDefinition)
444                    throws SystemException {
445    
446                    return dlFolderFinder.countFE_FS_ByG_F(
447                            groupId, folderId, queryDefinition);
448            }
449    
450            @Override
451            public DLFolder getFolder(long folderId)
452                    throws PortalException, SystemException {
453    
454                    return dlFolderPersistence.findByPrimaryKey(folderId);
455            }
456    
457            @Override
458            public DLFolder getFolder(long groupId, long parentFolderId, String name)
459                    throws PortalException, SystemException {
460    
461                    return dlFolderPersistence.findByG_P_N(groupId, parentFolderId, name);
462            }
463    
464            @Override
465            public long getFolderId(long companyId, long folderId)
466                    throws SystemException {
467    
468                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
469    
470                            // Ensure folder exists and belongs to the proper company
471    
472                            DLFolder dlFolder = dlFolderPersistence.fetchByPrimaryKey(folderId);
473    
474                            if ((dlFolder == null) || (companyId != dlFolder.getCompanyId())) {
475                                    folderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
476                            }
477                    }
478    
479                    return folderId;
480            }
481    
482            @Override
483            public List<DLFolder> getFolders(long groupId, long parentFolderId)
484                    throws SystemException {
485    
486                    return getFolders(groupId, parentFolderId, true);
487            }
488    
489            @Override
490            public List<DLFolder> getFolders(
491                            long groupId, long parentFolderId, boolean includeMountfolders)
492                    throws SystemException {
493    
494                    if (includeMountfolders) {
495                            return dlFolderPersistence.findByG_P(groupId, parentFolderId);
496                    }
497                    else {
498                            return dlFolderPersistence.findByG_M_P_H(
499                                    groupId, false, parentFolderId, false);
500                    }
501            }
502    
503            @Override
504            public List<DLFolder> getFolders(
505                            long groupId, long parentFolderId, boolean includeMountfolders,
506                            int start, int end, OrderByComparator obc)
507                    throws SystemException {
508    
509                    if (includeMountfolders) {
510                            return dlFolderPersistence.findByG_P(
511                                    groupId, parentFolderId, start, end, obc);
512                    }
513                    else {
514                            return dlFolderPersistence.findByG_M_P_H(
515                                    groupId, false, parentFolderId, false, start, end, obc);
516                    }
517            }
518    
519            @Override
520            public List<DLFolder> getFolders(
521                            long groupId, long parentFolderId, int start, int end,
522                            OrderByComparator obc)
523                    throws SystemException {
524    
525                    return getFolders(groupId, parentFolderId, true, start, end, obc);
526            }
527    
528            /**
529             * @deprecated As of 6.2.0, replaced by {@link
530             *             #getFoldersAndFileEntriesAndFileShortcuts(long, long,
531             *             String[], boolean, QueryDefinition)}
532             */
533            @Override
534            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
535                            long groupId, long folderId, int status,
536                            boolean includeMountFolders, int start, int end,
537                            OrderByComparator obc)
538                    throws SystemException {
539    
540                    QueryDefinition queryDefinition = new QueryDefinition(
541                            status, start, end, obc);
542    
543                    return getFoldersAndFileEntriesAndFileShortcuts(
544                            groupId, folderId, null, includeMountFolders, queryDefinition);
545            }
546    
547            /**
548             * @deprecated As of 6.2.0, replaced by {@link
549             *             #getFoldersAndFileEntriesAndFileShortcutsCount(long, long,
550             *             String[], boolean, QueryDefinition)}
551             */
552            @Override
553            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
554                            long groupId, long folderId, int status, String[] mimeTypes,
555                            boolean includeMountFolders, int start, int end,
556                            OrderByComparator obc)
557                    throws SystemException {
558    
559                    QueryDefinition queryDefinition = new QueryDefinition(
560                            status, start, end, obc);
561    
562                    return getFoldersAndFileEntriesAndFileShortcuts(
563                            groupId, folderId, mimeTypes, includeMountFolders, queryDefinition);
564            }
565    
566            @Override
567            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
568                            long groupId, long folderId, String[] mimeTypes,
569                            boolean includeMountFolders, QueryDefinition queryDefinition)
570                    throws SystemException {
571    
572                    return dlFolderFinder.findF_FE_FS_ByG_F_M_M(
573                            groupId, folderId, mimeTypes, includeMountFolders, queryDefinition);
574            }
575    
576            /**
577             * @deprecated As of 6.2.0, replaced by {@link
578             *             #getFoldersAndFileEntriesAndFileShortcutsCount(long, long,
579             *             String[], boolean, QueryDefinition)}
580             */
581            @Override
582            public int getFoldersAndFileEntriesAndFileShortcutsCount(
583                            long groupId, long folderId, int status,
584                            boolean includeMountFolders)
585                    throws SystemException {
586    
587                    QueryDefinition queryDefinition = new QueryDefinition(status);
588    
589                    return getFoldersAndFileEntriesAndFileShortcutsCount(
590                            groupId, folderId, null, includeMountFolders, queryDefinition);
591            }
592    
593            /**
594             * @deprecated As of 6.2.0, replaced by {@link
595             *             #getFoldersAndFileEntriesAndFileShortcutsCount(long, long,
596             *             String[], boolean, QueryDefinition)}
597             */
598            @Override
599            public int getFoldersAndFileEntriesAndFileShortcutsCount(
600                            long groupId, long folderId, int status, String[] mimeTypes,
601                            boolean includeMountFolders)
602                    throws SystemException {
603    
604                    QueryDefinition queryDefinition = new QueryDefinition(status);
605    
606                    return getFoldersAndFileEntriesAndFileShortcutsCount(
607                            groupId, folderId, mimeTypes, includeMountFolders, queryDefinition);
608            }
609    
610            @Override
611            public int getFoldersAndFileEntriesAndFileShortcutsCount(
612                            long groupId, long folderId, String[] mimeTypes,
613                            boolean includeMountFolders, QueryDefinition queryDefinition)
614                    throws SystemException {
615    
616                    return dlFolderFinder.countF_FE_FS_ByG_F_M_M(
617                            groupId, folderId, mimeTypes, includeMountFolders, queryDefinition);
618            }
619    
620            @Override
621            public int getFoldersCount(long groupId, long parentFolderId)
622                    throws SystemException {
623    
624                    return getFoldersCount(groupId, parentFolderId, true);
625            }
626    
627            @Override
628            public int getFoldersCount(
629                            long groupId, long parentFolderId, boolean includeMountfolders)
630                    throws SystemException {
631    
632                    if (includeMountfolders) {
633                            return dlFolderPersistence.countByG_P(groupId, parentFolderId);
634                    }
635                    else {
636                            return dlFolderPersistence.countByG_M_P_H(
637                                    groupId, false, parentFolderId, false);
638                    }
639            }
640    
641            @Override
642            public DLFolder getMountFolder(long repositoryId)
643                    throws PortalException, SystemException {
644    
645                    return dlFolderPersistence.findByRepositoryId(repositoryId);
646            }
647    
648            @Override
649            public List<DLFolder> getMountFolders(
650                            long groupId, long parentFolderId, int start, int end,
651                            OrderByComparator obc)
652                    throws SystemException {
653    
654                    return dlFolderPersistence.findByG_M_P_H(
655                            groupId, true, parentFolderId, false, start, end, obc);
656            }
657    
658            @Override
659            public int getMountFoldersCount(long groupId, long parentFolderId)
660                    throws SystemException {
661    
662                    return dlFolderPersistence.countByG_M_P_H(
663                            groupId, true, parentFolderId, false);
664            }
665    
666            @Override
667            public List<DLFolder> getNoAssetFolders() throws SystemException {
668                    return dlFolderFinder.findF_ByNoAssets();
669            }
670    
671            @Override
672            public void getSubfolderIds(
673                            List<Long> folderIds, long groupId, long folderId)
674                    throws SystemException {
675    
676                    List<DLFolder> dlFolders = dlFolderPersistence.findByG_P(
677                            groupId, folderId);
678    
679                    for (DLFolder dlFolder : dlFolders) {
680                            folderIds.add(dlFolder.getFolderId());
681    
682                            getSubfolderIds(
683                                    folderIds, dlFolder.getGroupId(), dlFolder.getFolderId());
684                    }
685            }
686    
687            @Override
688            public boolean hasFolderLock(long userId, long folderId)
689                    throws SystemException {
690    
691                    return lockLocalService.hasLock(
692                            userId, DLFolder.class.getName(), folderId);
693            }
694    
695            @Override
696            public Lock lockFolder(long userId, long folderId)
697                    throws PortalException, SystemException {
698    
699                    return lockFolder(
700                            userId, folderId, null, false, DLFolderImpl.LOCK_EXPIRATION_TIME);
701            }
702    
703            @Override
704            public Lock lockFolder(
705                            long userId, long folderId, String owner, boolean inheritable,
706                            long expirationTime)
707                    throws PortalException, SystemException {
708    
709                    if ((expirationTime <= 0) ||
710                            (expirationTime > DLFolderImpl.LOCK_EXPIRATION_TIME)) {
711    
712                            expirationTime = DLFolderImpl.LOCK_EXPIRATION_TIME;
713                    }
714    
715                    return lockLocalService.lock(
716                            userId, DLFolder.class.getName(), folderId, owner, inheritable,
717                            expirationTime);
718            }
719    
720            @Indexable(type = IndexableType.REINDEX)
721            @Override
722            public DLFolder moveFolder(
723                            long userId, long folderId, long parentFolderId,
724                            ServiceContext serviceContext)
725                    throws PortalException, SystemException {
726    
727                    boolean hasLock = hasFolderLock(userId, folderId);
728    
729                    Lock lock = null;
730    
731                    if (!hasLock) {
732    
733                            // Lock
734    
735                            lock = lockFolder(userId, folderId);
736                    }
737    
738                    try {
739                            DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
740    
741                            parentFolderId = getParentFolderId(dlFolder, parentFolderId);
742    
743                            validateFolder(
744                                    dlFolder.getFolderId(), dlFolder.getGroupId(), parentFolderId,
745                                    dlFolder.getName());
746    
747                            dlFolder.setModifiedDate(serviceContext.getModifiedDate(null));
748                            dlFolder.setParentFolderId(parentFolderId);
749                            dlFolder.setTreePath(dlFolder.buildTreePath());
750                            dlFolder.setExpandoBridgeAttributes(serviceContext);
751    
752                            dlFolderPersistence.update(dlFolder);
753    
754                            dlAppHelperLocalService.moveFolder(new LiferayFolder(dlFolder));
755    
756                            return dlFolder;
757                    }
758                    finally {
759                            if (!hasLock) {
760    
761                                    // Unlock
762    
763                                    unlockFolder(folderId, lock.getUuid());
764                            }
765                    }
766            }
767    
768            @Override
769            public void rebuildTree(long companyId)
770                    throws PortalException, SystemException {
771    
772                    List<DLFolder> dlFolders = dlFolderPersistence.findByC_NotS(
773                            companyId, WorkflowConstants.STATUS_IN_TRASH);
774    
775                    for (DLFolder dlFolder : dlFolders) {
776                            if (dlFolder.isInTrashContainer()) {
777                                    continue;
778                            }
779    
780                            dlFolder.setTreePath(dlFolder.buildTreePath());
781    
782                            dlFolderPersistence.update(dlFolder);
783                    }
784            }
785    
786            @Override
787            public void unlockFolder(
788                            long groupId, long parentFolderId, String name, String lockUuid)
789                    throws PortalException, SystemException {
790    
791                    DLFolder dlFolder = getFolder(groupId, parentFolderId, name);
792    
793                    unlockFolder(dlFolder.getFolderId(), lockUuid);
794            }
795    
796            @Override
797            public void unlockFolder(long folderId, String lockUuid)
798                    throws PortalException, SystemException {
799    
800                    if (Validator.isNotNull(lockUuid)) {
801                            try {
802                                    Lock lock = lockLocalService.getLock(
803                                            DLFolder.class.getName(), folderId);
804    
805                                    if (!lockUuid.equals(lock.getUuid())) {
806                                            throw new InvalidLockException("UUIDs do not match");
807                                    }
808                            }
809                            catch (PortalException pe) {
810                                    if (pe instanceof ExpiredLockException ||
811                                            pe instanceof NoSuchLockException) {
812                                    }
813                                    else {
814                                            throw pe;
815                                    }
816                            }
817                    }
818    
819                    lockLocalService.unlock(DLFolder.class.getName(), folderId);
820            }
821    
822            @Indexable(type = IndexableType.REINDEX)
823            @Override
824            public DLFolder updateFolder(
825                            long folderId, long parentFolderId, String name, String description,
826                            long defaultFileEntryTypeId, List<Long> fileEntryTypeIds,
827                            boolean overrideFileEntryTypes, ServiceContext serviceContext)
828                    throws PortalException, SystemException {
829    
830                    boolean hasLock = hasFolderLock(serviceContext.getUserId(), folderId);
831    
832                    Lock lock = null;
833    
834                    if (!hasLock) {
835    
836                            // Lock
837    
838                            lock = lockFolder(
839                                    serviceContext.getUserId(), folderId, null, false,
840                                    DLFolderImpl.LOCK_EXPIRATION_TIME);
841                    }
842    
843                    try {
844    
845                            // File entry types
846    
847                            DLFolder dlFolder = null;
848    
849                            if (folderId > DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
850                                    dlFolder = dlFolderLocalService.updateFolderAndFileEntryTypes(
851                                            serviceContext.getUserId(), folderId, parentFolderId, name,
852                                            description, defaultFileEntryTypeId, fileEntryTypeIds,
853                                            overrideFileEntryTypes, serviceContext);
854    
855                                    dlFileEntryTypeLocalService.cascadeFileEntryTypes(
856                                            serviceContext.getUserId(), dlFolder);
857                            }
858    
859                            // Workflow definitions
860    
861                            List<ObjectValuePair<Long, String>> workflowDefinitionOVPs =
862                                    new ArrayList<ObjectValuePair<Long, String>>();
863    
864                            if (fileEntryTypeIds.isEmpty()) {
865                                    fileEntryTypeIds.add(
866                                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_ALL);
867                            }
868                            else {
869                                    workflowDefinitionOVPs.add(
870                                            new ObjectValuePair<Long, String>(
871                                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_ALL,
872                                                    StringPool.BLANK));
873                            }
874    
875                            for (long fileEntryTypeId : fileEntryTypeIds) {
876                                    String workflowDefinition = StringPool.BLANK;
877    
878                                    if (overrideFileEntryTypes ||
879                                            (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID)) {
880    
881                                            workflowDefinition = ParamUtil.getString(
882                                                    serviceContext, "workflowDefinition" + fileEntryTypeId);
883                                    }
884    
885                                    workflowDefinitionOVPs.add(
886                                            new ObjectValuePair<Long, String>(
887                                                    fileEntryTypeId, workflowDefinition));
888                            }
889    
890                            workflowDefinitionLinkLocalService.updateWorkflowDefinitionLinks(
891                                    serviceContext.getUserId(), serviceContext.getCompanyId(),
892                                    serviceContext.getScopeGroupId(), DLFolder.class.getName(),
893                                    folderId, workflowDefinitionOVPs);
894    
895                            return dlFolder;
896                    }
897                    finally {
898                            if (!hasLock) {
899    
900                                    // Unlock
901    
902                                    unlockFolder(folderId, lock.getUuid());
903                            }
904                    }
905            }
906    
907            @Indexable(type = IndexableType.REINDEX)
908            @Override
909            public DLFolder updateFolder(
910                            long folderId, String name, String description,
911                            long defaultFileEntryTypeId, List<Long> fileEntryTypeIds,
912                            boolean overrideFileEntryTypes, ServiceContext serviceContext)
913                    throws PortalException, SystemException {
914    
915                    return updateFolder(
916                            folderId, folderId, name, description, defaultFileEntryTypeId,
917                            fileEntryTypeIds, overrideFileEntryTypes, serviceContext);
918            }
919    
920            @Override
921            public DLFolder updateFolderAndFileEntryTypes(
922                            long userId, long folderId, long parentFolderId, String name,
923                            String description, long defaultFileEntryTypeId,
924                            List<Long> fileEntryTypeIds, boolean overrideFileEntryTypes,
925                            ServiceContext serviceContext)
926                    throws PortalException, SystemException {
927    
928                    boolean hasLock = hasFolderLock(userId, folderId);
929    
930                    Lock lock = null;
931    
932                    if (!hasLock) {
933    
934                            // Lock
935    
936                            lock = lockFolder(
937                                    userId, folderId, null, false,
938                                    DLFolderImpl.LOCK_EXPIRATION_TIME);
939                    }
940    
941                    try {
942    
943                            // Folder
944    
945                            if (!overrideFileEntryTypes) {
946                                    fileEntryTypeIds = Collections.emptyList();
947                            }
948    
949                            DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
950    
951                            parentFolderId = getParentFolderId(dlFolder, parentFolderId);
952    
953                            validateFolder(
954                                    folderId, dlFolder.getGroupId(), parentFolderId, name);
955    
956                            dlFolder.setModifiedDate(serviceContext.getModifiedDate(null));
957                            dlFolder.setParentFolderId(parentFolderId);
958                            dlFolder.setTreePath(dlFolder.buildTreePath());
959                            dlFolder.setName(name);
960                            dlFolder.setDescription(description);
961                            dlFolder.setExpandoBridgeAttributes(serviceContext);
962                            dlFolder.setOverrideFileEntryTypes(overrideFileEntryTypes);
963                            dlFolder.setDefaultFileEntryTypeId(defaultFileEntryTypeId);
964    
965                            dlFolderPersistence.update(dlFolder);
966    
967                            // File entry types
968    
969                            if (fileEntryTypeIds != null) {
970                                    dlFileEntryTypeLocalService.updateFolderFileEntryTypes(
971                                            dlFolder, fileEntryTypeIds, defaultFileEntryTypeId,
972                                            serviceContext);
973                            }
974    
975                            // App helper
976    
977                            dlAppHelperLocalService.updateFolder(
978                                    userId, new LiferayFolder(dlFolder), serviceContext);
979    
980                            return dlFolder;
981                    }
982                    finally {
983                            if (!hasLock) {
984    
985                                    // Unlock
986    
987                                    unlockFolder(folderId, lock.getUuid());
988                            }
989                    }
990            }
991    
992            /**
993             * @deprecated As of 6.2.0
994             */
995            @Override
996            public void updateLastPostDate(long folderId, Date lastPostDate)
997                    throws PortalException, SystemException {
998    
999                    DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
1000    
1001                    dlFolder.setLastPostDate(lastPostDate);
1002    
1003                    dlFolderPersistence.update(dlFolder);
1004            }
1005    
1006            @Override
1007            public DLFolder updateStatus(
1008                            long userId, long folderId, int status,
1009                            Map<String, Serializable> workflowContext,
1010                            ServiceContext serviceContext)
1011                    throws PortalException, SystemException {
1012    
1013                    // Folder
1014    
1015                    User user = userPersistence.findByPrimaryKey(userId);
1016    
1017                    DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
1018    
1019                    int oldStatus = dlFolder.getStatus();
1020    
1021                    dlFolder.setStatus(status);
1022                    dlFolder.setStatusByUserId(user.getUserId());
1023                    dlFolder.setStatusByUserName(user.getFullName());
1024                    dlFolder.setStatusDate(new Date());
1025    
1026                    dlFolderPersistence.update(dlFolder);
1027    
1028                    // Folders, file entries, and file shortcuts
1029    
1030                    QueryDefinition queryDefinition = new QueryDefinition(
1031                            WorkflowConstants.STATUS_ANY);
1032    
1033                    List<Object> foldersAndFileEntriesAndFileShortcuts =
1034                            getFoldersAndFileEntriesAndFileShortcuts(
1035                                    dlFolder.getGroupId(), folderId, null, false, queryDefinition);
1036    
1037                    dlAppHelperLocalService.updateDependentStatus(
1038                            user, foldersAndFileEntriesAndFileShortcuts, status);
1039    
1040                    // Asset
1041    
1042                    if (status == WorkflowConstants.STATUS_APPROVED) {
1043                            assetEntryLocalService.updateVisible(
1044                                    DLFolder.class.getName(), dlFolder.getFolderId(), true);
1045                    }
1046                    else if (status == WorkflowConstants.STATUS_IN_TRASH) {
1047                            assetEntryLocalService.updateVisible(
1048                                    DLFolder.class.getName(), dlFolder.getFolderId(), false);
1049                    }
1050    
1051                    // Trash
1052    
1053                    if (status == WorkflowConstants.STATUS_IN_TRASH) {
1054                            UnicodeProperties typeSettingsProperties = new UnicodeProperties();
1055    
1056                            typeSettingsProperties.put("title", dlFolder.getName());
1057    
1058                            trashEntryLocalService.addTrashEntry(
1059                                    userId, dlFolder.getGroupId(), DLFolderConstants.getClassName(),
1060                                    dlFolder.getFolderId(), dlFolder.getUuid(), null,
1061                                    WorkflowConstants.STATUS_APPROVED, null,
1062                                    typeSettingsProperties);
1063                    }
1064                    else {
1065                            trashEntryLocalService.deleteEntry(
1066                                    DLFolderConstants.getClassName(), dlFolder.getFolderId());
1067                    }
1068    
1069                    // Indexer
1070    
1071                    if (((status == WorkflowConstants.STATUS_APPROVED) ||
1072                             (status == WorkflowConstants.STATUS_IN_TRASH) ||
1073                             (oldStatus == WorkflowConstants.STATUS_IN_TRASH)) &&
1074                            ((serviceContext == null) || serviceContext.isIndexingEnabled())) {
1075    
1076                            Indexer indexer = IndexerRegistryUtil.nullSafeGetIndexer(
1077                                    DLFolderConstants.getClassName());
1078    
1079                            indexer.reindex(dlFolder);
1080                    }
1081    
1082                    return dlFolder;
1083            }
1084    
1085            protected void addFolderResources(
1086                            DLFolder dlFolder, boolean addGroupPermissions,
1087                            boolean addGuestPermissions)
1088                    throws PortalException, SystemException {
1089    
1090                    resourceLocalService.addResources(
1091                            dlFolder.getCompanyId(), dlFolder.getGroupId(),
1092                            dlFolder.getUserId(), DLFolder.class.getName(),
1093                            dlFolder.getFolderId(), false, addGroupPermissions,
1094                            addGuestPermissions);
1095            }
1096    
1097            protected void addFolderResources(
1098                            DLFolder dlFolder, String[] groupPermissions,
1099                            String[] guestPermissions)
1100                    throws PortalException, SystemException {
1101    
1102                    resourceLocalService.addModelResources(
1103                            dlFolder.getCompanyId(), dlFolder.getGroupId(),
1104                            dlFolder.getUserId(), DLFolder.class.getName(),
1105                            dlFolder.getFolderId(), groupPermissions, guestPermissions);
1106            }
1107    
1108            protected void addFolderResources(
1109                            long folderId, boolean addGroupPermissions,
1110                            boolean addGuestPermissions)
1111                    throws PortalException, SystemException {
1112    
1113                    DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
1114    
1115                    addFolderResources(dlFolder, addGroupPermissions, addGuestPermissions);
1116            }
1117    
1118            protected void addFolderResources(
1119                            long folderId, String[] groupPermissions, String[] guestPermissions)
1120                    throws PortalException, SystemException {
1121    
1122                    DLFolder dlFolder = dlFolderPersistence.findByPrimaryKey(folderId);
1123    
1124                    addFolderResources(dlFolder, groupPermissions, guestPermissions);
1125            }
1126    
1127            protected long getParentFolderId(DLFolder dlFolder, long parentFolderId)
1128                    throws SystemException {
1129    
1130                    if (parentFolderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1131                            return parentFolderId;
1132                    }
1133    
1134                    if (dlFolder.getFolderId() == parentFolderId) {
1135                            return dlFolder.getParentFolderId();
1136                    }
1137    
1138                    DLFolder parentDLFolder = dlFolderPersistence.fetchByPrimaryKey(
1139                            parentFolderId);
1140    
1141                    if ((parentDLFolder == null) ||
1142                            (dlFolder.getGroupId() != parentDLFolder.getGroupId())) {
1143    
1144                            return dlFolder.getParentFolderId();
1145                    }
1146    
1147                    List<Long> subfolderIds = new ArrayList<Long>();
1148    
1149                    getSubfolderIds(
1150                            subfolderIds, dlFolder.getGroupId(), dlFolder.getFolderId());
1151    
1152                    if (subfolderIds.contains(parentFolderId)) {
1153                            return dlFolder.getParentFolderId();
1154                    }
1155    
1156                    return parentFolderId;
1157            }
1158    
1159            protected long getParentFolderId(long groupId, long parentFolderId)
1160                    throws SystemException {
1161    
1162                    if (parentFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1163                            DLFolder parentDLFolder = dlFolderPersistence.fetchByPrimaryKey(
1164                                    parentFolderId);
1165    
1166                            if ((parentDLFolder == null) ||
1167                                    (groupId != parentDLFolder.getGroupId())) {
1168    
1169                                    parentFolderId = DLFolderConstants.DEFAULT_PARENT_FOLDER_ID;
1170                            }
1171                    }
1172    
1173                    return parentFolderId;
1174            }
1175    
1176            protected void validateFolder(
1177                            long folderId, long groupId, long parentFolderId, String name)
1178                    throws PortalException, SystemException {
1179    
1180                    validateFolderName(name);
1181    
1182                    try {
1183                            dlFileEntryLocalService.getFileEntry(groupId, parentFolderId, name);
1184    
1185                            throw new DuplicateFileException(name);
1186                    }
1187                    catch (NoSuchFileEntryException nsfee) {
1188                    }
1189    
1190                    DLFolder dlFolder = dlFolderPersistence.fetchByG_P_N(
1191                            groupId, parentFolderId, name);
1192    
1193                    if ((dlFolder != null) && (dlFolder.getFolderId() != folderId)) {
1194                            throw new DuplicateFolderNameException(name);
1195                    }
1196            }
1197    
1198            protected void validateFolder(
1199                            long groupId, long parentFolderId, String name)
1200                    throws PortalException, SystemException {
1201    
1202                    long folderId = 0;
1203    
1204                    validateFolder(folderId, groupId, parentFolderId, name);
1205            }
1206    
1207            protected void validateFolderName(String name) throws PortalException {
1208                    if (!AssetUtil.isValidWord(name)) {
1209                            throw new FolderNameException();
1210                    }
1211            }
1212    
1213            private static Log _log = LogFactoryUtil.getLog(
1214                    DLFolderLocalServiceImpl.class);
1215    
1216    }