001    /**
002     * Copyright (c) 2000-present 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.NoSuchGroupException;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
022    import com.liferay.portal.kernel.lock.Lock;
023    import com.liferay.portal.kernel.lock.LockManagerUtil;
024    import com.liferay.portal.kernel.log.Log;
025    import com.liferay.portal.kernel.log.LogFactoryUtil;
026    import com.liferay.portal.kernel.repository.InvalidRepositoryIdException;
027    import com.liferay.portal.kernel.repository.Repository;
028    import com.liferay.portal.kernel.repository.RepositoryException;
029    import com.liferay.portal.kernel.repository.RepositoryProviderUtil;
030    import com.liferay.portal.kernel.repository.capabilities.TrashCapability;
031    import com.liferay.portal.kernel.repository.model.FileEntry;
032    import com.liferay.portal.kernel.repository.model.FileShortcut;
033    import com.liferay.portal.kernel.repository.model.FileVersion;
034    import com.liferay.portal.kernel.repository.model.Folder;
035    import com.liferay.portal.kernel.repository.model.RepositoryEntry;
036    import com.liferay.portal.kernel.search.Hits;
037    import com.liferay.portal.kernel.search.Query;
038    import com.liferay.portal.kernel.search.SearchContext;
039    import com.liferay.portal.kernel.search.SearchException;
040    import com.liferay.portal.kernel.transaction.TransactionCommitCallbackUtil;
041    import com.liferay.portal.kernel.util.ArrayUtil;
042    import com.liferay.portal.kernel.util.ContentTypes;
043    import com.liferay.portal.kernel.util.FileUtil;
044    import com.liferay.portal.kernel.util.GetterUtil;
045    import com.liferay.portal.kernel.util.MimeTypesUtil;
046    import com.liferay.portal.kernel.util.OrderByComparator;
047    import com.liferay.portal.kernel.util.StringBundler;
048    import com.liferay.portal.kernel.util.StringPool;
049    import com.liferay.portal.kernel.util.TempFileEntryUtil;
050    import com.liferay.portal.kernel.util.Validator;
051    import com.liferay.portal.kernel.workflow.WorkflowConstants;
052    import com.liferay.portal.security.permission.ActionKeys;
053    import com.liferay.portal.service.ServiceContext;
054    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
055    import com.liferay.portlet.documentlibrary.NoSuchFileShortcutException;
056    import com.liferay.portlet.documentlibrary.NoSuchFileVersionException;
057    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
058    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
059    import com.liferay.portlet.documentlibrary.service.base.DLAppServiceBaseImpl;
060    import com.liferay.portlet.documentlibrary.service.permission.DLFileEntryPermission;
061    import com.liferay.portlet.documentlibrary.service.permission.DLFileShortcutPermission;
062    import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
063    import com.liferay.portlet.documentlibrary.service.permission.DLPermission;
064    import com.liferay.portlet.documentlibrary.util.DLAppUtil;
065    import com.liferay.portlet.documentlibrary.util.DLProcessorRegistryUtil;
066    import com.liferay.portlet.documentlibrary.util.comparator.FolderNameComparator;
067    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelModifiedDateComparator;
068    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelTitleComparator;
069    
070    import java.io.File;
071    import java.io.IOException;
072    import java.io.InputStream;
073    
074    import java.util.ArrayList;
075    import java.util.LinkedList;
076    import java.util.List;
077    import java.util.Queue;
078    import java.util.concurrent.Callable;
079    
080    /**
081     * Provides the remote service for accessing, adding, checking in/out, deleting,
082     * locking/unlocking, moving, subscription handling of, trash handling of,
083     * updating, and verifying document library file entries and folders. Its
084     * methods include permission checks. All portlets should interact with the
085     * document library through this class or through DLAppLocalService, rather than
086     * through the individual document library service classes.
087     *
088     * <p>
089     * This class provides a unified interface to all Liferay and third party
090     * repositories. While the method signatures are universal for all repositories.
091     * Additional implementation-specific parameters may be specified in the
092     * serviceContext.
093     * </p>
094     *
095     * <p>
096     * The <code>repositoryId</code> parameter used by most of the methods is the
097     * primary key of the specific repository. If the repository is a default
098     * Liferay repository, the <code>repositoryId</code> is the <code>groupId</code>
099     * or <code>scopeGroupId</code>. Otherwise, the <code>repositoryId</code> will
100     * correspond to values obtained from {@link
101     * com.liferay.portal.service.RepositoryServiceUtil}.
102     * </p>
103     *
104     * @author Alexander Chow
105     * @author Mika Koivisto
106     * @author Shuyang Zhou
107     * @see    DLAppLocalServiceImpl
108     */
109    public class DLAppServiceImpl extends DLAppServiceBaseImpl {
110    
111            /**
112             * Adds a file entry and associated metadata. It is created based on a byte
113             * array.
114             *
115             * <p>
116             * This method takes two file names, the <code>sourceFileName</code> and the
117             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
118             * name of the actual file being uploaded. The <code>title</code>
119             * corresponds to a name the client wishes to assign this file after it has
120             * been uploaded to the portal. If it is <code>null</code>, the <code>
121             * sourceFileName</code> will be used.
122             * </p>
123             *
124             * @param  repositoryId the primary key of the repository
125             * @param  folderId the primary key of the file entry's parent folder
126             * @param  sourceFileName the original file's name
127             * @param  mimeType the file's MIME type
128             * @param  title the name to be assigned to the file (optionally <code>null
129             *         </code>)
130             * @param  description the file's description
131             * @param  changeLog the file's version change log
132             * @param  bytes the file's data (optionally <code>null</code>)
133             * @param  serviceContext the service context to be applied. Can set the
134             *         asset category IDs, asset tag names, and expando bridge
135             *         attributes for the file entry. In a Liferay repository, it may
136             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
137             *         type </li> <li> fieldsMap - mapping for fields associated with a
138             *         custom file entry type </li> </ul>
139             * @return the file entry
140             * @throws PortalException if the parent folder could not be found or if the
141             *         file entry's information was invalid
142             */
143            @Override
144            public FileEntry addFileEntry(
145                            long repositoryId, long folderId, String sourceFileName,
146                            String mimeType, String title, String description, String changeLog,
147                            byte[] bytes, ServiceContext serviceContext)
148                    throws PortalException {
149    
150                    File file = null;
151    
152                    try {
153                            if (ArrayUtil.isNotEmpty(bytes)) {
154                                    file = FileUtil.createTempFile(bytes);
155                            }
156    
157                            return addFileEntry(
158                                    repositoryId, folderId, sourceFileName, mimeType, title,
159                                    description, changeLog, file, serviceContext);
160                    }
161                    catch (IOException ioe) {
162                            throw new SystemException("Unable to write temporary file", ioe);
163                    }
164                    finally {
165                            FileUtil.delete(file);
166                    }
167            }
168    
169            /**
170             * Adds a file entry and associated metadata. It is created based on a
171             * {@link File} object.
172             *
173             * <p>
174             * This method takes two file names, the <code>sourceFileName</code> and the
175             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
176             * name of the actual file being uploaded. The <code>title</code>
177             * corresponds to a name the client wishes to assign this file after it has
178             * been uploaded to the portal. If it is <code>null</code>, the <code>
179             * sourceFileName</code> will be used.
180             * </p>
181             *
182             * @param  repositoryId the primary key of the repository
183             * @param  folderId the primary key of the file entry's parent folder
184             * @param  sourceFileName the original file's name
185             * @param  mimeType the file's MIME type
186             * @param  title the name to be assigned to the file (optionally <code>null
187             *         </code>)
188             * @param  description the file's description
189             * @param  changeLog the file's version change log
190             * @param  file the file's data (optionally <code>null</code>)
191             * @param  serviceContext the service context to be applied. Can set the
192             *         asset category IDs, asset tag names, and expando bridge
193             *         attributes for the file entry. In a Liferay repository, it may
194             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
195             *         type </li> <li> fieldsMap - mapping for fields associated with a
196             *         custom file entry type </li> </ul>
197             * @return the file entry
198             * @throws PortalException if the parent folder could not be found or if the
199             *         file entry's information was invalid
200             */
201            @Override
202            public FileEntry addFileEntry(
203                            long repositoryId, long folderId, String sourceFileName,
204                            String mimeType, String title, String description, String changeLog,
205                            File file, ServiceContext serviceContext)
206                    throws PortalException {
207    
208                    if ((file == null) || !file.exists() || (file.length() == 0)) {
209                            return addFileEntry(
210                                    repositoryId, folderId, sourceFileName, mimeType, title,
211                                    description, changeLog, null, 0, serviceContext);
212                    }
213    
214                    mimeType = DLAppUtil.getMimeType(sourceFileName, mimeType, title, file);
215    
216                    Repository repository = getRepository(repositoryId);
217    
218                    FileEntry fileEntry = repository.addFileEntry(
219                            getUserId(), folderId, sourceFileName, mimeType, title, description,
220                            changeLog, file, serviceContext);
221    
222                    return fileEntry;
223            }
224    
225            /**
226             * Adds a file entry and associated metadata. It is created based on a
227             * {@link InputStream} object.
228             *
229             * <p>
230             * This method takes two file names, the <code>sourceFileName</code> and the
231             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
232             * name of the actual file being uploaded. The <code>title</code>
233             * corresponds to a name the client wishes to assign this file after it has
234             * been uploaded to the portal. If it is <code>null</code>, the <code>
235             * sourceFileName</code> will be used.
236             * </p>
237             *
238             * @param  repositoryId the primary key of the repository
239             * @param  folderId the primary key of the file entry's parent folder
240             * @param  sourceFileName the original file's name
241             * @param  mimeType the file's MIME type
242             * @param  title the name to be assigned to the file (optionally <code>null
243             *         </code>)
244             * @param  description the file's description
245             * @param  changeLog the file's version change log
246             * @param  is the file's data (optionally <code>null</code>)
247             * @param  size the file's size (optionally <code>0</code>)
248             * @param  serviceContext the service context to be applied. Can set the
249             *         asset category IDs, asset tag names, and expando bridge
250             *         attributes for the file entry. In a Liferay repository, it may
251             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
252             *         type </li> <li> fieldsMap - mapping for fields associated with a
253             *         custom file entry type </li> </ul>
254             * @return the file entry
255             * @throws PortalException if the parent folder could not be found or if the
256             *         file entry's information was invalid
257             */
258            @Override
259            public FileEntry addFileEntry(
260                            long repositoryId, long folderId, String sourceFileName,
261                            String mimeType, String title, String description, String changeLog,
262                            InputStream is, long size, ServiceContext serviceContext)
263                    throws PortalException {
264    
265                    if (is == null) {
266                            is = new UnsyncByteArrayInputStream(new byte[0]);
267                            size = 0;
268                    }
269    
270                    if (Validator.isNull(mimeType) ||
271                            mimeType.equals(ContentTypes.APPLICATION_OCTET_STREAM)) {
272    
273                            String extension = DLAppUtil.getExtension(title, sourceFileName);
274    
275                            if (size == 0) {
276                                    mimeType = MimeTypesUtil.getExtensionContentType(extension);
277                            }
278                            else {
279                                    File file = null;
280    
281                                    try {
282                                            file = FileUtil.createTempFile(is);
283    
284                                            return addFileEntry(
285                                                    repositoryId, folderId, sourceFileName, mimeType, title,
286                                                    description, changeLog, file, serviceContext);
287                                    }
288                                    catch (IOException ioe) {
289                                            throw new SystemException(
290                                                    "Unable to write temporary file", ioe);
291                                    }
292                                    finally {
293                                            FileUtil.delete(file);
294                                    }
295                            }
296                    }
297    
298                    Repository repository = getRepository(repositoryId);
299    
300                    FileEntry fileEntry = repository.addFileEntry(
301                            getUserId(), folderId, sourceFileName, mimeType, title, description,
302                            changeLog, is, size, serviceContext);
303    
304                    return fileEntry;
305            }
306    
307            /**
308             * Adds a file shortcut to the existing file entry. This method is only
309             * supported by the Liferay repository.
310             *
311             * @param  repositoryId the primary key of the repository
312             * @param  folderId the primary key of the file shortcut's parent folder
313             * @param  toFileEntryId the primary key of the file shortcut's file entry
314             * @param  serviceContext the service context to be applied. Can set the
315             *         asset category IDs, asset tag names, and expando bridge
316             *         attributes for the file entry.
317             * @return the file shortcut
318             * @throws PortalException if the parent folder or file entry could not be
319             *         found, or if the file shortcut's information was invalid
320             */
321            @Override
322            public FileShortcut addFileShortcut(
323                            long repositoryId, long folderId, long toFileEntryId,
324                            ServiceContext serviceContext)
325                    throws PortalException {
326    
327                    Repository repository = getRepository(repositoryId);
328    
329                    return repository.addFileShortcut(
330                            getUserId(), folderId, toFileEntryId, serviceContext);
331            }
332    
333            /**
334             * Adds a folder.
335             *
336             * @param  repositoryId the primary key of the repository
337             * @param  parentFolderId the primary key of the folder's parent folder
338             * @param  name the folder's name
339             * @param  description the folder's description
340             * @param  serviceContext the service context to be applied. In a Liferay
341             *         repository, it may include boolean mountPoint specifying whether
342             *         folder is a facade for mounting a third-party repository
343             * @return the folder
344             * @throws PortalException if the parent folder could not be found or if the
345             *         new folder's information was invalid
346             */
347            @Override
348            public Folder addFolder(
349                            long repositoryId, long parentFolderId, String name,
350                            String description, ServiceContext serviceContext)
351                    throws PortalException {
352    
353                    Repository repository = getRepository(repositoryId);
354    
355                    Folder folder = repository.addFolder(
356                            getUserId(), parentFolderId, name, description, serviceContext);
357    
358                    dlAppHelperLocalService.addFolder(getUserId(), folder, serviceContext);
359    
360                    return folder;
361            }
362    
363            /**
364             * Adds a temporary file entry.
365             *
366             * <p>
367             * This allows a client to upload a file into a temporary location and
368             * manipulate its metadata prior to making it available for public usage.
369             * This is different from checking in and checking out a file entry.
370             * </p>
371             *
372             * @param  groupId the primary key of the group
373             * @param  folderId the primary key of the folder where the file entry will
374             *         eventually reside
375             * @param  folderName the temporary folder's name
376             * @param  fileName the file's original name
377             * @param  file the file's data (optionally <code>null</code>)
378             * @param  mimeType the file's MIME type
379             * @return the temporary file entry
380             * @throws PortalException if the file name was invalid
381             * @see    TempFileEntryUtil
382             */
383            @Override
384            public FileEntry addTempFileEntry(
385                            long groupId, long folderId, String folderName, String fileName,
386                            File file, String mimeType)
387                    throws PortalException {
388    
389                    DLFolderPermission.check(
390                            getPermissionChecker(), groupId, folderId, ActionKeys.ADD_DOCUMENT);
391    
392                    return TempFileEntryUtil.addTempFileEntry(
393                            groupId, getUserId(), folderName, fileName, file, mimeType);
394            }
395    
396            /**
397             * Adds a temporary file entry. It is created based on the {@link
398             * InputStream} object.
399             *
400             * <p>
401             * This allows a client to upload a file into a temporary location and
402             * manipulate its metadata prior to making it available for public usage.
403             * This is different from checking in and checking out a file entry.
404             * </p>
405             *
406             * @param  groupId the primary key of the group
407             * @param  folderId the primary key of the folder where the file entry will
408             *         eventually reside
409             * @param  folderName the temporary folder's name
410             * @param  fileName the file's original name
411             * @param  inputStream the file's data
412             * @param  mimeType the file's MIME type
413             * @return the temporary file entry
414             * @throws PortalException if the file name was invalid or if a portal
415             *         exception occurred
416             * @see    TempFileEntryUtil
417             */
418            @Override
419            public FileEntry addTempFileEntry(
420                            long groupId, long folderId, String folderName, String fileName,
421                            InputStream inputStream, String mimeType)
422                    throws PortalException {
423    
424                    DLFolderPermission.check(
425                            getPermissionChecker(), groupId, folderId, ActionKeys.ADD_DOCUMENT);
426    
427                    return TempFileEntryUtil.addTempFileEntry(
428                            groupId, getUserId(), folderName, fileName, inputStream, mimeType);
429            }
430    
431            /**
432             * Cancels the check out of the file entry. If a user has not checked out
433             * the specified file entry, invoking this method will result in no changes.
434             *
435             * <p>
436             * When a file entry is checked out, a PWC (private working copy) is created
437             * and the original file entry is locked. A client can make as many changes
438             * to the PWC as he desires without those changes being visible to other
439             * users. If the user is satisfied with the changes, he may elect to check
440             * in his changes, resulting in a new file version based on the PWC; the PWC
441             * will be removed and the file entry will be unlocked. If the user is not
442             * satisfied with the changes, he may elect to cancel his check out; this
443             * results in the deletion of the PWC and unlocking of the file entry.
444             * </p>
445             *
446             * @param  fileEntryId the primary key of the file entry to cancel the
447             *         checkout
448             * @throws PortalException if the file entry could not be found
449             * @see    #checkInFileEntry(long, boolean, String, ServiceContext)
450             * @see    #checkOutFileEntry(long, ServiceContext)
451             */
452            @Override
453            public void cancelCheckOut(long fileEntryId) throws PortalException {
454                    Repository repository = getFileEntryRepository(fileEntryId);
455    
456                    FileEntry fileEntry = repository.getFileEntry(fileEntryId);
457    
458                    FileVersion draftFileVersion = repository.cancelCheckOut(fileEntryId);
459    
460                    ServiceContext serviceContext = new ServiceContext();
461    
462                    serviceContext.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH);
463    
464                    dlAppHelperLocalService.cancelCheckOut(
465                            getUserId(), fileEntry, null, fileEntry.getFileVersion(),
466                            draftFileVersion, serviceContext);
467            }
468    
469            /**
470             * Checks in the file entry. If a user has not checked out the specified
471             * file entry, invoking this method will result in no changes.
472             *
473             * <p>
474             * When a file entry is checked out, a PWC (private working copy) is created
475             * and the original file entry is locked. A client can make as many changes
476             * to the PWC as he desires without those changes being visible to other
477             * users. If the user is satisfied with the changes, he may elect to check
478             * in his changes, resulting in a new file version based on the PWC; the PWC
479             * will be removed and the file entry will be unlocked. If the user is not
480             * satisfied with the changes, he may elect to cancel his check out; this
481             * results in the deletion of the PWC and unlocking of the file entry.
482             * </p>
483             *
484             * @param  fileEntryId the primary key of the file entry to check in
485             * @param  majorVersion whether the new file version is a major version
486             * @param  changeLog the file's version change log
487             * @param  serviceContext the service context to be applied
488             * @throws PortalException if the file entry could not be found
489             * @see    #cancelCheckOut(long)
490             * @see    #checkOutFileEntry(long, ServiceContext)
491             */
492            @Override
493            public void checkInFileEntry(
494                            long fileEntryId, boolean majorVersion, String changeLog,
495                            ServiceContext serviceContext)
496                    throws PortalException {
497    
498                    Repository repository = getFileEntryRepository(fileEntryId);
499    
500                    repository.checkInFileEntry(
501                            getUserId(), fileEntryId, majorVersion, changeLog, serviceContext);
502    
503                    FileEntry fileEntry = getFileEntry(fileEntryId);
504    
505                    FileVersion fileVersion = fileEntry.getLatestFileVersion();
506    
507                    dlAppHelperLocalService.updateFileEntry(
508                            getUserId(), fileEntry, null, fileVersion,
509                            fileVersion.getFileVersionId());
510            }
511    
512            /**
513             * @deprecated As of 6.2.0, replaced by {@link #checkInFileEntry(long,
514             *             String, ServiceContext)}
515             */
516            @Deprecated
517            @Override
518            public void checkInFileEntry(long fileEntryId, String lockUuid)
519                    throws PortalException {
520    
521                    checkInFileEntry(fileEntryId, lockUuid, new ServiceContext());
522            }
523    
524            /**
525             * Checks in the file entry using the lock's UUID. If a user has not checked
526             * out the specified file entry, invoking this method will result in no
527             * changes. This method is primarily used by WebDAV.
528             *
529             * <p>
530             * When a file entry is checked out, a PWC (private working copy) is created
531             * and the original file entry is locked. A client can make as many changes
532             * to the PWC as he desires without those changes being visible to other
533             * users. If the user is satisfied with the changes, he may elect to check
534             * in his changes, resulting in a new file version based on the PWC; the PWC
535             * will be removed and the file entry will be unlocked. If the user is not
536             * satisfied with the changes, he may elect to cancel his check out; this
537             * results in the deletion of the PWC and unlocking of the file entry.
538             * </p>
539             *
540             * @param  fileEntryId the primary key of the file entry to check in
541             * @param  lockUuid the lock's UUID
542             * @param  serviceContext the service context to be applied
543             * @throws PortalException if the file entry could not be found
544             * @see    #cancelCheckOut(long)
545             * @see    #checkOutFileEntry(long, String, long, ServiceContext)
546             */
547            @Override
548            public void checkInFileEntry(
549                            long fileEntryId, String lockUuid, ServiceContext serviceContext)
550                    throws PortalException {
551    
552                    Repository repository = getFileEntryRepository(fileEntryId);
553    
554                    repository.checkInFileEntry(
555                            getUserId(), fileEntryId, lockUuid, serviceContext);
556    
557                    FileEntry fileEntry = getFileEntry(fileEntryId);
558    
559                    FileVersion fileVersion = fileEntry.getLatestFileVersion();
560    
561                    dlAppHelperLocalService.updateFileEntry(
562                            getUserId(), fileEntry, null, fileVersion,
563                            fileVersion.getFileVersionId());
564            }
565    
566            /**
567             * Check out a file entry.
568             *
569             * <p>
570             * When a file entry is checked out, a PWC (private working copy) is created
571             * and the original file entry is locked. A client can make as many changes
572             * to the PWC as he desires without those changes being visible to other
573             * users. If the user is satisfied with the changes, he may elect to check
574             * in his changes, resulting in a new file version based on the PWC; the PWC
575             * will be removed and the file entry will be unlocked. If the user is not
576             * satisfied with the changes, he may elect to cancel his check out; this
577             * results in the deletion of the PWC and unlocking of the file entry.
578             * </p>
579             *
580             * @param  fileEntryId the file entry to check out
581             * @param  serviceContext the service context to be applied
582             * @throws PortalException if the file entry could not be found
583             * @see    #cancelCheckOut(long)
584             * @see    #checkInFileEntry(long, boolean, String, ServiceContext)
585             */
586            @Override
587            public void checkOutFileEntry(
588                            long fileEntryId, ServiceContext serviceContext)
589                    throws PortalException {
590    
591                    Repository repository = getFileEntryRepository(fileEntryId);
592    
593                    FileEntry fileEntry = repository.checkOutFileEntry(
594                            fileEntryId, serviceContext);
595    
596                    FileVersion fileVersion = fileEntry.getLatestFileVersion();
597    
598                    dlAppHelperLocalService.updateFileEntry(
599                            getUserId(), fileEntry, null, fileVersion, fileEntryId);
600            }
601    
602            /**
603             * Checks out the file entry. This method is primarily used by WebDAV.
604             *
605             * <p>
606             * When a file entry is checked out, a PWC (private working copy) is created
607             * and the original file entry is locked. A client can make as many changes
608             * to the PWC as he desires without those changes being visible to other
609             * users. If the user is satisfied with the changes, he may elect to check
610             * in his changes, resulting in a new file version based on the PWC; the PWC
611             * will be removed and the file entry will be unlocked. If the user is not
612             * satisfied with the changes, he may elect to cancel his check out; this
613             * results in the deletion of the PWC and unlocking of the file entry.
614             * </p>
615             *
616             * @param  fileEntryId the file entry to check out
617             * @param  owner the owner string for the checkout (optionally
618             *         <code>null</code>)
619             * @param  expirationTime the time in milliseconds before the lock expires.
620             *         If the value is <code>0</code>, the default expiration time will
621             *         be used from <code>portal.properties>.
622             * @param  serviceContext the service context to be applied
623             * @return the file entry
624             * @throws PortalException if the file entry could not be found
625             * @see    #cancelCheckOut(long)
626             * @see    #checkInFileEntry(long, String)
627             */
628            @Override
629            public FileEntry checkOutFileEntry(
630                            long fileEntryId, String owner, long expirationTime,
631                            ServiceContext serviceContext)
632                    throws PortalException {
633    
634                    Repository repository = getFileEntryRepository(fileEntryId);
635    
636                    FileEntry fileEntry = repository.checkOutFileEntry(
637                            fileEntryId, owner, expirationTime, serviceContext);
638    
639                    FileVersion fileVersion = fileEntry.getLatestFileVersion();
640    
641                    dlAppHelperLocalService.updateFileEntry(
642                            getUserId(), fileEntry, null, fileVersion, fileEntryId);
643    
644                    return fileEntry;
645            }
646    
647            /**
648             * Performs a deep copy of the folder.
649             *
650             * @param  repositoryId the primary key of the repository
651             * @param  sourceFolderId the primary key of the folder to copy
652             * @param  parentFolderId the primary key of the new folder's parent folder
653             * @param  name the new folder's name
654             * @param  description the new folder's description
655             * @param  serviceContext the service context to be applied
656             * @return the folder
657             * @throws PortalException if the source folder or the new parent folder
658             *         could not be found or if the new folder's information was invalid
659             */
660            @Override
661            public Folder copyFolder(
662                            long repositoryId, long sourceFolderId, long parentFolderId,
663                            String name, String description, ServiceContext serviceContext)
664                    throws PortalException {
665    
666                    Repository repository = getRepository(repositoryId);
667    
668                    Folder srcFolder = repository.getFolder(sourceFolderId);
669    
670                    Folder destFolder = repository.addFolder(
671                            getUserId(), parentFolderId, name, description, serviceContext);
672    
673                    dlAppHelperLocalService.addFolder(
674                            getUserId(), destFolder, serviceContext);
675    
676                    copyFolder(repository, srcFolder, destFolder, serviceContext);
677    
678                    return destFolder;
679            }
680    
681            /**
682             * Deletes the file entry with the primary key.
683             *
684             * @param  fileEntryId the primary key of the file entry
685             * @throws PortalException if the file entry could not be found
686             */
687            @Override
688            public void deleteFileEntry(long fileEntryId) throws PortalException {
689                    Repository repository = getFileEntryRepository(fileEntryId);
690    
691                    FileEntry fileEntry = repository.getFileEntry(fileEntryId);
692    
693                    dlAppHelperLocalService.deleteFileEntry(fileEntry);
694    
695                    repository.deleteFileEntry(fileEntryId);
696            }
697    
698            /**
699             * Deletes the file entry with the title in the folder.
700             *
701             * @param  repositoryId the primary key of the repository
702             * @param  folderId the primary key of the file entry's parent folder
703             * @param  title the file entry's title
704             * @throws PortalException if the file entry could not be found
705             */
706            @Override
707            public void deleteFileEntryByTitle(
708                            long repositoryId, long folderId, String title)
709                    throws PortalException {
710    
711                    Repository repository = getRepository(repositoryId);
712    
713                    FileEntry fileEntry = repository.getFileEntry(folderId, title);
714    
715                    dlAppHelperLocalService.deleteFileEntry(fileEntry);
716    
717                    repository.deleteFileEntry(folderId, title);
718            }
719    
720            /**
721             * Deletes the file shortcut with the primary key. This method is only
722             * supported by the Liferay repository.
723             *
724             * @param  fileShortcutId the primary key of the file shortcut
725             * @throws PortalException if the file shortcut could not be found
726             */
727            @Override
728            public void deleteFileShortcut(long fileShortcutId) throws PortalException {
729                    Repository repository = getFileShortcutRepository(fileShortcutId);
730    
731                    repository.deleteFileShortcut(fileShortcutId);
732            }
733    
734            /**
735             * Deletes the file version. File versions can only be deleted if it is
736             * approved and there are other approved file versions available. This
737             * method is only supported by the Liferay repository.
738             *
739             * @param  fileEntryId the primary key of the file entry
740             * @param  version the version label of the file version
741             * @throws PortalException if the file version could not be found or invalid
742             */
743            @Override
744            public void deleteFileVersion(long fileEntryId, String version)
745                    throws PortalException {
746    
747                    Repository repository = getFileEntryRepository(fileEntryId);
748    
749                    repository.deleteFileVersion(fileEntryId, version);
750            }
751    
752            /**
753             * Deletes the folder with the primary key and all of its subfolders and
754             * file entries.
755             *
756             * @param  folderId the primary key of the folder
757             * @throws PortalException if the folder could not be found
758             */
759            @Override
760            public void deleteFolder(long folderId) throws PortalException {
761                    Repository repository = getFolderRepository(folderId);
762    
763                    Folder folder = repository.getFolder(folderId);
764    
765                    if (repository.isCapabilityProvided(TrashCapability.class)) {
766                            TrashCapability trashCapability = repository.getCapability(
767                                    TrashCapability.class);
768    
769                            if (trashCapability.isInTrash(folder)) {
770                                    trashEntryService.deleteEntry(
771                                            DLFolderConstants.getClassName(), folder.getFolderId());
772    
773                                    return;
774                            }
775                    }
776    
777                    List<FileEntry> fileEntries = repository.getRepositoryFileEntries(
778                            0, folderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
779    
780                    for (FileEntry fileEntry : fileEntries) {
781                            dlAppHelperLocalService.deleteFileEntry(fileEntry);
782                    }
783    
784                    repository.deleteFolder(folderId);
785    
786                    dlAppHelperLocalService.deleteFolder(folder);
787            }
788    
789            /**
790             * Deletes the folder with the name in the parent folder and all of its
791             * subfolders and file entries.
792             *
793             * @param  repositoryId the primary key of the repository
794             * @param  parentFolderId the primary key of the folder's parent folder
795             * @param  name the folder's name
796             * @throws PortalException if the folder could not be found
797             */
798            @Override
799            public void deleteFolder(
800                            long repositoryId, long parentFolderId, String name)
801                    throws PortalException {
802    
803                    Repository repository = getRepository(repositoryId);
804    
805                    Folder folder = repository.getFolder(parentFolderId, name);
806    
807                    if (repository.isCapabilityProvided(TrashCapability.class)) {
808                            TrashCapability trashCapability = repository.getCapability(
809                                    TrashCapability.class);
810    
811                            if (trashCapability.isInTrash(folder)) {
812                                    trashEntryService.deleteEntry(
813                                            DLFolderConstants.getClassName(), folder.getFolderId());
814    
815                                    return;
816                            }
817                    }
818    
819                    repository.deleteFolder(parentFolderId, name);
820            }
821    
822            /**
823             * Deletes the temporary file entry.
824             *
825             * @param  groupId the primary key of the group
826             * @param  folderId the primary key of the folder where the file entry was
827             *         eventually to reside
828             * @param  folderName the temporary folder's name
829             * @param  fileName the file's original name
830             * @throws PortalException if the file name was invalid
831             * @see    TempFileEntryUtil
832             */
833            @Override
834            public void deleteTempFileEntry(
835                            long groupId, long folderId, String folderName, String fileName)
836                    throws PortalException {
837    
838                    DLFolderPermission.check(
839                            getPermissionChecker(), groupId, folderId, ActionKeys.ADD_DOCUMENT);
840    
841                    TempFileEntryUtil.deleteTempFileEntry(
842                            groupId, getUserId(), folderName, fileName);
843            }
844    
845            /**
846             * Returns all the file entries in the folder.
847             *
848             * @param  repositoryId the primary key of the file entry's repository
849             * @param  folderId the primary key of the file entry's folder
850             * @return the file entries in the folder
851             * @throws PortalException if the folder could not be found
852             */
853            @Override
854            public List<FileEntry> getFileEntries(long repositoryId, long folderId)
855                    throws PortalException {
856    
857                    return getFileEntries(
858                            repositoryId, folderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
859            }
860    
861            /**
862             * Returns a name-ordered range of all the file entries in the folder.
863             *
864             * <p>
865             * Useful when paginating results. Returns a maximum of <code>end -
866             * start</code> instances. <code>start</code> and <code>end</code> are not
867             * primary keys, they are indexes in the result set. Thus, <code>0</code>
868             * refers to the first result in the set. Setting both <code>start</code>
869             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
870             * result set.
871             * </p>
872             *
873             * @param  repositoryId the primary key of the file entry's repository
874             * @param  folderId the primary key of the file entry's folder
875             * @param  start the lower bound of the range of results
876             * @param  end the upper bound of the range of results (not inclusive)
877             * @return the name-ordered range of file entries in the folder
878             * @throws PortalException if the folder could not be found
879             */
880            @Override
881            public List<FileEntry> getFileEntries(
882                            long repositoryId, long folderId, int start, int end)
883                    throws PortalException {
884    
885                    return getFileEntries(
886                            repositoryId, folderId, start, end,
887                            new RepositoryModelTitleComparator<FileEntry>(true));
888            }
889    
890            /**
891             * Returns an ordered range of all the file entries in the folder.
892             *
893             * <p>
894             * Useful when paginating results. Returns a maximum of <code>end -
895             * start</code> instances. <code>start</code> and <code>end</code> are not
896             * primary keys, they are indexes in the result set. Thus, <code>0</code>
897             * refers to the first result in the set. Setting both <code>start</code>
898             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
899             * result set.
900             * </p>
901             *
902             * @param  repositoryId the primary key of the file entry's repository
903             * @param  folderId the primary key of the file entry's folder
904             * @param  start the lower bound of the range of results
905             * @param  end the upper bound of the range of results (not inclusive)
906             * @param  obc the comparator to order the file entries (optionally
907             *         <code>null</code>)
908             * @return the range of file entries in the folder ordered by comparator
909             *         <code>obc</code>
910             * @throws PortalException if the folder could not be found
911             */
912            @Override
913            public List<FileEntry> getFileEntries(
914                            long repositoryId, long folderId, int start, int end,
915                            OrderByComparator<FileEntry> obc)
916                    throws PortalException {
917    
918                    Repository repository = getRepository(repositoryId);
919    
920                    return repository.getFileEntries(folderId, start, end, obc);
921            }
922    
923            /**
924             * Returns the file entries with the file entry type in the folder.
925             *
926             * @param  repositoryId the primary key of the file entry's repository
927             * @param  folderId the primary key of the file entry's folder
928             * @param  fileEntryTypeId the primary key of the file entry type
929             * @return the file entries with the file entry type in the folder
930             * @throws PortalException if the folder could not be found
931             */
932            @Override
933            public List<FileEntry> getFileEntries(
934                            long repositoryId, long folderId, long fileEntryTypeId)
935                    throws PortalException {
936    
937                    return getFileEntries(
938                            repositoryId, folderId, fileEntryTypeId, QueryUtil.ALL_POS,
939                            QueryUtil.ALL_POS);
940            }
941    
942            /**
943             * Returns a name-ordered range of all the file entries with the file entry
944             * type in the folder.
945             *
946             * @param  repositoryId the primary key of the file entry's repository
947             * @param  folderId the primary key of the file entry's folder
948             * @param  fileEntryTypeId the primary key of the file entry type
949             * @param  start the lower bound of the range of results
950             * @param  end the upper bound of the range of results (not inclusive)
951             * @return the name-ordered range of the file entries in the folder
952             * @throws PortalException if the folder could not be found
953             */
954            @Override
955            public List<FileEntry> getFileEntries(
956                            long repositoryId, long folderId, long fileEntryTypeId, int start,
957                            int end)
958                    throws PortalException {
959    
960                    return getFileEntries(
961                            repositoryId, folderId, fileEntryTypeId, start, end,
962                            new RepositoryModelTitleComparator<FileEntry>(true));
963            }
964    
965            /**
966             * Returns an ordered range of all the file entries with the file entry type
967             * in the folder.
968             *
969             * @param  repositoryId the primary key of the repository
970             * @param  folderId the primary key of the folder
971             * @param  fileEntryTypeId the primary key of the file entry type
972             * @param  start the lower bound of the range of results
973             * @param  end the upper bound of the range of results (not inclusive)
974             * @param  obc the comparator to order the results by (optionally
975             *         <code>null</code>)
976             * @return the range of file entries with the file entry type in the folder
977             *         ordered by <code>null</code>
978             * @throws PortalException if the folder could not be found
979             */
980            @Override
981            public List<FileEntry> getFileEntries(
982                            long repositoryId, long folderId, long fileEntryTypeId, int start,
983                            int end, OrderByComparator<FileEntry> obc)
984                    throws PortalException {
985    
986                    Repository repository = getRepository(repositoryId);
987    
988                    return repository.getFileEntries(
989                            folderId, fileEntryTypeId, start, end, obc);
990            }
991    
992            @Override
993            public List<FileEntry> getFileEntries(
994                            long repositoryId, long folderId, String[] mimeTypes)
995                    throws PortalException {
996    
997                    return getFileEntries(
998                            repositoryId, folderId, mimeTypes, QueryUtil.ALL_POS,
999                            QueryUtil.ALL_POS,
1000                            new RepositoryModelTitleComparator<FileEntry>(true));
1001            }
1002    
1003            @Override
1004            public List<FileEntry> getFileEntries(
1005                            long repositoryId, long folderId, String[] mimeTypes, int start,
1006                            int end, OrderByComparator<FileEntry> obc)
1007                    throws PortalException {
1008    
1009                    Repository repository = getRepository(repositoryId);
1010    
1011                    return repository.getFileEntries(folderId, mimeTypes, start, end, obc);
1012            }
1013    
1014            /**
1015             * Returns a range of all the file entries and shortcuts in the folder.
1016             *
1017             * <p>
1018             * Useful when paginating results. Returns a maximum of <code>end -
1019             * start</code> instances. <code>start</code> and <code>end</code> are not
1020             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1021             * refers to the first result in the set. Setting both <code>start</code>
1022             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1023             * result set.
1024             * </p>
1025             *
1026             * @param  repositoryId the primary key of the repository
1027             * @param  folderId the primary key of the folder
1028             * @param  status the workflow status
1029             * @param  start the lower bound of the range of results
1030             * @param  end the upper bound of the range of results (not inclusive)
1031             * @return the range of file entries and shortcuts in the folder
1032             * @throws PortalException if the folder could not be found
1033             */
1034            @Override
1035            @SuppressWarnings("rawtypes")
1036            public List<Object> getFileEntriesAndFileShortcuts(
1037                            long repositoryId, long folderId, int status, int start, int end)
1038                    throws PortalException {
1039    
1040                    Repository repository = getRepository(repositoryId);
1041    
1042                    return (List)repository.getFileEntriesAndFileShortcuts(
1043                            folderId, status, start, end);
1044            }
1045    
1046            /**
1047             * Returns the number of file entries and shortcuts in the folder.
1048             *
1049             * @param  repositoryId the primary key of the repository
1050             * @param  folderId the primary key of the folder
1051             * @param  status the workflow status
1052             * @return the number of file entries and shortcuts in the folder
1053             * @throws PortalException if the folder ould not be found
1054             */
1055            @Override
1056            public int getFileEntriesAndFileShortcutsCount(
1057                            long repositoryId, long folderId, int status)
1058                    throws PortalException {
1059    
1060                    Repository repository = getRepository(repositoryId);
1061    
1062                    return repository.getFileEntriesAndFileShortcutsCount(folderId, status);
1063            }
1064    
1065            /**
1066             * Returns the number of file entries and shortcuts in the folder.
1067             *
1068             * @param  repositoryId the primary key of the repository
1069             * @param  folderId the primary key of the folder
1070             * @param  status the workflow status
1071             * @param  mimeTypes allowed media types
1072             * @return the number of file entries and shortcuts in the folder
1073             * @throws PortalException if the folder ould not be found
1074             */
1075            @Override
1076            public int getFileEntriesAndFileShortcutsCount(
1077                            long repositoryId, long folderId, int status, String[] mimeTypes)
1078                    throws PortalException {
1079    
1080                    Repository repository = getRepository(repositoryId);
1081    
1082                    return repository.getFileEntriesAndFileShortcutsCount(
1083                            folderId, status, mimeTypes);
1084            }
1085    
1086            /**
1087             * Returns the number of file entries in the folder.
1088             *
1089             * @param  repositoryId the primary key of the file entry's repository
1090             * @param  folderId the primary key of the file entry's folder
1091             * @return the number of file entries in the folder
1092             * @throws PortalException if the folder could not be found
1093             */
1094            @Override
1095            public int getFileEntriesCount(long repositoryId, long folderId)
1096                    throws PortalException {
1097    
1098                    Repository repository = getRepository(repositoryId);
1099    
1100                    return repository.getFileEntriesCount(folderId);
1101            }
1102    
1103            /**
1104             * Returns the number of file entries with the file entry type in the
1105             * folder.
1106             *
1107             * @param  repositoryId the primary key of the file entry's repository
1108             * @param  folderId the primary key of the file entry's folder
1109             * @param  fileEntryTypeId the primary key of the file entry type
1110             * @return the number of file entries with the file entry type in the folder
1111             * @throws PortalException if the folder could not be found
1112             */
1113            @Override
1114            public int getFileEntriesCount(
1115                            long repositoryId, long folderId, long fileEntryTypeId)
1116                    throws PortalException {
1117    
1118                    Repository repository = getRepository(repositoryId);
1119    
1120                    return repository.getFileEntriesCount(folderId, fileEntryTypeId);
1121            }
1122    
1123            @Override
1124            public int getFileEntriesCount(
1125                            long repositoryId, long folderId, String[] mimeTypes)
1126                    throws PortalException {
1127    
1128                    Repository repository = getRepository(repositoryId);
1129    
1130                    return repository.getFileEntriesCount(folderId, mimeTypes);
1131            }
1132    
1133            /**
1134             * Returns the file entry with the primary key.
1135             *
1136             * @param  fileEntryId the primary key of the file entry
1137             * @return the file entry with the primary key
1138             * @throws PortalException if the file entry could not be found
1139             */
1140            @Override
1141            public FileEntry getFileEntry(long fileEntryId) throws PortalException {
1142                    Repository repository = getFileEntryRepository(fileEntryId);
1143    
1144                    return repository.getFileEntry(fileEntryId);
1145            }
1146    
1147            /**
1148             * Returns the file entry with the title in the folder.
1149             *
1150             * @param  groupId the primary key of the file entry's group
1151             * @param  folderId the primary key of the file entry's folder
1152             * @param  title the file entry's title
1153             * @return the file entry with the title in the folder
1154             * @throws PortalException if the file entry could not be found
1155             */
1156            @Override
1157            public FileEntry getFileEntry(long groupId, long folderId, String title)
1158                    throws PortalException {
1159    
1160                    try {
1161                            Repository repository = getRepository(groupId);
1162    
1163                            return repository.getFileEntry(folderId, title);
1164                    }
1165                    catch (NoSuchFileEntryException nsfee) {
1166                            if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1167                                    Repository repository = getFolderRepository(folderId);
1168    
1169                                    return repository.getFileEntry(folderId, title);
1170                            }
1171                            else {
1172                                    throw nsfee;
1173                            }
1174                    }
1175            }
1176    
1177            /**
1178             * Returns the file entry with the UUID and group.
1179             *
1180             * @param  uuid the file entry's UUID
1181             * @param  groupId the primary key of the file entry's group
1182             * @return the file entry with the UUID and group
1183             * @throws PortalException if the file entry could not be found
1184             */
1185            @Override
1186            public FileEntry getFileEntryByUuidAndGroupId(String uuid, long groupId)
1187                    throws PortalException {
1188    
1189                    FileEntry fileEntry = fetchFileEntryByUuidAndRepositoryId(
1190                            uuid, groupId);
1191    
1192                    if (fileEntry != null) {
1193                            return fileEntry;
1194                    }
1195    
1196                    List<com.liferay.portal.model.Repository> repositories =
1197                            repositoryPersistence.findByGroupId(groupId);
1198    
1199                    for (com.liferay.portal.model.Repository repository : repositories) {
1200                            fileEntry = fetchFileEntryByUuidAndRepositoryId(
1201                                    uuid, repository.getRepositoryId());
1202    
1203                            if (fileEntry != null) {
1204                                    return fileEntry;
1205                            }
1206                    }
1207    
1208                    StringBundler msg = new StringBundler(6);
1209    
1210                    msg.append("No DLFileEntry exists with the key {");
1211                    msg.append("uuid=");
1212                    msg.append(uuid);
1213                    msg.append(", groupId=");
1214                    msg.append(groupId);
1215                    msg.append(StringPool.CLOSE_CURLY_BRACE);
1216    
1217                    throw new NoSuchFileEntryException(msg.toString());
1218            }
1219    
1220            /**
1221             * Returns the file shortcut with the primary key. This method is only
1222             * supported by the Liferay repository.
1223             *
1224             * @param  fileShortcutId the primary key of the file shortcut
1225             * @return the file shortcut with the primary key
1226             * @throws PortalException if the file shortcut could not be found
1227             */
1228            @Override
1229            public FileShortcut getFileShortcut(long fileShortcutId)
1230                    throws PortalException {
1231    
1232                    Repository repository = getFileShortcutRepository(fileShortcutId);
1233    
1234                    return repository.getFileShortcut(fileShortcutId);
1235            }
1236    
1237            /**
1238             * Returns the file version with the primary key.
1239             *
1240             * @param  fileVersionId the primary key of the file version
1241             * @return the file version with the primary key
1242             * @throws PortalException if the file version could not be found
1243             */
1244            @Override
1245            public FileVersion getFileVersion(long fileVersionId)
1246                    throws PortalException {
1247    
1248                    Repository repository = getFileVersionRepository(fileVersionId);
1249    
1250                    return repository.getFileVersion(fileVersionId);
1251            }
1252    
1253            /**
1254             * Returns the folder with the primary key.
1255             *
1256             * @param  folderId the primary key of the folder
1257             * @return the folder with the primary key
1258             * @throws PortalException if the folder could not be found
1259             */
1260            @Override
1261            public Folder getFolder(long folderId) throws PortalException {
1262                    Repository repository = getFolderRepository(folderId);
1263    
1264                    return repository.getFolder(folderId);
1265            }
1266    
1267            /**
1268             * Returns the folder with the name in the parent folder.
1269             *
1270             * @param  repositoryId the primary key of the folder's repository
1271             * @param  parentFolderId the primary key of the folder's parent folder
1272             * @param  name the folder's name
1273             * @return the folder with the name in the parent folder
1274             * @throws PortalException if the folder could not be found
1275             */
1276            @Override
1277            public Folder getFolder(long repositoryId, long parentFolderId, String name)
1278                    throws PortalException {
1279    
1280                    Repository repository = getRepository(repositoryId);
1281    
1282                    return repository.getFolder(parentFolderId, name);
1283            }
1284    
1285            /**
1286             * Returns all immediate subfolders of the parent folder.
1287             *
1288             * @param  repositoryId the primary key of the folder's repository
1289             * @param  parentFolderId the primary key of the folder's parent folder
1290             * @return the immediate subfolders of the parent folder
1291             * @throws PortalException if the parent folder could not be found
1292             */
1293            @Override
1294            public List<Folder> getFolders(long repositoryId, long parentFolderId)
1295                    throws PortalException {
1296    
1297                    return getFolders(
1298                            repositoryId, parentFolderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1299            }
1300    
1301            /**
1302             * Returns all immediate subfolders of the parent folder, optionally
1303             * including mount folders for third-party repositories.
1304             *
1305             * @param  repositoryId the primary key of the folder's repository
1306             * @param  parentFolderId the primary key of the folder's parent folder
1307             * @param  includeMountFolders whether to include mount folders for
1308             *         third-party repositories
1309             * @return the immediate subfolders of the parent folder
1310             * @throws PortalException if the parent folder could not be found
1311             */
1312            @Override
1313            public List<Folder> getFolders(
1314                            long repositoryId, long parentFolderId, boolean includeMountFolders)
1315                    throws PortalException {
1316    
1317                    return getFolders(
1318                            repositoryId, parentFolderId, includeMountFolders,
1319                            QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1320            }
1321    
1322            /**
1323             * Returns a name-ordered range of all the immediate subfolders of the
1324             * parent folder, optionally including mount folders for third-party
1325             * repositories.
1326             *
1327             * <p>
1328             * Useful when paginating results. Returns a maximum of <code>end -
1329             * start</code> instances. <code>start</code> and <code>end</code> are not
1330             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1331             * refers to the first result in the set. Setting both <code>start</code>
1332             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1333             * result set.
1334             * </p>
1335             *
1336             * @param  repositoryId the primary key of the folder's repository
1337             * @param  parentFolderId the primary key of the folder's parent folder
1338             * @param  includeMountFolders whether to include mount folders for
1339             *         third-party repositories
1340             * @param  start the lower bound of the range of results
1341             * @param  end the upper bound of the range of results (not inclusive)
1342             * @return the name-ordered range of immediate subfolders of the parent
1343             *         folder
1344             * @throws PortalException if the parent folder could not be found
1345             */
1346            @Override
1347            public List<Folder> getFolders(
1348                            long repositoryId, long parentFolderId, boolean includeMountFolders,
1349                            int start, int end)
1350                    throws PortalException {
1351    
1352                    return getFolders(
1353                            repositoryId, parentFolderId, includeMountFolders, start, end,
1354                            new FolderNameComparator(true));
1355            }
1356    
1357            /**
1358             * Returns an ordered range of all the immediate subfolders of the parent
1359             * folder.
1360             *
1361             * <p>
1362             * Useful when paginating results. Returns a maximum of <code>end -
1363             * start</code> instances. <code>start</code> and <code>end</code> are not
1364             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1365             * refers to the first result in the set. Setting both <code>start</code>
1366             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1367             * result set.
1368             * </p>
1369             *
1370             * @param  repositoryId the primary key of the folder's repository
1371             * @param  parentFolderId the primary key of the folder's parent folder
1372             * @param  includeMountFolders whether to include mount folders for
1373             *         third-party repositories
1374             * @param  start the lower bound of the range of results
1375             * @param  end the upper bound of the range of results (not inclusive)
1376             * @param  obc the comparator to order the folders (optionally
1377             *         <code>null</code>)
1378             * @return the range of immediate subfolders of the parent folder ordered by
1379             *         comparator <code>obc</code>
1380             * @throws PortalException if the parent folder could not be found
1381             */
1382            @Override
1383            public List<Folder> getFolders(
1384                            long repositoryId, long parentFolderId, boolean includeMountFolders,
1385                            int start, int end, OrderByComparator<Folder> obc)
1386                    throws PortalException {
1387    
1388                    Repository repository = getRepository(repositoryId);
1389    
1390                    return repository.getFolders(
1391                            parentFolderId, includeMountFolders, start, end, obc);
1392            }
1393    
1394            /**
1395             * Returns an ordered range of all the immediate subfolders of the parent
1396             * folder.
1397             *
1398             * <p>
1399             * Useful when paginating results. Returns a maximum of <code>end -
1400             * start</code> instances. <code>start</code> and <code>end</code> are not
1401             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1402             * refers to the first result in the set. Setting both <code>start</code>
1403             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1404             * result set.
1405             * </p>
1406             *
1407             * @param  repositoryId the primary key of the folder's repository
1408             * @param  parentFolderId the primary key of the folder's parent folder
1409             * @param  status the workflow status
1410             * @param  includeMountFolders whether to include mount folders for
1411             *         third-party repositories
1412             * @param  start the lower bound of the range of results
1413             * @param  end the upper bound of the range of results (not inclusive)
1414             * @param  obc the comparator to order the folders (optionally
1415             *         <code>null</code>)
1416             * @return the range of immediate subfolders of the parent folder ordered by
1417             *         comparator <code>obc</code>
1418             * @throws PortalException if the parent folder could not be found
1419             */
1420            @Override
1421            public List<Folder> getFolders(
1422                            long repositoryId, long parentFolderId, int status,
1423                            boolean includeMountFolders, int start, int end,
1424                            OrderByComparator<Folder> obc)
1425                    throws PortalException {
1426    
1427                    Repository repository = getRepository(repositoryId);
1428    
1429                    return repository.getFolders(
1430                            parentFolderId, status, includeMountFolders, start, end, obc);
1431            }
1432    
1433            /**
1434             * Returns a name-ordered range of all the immediate subfolders of the
1435             * parent folder.
1436             *
1437             * <p>
1438             * Useful when paginating results. Returns a maximum of <code>end -
1439             * start</code> instances. <code>start</code> and <code>end</code> are not
1440             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1441             * refers to the first result in the set. Setting both <code>start</code>
1442             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1443             * result set.
1444             * </p>
1445             *
1446             * @param  repositoryId the primary key of the folder's repository
1447             * @param  parentFolderId the primary key of the folder's parent folder
1448             * @param  start the lower bound of the range of results
1449             * @param  end the upper bound of the range of results (not inclusive)
1450             * @return the name-ordered range of immediate subfolders of the parent
1451             *         folder
1452             * @throws PortalException if the parent folder could not be found
1453             */
1454            @Override
1455            public List<Folder> getFolders(
1456                            long repositoryId, long parentFolderId, int start, int end)
1457                    throws PortalException {
1458    
1459                    return getFolders(
1460                            repositoryId, parentFolderId, start, end,
1461                            new FolderNameComparator(true));
1462            }
1463    
1464            /**
1465             * Returns an ordered range of all the immediate subfolders of the parent
1466             * folder.
1467             *
1468             * <p>
1469             * Useful when paginating results. Returns a maximum of <code>end -
1470             * start</code> instances. <code>start</code> and <code>end</code> are not
1471             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1472             * refers to the first result in the set. Setting both <code>start</code>
1473             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1474             * result set.
1475             * </p>
1476             *
1477             * @param  repositoryId the primary key of the folder's repository
1478             * @param  parentFolderId the primary key of the folder's parent folder
1479             * @param  start the lower bound of the range of results
1480             * @param  end the upper bound of the range of results (not inclusive)
1481             * @param  obc the comparator to order the folders (optionally
1482             *         <code>null</code>)
1483             * @return the range of immediate subfolders of the parent folder ordered by
1484             *         comparator <code>obc</code>
1485             * @throws PortalException if the parent folder could not be found
1486             */
1487            @Override
1488            public List<Folder> getFolders(
1489                            long repositoryId, long parentFolderId, int start, int end,
1490                            OrderByComparator<Folder> obc)
1491                    throws PortalException {
1492    
1493                    Repository repository = getRepository(repositoryId);
1494    
1495                    return repository.getFolders(parentFolderId, true, start, end, obc);
1496            }
1497    
1498            /**
1499             * Returns a name-ordered range of all the immediate subfolders, file
1500             * entries, and file shortcuts in the parent folder.
1501             *
1502             * <p>
1503             * Useful when paginating results. Returns a maximum of <code>end -
1504             * start</code> instances. <code>start</code> and <code>end</code> are not
1505             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1506             * refers to the first result in the set. Setting both <code>start</code>
1507             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1508             * result set.
1509             * </p>
1510             *
1511             * @param  repositoryId the primary key of the repository
1512             * @param  folderId the primary key of the parent folder
1513             * @param  status the workflow status
1514             * @param  includeMountFolders whether to include mount folders for
1515             *         third-party repositories
1516             * @param  start the lower bound of the range of results
1517             * @param  end the upper bound of the range of results (not inclusive)
1518             * @return the name-ordered range of immediate subfolders, file entries, and
1519             *         file shortcuts in the parent folder
1520             * @throws PortalException if the parent folder could not be found
1521             */
1522            @Override
1523            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
1524                            long repositoryId, long folderId, int status,
1525                            boolean includeMountFolders, int start, int end)
1526                    throws PortalException {
1527    
1528                    return getFoldersAndFileEntriesAndFileShortcuts(
1529                            repositoryId, folderId, status, includeMountFolders, start, end,
1530                            new RepositoryModelTitleComparator<Object>(true));
1531            }
1532    
1533            /**
1534             * Returns an ordered range of all the immediate subfolders, file entries,
1535             * and file shortcuts in the parent folder.
1536             *
1537             * <p>
1538             * Useful when paginating results. Returns a maximum of <code>end -
1539             * start</code> instances. <code>start</code> and <code>end</code> are not
1540             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1541             * refers to the first result in the set. Setting both <code>start</code>
1542             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1543             * result set.
1544             * </p>
1545             *
1546             * @param  repositoryId the primary key of the repository
1547             * @param  folderId the primary key of the parent folder
1548             * @param  status the workflow status
1549             * @param  includeMountFolders whether to include mount folders for
1550             *         third-party repositories
1551             * @param  start the lower bound of the range of results
1552             * @param  end the upper bound of the range of results (not inclusive)
1553             * @param  obc the comparator to order the results (optionally
1554             *         <code>null</code>)
1555             * @return the range of immediate subfolders, file entries, and file
1556             *         shortcuts in the parent folder ordered by comparator
1557             *         <code>obc</code>
1558             * @throws PortalException if the parent folder could not be found
1559             */
1560            @Override
1561            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
1562                            long repositoryId, long folderId, int status,
1563                            boolean includeMountFolders, int start, int end,
1564                            OrderByComparator<?> obc)
1565                    throws PortalException {
1566    
1567                    return getFoldersAndFileEntriesAndFileShortcuts(
1568                            repositoryId, folderId, status, null, includeMountFolders, start,
1569                            end, obc);
1570            }
1571    
1572            @Override
1573            @SuppressWarnings("rawtypes")
1574            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
1575                            long repositoryId, long folderId, int status, String[] mimeTypes,
1576                            boolean includeMountFolders, int start, int end,
1577                            OrderByComparator<?> obc)
1578                    throws PortalException {
1579    
1580                    Repository repository = getRepository(repositoryId);
1581    
1582                    return (List)repository.getFoldersAndFileEntriesAndFileShortcuts(
1583                            folderId, status, mimeTypes, includeMountFolders, start, end, obc);
1584            }
1585    
1586            /**
1587             * Returns the number of immediate subfolders, file entries, and file
1588             * shortcuts in the parent folder.
1589             *
1590             * @param  repositoryId the primary key of the repository
1591             * @param  folderId the primary key of the parent folder
1592             * @param  status the workflow status
1593             * @param  includeMountFolders whether to include mount folders for
1594             *         third-party repositories
1595             * @return the number of immediate subfolders, file entries, and file
1596             *         shortcuts in the parent folder
1597             * @throws PortalException if the folder could not be found
1598             */
1599            @Override
1600            public int getFoldersAndFileEntriesAndFileShortcutsCount(
1601                            long repositoryId, long folderId, int status,
1602                            boolean includeMountFolders)
1603                    throws PortalException {
1604    
1605                    return getFoldersAndFileEntriesAndFileShortcutsCount(
1606                            repositoryId, folderId, status, null, includeMountFolders);
1607            }
1608    
1609            @Override
1610            public int getFoldersAndFileEntriesAndFileShortcutsCount(
1611                            long repositoryId, long folderId, int status, String[] mimeTypes,
1612                            boolean includeMountFolders)
1613                    throws PortalException {
1614    
1615                    Repository repository = getRepository(repositoryId);
1616    
1617                    return repository.getFoldersAndFileEntriesAndFileShortcutsCount(
1618                            folderId, status, mimeTypes, includeMountFolders);
1619            }
1620    
1621            /**
1622             * Returns the number of immediate subfolders of the parent folder.
1623             *
1624             * @param  repositoryId the primary key of the folder's repository
1625             * @param  parentFolderId the primary key of the folder's parent folder
1626             * @return the number of immediate subfolders of the parent folder
1627             * @throws PortalException if the parent folder could not be found
1628             */
1629            @Override
1630            public int getFoldersCount(long repositoryId, long parentFolderId)
1631                    throws PortalException {
1632    
1633                    return getFoldersCount(repositoryId, parentFolderId, true);
1634            }
1635    
1636            /**
1637             * Returns the number of immediate subfolders of the parent folder,
1638             * optionally including mount folders for third-party repositories.
1639             *
1640             * @param  repositoryId the primary key of the folder's repository
1641             * @param  parentFolderId the primary key of the folder's parent folder
1642             * @param  includeMountFolders whether to include mount folders for
1643             *         third-party repositories
1644             * @return the number of immediate subfolders of the parent folder
1645             * @throws PortalException if the parent folder could not be found
1646             */
1647            @Override
1648            public int getFoldersCount(
1649                            long repositoryId, long parentFolderId, boolean includeMountFolders)
1650                    throws PortalException {
1651    
1652                    Repository repository = getRepository(repositoryId);
1653    
1654                    return repository.getFoldersCount(parentFolderId, includeMountFolders);
1655            }
1656    
1657            /**
1658             * Returns the number of immediate subfolders of the parent folder,
1659             * optionally including mount folders for third-party repositories.
1660             *
1661             * @param  repositoryId the primary key of the folder's repository
1662             * @param  parentFolderId the primary key of the folder's parent folder
1663             * @param  status the workflow status
1664             * @param  includeMountFolders whether to include mount folders for
1665             *         third-party repositories
1666             * @return the number of immediate subfolders of the parent folder
1667             * @throws PortalException if the parent folder could not be found
1668             */
1669            @Override
1670            public int getFoldersCount(
1671                            long repositoryId, long parentFolderId, int status,
1672                            boolean includeMountFolders)
1673                    throws PortalException {
1674    
1675                    Repository repository = getRepository(repositoryId);
1676    
1677                    return repository.getFoldersCount(
1678                            parentFolderId, status, includeMountFolders);
1679            }
1680    
1681            /**
1682             * Returns the number of immediate subfolders and file entries across the
1683             * folders.
1684             *
1685             * @param  repositoryId the primary key of the repository
1686             * @param  folderIds the primary keys of folders from which to count
1687             *         immediate subfolders and file entries
1688             * @param  status the workflow status
1689             * @return the number of immediate subfolders and file entries across the
1690             *         folders
1691             * @throws PortalException if the repository could not be found
1692             */
1693            @Override
1694            public int getFoldersFileEntriesCount(
1695                            long repositoryId, List<Long> folderIds, int status)
1696                    throws PortalException {
1697    
1698                    Repository repository = getRepository(repositoryId);
1699    
1700                    return repository.getFoldersFileEntriesCount(folderIds, status);
1701            }
1702    
1703            /**
1704             * Returns an ordered range of all the file entries in the group starting at
1705             * the repository default parent folder that are stored within the Liferay
1706             * repository. This method is primarily used to search for recently modified
1707             * file entries. It can be limited to the file entries modified by a given
1708             * user.
1709             *
1710             * <p>
1711             * Useful when paginating results. Returns a maximum of <code>end -
1712             * start</code> instances. <code>start</code> and <code>end</code> are not
1713             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1714             * refers to the first result in the set. Setting both <code>start</code>
1715             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1716             * result set.
1717             * </p>
1718             *
1719             * @param  groupId the primary key of the group
1720             * @param  userId the primary key of the user who created the file
1721             *         (optionally <code>0</code>)
1722             * @param  start the lower bound of the range of results
1723             * @param  end the upper bound of the range of results (not inclusive)
1724             * @return the range of matching file entries ordered by date modified
1725             * @throws PortalException if the group could not be found
1726             */
1727            @Override
1728            public List<FileEntry> getGroupFileEntries(
1729                            long groupId, long userId, int start, int end)
1730                    throws PortalException {
1731    
1732                    return getGroupFileEntries(
1733                            groupId, userId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, start,
1734                            end, new RepositoryModelModifiedDateComparator<FileEntry>());
1735            }
1736    
1737            /**
1738             * Returns an ordered range of all the file entries in the group that are
1739             * stored within the Liferay repository. This method is primarily used to
1740             * search for recently modified file entries. It can be limited to the file
1741             * entries modified by a given user.
1742             *
1743             * <p>
1744             * Useful when paginating results. Returns a maximum of <code>end -
1745             * start</code> instances. <code>start</code> and <code>end</code> are not
1746             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1747             * refers to the first result in the set. Setting both <code>start</code>
1748             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1749             * result set.
1750             * </p>
1751             *
1752             * @param  groupId the primary key of the group
1753             * @param  userId the primary key of the user who created the file
1754             *         (optionally <code>0</code>)
1755             * @param  start the lower bound of the range of results
1756             * @param  end the upper bound of the range of results (not inclusive)
1757             * @param  obc the comparator to order the file entries (optionally
1758             *         <code>null</code>)
1759             * @return the range of matching file entries ordered by comparator
1760             *         <code>obc</code>
1761             * @throws PortalException if the group could not be found
1762             */
1763            @Override
1764            public List<FileEntry> getGroupFileEntries(
1765                            long groupId, long userId, int start, int end,
1766                            OrderByComparator<FileEntry> obc)
1767                    throws PortalException {
1768    
1769                    return getGroupFileEntries(
1770                            groupId, userId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, start,
1771                            end, obc);
1772            }
1773    
1774            /**
1775             * Returns an ordered range of all the file entries in the group starting at
1776             * the root folder that are stored within the Liferay repository. This
1777             * method is primarily used to search for recently modified file entries. It
1778             * can be limited to the file entries modified by a given user.
1779             *
1780             * <p>
1781             * Useful when paginating results. Returns a maximum of <code>end -
1782             * start</code> instances. <code>start</code> and <code>end</code> are not
1783             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1784             * refers to the first result in the set. Setting both <code>start</code>
1785             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1786             * result set.
1787             * </p>
1788             *
1789             * @param  groupId the primary key of the group
1790             * @param  userId the primary key of the user who created the file
1791             *         (optionally <code>0</code>)
1792             * @param  rootFolderId the primary key of the root folder to begin the
1793             *         search
1794             * @param  start the lower bound of the range of results
1795             * @param  end the upper bound of the range of results (not inclusive)
1796             * @return the range of matching file entries ordered by date modified
1797             * @throws PortalException if the group could not be found
1798             */
1799            @Override
1800            public List<FileEntry> getGroupFileEntries(
1801                            long groupId, long userId, long rootFolderId, int start, int end)
1802                    throws PortalException {
1803    
1804                    return getGroupFileEntries(
1805                            groupId, userId, rootFolderId, start, end,
1806                            new RepositoryModelModifiedDateComparator<FileEntry>());
1807            }
1808    
1809            /**
1810             * Returns an ordered range of all the file entries in the group starting at
1811             * the root folder that are stored within the Liferay repository. This
1812             * method is primarily used to search for recently modified file entries. It
1813             * can be limited to the file entries modified by a given user.
1814             *
1815             * <p>
1816             * Useful when paginating results. Returns a maximum of <code>end -
1817             * start</code> instances. <code>start</code> and <code>end</code> are not
1818             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1819             * refers to the first result in the set. Setting both <code>start</code>
1820             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1821             * result set.
1822             * </p>
1823             *
1824             * @param  groupId the primary key of the group
1825             * @param  userId the primary key of the user who created the file
1826             *         (optionally <code>0</code>)
1827             * @param  rootFolderId the primary key of the root folder to begin the
1828             *         search
1829             * @param  start the lower bound of the range of results
1830             * @param  end the upper bound of the range of results (not inclusive)
1831             * @param  obc the comparator to order the file entries (optionally
1832             *         <code>null</code>)
1833             * @return the range of matching file entries ordered by comparator
1834             *         <code>obc</code>
1835             * @throws PortalException if the group could not be found
1836             */
1837            @Override
1838            public List<FileEntry> getGroupFileEntries(
1839                            long groupId, long userId, long rootFolderId, int start, int end,
1840                            OrderByComparator<FileEntry> obc)
1841                    throws PortalException {
1842    
1843                    Repository repository = getRepository(groupId);
1844    
1845                    return repository.getRepositoryFileEntries(
1846                            userId, rootFolderId, start, end, obc);
1847            }
1848    
1849            @Override
1850            public List<FileEntry> getGroupFileEntries(
1851                            long groupId, long userId, long rootFolderId, String[] mimeTypes,
1852                            int status, int start, int end, OrderByComparator<FileEntry> obc)
1853                    throws PortalException {
1854    
1855                    Repository repository = getRepository(groupId);
1856    
1857                    return repository.getRepositoryFileEntries(
1858                            userId, rootFolderId, mimeTypes, status, start, end, obc);
1859            }
1860    
1861            /**
1862             * Returns the number of file entries in a group starting at the repository
1863             * default parent folder that are stored within the Liferay repository. This
1864             * method is primarily used to search for recently modified file entries. It
1865             * can be limited to the file entries modified by a given user.
1866             *
1867             * @param  groupId the primary key of the group
1868             * @param  userId the primary key of the user who created the file
1869             *         (optionally <code>0</code>)
1870             * @return the number of matching file entries
1871             * @throws PortalException if the group could not be found
1872             */
1873            @Override
1874            public int getGroupFileEntriesCount(long groupId, long userId)
1875                    throws PortalException {
1876    
1877                    return getGroupFileEntriesCount(
1878                            groupId, userId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID);
1879            }
1880    
1881            /**
1882             * Returns the number of file entries in a group starting at the root folder
1883             * that are stored within the Liferay repository. This method is primarily
1884             * used to search for recently modified file entries. It can be limited to
1885             * the file entries modified by a given user.
1886             *
1887             * @param  groupId the primary key of the group
1888             * @param  userId the primary key of the user who created the file
1889             *         (optionally <code>0</code>)
1890             * @param  rootFolderId the primary key of the root folder to begin the
1891             *         search
1892             * @return the number of matching file entries
1893             * @throws PortalException if the group could not be found
1894             */
1895            @Override
1896            public int getGroupFileEntriesCount(
1897                            long groupId, long userId, long rootFolderId)
1898                    throws PortalException {
1899    
1900                    Repository repository = getRepository(groupId);
1901    
1902                    return repository.getRepositoryFileEntriesCount(userId, rootFolderId);
1903            }
1904    
1905            @Override
1906            public int getGroupFileEntriesCount(
1907                            long groupId, long userId, long rootFolderId, String[] mimeTypes,
1908                            int status)
1909                    throws PortalException {
1910    
1911                    Repository repository = getRepository(groupId);
1912    
1913                    return repository.getRepositoryFileEntriesCount(
1914                            userId, rootFolderId, mimeTypes, status);
1915            }
1916    
1917            /**
1918             * Returns all immediate subfolders of the parent folder that are used for
1919             * mounting third-party repositories. This method is only supported by the
1920             * Liferay repository.
1921             *
1922             * @param  repositoryId the primary key of the folder's repository
1923             * @param  parentFolderId the primary key of the folder's parent folder
1924             * @return the immediate subfolders of the parent folder that are used for
1925             *         mounting third-party repositories
1926             * @throws PortalException if the repository or parent folder could not be
1927             *         found
1928             */
1929            @Override
1930            public List<Folder> getMountFolders(long repositoryId, long parentFolderId)
1931                    throws PortalException {
1932    
1933                    return getMountFolders(
1934                            repositoryId, parentFolderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1935            }
1936    
1937            /**
1938             * Returns a name-ordered range of all the immediate subfolders of the
1939             * parent folder that are used for mounting third-party repositories. This
1940             * method is only supported by the Liferay repository.
1941             *
1942             * <p>
1943             * Useful when paginating results. Returns a maximum of <code>end -
1944             * start</code> instances. <code>start</code> and <code>end</code> are not
1945             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1946             * refers to the first result in the set. Setting both <code>start</code>
1947             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1948             * result set.
1949             * </p>
1950             *
1951             * @param  repositoryId the primary key of the repository
1952             * @param  parentFolderId the primary key of the parent folder
1953             * @param  start the lower bound of the range of results
1954             * @param  end the upper bound of the range of results (not inclusive)
1955             * @return the name-ordered range of immediate subfolders of the parent
1956             *         folder that are used for mounting third-party repositories
1957             * @throws PortalException if the repository or parent folder could not be
1958             *         found
1959             */
1960            @Override
1961            public List<Folder> getMountFolders(
1962                            long repositoryId, long parentFolderId, int start, int end)
1963                    throws PortalException {
1964    
1965                    return getMountFolders(
1966                            repositoryId, parentFolderId, start, end,
1967                            new FolderNameComparator(true));
1968            }
1969    
1970            /**
1971             * Returns an ordered range of all the immediate subfolders of the parent
1972             * folder that are used for mounting third-party repositories. This method
1973             * is only supported by the Liferay repository.
1974             *
1975             * <p>
1976             * Useful when paginating results. Returns a maximum of <code>end -
1977             * start</code> instances. <code>start</code> and <code>end</code> are not
1978             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1979             * refers to the first result in the set. Setting both <code>start</code>
1980             * and <code>end</code> to {@link QueryUtil#ALL_POS} will return the full
1981             * result set.
1982             * </p>
1983             *
1984             * @param  repositoryId the primary key of the folder's repository
1985             * @param  parentFolderId the primary key of the folder's parent folder
1986             * @param  start the lower bound of the range of results
1987             * @param  end the upper bound of the range of results (not inclusive)
1988             * @param  obc the comparator to order the folders (optionally
1989             *         <code>null</code>)
1990             * @return the range of immediate subfolders of the parent folder that are
1991             *         used for mounting third-party repositories ordered by comparator
1992             *         <code>obc</code>
1993             * @throws PortalException if the repository or parent folder could not be
1994             *         found
1995             */
1996            @Override
1997            public List<Folder> getMountFolders(
1998                            long repositoryId, long parentFolderId, int start, int end,
1999                            OrderByComparator<Folder> obc)
2000                    throws PortalException {
2001    
2002                    Repository repository = getRepository(repositoryId);
2003    
2004                    return repository.getMountFolders(parentFolderId, start, end, obc);
2005            }
2006    
2007            /**
2008             * Returns the number of immediate subfolders of the parent folder that are
2009             * used for mounting third-party repositories. This method is only supported
2010             * by the Liferay repository.
2011             *
2012             * @param  repositoryId the primary key of the repository
2013             * @param  parentFolderId the primary key of the parent folder
2014             * @return the number of folders of the parent folder that are used for
2015             *         mounting third-party repositories
2016             * @throws PortalException if the repository or parent folder could not be
2017             *         found
2018             */
2019            @Override
2020            public int getMountFoldersCount(long repositoryId, long parentFolderId)
2021                    throws PortalException {
2022    
2023                    Repository repository = getRepository(repositoryId);
2024    
2025                    return repository.getMountFoldersCount(parentFolderId);
2026            }
2027    
2028            @Override
2029            public void getSubfolderIds(
2030                            long repositoryId, List<Long> folderIds, long folderId)
2031                    throws PortalException {
2032    
2033                    Repository repository = getRepository(repositoryId);
2034    
2035                    repository.getSubfolderIds(folderIds, folderId);
2036            }
2037    
2038            /**
2039             * Returns all the descendant folders of the folder with the primary key.
2040             *
2041             * @param  repositoryId the primary key of the repository
2042             * @param  folderId the primary key of the folder
2043             * @return the descendant folders of the folder with the primary key
2044             * @throws PortalException if the repository or parent folder could not be
2045             *         found
2046             */
2047            @Override
2048            public List<Long> getSubfolderIds(long repositoryId, long folderId)
2049                    throws PortalException {
2050    
2051                    return getSubfolderIds(repositoryId, folderId, true);
2052            }
2053    
2054            /**
2055             * Returns descendant folders of the folder with the primary key, optionally
2056             * limiting to one level deep.
2057             *
2058             * @param  repositoryId the primary key of the repository
2059             * @param  folderId the primary key of the folder
2060             * @param  recurse whether to recurse through each subfolder
2061             * @return the descendant folders of the folder with the primary key
2062             * @throws PortalException if the repository or parent folder could not be
2063             *         found
2064             */
2065            @Override
2066            public List<Long> getSubfolderIds(
2067                            long repositoryId, long folderId, boolean recurse)
2068                    throws PortalException {
2069    
2070                    Repository repository = getRepository(repositoryId);
2071    
2072                    return repository.getSubfolderIds(folderId, recurse);
2073            }
2074    
2075            /**
2076             * Returns all the temporary file entry names.
2077             *
2078             * @param  groupId the primary key of the group
2079             * @param  folderId the primary key of the folder where the file entry will
2080             *         eventually reside
2081             * @param  folderName the temporary folder's name
2082             * @return the temporary file entry names
2083             * @throws PortalException if the folder was invalid
2084             * @see    #addTempFileEntry(long, long, String, String, File, String)
2085             * @see    TempFileEntryUtil
2086             */
2087            @Override
2088            public String[] getTempFileNames(
2089                            long groupId, long folderId, String folderName)
2090                    throws PortalException {
2091    
2092                    DLFolderPermission.check(
2093                            getPermissionChecker(), groupId, folderId, ActionKeys.ADD_DOCUMENT);
2094    
2095                    return TempFileEntryUtil.getTempFileNames(
2096                            groupId, getUserId(), folderName);
2097            }
2098    
2099            /**
2100             * Locks the folder. This method is primarily used by WebDAV.
2101             *
2102             * @param  repositoryId the primary key of the repository
2103             * @param  folderId the primary key of the folder
2104             * @return the lock object
2105             * @throws PortalException if the repository or folder could not be found
2106             */
2107            @Override
2108            public Lock lockFolder(long repositoryId, long folderId)
2109                    throws PortalException {
2110    
2111                    Repository repository = getRepository(repositoryId);
2112    
2113                    return repository.lockFolder(folderId);
2114            }
2115    
2116            /**
2117             * Locks the folder. This method is primarily used by WebDAV.
2118             *
2119             * @param  repositoryId the primary key of the repository
2120             * @param  folderId the primary key of the folder
2121             * @param  owner the owner string for the checkout (optionally
2122             *         <code>null</code>)
2123             * @param  inheritable whether the lock must propagate to descendants
2124             * @param  expirationTime the time in milliseconds before the lock expires.
2125             *         If the value is <code>0</code>, the default expiration time will
2126             *         be used from <code>portal.properties>.
2127             * @return the lock object
2128             * @throws PortalException if the repository or folder could not be found
2129             */
2130            @Override
2131            public Lock lockFolder(
2132                            long repositoryId, long folderId, String owner, boolean inheritable,
2133                            long expirationTime)
2134                    throws PortalException {
2135    
2136                    Repository repository = getRepository(repositoryId);
2137    
2138                    return repository.lockFolder(
2139                            folderId, owner, inheritable, expirationTime);
2140            }
2141    
2142            /**
2143             * Moves the file entry to the new folder.
2144             *
2145             * @param  fileEntryId the primary key of the file entry
2146             * @param  newFolderId the primary key of the new folder
2147             * @param  serviceContext the service context to be applied
2148             * @return the file entry
2149             * @throws PortalException if the file entry or the new folder could not be
2150             *         found
2151             */
2152            @Override
2153            public FileEntry moveFileEntry(
2154                            long fileEntryId, long newFolderId, ServiceContext serviceContext)
2155                    throws PortalException {
2156    
2157                    Repository fromRepository = getFileEntryRepository(fileEntryId);
2158                    Repository toRepository = getFolderRepository(
2159                            newFolderId, serviceContext.getScopeGroupId());
2160    
2161                    if (newFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
2162                            Folder toFolder = toRepository.getFolder(newFolderId);
2163    
2164                            if (toFolder.isMountPoint()) {
2165                                    toRepository = getRepository(toFolder.getRepositoryId());
2166                            }
2167                    }
2168    
2169                    if (fromRepository.getRepositoryId() ==
2170                                    toRepository.getRepositoryId()) {
2171    
2172                            // Move file entries within repository
2173    
2174                            return fromRepository.moveFileEntry(
2175                                    getUserId(), fileEntryId, newFolderId, serviceContext);
2176                    }
2177    
2178                    // Move file entries between repositories
2179    
2180                    return moveFileEntries(
2181                            fileEntryId, newFolderId, fromRepository, toRepository,
2182                            serviceContext);
2183            }
2184    
2185            /**
2186             * Moves the file entry from a trashed folder to the new folder.
2187             *
2188             * @param  fileEntryId the primary key of the file entry
2189             * @param  newFolderId the primary key of the new folder
2190             * @param  serviceContext the service context to be applied
2191             * @return the file entry
2192             * @throws PortalException if the file entry or the new folder could not be
2193             *         found
2194             */
2195            @Override
2196            public FileEntry moveFileEntryFromTrash(
2197                            long fileEntryId, long newFolderId, ServiceContext serviceContext)
2198                    throws PortalException {
2199    
2200                    Repository repository = getFileEntryRepository(fileEntryId);
2201    
2202                    TrashCapability trashCapability = repository.getCapability(
2203                            TrashCapability.class);
2204    
2205                    FileEntry fileEntry = repository.getFileEntry(fileEntryId);
2206    
2207                    DLFileEntryPermission.check(
2208                            getPermissionChecker(), fileEntry, ActionKeys.UPDATE);
2209    
2210                    Folder destinationFolder = repository.getFolder(newFolderId);
2211    
2212                    return trashCapability.moveFileEntryFromTrash(
2213                            getUserId(), fileEntry, destinationFolder, serviceContext);
2214            }
2215    
2216            /**
2217             * Moves the file entry with the primary key to the trash portlet.
2218             *
2219             * @param  fileEntryId the primary key of the file entry
2220             * @return the file entry
2221             * @throws PortalException if the file entry could not be found
2222             */
2223            @Override
2224            public FileEntry moveFileEntryToTrash(long fileEntryId)
2225                    throws PortalException {
2226    
2227                    Repository repository = getFileEntryRepository(fileEntryId);
2228    
2229                    TrashCapability trashCapability = repository.getCapability(
2230                            TrashCapability.class);
2231    
2232                    FileEntry fileEntry = repository.getFileEntry(fileEntryId);
2233    
2234                    DLFileEntryPermission.check(
2235                            getPermissionChecker(), fileEntry, ActionKeys.DELETE);
2236    
2237                    return trashCapability.moveFileEntryToTrash(getUserId(), fileEntry);
2238            }
2239    
2240            /**
2241             * Moves the file shortcut from a trashed folder to the new folder.
2242             *
2243             * @param  fileShortcutId the primary key of the file shortcut
2244             * @param  newFolderId the primary key of the new folder
2245             * @param  serviceContext the service context to be applied
2246             * @return the file shortcut
2247             * @throws PortalException if the file entry or the new folder could not be
2248             *         found
2249             */
2250            @Override
2251            public FileShortcut moveFileShortcutFromTrash(
2252                            long fileShortcutId, long newFolderId,
2253                            ServiceContext serviceContext)
2254                    throws PortalException {
2255    
2256                    FileShortcut fileShortcut = getFileShortcut(fileShortcutId);
2257    
2258                    DLFileShortcutPermission.check(
2259                            getPermissionChecker(), fileShortcut, ActionKeys.UPDATE);
2260    
2261                    return dlAppHelperLocalService.moveFileShortcutFromTrash(
2262                            getUserId(), fileShortcut, newFolderId, serviceContext);
2263            }
2264    
2265            /**
2266             * Moves the file shortcut with the primary key to the trash portlet.
2267             *
2268             * @param  fileShortcutId the primary key of the file shortcut
2269             * @return the file shortcut
2270             * @throws PortalException if the file shortcut could not be found
2271             */
2272            @Override
2273            public FileShortcut moveFileShortcutToTrash(long fileShortcutId)
2274                    throws PortalException {
2275    
2276                    Repository repository = getFileShortcutRepository(fileShortcutId);
2277    
2278                    TrashCapability trashCapability = repository.getCapability(
2279                            TrashCapability.class);
2280    
2281                    FileShortcut fileShortcut = repository.getFileShortcut(fileShortcutId);
2282    
2283                    DLFileShortcutPermission.check(
2284                            getPermissionChecker(), fileShortcut, ActionKeys.DELETE);
2285    
2286                    return trashCapability.moveFileShortcutToTrash(
2287                            getUserId(), fileShortcut);
2288            }
2289    
2290            /**
2291             * Moves the folder to the new parent folder with the primary key.
2292             *
2293             * @param  folderId the primary key of the folder
2294             * @param  parentFolderId the primary key of the new parent folder
2295             * @param  serviceContext the service context to be applied
2296             * @return the file entry
2297             * @throws PortalException if the folder could not be found
2298             */
2299            @Override
2300            public Folder moveFolder(
2301                            long folderId, long parentFolderId, ServiceContext serviceContext)
2302                    throws PortalException {
2303    
2304                    Repository fromRepository = getFolderRepository(folderId);
2305                    Repository toRepository = getFolderRepository(
2306                            parentFolderId, serviceContext.getScopeGroupId());
2307    
2308                    if (parentFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
2309                            Folder toFolder = toRepository.getFolder(parentFolderId);
2310    
2311                            if (toFolder.isMountPoint()) {
2312                                    toRepository = getRepository(toFolder.getRepositoryId());
2313                            }
2314                    }
2315    
2316                    if (fromRepository.getRepositoryId() ==
2317                                    toRepository.getRepositoryId()) {
2318    
2319                            // Move file entries within repository
2320    
2321                            return fromRepository.moveFolder(
2322                                    getUserId(), folderId, parentFolderId, serviceContext);
2323                    }
2324    
2325                    // Move file entries between repositories
2326    
2327                    return moveFolders(
2328                            folderId, parentFolderId, fromRepository, toRepository,
2329                            serviceContext);
2330            }
2331    
2332            /**
2333             * Moves the folder with the primary key from the trash portlet to the new
2334             * parent folder with the primary key.
2335             *
2336             * @param  folderId the primary key of the folder
2337             * @param  parentFolderId the primary key of the new parent folder
2338             * @param  serviceContext the service context to be applied
2339             * @return the file entry
2340             * @throws PortalException if the folder could not be found
2341             */
2342            @Override
2343            public Folder moveFolderFromTrash(
2344                            long folderId, long parentFolderId, ServiceContext serviceContext)
2345                    throws PortalException {
2346    
2347                    Repository repository = getFolderRepository(folderId);
2348    
2349                    TrashCapability trashCapability = repository.getCapability(
2350                            TrashCapability.class);
2351    
2352                    Folder folder = repository.getFolder(folderId);
2353    
2354                    DLFolderPermission.check(
2355                            getPermissionChecker(), folder, ActionKeys.UPDATE);
2356    
2357                    Folder destinationFolder = null;
2358    
2359                    if (parentFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
2360                            destinationFolder = repository.getFolder(parentFolderId);
2361                    }
2362    
2363                    return trashCapability.moveFolderFromTrash(
2364                            getUserId(), folder, destinationFolder, serviceContext);
2365            }
2366    
2367            /**
2368             * Moves the folder with the primary key to the trash portlet.
2369             *
2370             * @param  folderId the primary key of the folder
2371             * @return the file entry
2372             * @throws PortalException if the folder could not be found
2373             */
2374            @Override
2375            public Folder moveFolderToTrash(long folderId) throws PortalException {
2376                    Repository repository = getFolderRepository(folderId);
2377    
2378                    TrashCapability trashCapability = repository.getCapability(
2379                            TrashCapability.class);
2380    
2381                    Folder folder = repository.getFolder(folderId);
2382    
2383                    DLFolderPermission.check(
2384                            getPermissionChecker(), folder, ActionKeys.DELETE);
2385    
2386                    return trashCapability.moveFolderToTrash(getUserId(), folder);
2387            }
2388    
2389            /**
2390             * Refreshes the lock for the file entry. This method is primarily used by
2391             * WebDAV.
2392             *
2393             * @param  lockUuid the lock's UUID
2394             * @param  companyId the primary key of the file entry's company
2395             * @param  expirationTime the time in milliseconds before the lock expires.
2396             *         If the value is <code>0</code>, the default expiration time will
2397             *         be used from <code>portal.properties>.
2398             * @return the lock object
2399             * @throws PortalException if the file entry or lock could not be found
2400             */
2401            @Override
2402            public Lock refreshFileEntryLock(
2403                            String lockUuid, long companyId, long expirationTime)
2404                    throws PortalException {
2405    
2406                    Lock lock = LockManagerUtil.getLockByUuidAndCompanyId(
2407                            lockUuid, companyId);
2408    
2409                    long fileEntryId = GetterUtil.getLong(lock.getKey());
2410    
2411                    Repository repository = getFileEntryRepository(fileEntryId);
2412    
2413                    return repository.refreshFileEntryLock(
2414                            lockUuid, companyId, expirationTime);
2415            }
2416    
2417            /**
2418             * Refreshes the lock for the folder. This method is primarily used by
2419             * WebDAV.
2420             *
2421             * @param  lockUuid the lock's UUID
2422             * @param  companyId the primary key of the file entry's company
2423             * @param  expirationTime the time in milliseconds before the lock expires.
2424             *         If the value is <code>0</code>, the default expiration time will
2425             *         be used from <code>portal.properties>.
2426             * @return the lock object
2427             * @throws PortalException if the folder or lock could not be found
2428             */
2429            @Override
2430            public Lock refreshFolderLock(
2431                            String lockUuid, long companyId, long expirationTime)
2432                    throws PortalException {
2433    
2434                    Lock lock = LockManagerUtil.getLockByUuidAndCompanyId(
2435                            lockUuid, companyId);
2436    
2437                    long folderId = GetterUtil.getLong(lock.getKey());
2438    
2439                    Repository repository = getFolderRepository(folderId);
2440    
2441                    return repository.refreshFolderLock(
2442                            lockUuid, companyId, expirationTime);
2443            }
2444    
2445            /**
2446             * Restores the file entry with the primary key from the trash portlet.
2447             *
2448             * @param  fileEntryId the primary key of the file entry
2449             * @throws PortalException if the file entry could not be found
2450             */
2451            @Override
2452            public void restoreFileEntryFromTrash(long fileEntryId)
2453                    throws PortalException {
2454    
2455                    Repository repository = getFileEntryRepository(fileEntryId);
2456    
2457                    TrashCapability trashCapability = repository.getCapability(
2458                            TrashCapability.class);
2459    
2460                    FileEntry fileEntry = repository.getFileEntry(fileEntryId);
2461    
2462                    DLFileEntryPermission.check(
2463                            getPermissionChecker(), fileEntry, ActionKeys.DELETE);
2464    
2465                    trashCapability.restoreFileEntryFromTrash(getUserId(), fileEntry);
2466            }
2467    
2468            /**
2469             * Restores the file shortcut with the primary key from the trash portlet.
2470             *
2471             * @param  fileShortcutId the primary key of the file shortcut
2472             * @throws PortalException if the file shortcut could not be found
2473             */
2474            @Override
2475            public void restoreFileShortcutFromTrash(long fileShortcutId)
2476                    throws PortalException {
2477    
2478                    FileShortcut fileShortcut = getFileShortcut(fileShortcutId);
2479    
2480                    DLFileShortcutPermission.check(
2481                            getPermissionChecker(), fileShortcut, ActionKeys.DELETE);
2482    
2483                    dlAppHelperLocalService.restoreFileShortcutFromTrash(
2484                            getUserId(), fileShortcut);
2485            }
2486    
2487            /**
2488             * Restores the folder with the primary key from the trash portlet.
2489             *
2490             * @param  folderId the primary key of the folder
2491             * @throws PortalException if the folder could not be found
2492             */
2493            @Override
2494            public void restoreFolderFromTrash(long folderId) throws PortalException {
2495                    Repository repository = getFolderRepository(folderId);
2496    
2497                    TrashCapability trashCapability = repository.getCapability(
2498                            TrashCapability.class);
2499    
2500                    Folder folder = repository.getFolder(folderId);
2501    
2502                    DLFolderPermission.check(
2503                            getPermissionChecker(), folder, ActionKeys.DELETE);
2504    
2505                    trashCapability.restoreFolderFromTrash(getUserId(), folder);
2506            }
2507    
2508            /**
2509             * Reverts the file entry to a previous version. A new version will be
2510             * created based on the previous version and metadata.
2511             *
2512             * @param  fileEntryId the primary key of the file entry
2513             * @param  version the version to revert back to
2514             * @param  serviceContext the service context to be applied
2515             * @throws PortalException if the file entry or version could not be found
2516             */
2517            @Override
2518            public void revertFileEntry(
2519                            long fileEntryId, String version, ServiceContext serviceContext)
2520                    throws PortalException {
2521    
2522                    Repository repository = getFileEntryRepository(fileEntryId);
2523    
2524                    repository.revertFileEntry(
2525                            getUserId(), fileEntryId, version, serviceContext);
2526    
2527                    FileEntry fileEntry = getFileEntry(fileEntryId);
2528    
2529                    dlAppHelperLocalService.updateFileEntry(
2530                            getUserId(), fileEntry, null, fileEntry.getFileVersion(),
2531                            serviceContext);
2532            }
2533    
2534            @Override
2535            public Hits search(
2536                            long repositoryId, long creatorUserId, int status, int start,
2537                            int end)
2538                    throws PortalException {
2539    
2540                    Repository repository = getRepository(repositoryId);
2541    
2542                    return repository.search(creatorUserId, status, start, end);
2543            }
2544    
2545            @Override
2546            public Hits search(
2547                            long repositoryId, long creatorUserId, long folderId,
2548                            String[] mimeTypes, int status, int start, int end)
2549                    throws PortalException {
2550    
2551                    Repository repository = getRepository(repositoryId);
2552    
2553                    return repository.search(
2554                            creatorUserId, folderId, mimeTypes, status, start, end);
2555            }
2556    
2557            @Override
2558            public Hits search(long repositoryId, SearchContext searchContext)
2559                    throws SearchException {
2560    
2561                    try {
2562                            Repository repository = getRepository(repositoryId);
2563    
2564                            return repository.search(searchContext);
2565                    }
2566                    catch (Exception e) {
2567                            throw new SearchException(e);
2568                    }
2569            }
2570    
2571            @Override
2572            public Hits search(
2573                            long repositoryId, SearchContext searchContext, Query query)
2574                    throws SearchException {
2575    
2576                    try {
2577                            Repository repository = getRepository(repositoryId);
2578    
2579                            return repository.search(searchContext, query);
2580                    }
2581                    catch (Exception e) {
2582                            throw new SearchException(e);
2583                    }
2584            }
2585    
2586            /**
2587             * Subscribe the user to changes in documents of the file entry type. This
2588             * method is only supported by the Liferay repository.
2589             *
2590             * @param  groupId the primary key of the file entry type's group
2591             * @param  fileEntryTypeId the primary key of the file entry type
2592             * @throws PortalException if the user or group could not be found, or if
2593             *         subscribing was not permissible
2594             */
2595            @Override
2596            public void subscribeFileEntryType(long groupId, long fileEntryTypeId)
2597                    throws PortalException {
2598    
2599                    DLPermission.check(
2600                            getPermissionChecker(), groupId, ActionKeys.SUBSCRIBE);
2601    
2602                    dlAppLocalService.subscribeFileEntryType(
2603                            getUserId(), groupId, fileEntryTypeId);
2604            }
2605    
2606            /**
2607             * Subscribe the user to document changes in the folder. This method is only
2608             * supported by the Liferay repository.
2609             *
2610             * @param  groupId the primary key of the folder's group
2611             * @param  folderId the primary key of the folder
2612             * @throws PortalException if the user or group could not be found, or if
2613             *         subscribing was not permissible
2614             */
2615            @Override
2616            public void subscribeFolder(long groupId, long folderId)
2617                    throws PortalException {
2618    
2619                    DLFolderPermission.check(
2620                            getPermissionChecker(), groupId, folderId, ActionKeys.SUBSCRIBE);
2621    
2622                    dlAppLocalService.subscribeFolder(getUserId(), groupId, folderId);
2623            }
2624    
2625            /**
2626             * @deprecated As of 6.2.0, replaced by {@link #checkInFileEntry(long,
2627             *             boolean, String, ServiceContext)}.
2628             */
2629            @Deprecated
2630            @Override
2631            public void unlockFileEntry(long fileEntryId) throws PortalException {
2632                    checkInFileEntry(
2633                            fileEntryId, false, StringPool.BLANK, new ServiceContext());
2634            }
2635    
2636            /**
2637             * @deprecated As of 6.2.0, replaced by {@link #checkInFileEntry(long,
2638             *             String)}.
2639             */
2640            @Deprecated
2641            @Override
2642            public void unlockFileEntry(long fileEntryId, String lockUuid)
2643                    throws PortalException {
2644    
2645                    checkInFileEntry(fileEntryId, lockUuid);
2646            }
2647    
2648            /**
2649             * Unlocks the folder. This method is primarily used by WebDAV.
2650             *
2651             * @param  repositoryId the primary key of the repository
2652             * @param  folderId the primary key of the folder
2653             * @param  lockUuid the lock's UUID
2654             * @throws PortalException if the repository or folder could not be found
2655             */
2656            @Override
2657            public void unlockFolder(long repositoryId, long folderId, String lockUuid)
2658                    throws PortalException {
2659    
2660                    Repository repository = getRepository(repositoryId);
2661    
2662                    repository.unlockFolder(folderId, lockUuid);
2663            }
2664    
2665            /**
2666             * Unlocks the folder. This method is primarily used by WebDAV.
2667             *
2668             * @param  repositoryId the primary key of the repository
2669             * @param  parentFolderId the primary key of the parent folder
2670             * @param  name the folder's name
2671             * @param  lockUuid the lock's UUID
2672             * @throws PortalException if the repository or folder could not be found
2673             */
2674            @Override
2675            public void unlockFolder(
2676                            long repositoryId, long parentFolderId, String name,
2677                            String lockUuid)
2678                    throws PortalException {
2679    
2680                    Repository repository = getRepository(repositoryId);
2681    
2682                    repository.unlockFolder(parentFolderId, name, lockUuid);
2683            }
2684    
2685            /**
2686             * Unsubscribe the user from changes in documents of the file entry type.
2687             * This method is only supported by the Liferay repository.
2688             *
2689             * @param  groupId the primary key of the file entry type's group
2690             * @param  fileEntryTypeId the primary key of the file entry type
2691             * @throws PortalException if the user or group could not be found, or if
2692             *         unsubscribing was not permissible
2693             */
2694            @Override
2695            public void unsubscribeFileEntryType(long groupId, long fileEntryTypeId)
2696                    throws PortalException {
2697    
2698                    DLPermission.check(
2699                            getPermissionChecker(), groupId, ActionKeys.SUBSCRIBE);
2700    
2701                    dlAppLocalService.unsubscribeFileEntryType(
2702                            getUserId(), groupId, fileEntryTypeId);
2703            }
2704    
2705            /**
2706             * Unsubscribe the user from document changes in the folder. This method is
2707             * only supported by the Liferay repository.
2708             *
2709             * @param  groupId the primary key of the folder's group
2710             * @param  folderId the primary key of the folder
2711             * @throws PortalException if the user or group could not be found, or if
2712             *         unsubscribing was not permissible
2713             */
2714            @Override
2715            public void unsubscribeFolder(long groupId, long folderId)
2716                    throws PortalException {
2717    
2718                    DLFolderPermission.check(
2719                            getPermissionChecker(), groupId, folderId, ActionKeys.SUBSCRIBE);
2720    
2721                    dlAppLocalService.unsubscribeFolder(getUserId(), groupId, folderId);
2722            }
2723    
2724            /**
2725             * Updates a file entry and associated metadata based on a byte array
2726             * object. If the file data is <code>null</code>, then only the associated
2727             * metadata (i.e., <code>title</code>, <code>description</code>, and
2728             * parameters in the <code>serviceContext</code>) will be updated.
2729             *
2730             * <p>
2731             * This method takes two file names, the <code>sourceFileName</code> and the
2732             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
2733             * name of the actual file being uploaded. The <code>title</code>
2734             * corresponds to a name the client wishes to assign this file after it has
2735             * been uploaded to the portal.
2736             * </p>
2737             *
2738             * @param  fileEntryId the primary key of the file entry
2739             * @param  sourceFileName the original file's name (optionally
2740             *         <code>null</code>)
2741             * @param  mimeType the file's MIME type (optionally <code>null</code>)
2742             * @param  title the new name to be assigned to the file (optionally <code>
2743             *         <code>null</code></code>)
2744             * @param  description the file's new description
2745             * @param  changeLog the file's version change log (optionally
2746             *         <code>null</code>)
2747             * @param  majorVersion whether the new file version is a major version
2748             * @param  bytes the file's data (optionally <code>null</code>)
2749             * @param  serviceContext the service context to be applied. Can set the
2750             *         asset category IDs, asset tag names, and expando bridge
2751             *         attributes for the file entry. In a Liferay repository, it may
2752             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
2753             *         type </li> <li> fieldsMap - mapping for fields associated with a
2754             *         custom file entry type </li> </ul>
2755             * @return the file entry
2756             * @throws PortalException if the file entry could not be found
2757             */
2758            @Override
2759            public FileEntry updateFileEntry(
2760                            long fileEntryId, String sourceFileName, String mimeType,
2761                            String title, String description, String changeLog,
2762                            boolean majorVersion, byte[] bytes, ServiceContext serviceContext)
2763                    throws PortalException {
2764    
2765                    File file = null;
2766    
2767                    try {
2768                            if (ArrayUtil.isNotEmpty(bytes)) {
2769                                    file = FileUtil.createTempFile(bytes);
2770                            }
2771    
2772                            return updateFileEntry(
2773                                    fileEntryId, sourceFileName, mimeType, title, description,
2774                                    changeLog, majorVersion, file, serviceContext);
2775                    }
2776                    catch (IOException ioe) {
2777                            throw new SystemException("Unable to write temporary file", ioe);
2778                    }
2779                    finally {
2780                            FileUtil.delete(file);
2781                    }
2782            }
2783    
2784            /**
2785             * Updates a file entry and associated metadata based on a {@link File}
2786             * object. If the file data is <code>null</code>, then only the associated
2787             * metadata (i.e., <code>title</code>, <code>description</code>, and
2788             * parameters in the <code>serviceContext</code>) will be updated.
2789             *
2790             * <p>
2791             * This method takes two file names, the <code>sourceFileName</code> and the
2792             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
2793             * name of the actual file being uploaded. The <code>title</code>
2794             * corresponds to a name the client wishes to assign this file after it has
2795             * been uploaded to the portal.
2796             * </p>
2797             *
2798             * @param  fileEntryId the primary key of the file entry
2799             * @param  sourceFileName the original file's name (optionally
2800             *         <code>null</code>)
2801             * @param  mimeType the file's MIME type (optionally <code>null</code>)
2802             * @param  title the new name to be assigned to the file (optionally <code>
2803             *         <code>null</code></code>)
2804             * @param  description the file's new description
2805             * @param  changeLog the file's version change log (optionally
2806             *         <code>null</code>)
2807             * @param  majorVersion whether the new file version is a major version
2808             * @param  file the file's data (optionally <code>null</code>)
2809             * @param  serviceContext the service context to be applied. Can set the
2810             *         asset category IDs, asset tag names, and expando bridge
2811             *         attributes for the file entry. In a Liferay repository, it may
2812             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
2813             *         type </li> <li> fieldsMap - mapping for fields associated with a
2814             *         custom file entry type </li> </ul>
2815             * @return the file entry
2816             * @throws PortalException if the file entry could not be found
2817             */
2818            @Override
2819            public FileEntry updateFileEntry(
2820                            long fileEntryId, String sourceFileName, String mimeType,
2821                            String title, String description, String changeLog,
2822                            boolean majorVersion, File file, ServiceContext serviceContext)
2823                    throws PortalException {
2824    
2825                    if ((file == null) || !file.exists() || (file.length() == 0)) {
2826                            return updateFileEntry(
2827                                    fileEntryId, sourceFileName, mimeType, title, description,
2828                                    changeLog, majorVersion, null, 0, serviceContext);
2829                    }
2830    
2831                    mimeType = DLAppUtil.getMimeType(sourceFileName, mimeType, title, file);
2832    
2833                    Repository repository = getFileEntryRepository(fileEntryId);
2834    
2835                    FileEntry fileEntry = repository.updateFileEntry(
2836                            getUserId(), fileEntryId, sourceFileName, mimeType, title,
2837                            description, changeLog, majorVersion, file, serviceContext);
2838    
2839                    dlAppHelperLocalService.updateFileEntry(
2840                            getUserId(), fileEntry, null, fileEntry.getFileVersion(),
2841                            serviceContext);
2842    
2843                    return fileEntry;
2844            }
2845    
2846            /**
2847             * Updates a file entry and associated metadata based on an {@link
2848             * InputStream} object. If the file data is <code>null</code>, then only the
2849             * associated metadata (i.e., <code>title</code>, <code>description</code>,
2850             * and parameters in the <code>serviceContext</code>) will be updated.
2851             *
2852             * <p>
2853             * This method takes two file names, the <code>sourceFileName</code> and the
2854             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
2855             * name of the actual file being uploaded. The <code>title</code>
2856             * corresponds to a name the client wishes to assign this file after it has
2857             * been uploaded to the portal.
2858             * </p>
2859             *
2860             * @param  fileEntryId the primary key of the file entry
2861             * @param  sourceFileName the original file's name (optionally
2862             *         <code>null</code>)
2863             * @param  mimeType the file's MIME type (optionally <code>null</code>)
2864             * @param  title the new name to be assigned to the file (optionally <code>
2865             *         <code>null</code></code>)
2866             * @param  description the file's new description
2867             * @param  changeLog the file's version change log (optionally
2868             *         <code>null</code>)
2869             * @param  majorVersion whether the new file version is a major version
2870             * @param  is the file's data (optionally <code>null</code>)
2871             * @param  size the file's size (optionally <code>0</code>)
2872             * @param  serviceContext the service context to be applied. Can set the
2873             *         asset category IDs, asset tag names, and expando bridge
2874             *         attributes for the file entry. In a Liferay repository, it may
2875             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
2876             *         type </li> <li> fieldsMap - mapping for fields associated with a
2877             *         custom file entry type </li> </ul>
2878             * @return the file entry
2879             * @throws PortalException if the file entry could not be found
2880             */
2881            @Override
2882            public FileEntry updateFileEntry(
2883                            long fileEntryId, String sourceFileName, String mimeType,
2884                            String title, String description, String changeLog,
2885                            boolean majorVersion, InputStream is, long size,
2886                            ServiceContext serviceContext)
2887                    throws PortalException {
2888    
2889                    if (Validator.isNull(mimeType) ||
2890                            mimeType.equals(ContentTypes.APPLICATION_OCTET_STREAM)) {
2891    
2892                            String extension = DLAppUtil.getExtension(title, sourceFileName);
2893    
2894                            if (size == 0) {
2895                                    mimeType = MimeTypesUtil.getExtensionContentType(extension);
2896                            }
2897                            else {
2898                                    File file = null;
2899    
2900                                    try {
2901                                            file = FileUtil.createTempFile(is);
2902    
2903                                            return updateFileEntry(
2904                                                    fileEntryId, sourceFileName, mimeType, title,
2905                                                    description, changeLog, majorVersion, file,
2906                                                    serviceContext);
2907                                    }
2908                                    catch (IOException ioe) {
2909                                            throw new SystemException(
2910                                                    "Unable to write temporary file", ioe);
2911                                    }
2912                                    finally {
2913                                            FileUtil.delete(file);
2914                                    }
2915                            }
2916                    }
2917    
2918                    Repository repository = getFileEntryRepository(fileEntryId);
2919    
2920                    FileEntry fileEntry = repository.updateFileEntry(
2921                            getUserId(), fileEntryId, sourceFileName, mimeType, title,
2922                            description, changeLog, majorVersion, is, size, serviceContext);
2923    
2924                    dlAppHelperLocalService.updateFileEntry(
2925                            getUserId(), fileEntry, null, fileEntry.getFileVersion(),
2926                            serviceContext);
2927    
2928                    return fileEntry;
2929            }
2930    
2931            @Override
2932            public FileEntry updateFileEntryAndCheckIn(
2933                            long fileEntryId, String sourceFileName, String mimeType,
2934                            String title, String description, String changeLog,
2935                            boolean majorVersion, File file, ServiceContext serviceContext)
2936                    throws PortalException {
2937    
2938                    if ((file == null) || !file.exists() || (file.length() == 0)) {
2939                            return updateFileEntryAndCheckIn(
2940                                    fileEntryId, sourceFileName, mimeType, title, description,
2941                                    changeLog, majorVersion, null, 0, serviceContext);
2942                    }
2943    
2944                    Repository repository = getFileEntryRepository(fileEntryId);
2945    
2946                    FileEntry fileEntry = repository.updateFileEntry(
2947                            getUserId(), fileEntryId, sourceFileName, mimeType, title,
2948                            description, changeLog, majorVersion, file, serviceContext);
2949    
2950                    repository.checkInFileEntry(
2951                            getUserId(), fileEntryId, majorVersion, changeLog, serviceContext);
2952    
2953                    dlAppHelperLocalService.updateFileEntry(
2954                            getUserId(), fileEntry, null, fileEntry.getFileVersion(),
2955                            serviceContext);
2956    
2957                    return fileEntry;
2958            }
2959    
2960            @Override
2961            public FileEntry updateFileEntryAndCheckIn(
2962                            long fileEntryId, String sourceFileName, String mimeType,
2963                            String title, String description, String changeLog,
2964                            boolean majorVersion, InputStream is, long size,
2965                            ServiceContext serviceContext)
2966                    throws PortalException {
2967    
2968                    Repository repository = getFileEntryRepository(fileEntryId);
2969    
2970                    FileEntry fileEntry = repository.updateFileEntry(
2971                            getUserId(), fileEntryId, sourceFileName, mimeType, title,
2972                            description, changeLog, majorVersion, is, size, serviceContext);
2973    
2974                    repository.checkInFileEntry(
2975                            getUserId(), fileEntryId, majorVersion, changeLog, serviceContext);
2976    
2977                    dlAppHelperLocalService.updateFileEntry(
2978                            getUserId(), fileEntry, null, fileEntry.getFileVersion(),
2979                            serviceContext);
2980    
2981                    return fileEntry;
2982            }
2983    
2984            /**
2985             * Updates a file shortcut to the existing file entry. This method is only
2986             * supported by the Liferay repository.
2987             *
2988             * @param  fileShortcutId the primary key of the file shortcut
2989             * @param  folderId the primary key of the file shortcut's parent folder
2990             * @param  toFileEntryId the primary key of the file shortcut's file entry
2991             * @param  serviceContext the service context to be applied. Can set the
2992             *         asset category IDs, asset tag names, and expando bridge
2993             *         attributes for the file entry.
2994             * @return the file shortcut
2995             * @throws PortalException if the file shortcut, folder, or file entry could
2996             *         not be found
2997             */
2998            @Override
2999            public FileShortcut updateFileShortcut(
3000                            long fileShortcutId, long folderId, long toFileEntryId,
3001                            ServiceContext serviceContext)
3002                    throws PortalException {
3003    
3004                    Repository repository = getFileShortcutRepository(fileShortcutId);
3005    
3006                    return repository.updateFileShortcut(
3007                            getUserId(), fileShortcutId, folderId, toFileEntryId,
3008                            serviceContext);
3009            }
3010    
3011            /**
3012             * Updates the folder.
3013             *
3014             * @param  folderId the primary key of the folder
3015             * @param  name the folder's new name
3016             * @param  description the folder's new description
3017             * @param  serviceContext the service context to be applied. In a Liferay
3018             *         repository, it may include:  <ul> <li> defaultFileEntryTypeId -
3019             *         the file entry type to default all Liferay file entries to </li>
3020             *         <li> dlFileEntryTypesSearchContainerPrimaryKeys - a
3021             *         comma-delimited list of file entry type primary keys allowed in
3022             *         the given folder and all descendants </li> <li> restrictionType -
3023             *         specifying restriction type of file entry types allowed </li>
3024             *         <li> workflowDefinitionXYZ - the workflow definition name
3025             *         specified per file entry type. The parameter name must be the
3026             *         string <code>workflowDefinition</code> appended by the
3027             *         <code>fileEntryTypeId</code> (optionally <code>0</code>).</li>
3028             *         </ul>
3029             * @return the folder
3030             * @throws PortalException if the current or new parent folder could not be
3031             *         found or if the new parent folder's information was invalid
3032             */
3033            @Override
3034            public Folder updateFolder(
3035                            long folderId, String name, String description,
3036                            ServiceContext serviceContext)
3037                    throws PortalException {
3038    
3039                    Repository repository = getFolderRepository(
3040                            folderId, serviceContext.getScopeGroupId());
3041    
3042                    Folder folder = repository.updateFolder(
3043                            folderId, name, description, serviceContext);
3044    
3045                    if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
3046                            dlAppHelperLocalService.updateFolder(
3047                                    getUserId(), folder, serviceContext);
3048                    }
3049    
3050                    return folder;
3051            }
3052    
3053            /**
3054             * Returns <code>true</code> if the file entry is checked out. This method
3055             * is primarily used by WebDAV.
3056             *
3057             * @param  repositoryId the primary key for the repository
3058             * @param  fileEntryId the primary key for the file entry
3059             * @param  lockUuid the lock's UUID
3060             * @return <code>true</code> if the file entry is checked out;
3061             *         <code>false</code> otherwise
3062             * @throws PortalException if the file entry could not be found
3063             */
3064            @Override
3065            public boolean verifyFileEntryCheckOut(
3066                            long repositoryId, long fileEntryId, String lockUuid)
3067                    throws PortalException {
3068    
3069                    Repository repository = getRepository(repositoryId);
3070    
3071                    return repository.verifyFileEntryCheckOut(fileEntryId, lockUuid);
3072            }
3073    
3074            @Override
3075            public boolean verifyFileEntryLock(
3076                            long repositoryId, long fileEntryId, String lockUuid)
3077                    throws PortalException {
3078    
3079                    Repository repository = getRepository(repositoryId);
3080    
3081                    return repository.verifyFileEntryLock(fileEntryId, lockUuid);
3082            }
3083    
3084            /**
3085             * Returns <code>true</code> if the inheritable lock exists. This method is
3086             * primarily used by WebDAV.
3087             *
3088             * @param  repositoryId the primary key for the repository
3089             * @param  folderId the primary key for the folder
3090             * @param  lockUuid the lock's UUID
3091             * @return <code>true</code> if the inheritable lock exists;
3092             *         <code>false</code> otherwise
3093             * @throws PortalException if the folder could not be found
3094             */
3095            @Override
3096            public boolean verifyInheritableLock(
3097                            long repositoryId, long folderId, String lockUuid)
3098                    throws PortalException {
3099    
3100                    Repository repository = getRepository(repositoryId);
3101    
3102                    return repository.verifyInheritableLock(folderId, lockUuid);
3103            }
3104    
3105            protected FileEntry copyFileEntry(
3106                            Repository toRepository, FileEntry fileEntry, long newFolderId,
3107                            ServiceContext serviceContext)
3108                    throws PortalException {
3109    
3110                    List<FileVersion> fileVersions = fileEntry.getFileVersions(
3111                            WorkflowConstants.STATUS_ANY);
3112    
3113                    FileVersion latestFileVersion = fileVersions.get(
3114                            fileVersions.size() - 1);
3115    
3116                    FileEntry destinationFileEntry = toRepository.addFileEntry(
3117                            getUserId(), newFolderId, fileEntry.getTitle(),
3118                            latestFileVersion.getMimeType(), latestFileVersion.getTitle(),
3119                            latestFileVersion.getDescription(), StringPool.BLANK,
3120                            latestFileVersion.getContentStream(false),
3121                            latestFileVersion.getSize(), serviceContext);
3122    
3123                    for (int i = fileVersions.size() - 2; i >= 0; i--) {
3124                            FileVersion fileVersion = fileVersions.get(i);
3125    
3126                            FileVersion previousFileVersion = fileVersions.get(i + 1);
3127    
3128                            try {
3129                                    destinationFileEntry = toRepository.updateFileEntry(
3130                                            getUserId(), destinationFileEntry.getFileEntryId(),
3131                                            fileVersion.getTitle(), fileVersion.getMimeType(),
3132                                            fileVersion.getTitle(), fileVersion.getDescription(),
3133                                            StringPool.BLANK,
3134                                            DLAppUtil.isMajorVersion(previousFileVersion, fileVersion),
3135                                            fileVersion.getContentStream(false), fileVersion.getSize(),
3136                                            serviceContext);
3137    
3138                                    FileVersion destinationFileVersion =
3139                                            destinationFileEntry.getFileVersion();
3140    
3141                                    dlAppHelperLocalService.updateFileEntry(
3142                                            getUserId(), destinationFileEntry, null,
3143                                            destinationFileVersion, serviceContext);
3144                            }
3145                            catch (PortalException pe) {
3146                                    toRepository.deleteFileEntry(
3147                                            destinationFileEntry.getFileEntryId());
3148    
3149                                    throw pe;
3150                            }
3151                    }
3152    
3153                    return destinationFileEntry;
3154            }
3155    
3156            protected void copyFolder(
3157                            Repository repository, Folder srcFolder, Folder destFolder,
3158                            ServiceContext serviceContext)
3159                    throws PortalException {
3160    
3161                    Queue<Folder[]> folders = new LinkedList<>();
3162                    final List<FileEntry> fileEntries = new ArrayList<>();
3163    
3164                    Folder curSrcFolder = srcFolder;
3165                    Folder curDestFolder = destFolder;
3166    
3167                    while (true) {
3168                            List<FileEntry> srcFileEntries = repository.getFileEntries(
3169                                    curSrcFolder.getFolderId(), QueryUtil.ALL_POS,
3170                                    QueryUtil.ALL_POS, null);
3171    
3172                            for (FileEntry srcFileEntry : srcFileEntries) {
3173                                    try {
3174                                            FileEntry fileEntry = repository.copyFileEntry(
3175                                                    getUserId(), curDestFolder.getGroupId(),
3176                                                    srcFileEntry.getFileEntryId(),
3177                                                    curDestFolder.getFolderId(), serviceContext);
3178    
3179                                            fileEntries.add(fileEntry);
3180                                    }
3181                                    catch (Exception e) {
3182                                            _log.error(e, e);
3183                                    }
3184                            }
3185    
3186                            List<Folder> srcSubfolders = repository.getFolders(
3187                                    curSrcFolder.getFolderId(), false, QueryUtil.ALL_POS,
3188                                    QueryUtil.ALL_POS, null);
3189    
3190                            for (Folder srcSubfolder : srcSubfolders) {
3191                                    Folder destSubfolder = repository.addFolder(
3192                                            getUserId(), curDestFolder.getFolderId(),
3193                                            srcSubfolder.getName(), srcSubfolder.getDescription(),
3194                                            serviceContext);
3195    
3196                                    dlAppHelperLocalService.addFolder(
3197                                            getUserId(), destSubfolder, serviceContext);
3198    
3199                                    folders.offer(new Folder[] {srcSubfolder, destSubfolder});
3200                            }
3201    
3202                            Folder[] next = folders.poll();
3203    
3204                            if (next == null) {
3205                                    break;
3206                            }
3207                            else {
3208                                    curSrcFolder = next[0];
3209                                    curDestFolder = next[1];
3210                            }
3211                    }
3212    
3213                    TransactionCommitCallbackUtil.registerCallback(
3214                            new Callable<Void>() {
3215    
3216                                    @Override
3217                                    public Void call() throws Exception {
3218                                            for (FileEntry fileEntry : fileEntries) {
3219                                                    DLProcessorRegistryUtil.trigger(fileEntry, null);
3220                                            }
3221    
3222                                            return null;
3223                                    }
3224    
3225                            });
3226            }
3227    
3228            protected void deleteFileEntry(
3229                            long oldFileEntryId, long newFileEntryId, Repository fromRepository,
3230                            Repository toRepository)
3231                    throws PortalException {
3232    
3233                    try {
3234                            FileEntry fileEntry = fromRepository.getFileEntry(oldFileEntryId);
3235    
3236                            dlAppHelperLocalService.deleteFileEntry(fileEntry);
3237    
3238                            fromRepository.deleteFileEntry(oldFileEntryId);
3239                    }
3240                    catch (PortalException pe) {
3241                            FileEntry fileEntry = toRepository.getFileEntry(newFileEntryId);
3242    
3243                            toRepository.deleteFileEntry(newFileEntryId);
3244    
3245                            dlAppHelperLocalService.deleteFileEntry(fileEntry);
3246    
3247                            throw pe;
3248                    }
3249            }
3250    
3251            protected FileEntry fetchFileEntryByUuidAndRepositoryId(
3252                            String uuid, long repositoryId)
3253                    throws PortalException {
3254    
3255                    try {
3256                            Repository repository = getRepository(repositoryId);
3257    
3258                            return repository.getFileEntryByUuid(uuid);
3259                    }
3260                    catch (NoSuchFileEntryException nsfee) {
3261                            if (_log.isDebugEnabled()) {
3262                                    _log.debug(nsfee, nsfee);
3263                            }
3264    
3265                            return null;
3266                    }
3267                    catch (RepositoryException re) {
3268                            throw new NoSuchFileEntryException(re);
3269                    }
3270            }
3271    
3272            protected Repository getFileEntryRepository(long fileEntryId)
3273                    throws PortalException {
3274    
3275                    try {
3276                            return RepositoryProviderUtil.getFileEntryRepository(fileEntryId);
3277                    }
3278                    catch (InvalidRepositoryIdException irie) {
3279                            StringBundler sb = new StringBundler(3);
3280    
3281                            sb.append("No FileEntry exists with the key {fileEntryId=");
3282                            sb.append(fileEntryId);
3283                            sb.append("}");
3284    
3285                            throw new NoSuchFileEntryException(sb.toString(), irie);
3286                    }
3287            }
3288    
3289            protected Repository getFileShortcutRepository(long fileShortcutId)
3290                    throws PortalException {
3291    
3292                    try {
3293                            return RepositoryProviderUtil.getFileShortcutRepository(
3294                                    fileShortcutId);
3295                    }
3296                    catch (InvalidRepositoryIdException irie) {
3297                            StringBundler sb = new StringBundler(3);
3298    
3299                            sb.append("No FileShortcut exists with the key {fileShortcutId=");
3300                            sb.append(fileShortcutId);
3301                            sb.append("}");
3302    
3303                            throw new NoSuchFileShortcutException(sb.toString(), irie);
3304                    }
3305            }
3306    
3307            protected Repository getFileVersionRepository(long fileVersionId)
3308                    throws PortalException {
3309    
3310                    try {
3311                            return RepositoryProviderUtil.getFileVersionRepository(
3312                                    fileVersionId);
3313                    }
3314                    catch (InvalidRepositoryIdException irie) {
3315                            StringBundler sb = new StringBundler(3);
3316    
3317                            sb.append("No FileVersion exists with the key {fileVersionId=");
3318                            sb.append(fileVersionId);
3319                            sb.append("}");
3320    
3321                            throw new NoSuchFileVersionException(sb.toString(), irie);
3322                    }
3323            }
3324    
3325            protected Repository getFolderRepository(long folderId)
3326                    throws PortalException {
3327    
3328                    try {
3329                            return RepositoryProviderUtil.getFolderRepository(folderId);
3330                    }
3331                    catch (InvalidRepositoryIdException irie) {
3332                            StringBundler sb = new StringBundler(3);
3333    
3334                            sb.append("No Folder exists with the key {folderId=");
3335                            sb.append(folderId);
3336                            sb.append("}");
3337    
3338                            throw new NoSuchFolderException(sb.toString(), irie);
3339                    }
3340            }
3341    
3342            protected Repository getFolderRepository(long folderId, long groupId)
3343                    throws PortalException {
3344    
3345                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
3346                            return getRepository(groupId);
3347                    }
3348    
3349                    return getFolderRepository(folderId);
3350            }
3351    
3352            protected Repository getRepository(long repositoryId)
3353                    throws PortalException {
3354    
3355                    try {
3356                            return RepositoryProviderUtil.getRepository(repositoryId);
3357                    }
3358                    catch (InvalidRepositoryIdException irie) {
3359                            StringBundler sb = new StringBundler(3);
3360    
3361                            sb.append("No Group exists with the key {repositoryId=");
3362                            sb.append(repositoryId);
3363                            sb.append("}");
3364    
3365                            throw new NoSuchGroupException(sb.toString(), irie);
3366                    }
3367            }
3368    
3369            protected FileEntry moveFileEntries(
3370                            long fileEntryId, long newFolderId, Repository fromRepository,
3371                            Repository toRepository, ServiceContext serviceContext)
3372                    throws PortalException {
3373    
3374                    FileEntry sourceFileEntry = fromRepository.getFileEntry(fileEntryId);
3375    
3376                    FileEntry destinationFileEntry = copyFileEntry(
3377                            toRepository, sourceFileEntry, newFolderId, serviceContext);
3378    
3379                    deleteFileEntry(
3380                            fileEntryId, destinationFileEntry.getFileEntryId(), fromRepository,
3381                            toRepository);
3382    
3383                    return destinationFileEntry;
3384            }
3385    
3386            protected Folder moveFolders(
3387                            long folderId, long parentFolderId, Repository fromRepository,
3388                            Repository toRepository, ServiceContext serviceContext)
3389                    throws PortalException {
3390    
3391                    Folder folder = fromRepository.getFolder(folderId);
3392    
3393                    Folder newFolder = toRepository.addFolder(
3394                            getUserId(), parentFolderId, folder.getName(),
3395                            folder.getDescription(), serviceContext);
3396    
3397                    dlAppHelperLocalService.addFolder(
3398                            getUserId(), newFolder, serviceContext);
3399    
3400                    List<RepositoryEntry> repositoryEntries =
3401                            fromRepository.getFoldersAndFileEntriesAndFileShortcuts(
3402                                    folderId, WorkflowConstants.STATUS_ANY, true, QueryUtil.ALL_POS,
3403                                    QueryUtil.ALL_POS, null);
3404    
3405                    try {
3406                            for (RepositoryEntry repositoryEntry : repositoryEntries) {
3407                                    if (repositoryEntry instanceof FileEntry) {
3408                                            FileEntry fileEntry = (FileEntry)repositoryEntry;
3409    
3410                                            copyFileEntry(
3411                                                    toRepository, fileEntry, newFolder.getFolderId(),
3412                                                    serviceContext);
3413                                    }
3414                                    else if (repositoryEntry instanceof Folder) {
3415                                            Folder currentFolder = (Folder)repositoryEntry;
3416    
3417                                            moveFolders(
3418                                                    currentFolder.getFolderId(), newFolder.getFolderId(),
3419                                                    fromRepository, toRepository, serviceContext);
3420                                    }
3421                                    else if (repositoryEntry instanceof FileShortcut) {
3422                                            if (newFolder.isSupportsShortcuts()) {
3423                                                    FileShortcut fileShortcut =
3424                                                            (FileShortcut)repositoryEntry;
3425    
3426                                                    toRepository.addFileShortcut(
3427                                                            getUserId(), newFolder.getFolderId(),
3428                                                            fileShortcut.getToFileEntryId(), serviceContext);
3429                                            }
3430                                    }
3431                            }
3432                    }
3433                    catch (PortalException pe) {
3434                            toRepository.deleteFolder(newFolder.getFolderId());
3435    
3436                            throw pe;
3437                    }
3438    
3439                    try {
3440                            fromRepository.deleteFolder(folderId);
3441                    }
3442                    catch (PortalException pe) {
3443                            toRepository.deleteFolder(newFolder.getFolderId());
3444    
3445                            throw pe;
3446                    }
3447    
3448                    return newFolder;
3449            }
3450    
3451            private static final Log _log = LogFactoryUtil.getLog(
3452                    DLAppServiceImpl.class);
3453    
3454    }