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