001    /**
002     * Copyright (c) 2000-2011 Liferay, Inc. All rights reserved.
003     *
004     * The contents of this file are subject to the terms of the Liferay Enterprise
005     * Subscription License ("License"). You may not use this file except in
006     * compliance with the License. You can obtain a copy of the License by
007     * contacting Liferay, Inc. See the License for the specific language governing
008     * permissions and limitations under the License, including but not limited to
009     * distribution rights of the Software.
010     *
011     *
012     *
013     */
014    
015    package com.liferay.portlet.documentlibrary.service.impl;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
021    import com.liferay.portal.kernel.log.Log;
022    import com.liferay.portal.kernel.log.LogFactoryUtil;
023    import com.liferay.portal.kernel.repository.Repository;
024    import com.liferay.portal.kernel.repository.model.FileEntry;
025    import com.liferay.portal.kernel.repository.model.FileVersion;
026    import com.liferay.portal.kernel.repository.model.Folder;
027    import com.liferay.portal.kernel.search.Hits;
028    import com.liferay.portal.kernel.search.Query;
029    import com.liferay.portal.kernel.search.SearchContext;
030    import com.liferay.portal.kernel.search.SearchException;
031    import com.liferay.portal.kernel.util.FileUtil;
032    import com.liferay.portal.kernel.util.GetterUtil;
033    import com.liferay.portal.kernel.util.OrderByComparator;
034    import com.liferay.portal.kernel.util.StringBundler;
035    import com.liferay.portal.kernel.util.StringPool;
036    import com.liferay.portal.kernel.util.TempFileUtil;
037    import com.liferay.portal.kernel.workflow.WorkflowConstants;
038    import com.liferay.portal.model.Lock;
039    import com.liferay.portal.security.permission.ActionKeys;
040    import com.liferay.portal.service.ServiceContext;
041    import com.liferay.portal.spring.transaction.TransactionCommitCallbackUtil;
042    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
043    import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
044    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
045    import com.liferay.portlet.documentlibrary.service.base.DLAppServiceBaseImpl;
046    import com.liferay.portlet.documentlibrary.service.permission.DLFolderPermission;
047    import com.liferay.portlet.documentlibrary.util.DLProcessorRegistryUtil;
048    import com.liferay.portlet.documentlibrary.util.comparator.RepositoryModelModifiedDateComparator;
049    
050    import java.io.File;
051    import java.io.IOException;
052    import java.io.InputStream;
053    
054    import java.util.ArrayList;
055    import java.util.LinkedList;
056    import java.util.List;
057    import java.util.Queue;
058    import java.util.concurrent.Callable;
059    
060    /**
061     * The document library remote service. All portlets should interact with the
062     * document library through this class or through {@link DLAppLocalServiceImpl},
063     * rather than through the individual document library service classes.
064     *
065     * <p>
066     * This class provides a unified interface to all Liferay and third party
067     * repositories. While the method signatures are universal for all repositories.
068     * Additional implementation-specific parameters may be specified in the
069     * serviceContext.
070     * </p>
071     *
072     * <p>
073     * The <code>repositoryId</code> parameter used by most of the methods is the
074     * primary key of the specific repository. If the repository is a default
075     * Liferay repository, the <code>repositoryId</code> is the <code>groupId</code>
076     * or <code>scopeGroupId</code>. Otherwise, the <code>repositoryId</code> will
077     * correspond to values obtained from {@link RepositoryServiceUtil}.
078     * </p>
079     *
080     * @author Alexander Chow
081     * @author Mika Koivisto
082     * @author Shuyang Zhou
083     * @see    DLAppLocalServiceImpl
084     */
085    public class DLAppServiceImpl extends DLAppServiceBaseImpl {
086    
087            /**
088             * Adds a file entry and associated metadata. It is created based on a byte
089             * array.
090             *
091             * <p>
092             * This method takes two file names, the <code>sourceFileName</code> and the
093             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
094             * name of the actual file being uploaded. The <code>title</code>
095             * corresponds to a name the client wishes to assign this file after it has
096             * been uploaded to the portal. If it is <code>null</code>, the <code>
097             * sourceFileName</code> will be used.
098             * </p>
099             *
100             * @param  repositoryId the primary key of the repository
101             * @param  folderId the primary key of the file entry's parent folder
102             * @param  sourceFileName the original file's name
103             * @param  mimeType the file's MIME type
104             * @param  title the name to be assigned to the file (optionally <code>null
105             *         </code>)
106             * @param  description the file's description
107             * @param  changeLog the file's version change log
108             * @param  bytes the file's data (optionally <code>null</code>)
109             * @param  serviceContext the service context to be applied. Can specify the
110             *         file entry's asset category IDs, asset tag names, and expando
111             *         bridge attributes. In a Liferay repository, it may include:
112             *
113             *         <ul>
114             *         <li>
115             *         fileEntryTypeId - ID for a custom file entry type
116             *         </li>
117             *         <li>
118             *         fieldsMap - mapping for fields associated with a custom file
119             *         entry type
120             *         </li>
121             *         </ul>
122             *
123             * @return the file entry
124             * @throws PortalException if the parent folder could not be found or if the
125             *         file entry's information was invalid
126             * @throws SystemException if a system exception occurred
127             */
128            public FileEntry addFileEntry(
129                            long repositoryId, long folderId, String sourceFileName,
130                            String mimeType, String title, String description, String changeLog,
131                            byte[] bytes, ServiceContext serviceContext)
132                    throws PortalException, SystemException {
133    
134                    File file = null;
135    
136                    try {
137                            if ((bytes != null) && (bytes.length > 0)) {
138                                    file = FileUtil.createTempFile(bytes);
139                            }
140    
141                            return addFileEntry(
142                                    repositoryId, folderId, sourceFileName, mimeType, title,
143                                    description, changeLog, file, serviceContext);
144                    }
145                    catch (IOException ioe) {
146                            throw new SystemException("Unable to write temporary file", ioe);
147                    }
148                    finally {
149                            FileUtil.delete(file);
150                    }
151            }
152    
153            /**
154             * Adds a file entry and associated metadata. It is created based on a
155             * {@link File} object.
156             *
157             * <p>
158             * This method takes two file names, the <code>sourceFileName</code> and the
159             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
160             * name of the actual file being uploaded. The <code>title</code>
161             * corresponds to a name the client wishes to assign this file after it has
162             * been uploaded to the portal. If it is <code>null</code>, the <code>
163             * sourceFileName</code> will be used.
164             * </p>
165             *
166             * @param  repositoryId the primary key of the repository
167             * @param  folderId the primary key of the file entry's parent folder
168             * @param  sourceFileName the original file's name
169             * @param  mimeType the file's MIME type
170             * @param  title the name to be assigned to the file (optionally <code>null
171             *         </code>)
172             * @param  description the file's description
173             * @param  changeLog the file's version change log
174             * @param  file the file's data (optionally <code>null</code>)
175             * @param  serviceContext the service context to be applied. Can specify the
176             *         file entry's asset category IDs, asset tag names, and expando
177             *         bridge attributes. In a Liferay repository, it may include:
178             *
179             *         <ul>
180             *         <li>
181             *         fileEntryTypeId - ID for a custom file entry type
182             *         </li>
183             *         <li>
184             *         fieldsMap - mapping for fields associated with a custom file
185             *         entry type
186             *         </li>
187             *         </ul>
188             *
189             * @return the file entry
190             * @throws PortalException if the parent folder could not be found or if the
191             *         file entry's information was invalid
192             * @throws SystemException if a system exception occurred
193             */
194            public FileEntry addFileEntry(
195                            long repositoryId, long folderId, String sourceFileName,
196                            String mimeType, String title, String description, String changeLog,
197                            File file, ServiceContext serviceContext)
198                    throws PortalException, SystemException {
199    
200                    if (file == null || !file.exists() || (file.length() == 0)) {
201                            return addFileEntry(
202                                    repositoryId, folderId, sourceFileName, mimeType, title,
203                                    description, changeLog, null, 0, serviceContext);
204                    }
205    
206                    Repository repository = getRepository(repositoryId);
207    
208                    FileEntry fileEntry = repository.addFileEntry(
209                            folderId, sourceFileName, mimeType, title, description, changeLog,
210                            file, serviceContext);
211    
212                    dlAppHelperLocalService.addFileEntry(
213                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
214    
215                    return fileEntry;
216            }
217    
218            /**
219             * Adds a file entry and associated metadata. It is created based on a
220             * {@link InputStream} object.
221             *
222             * <p>
223             * This method takes two file names, the <code>sourceFileName</code> and the
224             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
225             * name of the actual file being uploaded. The <code>title</code>
226             * corresponds to a name the client wishes to assign this file after it has
227             * been uploaded to the portal. If it is <code>null</code>, the <code>
228             * sourceFileName</code> will be used.
229             * </p>
230             *
231             * @param  repositoryId the primary key of the repository
232             * @param  folderId the primary key of the file entry's parent folder
233             * @param  sourceFileName the original file's name
234             * @param  mimeType the file's MIME type
235             * @param  title the name to be assigned to the file (optionally <code>null
236             *         </code>)
237             * @param  description the file's description
238             * @param  changeLog the file's version change log
239             * @param  is the file's data (optionally <code>null</code>)
240             * @param  size the file's size (optionally <code>0</code>)
241             * @param  serviceContext the service context to be applied. Can specify the
242             *         file entry's asset category IDs, asset tag names, and expando
243             *         bridge attributes. In a Liferay repository, it may include:
244             *
245             *         <ul>
246             *         <li>
247             *         fileEntryTypeId - ID for a custom file entry type
248             *         </li>
249             *         <li>
250             *         fieldsMap - mapping for fields associated with a custom file
251             *         entry type
252             *         </li>
253             *         </ul>
254             *
255             * @return the file entry
256             * @throws PortalException if the parent folder could not be found or if the
257             *         file entry's information was invalid
258             * @throws SystemException if a system exception occurred
259             */
260            public FileEntry addFileEntry(
261                            long repositoryId, long folderId, String sourceFileName,
262                            String mimeType, String title, String description, String changeLog,
263                            InputStream is, long size, ServiceContext serviceContext)
264                    throws PortalException, SystemException {
265    
266                    if (is == null) {
267                            is = new UnsyncByteArrayInputStream(new byte[0]);
268                            size = 0;
269                    }
270    
271                    Repository repository = getRepository(repositoryId);
272    
273                    FileEntry fileEntry = repository.addFileEntry(
274                            folderId, sourceFileName, mimeType, title, description, changeLog,
275                            is, size, serviceContext);
276    
277                    dlAppHelperLocalService.addFileEntry(
278                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
279    
280                    return fileEntry;
281            }
282    
283            /**
284             * Adds a file shortcut to the existing file entry. This method is only
285             * supported by the Liferay repository.
286             *
287             * @param  repositoryId the primary key of the repository
288             * @param  folderId the primary key of the file shortcut's parent folder
289             * @param  toFileEntryId the primary key of the file shortcut's file entry
290             * @param  serviceContext the service context to be applied. Can specify the
291             *         file entry's asset category IDs, asset tag names, and expando
292             *         bridge attributes.
293             * @return the file shortcut
294             * @throws PortalException if the parent folder or file entry could not be
295             *         found, or if the file shortcut's information was invalid
296             * @throws SystemException if a system exception occurred
297             */
298            public DLFileShortcut addFileShortcut(
299                            long repositoryId, long folderId, long toFileEntryId,
300                            ServiceContext serviceContext)
301                    throws PortalException, SystemException {
302    
303                    return dlFileShortcutService.addFileShortcut(
304                            repositoryId, folderId, toFileEntryId, serviceContext);
305            }
306    
307            /**
308             * Adds a folder.
309             *
310             * @param  repositoryId the primary key of the repository
311             * @param  parentFolderId the primary key of the folder's parent folder
312             * @param  name the folder's name
313             * @param  description the folder's description
314             * @param  serviceContext the service context to be applied. In a Liferay
315             *         repository, it may include boolean mountPoint specifying whether
316             *         folder is a facade for mounting a third-party repository
317             * @return the folder
318             * @throws PortalException if the parent folder could not be found or if the
319             *         new folder's information was invalid
320             * @throws SystemException if a system exception occurred
321             */
322            public Folder addFolder(
323                            long repositoryId, long parentFolderId, String name,
324                            String description, ServiceContext serviceContext)
325                    throws PortalException, SystemException {
326    
327                    Repository repository = getRepository(repositoryId);
328    
329                    return repository.addFolder(
330                            parentFolderId, name, description, serviceContext);
331            }
332    
333            /**
334             * Adds a temporary file entry.
335             *
336             * <p>
337             * This allows a client to upload a file into a temporary location and
338             * manipulate its metadata prior to making it available for public usage.
339             * This is different from checking in and checking out a file entry.
340             * </p>
341             *
342             * @param  groupId the primary key of the group
343             * @param  folderId the primary key of the folder where the file entry will
344             *         eventually reside
345             * @param  fileName the file's original name
346             * @param  tempFolderName the temporary folder's name
347             * @param  file the file's data
348             * @return the file's name
349             * @throws IOException if a problem occurred in the access or storage of the
350             *         file
351             * @throws PortalException if the file name was invalid
352             * @throws SystemException if a system exception occurred
353             * @see    com.liferay.portal.kernel.util.TempFileUtil
354             */
355            public String addTempFileEntry(
356                            long groupId, long folderId, String fileName, String tempFolderName,
357                            File file)
358                    throws IOException, PortalException, SystemException {
359    
360                    DLFolderPermission.check(
361                            getPermissionChecker(), groupId, folderId, ActionKeys.ADD_DOCUMENT);
362    
363                    return TempFileUtil.addTempFile(
364                            getUserId(), fileName, tempFolderName, file);
365            }
366    
367            public String addTempFileEntry(
368                            long groupId, long folderId, String fileName, String tempFolderName,
369                            InputStream inputStream)
370                    throws IOException, PortalException, SystemException {
371    
372                    DLFolderPermission.check(
373                            getPermissionChecker(), groupId, folderId, ActionKeys.ADD_DOCUMENT);
374    
375                    return TempFileUtil.addTempFile(
376                            getUserId(), fileName, tempFolderName, inputStream);
377            }
378    
379            /**
380             * Cancels the check out of the file entry. If a user has not checked out
381             * the specified file entry, invoking this method will result in no changes.
382             *
383             * <p>
384             * When a file entry is checked out, a PWC (private working copy) is created
385             * and the original file entry is locked. A client can make as many changes
386             * to the PWC as he desires without those changes being visible to other
387             * users. If the user is satisfied with the changes, he may elect to check
388             * in his changes, resulting in a new file version based on the PWC; the PWC
389             * will be removed and the file entry will be unlocked. If the user is not
390             * satisfied with the changes, he may elect to cancel his check out; this
391             * results in the deletion of the PWC and unlocking of the file entry.
392             * </p>
393             *
394             * @param  fileEntryId the primary key of the file entry to cancel the
395             *         checkout
396             * @throws PortalException if the file entry could not be found
397             * @throws SystemException if a system exception occurred
398             * @see    #checkInFileEntry(long, boolean, String, ServiceContext)
399             * @see    #checkOutFileEntry(long)
400             */
401            public void cancelCheckOut(long fileEntryId)
402                    throws PortalException, SystemException {
403    
404                    Repository repository = getRepository(0, fileEntryId, 0);
405    
406                    FileEntry fileEntry = repository.getFileEntry(fileEntryId);
407    
408                    DLProcessorRegistryUtil.cleanUp(
409                            fileEntry.getLatestFileVersion());
410    
411                    repository.cancelCheckOut(fileEntryId);
412    
413                    ServiceContext serviceContext = new ServiceContext();
414    
415                    serviceContext.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH);
416    
417                    dlAppHelperLocalService.updateFileEntry(
418                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
419            }
420    
421            /**
422             * Checks in the file entry. If a user has not checked out the specified
423             * file entry, invoking this method will result in no changes.
424             *
425             * <p>
426             * When a file entry is checked out, a PWC (private working copy) is created
427             * and the original file entry is locked. A client can make as many changes
428             * to the PWC as he desires without those changes being visible to other
429             * users. If the user is satisfied with the changes, he may elect to check
430             * in his changes, resulting in a new file version based on the PWC; the PWC
431             * will be removed and the file entry will be unlocked. If the user is not
432             * satisfied with the changes, he may elect to cancel his check out; this
433             * results in the deletion of the PWC and unlocking of the file entry.
434             * </p>
435             *
436             * @param  fileEntryId the primary key of the file entry to check in
437             * @param  majorVersion whether the new file version is a major version
438             * @param  changeLog the file's version change log
439             * @param  serviceContext the service context to be applied
440             * @throws PortalException if the file entry could not be found
441             * @throws SystemException if a system exception occurred
442             * @see    #cancelCheckOut(long)
443             * @see    #checkOutFileEntry(long)
444             */
445            public void checkInFileEntry(
446                            long fileEntryId, boolean majorVersion, String changeLog,
447                            ServiceContext serviceContext)
448                    throws PortalException, SystemException {
449    
450                    Repository repository = getRepository(0, fileEntryId, 0);
451    
452                    repository.checkInFileEntry(
453                            fileEntryId, majorVersion, changeLog, serviceContext);
454    
455                    FileEntry fileEntry = getFileEntry(fileEntryId);
456    
457                    dlAppHelperLocalService.updateFileEntry(
458                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
459            }
460    
461            /**
462             * Checks in the file entry using the lock's UUID. If a user has not checked
463             * out the specified file entry, invoking this method will result in no
464             * changes. This method is primarily used by WebDAV.
465             *
466             * <p>
467             * When a file entry is checked out, a PWC (private working copy) is created
468             * and the original file entry is locked. A client can make as many changes
469             * to the PWC as he desires without those changes being visible to other
470             * users. If the user is satisfied with the changes, he may elect to check
471             * in his changes, resulting in a new file version based on the PWC; the PWC
472             * will be removed and the file entry will be unlocked. If the user is not
473             * satisfied with the changes, he may elect to cancel his check out; this
474             * results in the deletion of the PWC and unlocking of the file entry.
475             * </p>
476             *
477             * @param  fileEntryId the primary key of the file entry to check in
478             * @param  lockUuid the lock's universally unique identifier
479             * @throws PortalException if the file entry could not be found
480             * @throws SystemException if a system exception occurred
481             * @see    #cancelCheckOut(long)
482             * @see    #checkOutFileEntry(long, String, long)
483             */
484            public void checkInFileEntry(long fileEntryId, String lockUuid)
485                    throws PortalException, SystemException {
486    
487                    Repository repository = getRepository(0, fileEntryId, 0);
488    
489                    repository.checkInFileEntry(fileEntryId, lockUuid);
490    
491                    FileEntry fileEntry = getFileEntry(fileEntryId);
492    
493                    ServiceContext serviceContext = new ServiceContext();
494    
495                    serviceContext.setWorkflowAction(WorkflowConstants.ACTION_PUBLISH);
496    
497                    dlAppHelperLocalService.updateFileEntry(
498                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
499            }
500    
501            /**
502             * Check out a file entry.
503             *
504             * <p>
505             * When a file entry is checked out, a PWC (private working copy) is created
506             * and the original file entry is locked. A client can make as many changes
507             * to the PWC as he desires without those changes being visible to other
508             * users. If the user is satisfied with the changes, he may elect to check
509             * in his changes, resulting in a new file version based on the PWC; the PWC
510             * will be removed and the file entry will be unlocked. If the user is not
511             * satisfied with the changes, he may elect to cancel his check out; this
512             * results in the deletion of the PWC and unlocking of the file entry.
513             * </p>
514             *
515             * @param  fileEntryId the file entry to check out
516             * @throws PortalException if the file entry could not be found
517             * @throws SystemException if a system exception occurred
518             * @see    #cancelCheckOut(long)
519             * @see    #checkInFileEntry(long, boolean, String, ServiceContext)
520             */
521            public void checkOutFileEntry(long fileEntryId)
522                    throws PortalException, SystemException {
523    
524                    Repository repository = getRepository(0, fileEntryId, 0);
525    
526                    FileEntry fileEntry = repository.checkOutFileEntry(fileEntryId);
527    
528                    dlAppHelperLocalService.updateAsset(
529                            getUserId(), fileEntry, fileEntry.getLatestFileVersion(),
530                            fileEntryId);
531            }
532    
533            /**
534             * Checks out the file entry. This method is primarily used by WebDAV.
535             *
536             * <p>
537             * When a file entry is checked out, a PWC (private working copy) is created
538             * and the original file entry is locked. A client can make as many changes
539             * to the PWC as he desires without those changes being visible to other
540             * users. If the user is satisfied with the changes, he may elect to check
541             * in his changes, resulting in a new file version based on the PWC; the PWC
542             * will be removed and the file entry will be unlocked. If the user is not
543             * satisfied with the changes, he may elect to cancel his check out; this
544             * results in the deletion of the PWC and unlocking of the file entry.
545             * </p>
546             *
547             * @param  fileEntryId the file entry to check out
548             * @param  owner the owner string for the checkout (optionally
549             *         <code>null</code>)
550             * @param  expirationTime the time in milliseconds before the lock expires.
551             *         If the value is <code>0</code>, the default expiration time will
552             *         be used from <code>portal.properties>.
553             * @return the file entry
554             * @throws PortalException if the file entry could not be found
555             * @throws SystemException if a system exception occurred
556             * @see    #cancelCheckOut(long)
557             * @see    #checkInFileEntry(long, String)
558             */
559            public FileEntry checkOutFileEntry(
560                            long fileEntryId, String owner, long expirationTime)
561                    throws PortalException, SystemException {
562    
563                    Repository repository = getRepository(0, fileEntryId, 0);
564    
565                    FileEntry fileEntry = repository.checkOutFileEntry(
566                            fileEntryId, owner, expirationTime);
567    
568                    dlAppHelperLocalService.updateAsset(
569                            getUserId(), fileEntry, fileEntry.getLatestFileVersion(),
570                            fileEntryId);
571    
572                    return fileEntry;
573            }
574    
575            /**
576             * Performs a deep copy of the folder.
577             *
578             * @param  repositoryId the primary key of the repository
579             * @param  sourceFolderId the primary key of the folder to copy
580             * @param  parentFolderId the primary key of the new folder's parent folder
581             * @param  name the new folder's name
582             * @param  description the new folder's description
583             * @param  serviceContext the service context to be applied
584             * @return the folder
585             * @throws PortalException if the source folder or the new parent folder
586             *         could not be found or if the new folder's information was invalid
587             * @throws SystemException if a system exception occurred
588             */
589            public Folder copyFolder(
590                            long repositoryId, long sourceFolderId, long parentFolderId,
591                            String name, String description, ServiceContext serviceContext)
592                    throws PortalException, SystemException {
593    
594                    Repository repository = getRepository(repositoryId);
595    
596                    Folder srcFolder = repository.getFolder(sourceFolderId);
597    
598                    Folder destFolder = repository.addFolder(
599                            parentFolderId, name,description, serviceContext);
600    
601                    copyFolder(repository, srcFolder, destFolder, serviceContext);
602    
603                    return destFolder;
604            }
605    
606            /**
607             * Deletes the file entry with the primary key.
608             *
609             * @param  fileEntryId the primary key of the file entry
610             * @throws PortalException if the file entry could not be found
611             * @throws SystemException if a system exception occurred
612             */
613            public void deleteFileEntry(long fileEntryId)
614                    throws PortalException, SystemException {
615    
616                    Repository repository = getRepository(0, fileEntryId, 0);
617    
618                    FileEntry fileEntry = repository.getFileEntry(fileEntryId);
619    
620                    dlAppHelperLocalService.deleteFileEntry(fileEntry);
621    
622                    repository.deleteFileEntry(fileEntryId);
623            }
624    
625            /**
626             * Deletes the file entry with the title in the folder.
627             *
628             * @param  repositoryId the primary key of the repository
629             * @param  folderId the primary key of the file entry's parent folder
630             * @param  title the file entry's title
631             * @throws PortalException if the file entry could not be found
632             * @throws SystemException if a system exception occurred
633             */
634            public void deleteFileEntryByTitle(
635                            long repositoryId, long folderId, String title)
636                    throws PortalException, SystemException {
637    
638                    Repository repository = getRepository(repositoryId);
639    
640                    FileEntry fileEntry = repository.getFileEntry(folderId, title);
641    
642                    dlAppHelperLocalService.deleteFileEntry(fileEntry);
643    
644                    repository.deleteFileEntry(folderId, title);
645            }
646    
647            /**
648             * Deletes the file shortcut with the primary key. This method is only
649             * supported by the Liferay repository.
650             *
651             * @param  fileShortcutId the primary key of the file shortcut
652             * @throws PortalException if the file shortcut could not be found
653             * @throws SystemException if a system exception occurred
654             */
655            public void deleteFileShortcut(long fileShortcutId)
656                    throws PortalException, SystemException {
657    
658                    dlFileShortcutService.deleteFileShortcut(fileShortcutId);
659            }
660    
661            /**
662             * Deletes the folder with the primary key and all of its subfolders and
663             * file entries.
664             *
665             * @param  folderId the primary key of the folder
666             * @throws PortalException if the folder could not be found
667             * @throws SystemException if a system exception occurred
668             */
669            public void deleteFolder(long folderId)
670                    throws PortalException, SystemException {
671    
672                    Repository repository = getRepository(folderId, 0, 0);
673    
674                    repository.deleteFolder(folderId);
675            }
676    
677            /**
678             * Deletes the folder with the name in the parent folder and all of its
679             * subfolders and file entries.
680             *
681             * @param  repositoryId the primary key of the repository
682             * @param  parentFolderId the primary key of the folder's parent folder
683             * @param  name the folder's name
684             * @throws PortalException if the folder could not be found
685             * @throws SystemException if a system exception occurred
686             */
687            public void deleteFolder(
688                            long repositoryId, long parentFolderId, String name)
689                    throws PortalException, SystemException {
690    
691                    Repository repository = getRepository(repositoryId);
692    
693                    repository.deleteFolder(parentFolderId, name);
694            }
695    
696            /**
697             * Deletes the temporary file entry.
698             *
699             * @param  groupId the primary key of the group
700             * @param  folderId the primary key of the folder where the file entry was
701             *         eventually to reside
702             * @param  fileName the file's original name
703             * @param  tempFolderName the temporary folder's name
704             * @throws PortalException if the file name was invalid
705             * @throws SystemException if a system exception occurred
706             * @see    com.liferay.portal.kernel.util.TempFileUtil
707             */
708            public void deleteTempFileEntry(
709                            long groupId, long folderId, String fileName, String tempFolderName)
710                    throws PortalException, SystemException {
711    
712                    DLFolderPermission.check(
713                            getPermissionChecker(), groupId, folderId, ActionKeys.ADD_DOCUMENT);
714    
715                    TempFileUtil.deleteTempFile(getUserId(), fileName, tempFolderName);
716            }
717    
718            /**
719             * Returns all the file entries in the folder.
720             *
721             * @param  repositoryId the primary key of the file entry's repository
722             * @param  folderId the primary key of the file entry's folder
723             * @return the file entries in the folder
724             * @throws PortalException if the folder could not be found
725             * @throws SystemException if a system exception occurred
726             */
727            public List<FileEntry> getFileEntries(long repositoryId, long folderId)
728                    throws PortalException, SystemException {
729    
730                    return getFileEntries(
731                            repositoryId, folderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
732            }
733    
734            /**
735             * Returns a range of all the file entries in the folder.
736             *
737             * <p>
738             * Useful when paginating results. Returns a maximum of <code>end -
739             * start</code> instances. <code>start</code> and <code>end</code> are not
740             * primary keys, they are indexes in the result set. Thus, <code>0</code>
741             * refers to the first result in the set. Setting both <code>start</code>
742             * and <code>end</code> to {@link
743             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
744             * result set.
745             * </p>
746             *
747             * @param  repositoryId the primary key of the file entry's repository
748             * @param  folderId the primary key of the file entry's folder
749             * @param  start the lower bound of the range of results
750             * @param  end the upper bound of the range of results (not inclusive)
751             * @return the range of file entries in the folder
752             * @throws PortalException if the folder could not be found
753             * @throws SystemException if a system exception occurred
754             */
755            public List<FileEntry> getFileEntries(
756                            long repositoryId, long folderId, int start, int end)
757                    throws PortalException, SystemException {
758    
759                    return getFileEntries(repositoryId, folderId, start, end, null);
760            }
761    
762            /**
763             * Returns an ordered range of all the file entries in the folder.
764             *
765             * <p>
766             * Useful when paginating results. Returns a maximum of <code>end -
767             * start</code> instances. <code>start</code> and <code>end</code> are not
768             * primary keys, they are indexes in the result set. Thus, <code>0</code>
769             * refers to the first result in the set. Setting both <code>start</code>
770             * and <code>end</code> to {@link
771             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
772             * result set.
773             * </p>
774             *
775             * @param  repositoryId the primary key of the file entry's repository
776             * @param  folderId the primary key of the file entry's folder
777             * @param  start the lower bound of the range of results
778             * @param  end the upper bound of the range of results (not inclusive)
779             * @param  obc the comparator to order the file entries (optionally
780             *         <code>null</code>)
781             * @return the range of file entries in the folder ordered by comparator
782             *         <code>obc</code>
783             * @throws PortalException if the folder could not be found
784             * @throws SystemException if a system exception occurred
785             */
786            public List<FileEntry> getFileEntries(
787                            long repositoryId, long folderId, int start, int end,
788                            OrderByComparator obc)
789                    throws PortalException, SystemException {
790    
791                    Repository repository = getRepository(repositoryId);
792    
793                    return repository.getFileEntries(folderId, start, end, obc);
794            }
795    
796            /**
797             * Returns the file entries with the file entry type in the folder.
798             *
799             * @param  repositoryId the primary key of the file entry's repository
800             * @param  folderId the primary key of the file entry's folder
801             * @param  fileEntryTypeId the primary key of the file entry type
802             * @return the file entries with the file entry type in the folder
803             * @throws PortalException if the folder could not be found
804             * @throws SystemException if a system exception occurred
805             */
806            public List<FileEntry> getFileEntries(
807                            long repositoryId, long folderId, long fileEntryTypeId)
808                    throws PortalException, SystemException {
809    
810                    return getFileEntries(
811                            repositoryId, folderId, fileEntryTypeId, QueryUtil.ALL_POS,
812                            QueryUtil.ALL_POS);
813            }
814    
815            /**
816             * Returns a range of all the file entries with the file entry type in the
817             * folder.
818             *
819             * @param  repositoryId the primary key of the file entry's repository
820             * @param  folderId the primary key of the file entry's folder
821             * @param  fileEntryTypeId the primary key of the file entry type
822             * @param  start the lower bound of the range of results
823             * @param  end the upper bound of the range of results (not inclusive)
824             * @return the file entries in the folder
825             * @throws PortalException if the folder could not be found
826             * @throws SystemException if a system exception occurred
827             */
828            public List<FileEntry> getFileEntries(
829                            long repositoryId, long folderId, long fileEntryTypeId, int start,
830                            int end)
831                    throws PortalException, SystemException {
832    
833                    return getFileEntries(
834                            repositoryId, folderId, fileEntryTypeId, start, end, null);
835            }
836    
837            /**
838             * Returns an ordered range of all the file entries with the file entry type
839             * in the folder.
840             *
841             * @param  repositoryId the primary key of the repository
842             * @param  folderId the primary key of the folder
843             * @param  fileEntryTypeId the primary key of the file entry type
844             * @param  start the lower bound of the range of results
845             * @param  end the upper bound of the range of results (not inclusive)
846             * @param  obc the comparator to order the results by (optionally
847             *         <code>null</code>)
848             * @return the range of file entries with the file entry type in the folder
849             *         ordered by <code>null</code>
850             * @throws PortalException if the folder could not be found
851             * @throws SystemException if a system exception occurred
852             */
853            public List<FileEntry> getFileEntries(
854                            long repositoryId, long folderId, long fileEntryTypeId, int start,
855                            int end, OrderByComparator obc)
856                    throws PortalException, SystemException {
857    
858                    Repository repository = getRepository(repositoryId);
859    
860                    return repository.getFileEntries(
861                            folderId, fileEntryTypeId, start, end, obc);
862            }
863    
864            /**
865             * Returns a range of all the file entries and shortcuts in the folder.
866             *
867             * <p>
868             * Useful when paginating results. Returns a maximum of <code>end -
869             * start</code> instances. <code>start</code> and <code>end</code> are not
870             * primary keys, they are indexes in the result set. Thus, <code>0</code>
871             * refers to the first result in the set. Setting both <code>start</code>
872             * and <code>end</code> to {@link
873             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
874             * result set.
875             * </p>
876             *
877             * @param  repositoryId the primary key of the repository
878             * @param  folderId the primary key of the folder
879             * @param  status the workflow status
880             * @param  start the lower bound of the range of results
881             * @param  end the upper bound of the range of results (not inclusive)
882             * @return the range of file entries and shortcuts in the folder
883             * @throws PortalException if the folder could not be found
884             * @throws SystemException if a system exception occurred
885             */
886            public List<Object> getFileEntriesAndFileShortcuts(
887                            long repositoryId, long folderId, int status, int start, int end)
888                    throws PortalException, SystemException {
889    
890                    Repository repository = getRepository(repositoryId);
891    
892                    return repository.getFileEntriesAndFileShortcuts(
893                            folderId, status, start, end);
894            }
895    
896            /**
897             * Returns the number of file entries and shortcuts in the folder.
898             *
899             * @param  repositoryId the primary key of the repository
900             * @param  folderId the primary key of the folder
901             * @param  status the workflow status
902             * @return the number of file entries and shortcuts in the folder
903             * @throws PortalException if the folder ould not be found
904             * @throws SystemException if a system exception occurred
905             */
906            public int getFileEntriesAndFileShortcutsCount(
907                            long repositoryId, long folderId, int status)
908                    throws PortalException, SystemException {
909    
910                    Repository repository = getRepository(repositoryId);
911    
912                    return repository.getFileEntriesAndFileShortcutsCount(
913                            folderId, status);
914            }
915    
916            /**
917             * Returns the number of file entries in the folder.
918             *
919             * @param  repositoryId the primary key of the file entry's repository
920             * @param  folderId the primary key of the file entry's folder
921             * @return the number of file entries in the folder
922             * @throws PortalException if the folder could not be found
923             * @throws SystemException if a system exception occurred
924             */
925            public int getFileEntriesCount(long repositoryId, long folderId)
926                    throws PortalException, SystemException {
927    
928                    Repository repository = getRepository(repositoryId);
929    
930                    return repository.getFileEntriesCount(folderId);
931            }
932    
933            /**
934             * Returns the number of file entries with the file entry type in the
935             * folder.
936             *
937             * @param  repositoryId the primary key of the file entry's repository
938             * @param  folderId the primary key of the file entry's folder
939             * @param  fileEntryTypeId the primary key of the file entry type
940             * @return the number of file entries with the file entry type in the folder
941             * @throws PortalException if the folder could not be found
942             * @throws SystemException if a system exception occurred
943             */
944            public int getFileEntriesCount(
945                            long repositoryId, long folderId, long fileEntryTypeId)
946                    throws PortalException, SystemException {
947    
948                    Repository repository = getRepository(repositoryId);
949    
950                    return repository.getFileEntriesCount(folderId, fileEntryTypeId);
951            }
952    
953            /**
954             * Returns the file entry with the primary key.
955             *
956             * @param  fileEntryId the primary key of the file entry
957             * @return the file entry with the primary key
958             * @throws PortalException if the file entry could not be found
959             * @throws SystemException if a system exception occurred
960             */
961            public FileEntry getFileEntry(long fileEntryId)
962                    throws PortalException, SystemException {
963    
964                    Repository repository = getRepository(0, fileEntryId, 0);
965    
966                    return repository.getFileEntry(fileEntryId);
967            }
968    
969            /**
970             * Returns the file entry with the title in the folder.
971             *
972             * @param  groupId the primary key of the file entry's group
973             * @param  folderId the primary key of the file entry's folder
974             * @param  title the file entry's title
975             * @return the file entry with the title in the folder
976             * @throws PortalException if the file entry could not be found
977             * @throws SystemException if a system exception occurred
978             */
979            public FileEntry getFileEntry(long groupId, long folderId, String title)
980                    throws PortalException, SystemException {
981    
982                    try {
983                            Repository repository = getRepository(groupId);
984    
985                            return repository.getFileEntry(folderId, title);
986                    }
987                    catch (NoSuchFileEntryException nsfee) {
988                            if (folderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
989                                    Repository repository = getRepository(folderId, 0, 0);
990    
991                                    return repository.getFileEntry(folderId, title);
992                            }
993                            else {
994                                    throw nsfee;
995                            }
996                    }
997            }
998    
999            /**
1000             * Returns the file entry with the UUID and group.
1001             *
1002             * @param  uuid the file entry's universally unique identifier
1003             * @param  groupId the primary key of the file entry's group
1004             * @return the file entry with the UUID and group
1005             * @throws PortalException if the file entry could not be found
1006             * @throws SystemException if a system exception occurred
1007             */
1008            public FileEntry getFileEntryByUuidAndGroupId(String uuid, long groupId)
1009                    throws PortalException, SystemException {
1010    
1011                    try {
1012                            Repository repository = getRepository(groupId);
1013    
1014                            return repository.getFileEntryByUuid(uuid);
1015                    }
1016                    catch (NoSuchFileEntryException nsfee) {
1017                            List<com.liferay.portal.model.Repository> repositories =
1018                                    repositoryPersistence.findByGroupId(groupId);
1019    
1020                            for (int i = 0; i < repositories.size(); i++) {
1021                                    try {
1022                                            long repositoryId = repositories.get(i).getRepositoryId();
1023    
1024                                            Repository repository = getRepository(repositoryId);
1025    
1026                                            return repository.getFileEntryByUuid(uuid);
1027                                    }
1028                                    catch (NoSuchFileEntryException nsfee2) {
1029                                    }
1030                            }
1031                    }
1032    
1033                    StringBundler msg = new StringBundler(6);
1034    
1035                    msg.append("No DLFileEntry exists with the key {");
1036                    msg.append("uuid=");
1037                    msg.append(uuid);
1038                    msg.append(", groupId=");
1039                    msg.append(groupId);
1040                    msg.append(StringPool.CLOSE_CURLY_BRACE);
1041    
1042                    throw new NoSuchFileEntryException(msg.toString());
1043            }
1044    
1045            /**
1046             * Returns the file shortcut with the primary key. This method is only
1047             * supported by the Liferay repository.
1048             *
1049             * @param  fileShortcutId the primary key of the file shortcut
1050             * @return the file shortcut with the primary key
1051             * @throws PortalException if the file shortcut could not be found
1052             * @throws SystemException if a system exception occurred
1053             */
1054            public DLFileShortcut getFileShortcut(long fileShortcutId)
1055                    throws PortalException, SystemException {
1056    
1057                    return dlFileShortcutService.getFileShortcut(fileShortcutId);
1058            }
1059    
1060            /**
1061             * Returns the folder with the primary key.
1062             *
1063             * @param  folderId the primary key of the folder
1064             * @return the folder with the primary key
1065             * @throws PortalException if the folder could not be found
1066             * @throws SystemException if a system exception occurred
1067             */
1068            public Folder getFolder(long folderId)
1069                    throws PortalException, SystemException {
1070    
1071                    Repository repository = getRepository(folderId, 0, 0);
1072    
1073                    return repository.getFolder(folderId);
1074            }
1075    
1076            /**
1077             * Returns the folder with the name in the parent folder.
1078             *
1079             * @param  repositoryId the primary key of the folder's repository
1080             * @param  parentFolderId the primary key of the folder's parent folder
1081             * @param  name the folder's name
1082             * @return the folder with the name in the parent folder
1083             * @throws PortalException if the folder could not be found
1084             * @throws SystemException if a system exception occurred
1085             */
1086            public Folder getFolder(long repositoryId, long parentFolderId, String name)
1087                    throws PortalException, SystemException {
1088    
1089                    Repository repository = getRepository(repositoryId);
1090    
1091                    return repository.getFolder(parentFolderId, name);
1092            }
1093    
1094            /**
1095             * Returns all immediate subfolders of the parent folder.
1096             *
1097             * @param  repositoryId the primary key of the folder's repository
1098             * @param  parentFolderId the primary key of the folder's parent folder
1099             * @return the immediate subfolders of the parent folder
1100             * @throws PortalException if the parent folder could not be found
1101             * @throws SystemException if a system exception occurred
1102             */
1103            public List<Folder> getFolders(long repositoryId, long parentFolderId)
1104                    throws PortalException, SystemException {
1105    
1106                    return getFolders(
1107                            repositoryId, parentFolderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1108            }
1109    
1110            /**
1111             * Returns all immediate subfolders of the parent folder, optionally
1112             * including mount folders for third-party repositories.
1113             *
1114             * @param  repositoryId the primary key of the folder's repository
1115             * @param  parentFolderId the primary key of the folder's parent folder
1116             * @param  includeMountFolders whether to include mount folders for
1117             *         third-party repositories
1118             * @return the immediate subfolders of the parent folder
1119             * @throws PortalException if the parent folder could not be found
1120             * @throws SystemException if a system exception occurred
1121             */
1122            public List<Folder> getFolders(
1123                            long repositoryId, long parentFolderId, boolean includeMountFolders)
1124                    throws PortalException, SystemException {
1125    
1126                    return getFolders(
1127                            repositoryId, parentFolderId, includeMountFolders,
1128                            QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1129            }
1130    
1131            /**
1132             * Returns a range of all the immediate subfolders of the parent folder,
1133             * optionally including mount folders for third-party repositories.
1134             *
1135             * <p>
1136             * Useful when paginating results. Returns a maximum of <code>end -
1137             * start</code> instances. <code>start</code> and <code>end</code> are not
1138             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1139             * refers to the first result in the set. Setting both <code>start</code>
1140             * and <code>end</code> to {@link
1141             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1142             * result set.
1143             * </p>
1144             *
1145             * @param  repositoryId the primary key of the folder's repository
1146             * @param  parentFolderId the primary key of the folder's parent folder
1147             * @param  includeMountFolders whether to include mount folders for
1148             *         third-party repositories
1149             * @param  start the lower bound of the range of results
1150             * @param  end the upper bound of the range of results (not inclusive)
1151             * @return the range of immediate subfolders of the parent folder
1152             * @throws PortalException if the parent folder could not be found
1153             * @throws SystemException if a system exception occurred
1154             */
1155            public List<Folder> getFolders(
1156                            long repositoryId, long parentFolderId, boolean includeMountFolders,
1157                            int start, int end)
1158                    throws PortalException, SystemException {
1159    
1160                    return getFolders(
1161                            repositoryId, parentFolderId, includeMountFolders, start, end,
1162                            null);
1163            }
1164    
1165            /**
1166             * Returns an ordered range of all the immediate subfolders of the parent
1167             * folder.
1168             *
1169             * <p>
1170             * Useful when paginating results. Returns a maximum of <code>end -
1171             * start</code> instances. <code>start</code> and <code>end</code> are not
1172             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1173             * refers to the first result in the set. Setting both <code>start</code>
1174             * and <code>end</code> to {@link
1175             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1176             * result set.
1177             * </p>
1178             *
1179             * @param  repositoryId the primary key of the folder's repository
1180             * @param  parentFolderId the primary key of the folder's parent folder
1181             * @param  includeMountFolders whether to include mount folders for
1182             *         third-party repositories
1183             * @param  start the lower bound of the range of results
1184             * @param  end the upper bound of the range of results (not inclusive)
1185             * @param  obc the comparator to order the folders (optionally
1186             *         <code>null</code>)
1187             * @return the range of immediate subfolders of the parent folder ordered by
1188             *         comparator <code>obc</code>
1189             * @throws PortalException if the parent folder could not be found
1190             * @throws SystemException if a system exception occurred
1191             */
1192            public List<Folder> getFolders(
1193                            long repositoryId, long parentFolderId, boolean includeMountFolders,
1194                            int start, int end, OrderByComparator obc)
1195                    throws PortalException, SystemException {
1196    
1197                    Repository repository = getRepository(repositoryId);
1198    
1199                    return repository.getFolders(
1200                            parentFolderId, includeMountFolders, start, end, obc);
1201            }
1202    
1203            /**
1204             * Returns a range of all the immediate subfolders of the parent folder.
1205             *
1206             * <p>
1207             * Useful when paginating results. Returns a maximum of <code>end -
1208             * start</code> instances. <code>start</code> and <code>end</code> are not
1209             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1210             * refers to the first result in the set. Setting both <code>start</code>
1211             * and <code>end</code> to {@link
1212             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1213             * result set.
1214             * </p>
1215             *
1216             * @param  repositoryId the primary key of the folder's repository
1217             * @param  parentFolderId the primary key of the folder's parent folder
1218             * @param  start the lower bound of the range of results
1219             * @param  end the upper bound of the range of results (not inclusive)
1220             * @return the range of immediate subfolders of the parent folder
1221             * @throws PortalException if the parent folder could not be found
1222             * @throws SystemException if a system exception occurred
1223             */
1224            public List<Folder> getFolders(
1225                            long repositoryId, long parentFolderId, int start, int end)
1226                    throws PortalException, SystemException {
1227    
1228                    return getFolders(repositoryId, parentFolderId, start, end, null);
1229            }
1230    
1231            /**
1232             * Returns an ordered range of all the immediate subfolders of the parent
1233             * folder.
1234             *
1235             * <p>
1236             * Useful when paginating results. Returns a maximum of <code>end -
1237             * start</code> instances. <code>start</code> and <code>end</code> are not
1238             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1239             * refers to the first result in the set. Setting both <code>start</code>
1240             * and <code>end</code> to {@link
1241             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1242             * result set.
1243             * </p>
1244             *
1245             * @param  repositoryId the primary key of the folder's repository
1246             * @param  parentFolderId the primary key of the folder's parent folder
1247             * @param  start the lower bound of the range of results
1248             * @param  end the upper bound of the range of results (not inclusive)
1249             * @param  obc the comparator to order the folders (optionally
1250             *         <code>null</code>)
1251             * @return the range of immediate subfolders of the parent folder ordered by
1252             *         comparator <code>obc</code>
1253             * @throws PortalException if the parent folder could not be found
1254             * @throws SystemException if a system exception occurred
1255             */
1256            public List<Folder> getFolders(
1257                            long repositoryId, long parentFolderId, int start, int end,
1258                            OrderByComparator obc)
1259                    throws PortalException, SystemException {
1260    
1261                    Repository repository = getRepository(repositoryId);
1262    
1263                    return repository.getFolders(parentFolderId, true, start, end, obc);
1264            }
1265    
1266            /**
1267             * Returns a range of all the immediate subfolders, file entries, and file
1268             * shortcuts in the parent folder.
1269             *
1270             * <p>
1271             * Useful when paginating results. Returns a maximum of <code>end -
1272             * start</code> instances. <code>start</code> and <code>end</code> are not
1273             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1274             * refers to the first result in the set. Setting both <code>start</code>
1275             * and <code>end</code> to {@link
1276             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1277             * result set.
1278             * </p>
1279             *
1280             * @param  repositoryId the primary key of the repository
1281             * @param  folderId the primary key of the parent folder
1282             * @param  status the workflow status
1283             * @param  includeMountFolders whether to include mount folders for
1284             *         third-party repositories
1285             * @param  start the lower bound of the range of results
1286             * @param  end the upper bound of the range of results (not inclusive)
1287             * @return the range of immediate subfolders, file entries, and file
1288             *         shortcuts in the parent folder ordered by comparator
1289             *         <code>obc</code>
1290             * @throws PortalException if the parent folder could not be found
1291             * @throws SystemException if a system exception occurred
1292             */
1293            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
1294                            long repositoryId, long folderId, int status,
1295                            boolean includeMountFolders, int start, int end)
1296                    throws PortalException, SystemException {
1297    
1298                    return getFoldersAndFileEntriesAndFileShortcuts(
1299                            repositoryId, folderId, status, includeMountFolders, start, end,
1300                            null);
1301            }
1302    
1303            /**
1304             * Returns an ordered range of all the immediate subfolders, file entries,
1305             * and file shortcuts in the parent folder.
1306             *
1307             * <p>
1308             * Useful when paginating results. Returns a maximum of <code>end -
1309             * start</code> instances. <code>start</code> and <code>end</code> are not
1310             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1311             * refers to the first result in the set. Setting both <code>start</code>
1312             * and <code>end</code> to {@link
1313             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1314             * result set.
1315             * </p>
1316             *
1317             * @param  repositoryId the primary key of the repository
1318             * @param  folderId the primary key of the parent folder
1319             * @param  status the workflow status
1320             * @param  includeMountFolders whether to include mount folders for
1321             *         third-party repositories
1322             * @param  start the lower bound of the range of results
1323             * @param  end the upper bound of the range of results (not inclusive)
1324             * @param  obc the comparator to order the results (optionally
1325             *         <code>null</code>)
1326             * @return the range of immediate subfolders, file entries, and file
1327             *         shortcuts in the parent folder ordered by comparator
1328             *         <code>obc</code>
1329             * @throws PortalException if the parent folder could not be found
1330             * @throws SystemException if a system exception occurred
1331             */
1332            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
1333                            long repositoryId, long folderId, int status,
1334                            boolean includeMountFolders, int start, int end,
1335                            OrderByComparator obc)
1336                    throws PortalException, SystemException {
1337    
1338                    return getFoldersAndFileEntriesAndFileShortcuts(
1339                            repositoryId, folderId, status, null, includeMountFolders, start,
1340                            end, obc);
1341            }
1342    
1343            public List<Object> getFoldersAndFileEntriesAndFileShortcuts(
1344                            long repositoryId, long folderId, int status, String[] mimeTypes,
1345                            boolean includeMountFolders, int start, int end,
1346                            OrderByComparator obc)
1347                    throws PortalException, SystemException {
1348    
1349                    Repository repository = getRepository(repositoryId);
1350    
1351                    return repository.getFoldersAndFileEntriesAndFileShortcuts(
1352                            folderId, status, mimeTypes, includeMountFolders, start, end, obc);
1353            }
1354    
1355            /**
1356             * Returns the number of immediate subfolders, file entries, and file
1357             * shortcuts in the parent folder.
1358             *
1359             * @param  repositoryId the primary key of the repository
1360             * @param  folderId the primary key of the parent folder
1361             * @param  status the workflow status
1362             * @param  includeMountFolders whether to include mount folders for
1363             *         third-party repositories
1364             * @return the number of immediate subfolders, file entries, and file
1365             *         shortcuts in the parent folder
1366             * @throws PortalException if the folder could not be found
1367             * @throws SystemException if a system exception occurred
1368             */
1369            public int getFoldersAndFileEntriesAndFileShortcutsCount(
1370                            long repositoryId, long folderId, int status,
1371                            boolean includeMountFolders)
1372                    throws PortalException, SystemException {
1373    
1374                    return getFoldersAndFileEntriesAndFileShortcutsCount(
1375                            repositoryId, folderId, status, null, includeMountFolders);
1376            }
1377    
1378            public int getFoldersAndFileEntriesAndFileShortcutsCount(
1379                            long repositoryId, long folderId, int status, String[] mimeTypes,
1380                            boolean includeMountFolders)
1381                    throws PortalException, SystemException {
1382    
1383                    Repository repository = getRepository(repositoryId);
1384    
1385                    return repository.getFoldersAndFileEntriesAndFileShortcutsCount(
1386                            folderId, status, mimeTypes, includeMountFolders);
1387            }
1388    
1389            /**
1390             * Returns the number of immediate subfolders of the parent folder.
1391             *
1392             * @param  repositoryId the primary key of the folder's repository
1393             * @param  parentFolderId the primary key of the folder's parent folder
1394             * @return the number of immediate subfolders of the parent folder
1395             * @throws PortalException if the parent folder could not be found
1396             * @throws SystemException if a system exception occurred
1397             */
1398            public int getFoldersCount(long repositoryId, long parentFolderId)
1399                    throws PortalException, SystemException {
1400    
1401                    return getFoldersCount(repositoryId, parentFolderId, true);
1402            }
1403    
1404            /**
1405             * Returns the number of immediate subfolders of the parent folder,
1406             * optionally including mount folders for third-party repositories.
1407             *
1408             * @param  repositoryId the primary key of the folder's repository
1409             * @param  parentFolderId the primary key of the folder's parent folder
1410             * @param  includeMountFolders whether to include mount folders for
1411             *         third-party repositories
1412             * @return the number of immediate subfolders of the parent folder
1413             * @throws PortalException if the parent folder could not be found
1414             * @throws SystemException if a system exception occurred
1415             */
1416            public int getFoldersCount(
1417                            long repositoryId, long parentFolderId, boolean includeMountFolders)
1418                    throws PortalException, SystemException {
1419    
1420                    Repository repository = getRepository(repositoryId);
1421    
1422                    return repository.getFoldersCount(parentFolderId, includeMountFolders);
1423            }
1424    
1425            /**
1426             * Returns the number of immediate subfolders and file entries across the
1427             * folders.
1428             *
1429             * @param  repositoryId the primary key of the repository
1430             * @param  folderIds the primary keys of folders from which to count
1431             *         immediate subfolders and file entries
1432             * @param  status the workflow status
1433             * @return the number of immediate subfolders and file entries across the
1434             *         folders
1435             * @throws PortalException if the repository could not be found
1436             * @throws SystemException if a system exception occurred
1437             */
1438            public int getFoldersFileEntriesCount(
1439                            long repositoryId, List<Long> folderIds, int status)
1440                    throws PortalException, SystemException {
1441    
1442                    Repository repository = getRepository(repositoryId);
1443    
1444                    return repository.getFoldersFileEntriesCount(folderIds, status);
1445            }
1446    
1447            /**
1448             * Returns an ordered range of all the file entries in the group starting at
1449             * the repository default parent folder that are stored within the Liferay
1450             * repository. This method is primarily used to search for recently modified
1451             * file entries. It can be limited to the file entries modified by a given
1452             * user.
1453             *
1454             * <p>
1455             * Useful when paginating results. Returns a maximum of <code>end -
1456             * start</code> instances. <code>start</code> and <code>end</code> are not
1457             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1458             * refers to the first result in the set. Setting both <code>start</code>
1459             * and <code>end</code> to {@link
1460             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1461             * result set.
1462             * </p>
1463             *
1464             * @param  groupId the primary key of the group
1465             * @param  userId the primary key of the user who created the file
1466             *         (optionally <code>0</code>)
1467             * @param  start the lower bound of the range of results
1468             * @param  end the upper bound of the range of results (not inclusive)
1469             * @return the range of matching file entries ordered by date modified
1470             * @throws PortalException if the group could not be found
1471             * @throws SystemException if a system exception occurred
1472             */
1473            public List<FileEntry> getGroupFileEntries(
1474                            long groupId, long userId, int start, int end)
1475                    throws PortalException, SystemException {
1476    
1477                    return getGroupFileEntries(
1478                            groupId, userId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
1479                            start, end, new RepositoryModelModifiedDateComparator());
1480            }
1481    
1482            /**
1483             * Returns an ordered range of all the file entries in the group that are
1484             * stored within the Liferay repository. This method is primarily used to
1485             * search for recently modified file entries. It can be limited to the file
1486             * entries modified by a given user.
1487             *
1488             * <p>
1489             * Useful when paginating results. Returns a maximum of <code>end -
1490             * start</code> instances. <code>start</code> and <code>end</code> are not
1491             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1492             * refers to the first result in the set. Setting both <code>start</code>
1493             * and <code>end</code> to {@link
1494             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1495             * result set.
1496             * </p>
1497             *
1498             * @param  groupId the primary key of the group
1499             * @param  userId the primary key of the user who created the file
1500             *         (optionally <code>0</code>)
1501             * @param  start the lower bound of the range of results
1502             * @param  end the upper bound of the range of results (not inclusive)
1503             * @param  obc the comparator to order the file entries (optionally
1504             *         <code>null</code>)
1505             * @return the range of matching file entries ordered by comparator
1506             *         <code>obc</code>
1507             * @throws PortalException if the group could not be found
1508             * @throws SystemException if a system exception occurred
1509             */
1510            public List<FileEntry> getGroupFileEntries(
1511                            long groupId, long userId, int start, int end,
1512                            OrderByComparator obc)
1513                    throws PortalException, SystemException {
1514    
1515                    return getGroupFileEntries(
1516                            groupId, userId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
1517                            start, end, obc);
1518            }
1519    
1520            /**
1521             * Returns an ordered range of all the file entries in the group starting at
1522             * the root folder that are stored within the Liferay repository. This
1523             * method is primarily used to search for recently modified file entries. It
1524             * can be limited to the file entries modified by a given user.
1525             *
1526             * <p>
1527             * Useful when paginating results. Returns a maximum of <code>end -
1528             * start</code> instances. <code>start</code> and <code>end</code> are not
1529             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1530             * refers to the first result in the set. Setting both <code>start</code>
1531             * and <code>end</code> to {@link
1532             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1533             * result set.
1534             * </p>
1535             *
1536             * @param  groupId the primary key of the group
1537             * @param  userId the primary key of the user who created the file
1538             *         (optionally <code>0</code>)
1539             * @param  rootFolderId the primary key of the root folder to begin the
1540             *         search
1541             * @param  start the lower bound of the range of results
1542             * @param  end the upper bound of the range of results (not inclusive)
1543             * @return the range of matching file entries ordered by date modified
1544             * @throws PortalException if the group could not be found
1545             * @throws SystemException if a system exception occurred
1546             */
1547            public List<FileEntry> getGroupFileEntries(
1548                            long groupId, long userId, long rootFolderId, int start, int end)
1549                    throws PortalException, SystemException {
1550    
1551                    return getGroupFileEntries(
1552                            groupId, userId, rootFolderId, start, end,
1553                            new RepositoryModelModifiedDateComparator());
1554            }
1555    
1556            /**
1557             * Returns an ordered range of all the file entries in the group starting at
1558             * the root folder that are stored within the Liferay repository. This
1559             * method is primarily used to search for recently modified file entries. It
1560             * can be limited to the file entries modified by a given user.
1561             *
1562             * <p>
1563             * Useful when paginating results. Returns a maximum of <code>end -
1564             * start</code> instances. <code>start</code> and <code>end</code> are not
1565             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1566             * refers to the first result in the set. Setting both <code>start</code>
1567             * and <code>end</code> to {@link
1568             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1569             * result set.
1570             * </p>
1571             *
1572             * @param  groupId the primary key of the group
1573             * @param  userId the primary key of the user who created the file
1574             *         (optionally <code>0</code>)
1575             * @param  rootFolderId the primary key of the root folder to begin the
1576             *         search
1577             * @param  start the lower bound of the range of results
1578             * @param  end the upper bound of the range of results (not inclusive)
1579             * @param  obc the comparator to order the file entries (optionally
1580             *         <code>null</code>)
1581             * @return the range of matching file entries ordered by comparator
1582             *         <code>obc</code>
1583             * @throws PortalException if the group could not be found
1584             * @throws SystemException if a system exception occurred
1585             */
1586            public List<FileEntry> getGroupFileEntries(
1587                            long groupId, long userId, long rootFolderId, int start, int end,
1588                            OrderByComparator obc)
1589                    throws PortalException, SystemException {
1590    
1591                    Repository repository = getRepository(groupId);
1592    
1593                    return repository.getRepositoryFileEntries(
1594                            userId, rootFolderId, start, end, obc);
1595            }
1596    
1597            /**
1598             * Returns the number of file entries in a group starting at the repository
1599             * default parent folder that are stored within the Liferay repository. This
1600             * method is primarily used to search for recently modified file entries. It
1601             * can be limited to the file entries modified by a given user.
1602             *
1603             * @param  groupId the primary key of the group
1604             * @param  userId the primary key of the user who created the file
1605             *         (optionally <code>0</code>)
1606             * @return the number of matching file entries
1607             * @throws PortalException if the group could not be found
1608             * @throws SystemException if a system exception occurred
1609             */
1610            public int getGroupFileEntriesCount(long groupId, long userId)
1611                    throws PortalException, SystemException {
1612    
1613                    return getGroupFileEntriesCount(
1614                            groupId, userId, DLFolderConstants.DEFAULT_PARENT_FOLDER_ID);
1615            }
1616    
1617            /**
1618             * Returns the number of file entries in a group starting at the root folder
1619             * that are stored within the Liferay repository. This method is primarily
1620             * used to search for recently modified file entries. It can be limited to
1621             * the file entries modified by a given user.
1622             *
1623             * @param  groupId the primary key of the group
1624             * @param  userId the primary key of the user who created the file
1625             *         (optionally <code>0</code>)
1626             * @param  rootFolderId the primary key of the root folder to begin the
1627             *         search
1628             * @return the number of matching file entries
1629             * @throws PortalException if the group could not be found
1630             * @throws SystemException if a system exception occurred
1631             */
1632            public int getGroupFileEntriesCount(
1633                            long groupId, long userId, long rootFolderId)
1634                    throws PortalException, SystemException {
1635    
1636                    Repository repository = getRepository(groupId);
1637    
1638                    return repository.getRepositoryFileEntriesCount(userId, rootFolderId);
1639            }
1640    
1641            /**
1642             * Returns all immediate subfolders of the parent folder that are used for
1643             * mounting third-party repositories. This method is only supported by the
1644             * Liferay repository.
1645             *
1646             * @param  repositoryId the primary key of the folder's repository
1647             * @param  parentFolderId the primary key of the folder's parent folder
1648             * @return the immediate subfolders of the parent folder that are used for
1649             *         mounting third-party repositories
1650             * @throws PortalException if the repository or parent folder could not be
1651             *         found
1652             * @throws SystemException if a system exception occurred
1653             */
1654            public List<Folder> getMountFolders(long repositoryId, long parentFolderId)
1655                    throws PortalException, SystemException {
1656    
1657                    return getMountFolders(
1658                            repositoryId, parentFolderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS);
1659            }
1660    
1661            /**
1662             * Returns a range of all the immediate subfolders of the parent folder that
1663             * are used for mounting third-party repositories. This method is only
1664             * supported by the Liferay repository.
1665             *
1666             * <p>
1667             * Useful when paginating results. Returns a maximum of <code>end -
1668             * start</code> instances. <code>start</code> and <code>end</code> are not
1669             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1670             * refers to the first result in the set. Setting both <code>start</code>
1671             * and <code>end</code> to {@link
1672             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1673             * result set.
1674             * </p>
1675             *
1676             * @param  repositoryId the primary key of the repository
1677             * @param  parentFolderId the primary key of the parent folder
1678             * @param  start the lower bound of the range of results
1679             * @param  end the upper bound of the range of results (not inclusive)
1680             * @return the range of immediate subfolders of the parent folder that are
1681             *         used for mounting third-party repositories
1682             * @throws PortalException if the repository or parent folder could not be
1683             *         found
1684             * @throws SystemException if a system exception occurred
1685             */
1686            public List<Folder> getMountFolders(
1687                            long repositoryId, long parentFolderId, int start, int end)
1688                    throws PortalException, SystemException {
1689    
1690                    return getMountFolders(repositoryId, parentFolderId, start, end, null);
1691            }
1692    
1693            /**
1694             * Returns an ordered range of all the immediate subfolders of the parent
1695             * folder that are used for mounting third-party repositories. This method
1696             * is only supported by the Liferay repository.
1697             *
1698             * <p>
1699             * Useful when paginating results. Returns a maximum of <code>end -
1700             * start</code> instances. <code>start</code> and <code>end</code> are not
1701             * primary keys, they are indexes in the result set. Thus, <code>0</code>
1702             * refers to the first result in the set. Setting both <code>start</code>
1703             * and <code>end</code> to {@link
1704             * com.liferay.portal.kernel.dao.orm.QueryUtil#ALL_POS} will return the full
1705             * result set.
1706             * </p>
1707             *
1708             * @param  repositoryId the primary key of the folder's repository
1709             * @param  parentFolderId the primary key of the folder's parent folder
1710             * @param  start the lower bound of the range of results
1711             * @param  end the upper bound of the range of results (not inclusive)
1712             * @param  obc the comparator to order the folders (optionally
1713             *         <code>null</code>)
1714             * @return the range of immediate subfolders of the parent folder that are
1715             *         used for mounting third-party repositories ordered by comparator
1716             *         <code>obc</code>
1717             * @throws PortalException if the repository or parent folder could not be
1718             *         found
1719             * @throws SystemException if a system exception occurred
1720             */
1721            public List<Folder> getMountFolders(
1722                            long repositoryId, long parentFolderId, int start, int end,
1723                            OrderByComparator obc)
1724                    throws PortalException, SystemException {
1725    
1726                    Repository repository = getRepository(repositoryId);
1727    
1728                    return repository.getMountFolders(parentFolderId, start, end, obc);
1729            }
1730    
1731            public void getSubfolderIds(
1732                            long repositoryId, List<Long> folderIds, long folderId)
1733                    throws PortalException, SystemException {
1734    
1735                    Repository repository = getRepository(repositoryId);
1736    
1737                    repository.getSubfolderIds(folderIds, folderId);
1738            }
1739    
1740            /**
1741             * Returns all the descendant folders of the folder with the primary key.
1742             *
1743             * @param  repositoryId the primary key of the repository
1744             * @param  folderId the primary key of the folder
1745             * @return the descendant folders of the folder with the primary key
1746             * @throws PortalException if the repository or parent folder could not be
1747             *         found
1748             * @throws SystemException if a system exception occurred
1749             */
1750            public List<Long> getSubfolderIds(long repositoryId, long folderId)
1751                    throws PortalException, SystemException {
1752    
1753                    return getSubfolderIds(repositoryId, folderId, true);
1754            }
1755    
1756            /**
1757             * Returns descendant folders of the folder with the primary key, optionally
1758             * limiting to one level deep.
1759             *
1760             * @param  repositoryId the primary key of the repository
1761             * @param  folderId the primary key of the folder
1762             * @param  recurse whether to recurse through each subfolder
1763             * @return the descendant folders of the folder with the primary key
1764             * @throws PortalException if the repository or parent folder could not be
1765             *         found
1766             * @throws SystemException if a system exception occurred
1767             */
1768            public List<Long> getSubfolderIds(
1769                            long repositoryId, long folderId, boolean recurse)
1770                    throws PortalException, SystemException {
1771    
1772                    Repository repository = getRepository(repositoryId);
1773    
1774                    return repository.getSubfolderIds(folderId, recurse);
1775            }
1776    
1777            /**
1778             * Returns all the temporary file entry names.
1779             *
1780             * @param  groupId the primary key of the group
1781             * @param  folderId the primary key of the folder where the file entry will
1782             *         eventually reside
1783             * @param  tempFolderName the temporary folder's name
1784             * @return the temporary file entry names
1785             * @throws PortalException if the folder was invalid
1786             * @throws SystemException if a system exception occurred
1787             * @see    #addTempFileEntry(long, long, String, String, File)
1788             * @see    com.liferay.portal.kernel.util.TempFileUtil
1789             */
1790            public String[] getTempFileEntryNames(
1791                            long groupId, long folderId, String tempFolderName)
1792                    throws PortalException, SystemException {
1793    
1794                    DLFolderPermission.check(
1795                            getPermissionChecker(), groupId, folderId, ActionKeys.ADD_DOCUMENT);
1796    
1797                    return TempFileUtil.getTempFileEntryNames(getUserId(), tempFolderName);
1798            }
1799    
1800            /**
1801             * Locks the folder. This method is primarily used by WebDAV.
1802             *
1803             * @param  repositoryId the primary key of the repository
1804             * @param  folderId the primary key of the folder
1805             * @return the lock object
1806             * @throws PortalException if the repository or folder could not be found
1807             * @throws SystemException if a system exception occurred
1808             */
1809            public Lock lockFolder(long repositoryId, long folderId)
1810                    throws PortalException, SystemException {
1811    
1812                    Repository repository = getRepository(repositoryId);
1813    
1814                    return repository.lockFolder(folderId);
1815            }
1816    
1817            /**
1818             * Locks the folder. This method is primarily used by WebDAV.
1819             *
1820             * @param  repositoryId the primary key of the repository
1821             * @param  folderId the primary key of the folder
1822             * @param  owner the owner string for the checkout (optionally
1823             *         <code>null</code>)
1824             * @param  inheritable whether the lock must propagate to descendants
1825             * @param  expirationTime the time in milliseconds before the lock expires.
1826             *         If the value is <code>0</code>, the default expiration time will
1827             *         be used from <code>portal.properties>.
1828             * @return the lock object
1829             * @throws PortalException if the repository or folder could not be found
1830             * @throws SystemException if a system exception occurred
1831             */
1832            public Lock lockFolder(
1833                            long repositoryId, long folderId, String owner, boolean inheritable,
1834                            long expirationTime)
1835                    throws PortalException, SystemException {
1836    
1837                    Repository repository = getRepository(repositoryId);
1838    
1839                    return repository.lockFolder(
1840                            folderId, owner, inheritable, expirationTime);
1841            }
1842    
1843            /**
1844             * Moves the file entry to the new folder.
1845             *
1846             * @param  fileEntryId the primary key of the file entry
1847             * @param  newFolderId the primary key of the new folder
1848             * @param  serviceContext the service context to be applied
1849             * @return the file entry
1850             * @throws PortalException if the file entry or the new folder could not be
1851             *         found
1852             * @throws SystemException if a system exception occurred
1853             */
1854            public FileEntry moveFileEntry(
1855                            long fileEntryId, long newFolderId, ServiceContext serviceContext)
1856                    throws PortalException, SystemException {
1857    
1858                    Repository fromRepository = getRepository(0, fileEntryId, 0);
1859                    Repository toRepository = getRepository(newFolderId, serviceContext);
1860    
1861                    if (fromRepository.getRepositoryId() ==
1862                                    toRepository.getRepositoryId()) {
1863    
1864                            // Move file entries within repository
1865    
1866                            return fromRepository.moveFileEntry(
1867                                    fileEntryId, newFolderId, serviceContext);
1868                    }
1869    
1870                    // Move file entries between repositories
1871    
1872                    return moveFileEntries(
1873                            fileEntryId, newFolderId, fromRepository, toRepository,
1874                            serviceContext);
1875            }
1876    
1877            /**
1878             * Moves the folder to the new parent folder with the primary key.
1879             *
1880             * @param  folderId the primary key of the folder
1881             * @param  parentFolderId the primary key of the new parent folder
1882             * @param  serviceContext the service context to be applied
1883             * @return the file entry
1884             * @throws PortalException if the folder could not be found
1885             * @throws SystemException if a system exception occurred
1886             */
1887            public Folder moveFolder(
1888                            long folderId, long parentFolderId, ServiceContext serviceContext)
1889                    throws PortalException, SystemException {
1890    
1891                    Repository fromRepository = getRepository(folderId, 0, 0);
1892                    Repository toRepository = getRepository(parentFolderId, serviceContext);
1893    
1894                    if (fromRepository.getRepositoryId() ==
1895                                    toRepository.getRepositoryId()) {
1896    
1897                            // Move file entries within repository
1898    
1899                            return fromRepository.moveFolder(
1900                                    folderId, parentFolderId, serviceContext);
1901                    }
1902    
1903                    // Move file entries between repositories
1904    
1905                    return moveFolders(
1906                            folderId, parentFolderId, fromRepository, toRepository,
1907                            serviceContext);
1908            }
1909    
1910            /**
1911             * Refreshes the lock for the file entry. This method is primarily used by
1912             * WebDAV.
1913             *
1914             * @param  lockUuid the lock's universally unique identifier
1915             * @param  expirationTime the time in milliseconds before the lock expires.
1916             *         If the value is <code>0</code>, the default expiration time will
1917             *         be used from <code>portal.properties>.
1918             * @return the lock object
1919             * @throws PortalException if the file entry or lock could not be found
1920             * @throws SystemException if a system exception occurred
1921             */
1922            public Lock refreshFileEntryLock(String lockUuid, long expirationTime)
1923                    throws PortalException, SystemException {
1924    
1925                    Lock lock = lockLocalService.getLockByUuid(lockUuid);
1926    
1927                    long fileEntryId = GetterUtil.getLong(lock.getKey());
1928    
1929                    Repository repository = getRepository(0, fileEntryId, 0);
1930    
1931                    return repository.refreshFileEntryLock(lockUuid, expirationTime);
1932            }
1933    
1934            /**
1935             * Refreshes the lock for the folder. This method is primarily used by
1936             * WebDAV.
1937             *
1938             * @param  lockUuid the lock's universally unique identifier
1939             * @param  expirationTime the time in milliseconds before the lock expires.
1940             *         If the value is <code>0</code>, the default expiration time will
1941             *         be used from <code>portal.properties>.
1942             * @return the lock object
1943             * @throws PortalException if the folder or lock could not be found
1944             * @throws SystemException if a system exception occurred
1945             */
1946            public Lock refreshFolderLock(String lockUuid, long expirationTime)
1947                    throws PortalException, SystemException {
1948    
1949                    Lock lock = lockLocalService.getLockByUuid(lockUuid);
1950    
1951                    long folderId = GetterUtil.getLong(lock.getKey());
1952    
1953                    Repository repository = getRepository(0, folderId, 0);
1954    
1955                    return repository.refreshFolderLock(lockUuid, expirationTime);
1956            }
1957    
1958            /**
1959             * Reverts the file entry to a previous version. A new version will be
1960             * created based on the previous version and metadata.
1961             *
1962             * @param  fileEntryId the primary key of the file entry
1963             * @param  version the version to revert back to
1964             * @param  serviceContext the service context to be applied
1965             * @throws PortalException if the file entry or version could not be found
1966             * @throws SystemException if a system exception occurred
1967             */
1968            public void revertFileEntry(
1969                            long fileEntryId, String version, ServiceContext serviceContext)
1970                    throws PortalException, SystemException {
1971    
1972                    Repository repository = getRepository(0, fileEntryId, 0);
1973    
1974                    repository.revertFileEntry(fileEntryId, version, serviceContext);
1975    
1976                    FileEntry fileEntry = getFileEntry(fileEntryId);
1977    
1978                    dlAppHelperLocalService.updateFileEntry(
1979                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
1980            }
1981    
1982            public Hits search(
1983                            long repositoryId, SearchContext searchContext)
1984                    throws SearchException {
1985    
1986                    try {
1987                            Repository repository = getRepository(repositoryId);
1988    
1989                            return repository.search(searchContext);
1990                    }
1991                    catch (Exception e) {
1992                            throw new SearchException(e);
1993                    }
1994            }
1995    
1996            public Hits search(
1997                            long repositoryId, SearchContext searchContext, Query query)
1998                    throws SearchException {
1999    
2000                    try {
2001                            Repository repository = getRepository(repositoryId);
2002    
2003                            return repository.search(searchContext, query);
2004                    }
2005                    catch (Exception e) {
2006                            throw new SearchException(e);
2007                    }
2008            }
2009    
2010            /**
2011             * Unlocks the folder. This method is primarily used by WebDAV.
2012             *
2013             * @param  repositoryId the primary key of the repository
2014             * @param  folderId the primary key of the folder
2015             * @param  lockUuid the lock's universally unique identifier
2016             * @throws PortalException if the repository or folder could not be found
2017             * @throws SystemException if a system exception occurred
2018             */
2019            public void unlockFolder(long repositoryId, long folderId, String lockUuid)
2020                    throws PortalException, SystemException {
2021    
2022                    Repository repository = getRepository(repositoryId);
2023    
2024                    repository.unlockFolder(folderId, lockUuid);
2025            }
2026    
2027            /**
2028             * Unlocks the folder. This method is primarily used by WebDAV.
2029             *
2030             * @param  repositoryId the primary key of the repository
2031             * @param  parentFolderId the primary key of the parent folder
2032             * @param  name the folder's name
2033             * @param  lockUuid the lock's universally unique identifier
2034             * @throws PortalException if the repository or folder could not be found
2035             * @throws SystemException if a system exception occurred
2036             */
2037            public void unlockFolder(
2038                            long repositoryId, long parentFolderId, String name,
2039                            String lockUuid)
2040                    throws PortalException, SystemException {
2041    
2042                    Repository repository = getRepository(repositoryId);
2043    
2044                    repository.unlockFolder(parentFolderId, name, lockUuid);
2045            }
2046    
2047            /**
2048             * Updates a file entry and associated metadata based on a byte array
2049             * object. If the file data is <code>null</code>, then only the associated
2050             * metadata (i.e., <code>title</code>, <code>description</code>, and
2051             * parameters in the <code>serviceContext</code>) will be updated.
2052             *
2053             * <p>
2054             * This method takes two file names, the <code>sourceFileName</code> and the
2055             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
2056             * name of the actual file being uploaded. The <code>title</code>
2057             * corresponds to a name the client wishes to assign this file after it has
2058             * been uploaded to the portal.
2059             * </p>
2060             *
2061             * @param  fileEntryId the primary key of the file entry
2062             * @param  sourceFileName the original file's name (optionally
2063             *         <code>null</code>)
2064             * @param  mimeType the file's MIME type (optionally <code>null</code>)
2065             * @param  title the new name to be assigned to the file (optionally <code>
2066             *         null</code>)
2067             * @param  description the file's new description
2068             * @param  changeLog the file's version change log (optionally
2069             *         <code>null</code>)
2070             * @param  majorVersion whether the new file version is a major version
2071             * @param  bytes the file's data (optionally <code>null</code>)
2072             * @param  serviceContext the service context to be applied. Can specify the
2073             *         file entry's asset category IDs, asset tag names, and expando
2074             *         bridge attributes. In a Liferay repository, it may include:
2075             *
2076             *         <ul>
2077             *         <li>
2078             *         fileEntryTypeId - ID for a custom file entry type
2079             *         </li>
2080             *         <li>
2081             *         fieldsMap - mapping for fields associated with a custom file
2082             *         entry type
2083             *         </li>
2084             *         </ul>
2085             *
2086             * @return the file entry
2087             * @throws PortalException if the file entry could not be found
2088             * @throws SystemException if a system exception occurred
2089             */
2090            public FileEntry updateFileEntry(
2091                            long fileEntryId, String sourceFileName, String mimeType,
2092                            String title, String description, String changeLog,
2093                            boolean majorVersion, byte[] bytes, ServiceContext serviceContext)
2094                    throws PortalException, SystemException {
2095    
2096                    File file = null;
2097    
2098                    try {
2099                            if ((bytes != null) && (bytes.length > 0)) {
2100                                    file = FileUtil.createTempFile(bytes);
2101                            }
2102    
2103                            return updateFileEntry(
2104                                    fileEntryId, sourceFileName, mimeType, title, description,
2105                                    changeLog, majorVersion, file, serviceContext);
2106                    }
2107                    catch (IOException ioe) {
2108                            throw new SystemException("Unable to write temporary file", ioe);
2109                    }
2110                    finally {
2111                            FileUtil.delete(file);
2112                    }
2113            }
2114    
2115            /**
2116             * Updates a file entry and associated metadata based on a {@link File}
2117             * object. If the file data is <code>null</code>, then only the associated
2118             * metadata (i.e., <code>title</code>, <code>description</code>, and
2119             * parameters in the <code>serviceContext</code>) will be updated.
2120             *
2121             * <p>
2122             * This method takes two file names, the <code>sourceFileName</code> and the
2123             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
2124             * name of the actual file being uploaded. The <code>title</code>
2125             * corresponds to a name the client wishes to assign this file after it has
2126             * been uploaded to the portal.
2127             * </p>
2128             *
2129             * @param  fileEntryId the primary key of the file entry
2130             * @param  sourceFileName the original file's name (optionally
2131             *         <code>null</code>)
2132             * @param  mimeType the file's MIME type (optionally <code>null</code>)
2133             * @param  title the new name to be assigned to the file (optionally <code>
2134             *         null</code>)
2135             * @param  description the file's new description
2136             * @param  changeLog the file's version change log (optionally
2137             *         <code>null</code>)
2138             * @param  majorVersion whether the new file version is a major version
2139             * @param  file EntryId the primary key of the file entry
2140             * @param  serviceContext the service context to be applied. Can specify the
2141             *         file entry's asset category IDs, asset tag names, and expando
2142             *         bridge attributes. In a Liferay repository, it may include:
2143             *
2144             *         <ul>
2145             *         <li>
2146             *         fileEntryTypeId - ID for a custom file entry type
2147             *         </li>
2148             *         <li>
2149             *         fieldsMap - mapping for fields associated with a custom file
2150             *         entry type
2151             *         </li>
2152             *         </ul>
2153             *
2154             * @return the file entry
2155             * @throws PortalException if the file entry could not be found
2156             * @throws SystemException if a system exception occurred
2157             */
2158            public FileEntry updateFileEntry(
2159                            long fileEntryId, String sourceFileName, String mimeType,
2160                            String title, String description, String changeLog,
2161                            boolean majorVersion, File file, ServiceContext serviceContext)
2162                    throws PortalException, SystemException {
2163    
2164                    if (file == null || !file.exists() || (file.length() == 0)) {
2165                            return updateFileEntry(
2166                                    fileEntryId, sourceFileName, mimeType, title, description,
2167                                    changeLog, majorVersion, null, 0, serviceContext);
2168                    }
2169    
2170                    Repository repository = getRepository(0, fileEntryId, 0);
2171    
2172                    FileEntry fileEntry = repository.updateFileEntry(
2173                            fileEntryId, sourceFileName, mimeType, title, description,
2174                            changeLog, majorVersion, file, serviceContext);
2175    
2176                    DLProcessorRegistryUtil.cleanUp(fileEntry.getLatestFileVersion());
2177    
2178                    dlAppHelperLocalService.updateFileEntry(
2179                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
2180    
2181                    return fileEntry;
2182            }
2183    
2184            /**
2185             * Updates a file entry and associated metadata based on an {@link
2186             * InputStream} object. If the file data is <code>null</code>, then only the
2187             * associated metadata (i.e., <code>title</code>, <code>description</code>,
2188             * and parameters in the <code>serviceContext</code>) will be updated.
2189             *
2190             * <p>
2191             * This method takes two file names, the <code>sourceFileName</code> and the
2192             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
2193             * name of the actual file being uploaded. The <code>title</code>
2194             * corresponds to a name the client wishes to assign this file after it has
2195             * been uploaded to the portal.
2196             * </p>
2197             *
2198             * @param  fileEntryId the primary key of the file entry
2199             * @param  sourceFileName the original file's name (optionally
2200             *         <code>null</code>)
2201             * @param  mimeType the file's MIME type (optionally <code>null</code>)
2202             * @param  title the new name to be assigned to the file (optionally <code>
2203             *         null</code>)
2204             * @param  description the file's new description
2205             * @param  changeLog the file's version change log (optionally
2206             *         <code>null</code>)
2207             * @param  majorVersion whether the new file version is a major version
2208             * @param  is the file's data (optionally <code>null</code>)
2209             * @param  size the file's size (optionally <code>0</code>)
2210             * @param  serviceContext the service context to be applied. Can specify the
2211             *         file entry's asset category IDs, asset tag names, and expando
2212             *         bridge attributes. In a Liferay repository, it may include:
2213             *
2214             *         <ul>
2215             *         <li>
2216             *         fileEntryTypeId - ID for a custom file entry type
2217             *         </li>
2218             *         <li>
2219             *         fieldsMap - mapping for fields associated with a custom file
2220             *         entry type
2221             *         </li>
2222             *         </ul>
2223             *
2224             * @return the file entry
2225             * @throws PortalException if the file entry could not be found
2226             * @throws SystemException if a system exception occurred
2227             */
2228            public FileEntry updateFileEntry(
2229                            long fileEntryId, String sourceFileName, String mimeType,
2230                            String title, String description, String changeLog,
2231                            boolean majorVersion, InputStream is, long size,
2232                            ServiceContext serviceContext)
2233                    throws PortalException, SystemException {
2234    
2235                    Repository repository = getRepository(0, fileEntryId, 0);
2236    
2237                    FileEntry fileEntry = repository.updateFileEntry(
2238                            fileEntryId, sourceFileName, mimeType, title, description,
2239                            changeLog, majorVersion, is, size, serviceContext);
2240    
2241                    if (is != null) {
2242                            DLProcessorRegistryUtil.cleanUp(
2243                                    fileEntry.getLatestFileVersion());
2244                    }
2245    
2246                    dlAppHelperLocalService.updateFileEntry(
2247                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
2248    
2249                    return fileEntry;
2250            }
2251    
2252            public FileEntry updateFileEntryAndCheckIn(
2253                            long fileEntryId, String sourceFileName, String mimeType,
2254                            String title, String description, String changeLog,
2255                            boolean majorVersion, File file, ServiceContext serviceContext)
2256                    throws PortalException, SystemException {
2257    
2258                    if ((file == null) || !file.exists() || (file.length() == 0)) {
2259                            return updateFileEntryAndCheckIn(
2260                                    fileEntryId, sourceFileName, mimeType, title, description,
2261                                    changeLog, majorVersion, null, 0, serviceContext);
2262                    }
2263    
2264                    Repository repository = getRepository(0, fileEntryId, 0);
2265    
2266                    FileEntry fileEntry = repository.updateFileEntry(
2267                            fileEntryId, sourceFileName, mimeType, title, description,
2268                            changeLog, majorVersion, file, serviceContext);
2269    
2270                    DLProcessorRegistryUtil.cleanUp(fileEntry.getLatestFileVersion());
2271    
2272                    repository.checkInFileEntry(
2273                            fileEntryId, majorVersion, changeLog, serviceContext);
2274    
2275                    dlAppHelperLocalService.updateFileEntry(
2276                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
2277    
2278                    return fileEntry;
2279            }
2280    
2281            public FileEntry updateFileEntryAndCheckIn(
2282                            long fileEntryId, String sourceFileName, String mimeType,
2283                            String title, String description, String changeLog,
2284                            boolean majorVersion, InputStream is, long size,
2285                            ServiceContext serviceContext)
2286                    throws PortalException, SystemException {
2287    
2288                    Repository repository = getRepository(0, fileEntryId, 0);
2289    
2290                    FileEntry fileEntry = repository.updateFileEntry(
2291                            fileEntryId, sourceFileName, mimeType, title, description,
2292                            changeLog, majorVersion, is, size, serviceContext);
2293    
2294                    if (is != null) {
2295                            DLProcessorRegistryUtil.cleanUp(
2296                                    fileEntry.getLatestFileVersion());
2297                    }
2298    
2299                    repository.checkInFileEntry(
2300                            fileEntryId, majorVersion, changeLog, serviceContext);
2301    
2302                    dlAppHelperLocalService.updateFileEntry(
2303                            getUserId(), fileEntry, fileEntry.getFileVersion(), serviceContext);
2304    
2305                    return fileEntry;
2306            }
2307    
2308            /**
2309             * Updates a file shortcut to the existing file entry. This method is only
2310             * supported by the Liferay repository.
2311             *
2312             * @param  fileShortcutId the primary key of the file shortcut
2313             * @param  folderId the primary key of the file shortcut's parent folder
2314             * @param  toFileEntryId the primary key of the file shortcut's file entry
2315             * @param  serviceContext the service context to be applied. Can specify the
2316             *         file entry's asset category IDs, asset tag names, and expando
2317             *         bridge attributes.
2318             * @return the file shortcut
2319             * @throws PortalException if the file shortcut, folder, or file entry could
2320             *         not be found
2321             * @throws SystemException if a system exception occurred
2322             */
2323            public DLFileShortcut updateFileShortcut(
2324                            long fileShortcutId, long folderId, long toFileEntryId,
2325                            ServiceContext serviceContext)
2326                    throws PortalException, SystemException {
2327    
2328                    return dlFileShortcutService.updateFileShortcut(
2329                            fileShortcutId, folderId, toFileEntryId, serviceContext);
2330            }
2331    
2332            /**
2333             * Updates the folder.
2334             *
2335             * @param  folderId the primary key of the folder
2336             * @param  name the folder's new name
2337             * @param  description the folder's new description
2338             * @param  serviceContext the service context to be applied. In a Liferay
2339             *         repository, it may include:
2340             *
2341             *         <ul>
2342             *         <li>
2343             *         defaultFileEntryTypeId - the file entry type to default all
2344             *         Liferay file entries to
2345             *         </li>
2346             *         <li>
2347             *         fileEntryTypeSearchContainerPrimaryKeys - a comma-delimited list
2348             *         of file entry type primary keys allowed in the given folder and
2349             *         all descendants
2350             *         </li>
2351             *         <li>
2352             *         overrideFileEntryTypes - boolean specifying whether to override
2353             *         ancestral folder's restriction of file entry types allowed
2354             *         </li>
2355             *         <li>
2356             *         workflowDefinitionXYZ - the workflow definition name specified
2357             *         per file entry type. The parameter name must be the string
2358             *         <code>workflowDefinition</code> appended by the
2359             *         <code>fileEntryTypeId</code> (optionally <code>0</code>).
2360             *         </li>
2361             *         </ul>
2362             *
2363             * @return the folder
2364             * @throws PortalException if the current or new parent folder could not be
2365             *         found or if the new parent folder's information was invalid
2366             * @throws SystemException if a system exception occurred
2367             */
2368            public Folder updateFolder(
2369                            long folderId, String name, String description,
2370                            ServiceContext serviceContext)
2371                    throws PortalException, SystemException {
2372    
2373                    Repository repository = null;
2374    
2375                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
2376                            repository = getRepository(serviceContext.getScopeGroupId());
2377                    }
2378                    else {
2379                            repository = getRepository(folderId, 0, 0);
2380                    }
2381    
2382                    return repository.updateFolder(
2383                            folderId, name, description, serviceContext);
2384            }
2385    
2386            /**
2387             * Returns <code>true</code> if the file entry is checked out. This method
2388             * is primarily used by WebDAV.
2389             *
2390             * @param  repositoryId the primary key for the repository
2391             * @param  fileEntryId the primary key for the file entry
2392             * @param  lockUuid the lock's universally unique identifier
2393             * @return <code>true</code> if the file entry is checked out;
2394             *         <code>false</code> otherwise
2395             * @throws PortalException if the file entry could not be found
2396             * @throws SystemException if a system exception occurred
2397             */
2398            public boolean verifyFileEntryCheckOut(
2399                            long repositoryId, long fileEntryId, String lockUuid)
2400                    throws PortalException, SystemException {
2401    
2402                    Repository repository = getRepository(repositoryId);
2403    
2404                    return repository.verifyFileEntryCheckOut(fileEntryId, lockUuid);
2405            }
2406    
2407            /**
2408             * Returns <code>true</code> if the inheritable lock exists. This method is
2409             * primarily used by WebDAV.
2410             *
2411             * @param  repositoryId the primary key for the repository
2412             * @param  folderId the primary key for the folder
2413             * @param  lockUuid the lock's universally unique identifier
2414             * @return <code>true</code> if the inheritable lock exists;
2415             *         <code>false</code> otherwise
2416             * @throws PortalException if the folder could not be found
2417             * @throws SystemException if a system exception occurred
2418             */
2419            public boolean verifyInheritableLock(
2420                            long repositoryId, long folderId, String lockUuid)
2421                    throws PortalException, SystemException {
2422    
2423                    Repository repository = getRepository(repositoryId);
2424    
2425                    return repository.verifyInheritableLock(
2426                            folderId, lockUuid);
2427            }
2428    
2429            protected FileEntry copyFileEntry(
2430                            Repository toRepository, FileEntry fileEntry, long newFolderId,
2431                            ServiceContext serviceContext)
2432                    throws PortalException, SystemException {
2433    
2434                    List<FileVersion> fileVersions = fileEntry.getFileVersions(
2435                            WorkflowConstants.STATUS_ANY);
2436    
2437                    FileVersion latestFileVersion = fileVersions.get(
2438                            fileVersions.size() - 1);
2439    
2440                    FileEntry destinationFileEntry = toRepository.addFileEntry(
2441                            newFolderId, fileEntry.getTitle(), latestFileVersion.getMimeType(),
2442                            latestFileVersion.getTitle(), latestFileVersion.getDescription(),
2443                            StringPool.BLANK, latestFileVersion.getContentStream(false),
2444                            latestFileVersion.getSize(), serviceContext);
2445    
2446                    for (int i = fileVersions.size() - 2; i >= 0 ; i--) {
2447                            FileVersion fileVersion = fileVersions.get(i);
2448    
2449                            FileVersion previousFileVersion = fileVersions.get(i + 1);
2450    
2451                            try {
2452                                    destinationFileEntry = toRepository.updateFileEntry(
2453                                            destinationFileEntry.getFileEntryId(), fileEntry.getTitle(),
2454                                            destinationFileEntry.getMimeType(),
2455                                            destinationFileEntry.getTitle(),
2456                                            destinationFileEntry.getDescription(), StringPool.BLANK,
2457                                            isMajorVersion(previousFileVersion, fileVersion),
2458                                            fileVersion.getContentStream(false), fileVersion.getSize(),
2459                                            serviceContext);
2460                            }
2461                            catch (PortalException pe) {
2462                                    toRepository.deleteFileEntry(
2463                                            destinationFileEntry.getFileEntryId());
2464    
2465                                    throw  pe;
2466                            }
2467                    }
2468    
2469                    dlAppHelperLocalService.addFileEntry(
2470                            getUserId(), destinationFileEntry,
2471                            destinationFileEntry.getFileVersion(), serviceContext);
2472    
2473                    return destinationFileEntry;
2474            }
2475    
2476            protected void copyFolder(
2477                            Repository repository, Folder srcFolder, Folder destFolder,
2478                            ServiceContext serviceContext)
2479                    throws PortalException, SystemException {
2480    
2481                    Queue<Folder[]> folders = new LinkedList<Folder[]>();
2482                    final List<FileEntry> fileEntries = new ArrayList<FileEntry>();
2483    
2484                    Folder curSrcFolder = srcFolder;
2485                    Folder curDestFolder = destFolder;
2486    
2487                    while (true) {
2488                            List<FileEntry> srcFileEntries = repository.getFileEntries(
2489                                    curSrcFolder.getFolderId(), QueryUtil.ALL_POS,
2490                                    QueryUtil.ALL_POS, null);
2491    
2492                            for (FileEntry srcFileEntry : srcFileEntries) {
2493                                    try {
2494                                            FileEntry fileEntry = repository.copyFileEntry(
2495                                                    curDestFolder.getGroupId(),
2496                                                    srcFileEntry.getFileEntryId(),
2497                                                    curDestFolder.getFolderId(), serviceContext);
2498    
2499                                            dlAppHelperLocalService.addFileEntry(
2500                                                    getUserId(), fileEntry, fileEntry.getFileVersion(),
2501                                                    serviceContext);
2502    
2503                                            fileEntries.add(fileEntry);
2504                                    }
2505                                    catch (Exception e) {
2506                                            _log.error(e, e);
2507    
2508                                            continue;
2509                                    }
2510                            }
2511    
2512                            List<Folder> srcSubfolders = repository.getFolders(
2513                                    curSrcFolder.getFolderId(), false, QueryUtil.ALL_POS,
2514                                    QueryUtil.ALL_POS, null);
2515    
2516                            for (Folder srcSubfolder : srcSubfolders) {
2517                                    Folder destSubfolder = repository.addFolder(
2518                                            curDestFolder.getFolderId(), srcSubfolder.getName(),
2519                                            srcSubfolder.getDescription(), serviceContext);
2520    
2521                                    folders.offer(new Folder[] {srcSubfolder, destSubfolder});
2522                            }
2523    
2524                            Folder[] next = folders.poll();
2525    
2526                            if (next == null) {
2527                                    break;
2528                            }
2529                            else {
2530                                    curSrcFolder = next[0];
2531                                    curDestFolder = next[1];
2532                            }
2533                    }
2534    
2535                    TransactionCommitCallbackUtil.registerCallback(
2536                            new Callable<Void>() {
2537    
2538                                    public Void call() throws Exception {
2539                                            for (FileEntry fileEntry : fileEntries) {
2540                                                    DLProcessorRegistryUtil.trigger(fileEntry);
2541                                            }
2542    
2543                                            return null;
2544                                    }
2545    
2546                            });
2547            }
2548    
2549            protected void deleteFileEntry(
2550                            long oldFileEntryId, long newFileEntryId,
2551                            Repository fromRepository, Repository toRepository)
2552                    throws PortalException, SystemException {
2553    
2554                    try {
2555                            FileEntry fileEntry = fromRepository.getFileEntry(oldFileEntryId);
2556    
2557                            dlAppHelperLocalService.deleteFileEntry(fileEntry);
2558    
2559                            fromRepository.deleteFileEntry(oldFileEntryId);
2560                    }
2561                    catch (PortalException pe) {
2562                            FileEntry fileEntry = toRepository.getFileEntry(newFileEntryId);
2563    
2564                            toRepository.deleteFileEntry(newFileEntryId);
2565    
2566                            dlAppHelperLocalService.deleteFileEntry(fileEntry);
2567    
2568                            throw pe;
2569                    }
2570            }
2571    
2572            protected Repository getRepository(long repositoryId)
2573                    throws PortalException, SystemException {
2574    
2575                    return repositoryService.getRepositoryImpl(repositoryId);
2576            }
2577    
2578            protected Repository getRepository(
2579                            long folderId, long fileEntryId, long fileVersionId)
2580                    throws PortalException, SystemException {
2581    
2582                    return repositoryService.getRepositoryImpl(
2583                            folderId, fileEntryId, fileVersionId);
2584            }
2585    
2586            protected Repository getRepository(
2587                            long folderId, ServiceContext serviceContext)
2588                    throws PortalException, SystemException{
2589    
2590                    Repository repository = null;
2591    
2592                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
2593                            repository = getRepository(serviceContext.getScopeGroupId());
2594                    }
2595                    else {
2596                            repository = getRepository(folderId, 0, 0);
2597                    }
2598    
2599                    return repository;
2600            }
2601    
2602            protected boolean isMajorVersion(
2603                    FileVersion previousFileVersion, FileVersion currentFileVersion) {
2604    
2605                    long currentVersion = GetterUtil.getLong(
2606                            currentFileVersion.getVersion());
2607                    long previousVersion = GetterUtil.getLong(
2608                            previousFileVersion.getVersion());
2609    
2610                    return (currentVersion - previousVersion) >= 1;
2611            }
2612    
2613            protected FileEntry moveFileEntries(
2614                            long fileEntryId, long newFolderId, Repository fromRepository,
2615                            Repository toRepository, ServiceContext serviceContext)
2616                    throws SystemException, PortalException {
2617    
2618                    FileEntry sourceFileEntry = fromRepository.getFileEntry(fileEntryId);
2619    
2620                    FileEntry destinationFileEntry = copyFileEntry(
2621                            toRepository, sourceFileEntry, newFolderId, serviceContext);
2622    
2623                    deleteFileEntry(
2624                            fileEntryId, destinationFileEntry.getFileEntryId(), fromRepository,
2625                            toRepository);
2626    
2627                    return destinationFileEntry;
2628            }
2629    
2630            protected Folder moveFolders(
2631                            long folderId, long parentFolderId, Repository fromRepository,
2632                            Repository toRepository, ServiceContext serviceContext)
2633                    throws PortalException, SystemException{
2634    
2635                    Folder folder = fromRepository.getFolder(folderId);
2636    
2637                    Folder newFolder = toRepository.addFolder(
2638                            parentFolderId, folder.getName(), folder.getDescription(),
2639                            serviceContext);
2640    
2641                    List<Object> foldersAndFileEntriesAndFileShortcuts =
2642                            getFoldersAndFileEntriesAndFileShortcuts(
2643                                    fromRepository.getRepositoryId(), folderId,
2644                                    WorkflowConstants.STATUS_ANY, true, QueryUtil.ALL_POS,
2645                                    QueryUtil.ALL_POS);
2646    
2647                    try {
2648                            for (Object folderAndFileEntryAndFileShortcut :
2649                                            foldersAndFileEntriesAndFileShortcuts) {
2650    
2651                                    if (folderAndFileEntryAndFileShortcut instanceof FileEntry) {
2652                                            FileEntry fileEntry =
2653                                                    (FileEntry)folderAndFileEntryAndFileShortcut;
2654    
2655                                            copyFileEntry(
2656                                                    toRepository, fileEntry, newFolder.getFolderId(),
2657                                                    serviceContext);
2658                                    }
2659                                    else if (folderAndFileEntryAndFileShortcut instanceof Folder) {
2660                                            Folder currentFolder =
2661                                                    (Folder)folderAndFileEntryAndFileShortcut;
2662    
2663                                            moveFolders(
2664                                                    currentFolder.getFolderId(), newFolder.getFolderId(),
2665                                                    fromRepository, toRepository, serviceContext);
2666    
2667                                    }
2668                                    else if (folderAndFileEntryAndFileShortcut
2669                                                            instanceof DLFileShortcut) {
2670    
2671                                            if (newFolder.isSupportsShortcuts()) {
2672                                                    DLFileShortcut dlFileShorcut =
2673                                                            (DLFileShortcut)folderAndFileEntryAndFileShortcut;
2674    
2675                                                    dlFileShortcutService.addFileShortcut(
2676                                                            dlFileShorcut.getGroupId(), newFolder.getFolderId(),
2677                                                            dlFileShorcut.getToFileEntryId(), serviceContext);
2678                                            }
2679                                    }
2680                            }
2681                    }
2682                    catch (PortalException pe) {
2683                            toRepository.deleteFolder(newFolder.getFolderId());
2684    
2685                            throw  pe;
2686                    }
2687    
2688                    try {
2689                            fromRepository.deleteFolder(folderId);
2690                    }
2691                    catch (PortalException pe) {
2692                            toRepository.deleteFolder(newFolder.getFolderId());
2693    
2694                            throw pe;
2695                    }
2696    
2697                    return newFolder;
2698            }
2699    
2700            private static Log _log = LogFactoryUtil.getLog(DLAppServiceImpl.class);
2701    
2702    }