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