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