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