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