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