001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.service.impl;
016    
017    import com.liferay.portal.NoSuchGroupException;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
022    import com.liferay.portal.kernel.repository.InvalidRepositoryIdException;
023    import com.liferay.portal.kernel.repository.LocalRepository;
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.util.ArrayUtil;
028    import com.liferay.portal.kernel.util.ContentTypes;
029    import com.liferay.portal.kernel.util.FileUtil;
030    import com.liferay.portal.kernel.util.MimeTypesUtil;
031    import com.liferay.portal.kernel.util.StringBundler;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.Validator;
034    import com.liferay.portal.kernel.workflow.WorkflowConstants;
035    import com.liferay.portal.model.Repository;
036    import com.liferay.portal.repository.liferayrepository.model.LiferayFolder;
037    import com.liferay.portal.service.ServiceContext;
038    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
039    import com.liferay.portlet.documentlibrary.NoSuchFileVersionException;
040    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
041    import com.liferay.portlet.documentlibrary.model.DLFileEntryType;
042    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
043    import com.liferay.portlet.documentlibrary.model.DLFileRank;
044    import com.liferay.portlet.documentlibrary.model.DLFileShortcut;
045    import com.liferay.portlet.documentlibrary.model.DLFolder;
046    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
047    import com.liferay.portlet.documentlibrary.service.base.DLAppLocalServiceBaseImpl;
048    import com.liferay.portlet.documentlibrary.util.DLAppUtil;
049    import com.liferay.portlet.documentlibrary.util.DLProcessorRegistryUtil;
050    
051    import java.io.File;
052    import java.io.IOException;
053    import java.io.InputStream;
054    
055    import java.util.List;
056    
057    /**
058     * Provides the local service for accessing, adding, deleting, moving,
059     * subscription handling of, trash handling of, and updating document library
060     * file entries, file ranks, and folders. All portlets should interact with the
061     * document library through this class or through DLAppService, rather than
062     * through the individual document library service classes.
063     *
064     * <p>
065     * This class provides a unified interface to all Liferay and third party
066     * repositories. While the method signatures are universal for all repositories.
067     * Additional implementation-specific parameters may be specified in the
068     * serviceContext.
069     * </p>
070     *
071     * <p>
072     * The <code>repositoryId</code> parameter used by most of the methods is the
073     * primary key of the specific repository. If the repository is a default
074     * Liferay repository, the <code>repositoryId</code> is the <code>groupId</code>
075     * or <code>scopeGroupId</code>. Otherwise, the <code>repositoryId</code> will
076     * correspond to values obtained from {@link
077     * com.liferay.portal.service.RepositoryLocalServiceUtil}.
078     * </p>
079     *
080     * @author Alexander Chow
081     * @author Mika Koivisto
082     * @see    DLAppServiceImpl
083     */
084    public class DLAppLocalServiceImpl extends DLAppLocalServiceBaseImpl {
085    
086            /**
087             * Adds a file entry and associated metadata based on a byte array.
088             *
089             * <p>
090             * This method takes two file names, the <code>sourceFileName</code> and the
091             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
092             * name of the actual file being uploaded. The <code>title</code>
093             * corresponds to a name the client wishes to assign this file after it has
094             * been uploaded to the portal. If it is <code>null</code>, the <code>
095             * sourceFileName</code> will be used.
096             * </p>
097             *
098             * @param  userId the primary key of the file entry's creator/owner
099             * @param  repositoryId the primary key of the file entry's repository
100             * @param  folderId the primary key of the file entry's parent folder
101             * @param  sourceFileName the original file's name
102             * @param  mimeType the file's MIME type
103             * @param  title the name to be assigned to the file (optionally <code>null
104             *         </code>)
105             * @param  description the file's description
106             * @param  changeLog the file's version change log
107             * @param  bytes the file's data (optionally <code>null</code>)
108             * @param  serviceContext the service context to be applied. Can set the
109             *         asset category IDs, asset tag names, and expando bridge
110             *         attributes for the file entry. In a Liferay repository, it may
111             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
112             *         type </li> <li> fieldsMap - mapping for fields associated with a
113             *         custom file entry type </li> </ul>
114             * @return the file entry
115             * @throws PortalException if the parent folder could not be found or if the
116             *         file entry's information was invalid
117             * @throws SystemException if a system exception occurred
118             */
119            @Override
120            public FileEntry addFileEntry(
121                            long userId, long repositoryId, long folderId,
122                            String sourceFileName, String mimeType, String title,
123                            String description, String changeLog, byte[] bytes,
124                            ServiceContext serviceContext)
125                    throws PortalException, SystemException {
126    
127                    File file = null;
128    
129                    try {
130                            if (ArrayUtil.isNotEmpty(bytes)) {
131                                    file = FileUtil.createTempFile(bytes);
132                            }
133    
134                            return addFileEntry(
135                                    userId, repositoryId, folderId, sourceFileName, mimeType, title,
136                                    description, changeLog, file, serviceContext);
137                    }
138                    catch (IOException ioe) {
139                            throw new SystemException("Unable to write temporary file", ioe);
140                    }
141                    finally {
142                            FileUtil.delete(file);
143                    }
144            }
145    
146            /**
147             * Adds a file entry and associated metadata based on a {@link java.io.File}
148             * object.
149             *
150             * <p>
151             * This method takes two file names, the <code>sourceFileName</code> and the
152             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
153             * name of the actual file being uploaded. The <code>title</code>
154             * corresponds to a name the client wishes to assign this file after it has
155             * been uploaded to the portal. If it is <code>null</code>, the <code>
156             * sourceFileName</code> will be used.
157             * </p>
158             *
159             * @param  userId the primary key of the file entry's creator/owner
160             * @param  repositoryId the primary key of the repository
161             * @param  folderId the primary key of the file entry's parent folder
162             * @param  sourceFileName the original file's name
163             * @param  mimeType the file's MIME type
164             * @param  title the name to be assigned to the file (optionally <code>null
165             *         </code>)
166             * @param  description the file's description
167             * @param  changeLog the file's version change log
168             * @param  file the file's data (optionally <code>null</code>)
169             * @param  serviceContext the service context to be applied. Can set the
170             *         asset category IDs, asset tag names, and expando bridge
171             *         attributes for the file entry. In a Liferay repository, it may
172             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
173             *         type </li> <li> fieldsMap - mapping for fields associated with a
174             *         custom file entry type </li> </ul>
175             * @return the file entry
176             * @throws PortalException if the parent folder could not be found or if the
177             *         file entry's information was invalid
178             * @throws SystemException if a system exception occurred
179             */
180            @Override
181            public FileEntry addFileEntry(
182                            long userId, long repositoryId, long folderId,
183                            String sourceFileName, String mimeType, String title,
184                            String description, String changeLog, File file,
185                            ServiceContext serviceContext)
186                    throws PortalException, SystemException {
187    
188                    if ((file == null) || !file.exists() || (file.length() == 0)) {
189                            return addFileEntry(
190                                    userId, repositoryId, folderId, sourceFileName, mimeType, title,
191                                    description, changeLog, null, 0, serviceContext);
192                    }
193    
194                    mimeType = DLAppUtil.getMimeType(sourceFileName, mimeType, title, file);
195    
196                    LocalRepository localRepository = getLocalRepository(repositoryId);
197    
198                    FileEntry fileEntry = localRepository.addFileEntry(
199                            userId, folderId, sourceFileName, mimeType, title, description,
200                            changeLog, file, serviceContext);
201    
202                    dlAppHelperLocalService.addFileEntry(
203                            userId, fileEntry, fileEntry.getFileVersion(), serviceContext);
204    
205                    return fileEntry;
206            }
207    
208            /**
209             * Adds a file entry and associated metadata based on an {@link InputStream}
210             * object.
211             *
212             * <p>
213             * This method takes two file names, the <code>sourceFileName</code> and the
214             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
215             * name of the actual file being uploaded. The <code>title</code>
216             * corresponds to a name the client wishes to assign this file after it has
217             * been uploaded to the portal. If it is <code>null</code>, the <code>
218             * sourceFileName</code> will be used.
219             * </p>
220             *
221             * @param  userId the primary key of the file entry's creator/owner
222             * @param  repositoryId the primary key of the repository
223             * @param  folderId the primary key of the file entry's parent folder
224             * @param  sourceFileName the original file's name
225             * @param  mimeType the file's MIME type
226             * @param  title the name to be assigned to the file (optionally <code>null
227             *         </code>)
228             * @param  description the file's description
229             * @param  changeLog the file's version change log
230             * @param  is the file's data (optionally <code>null</code>)
231             * @param  size the file's size (optionally <code>0</code>)
232             * @param  serviceContext the service context to be applied. Can set the
233             *         asset category IDs, asset tag names, and expando bridge
234             *         attributes for the file entry. In a Liferay repository, it may
235             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
236             *         type </li> <li> fieldsMap - mapping for fields associated with a
237             *         custom file entry type </li> </ul>
238             * @return the file entry
239             * @throws PortalException if the parent folder could not be found or if the
240             *         file entry's information was invalid
241             * @throws SystemException if a system exception occurred
242             */
243            @Override
244            public FileEntry addFileEntry(
245                            long userId, long repositoryId, long folderId,
246                            String sourceFileName, String mimeType, String title,
247                            String description, String changeLog, InputStream is, long size,
248                            ServiceContext serviceContext)
249                    throws PortalException, SystemException {
250    
251                    if (is == null) {
252                            is = new UnsyncByteArrayInputStream(new byte[0]);
253                            size = 0;
254                    }
255    
256                    if (Validator.isNull(mimeType) ||
257                            mimeType.equals(ContentTypes.APPLICATION_OCTET_STREAM)) {
258    
259                            String extension = DLAppUtil.getExtension(title, sourceFileName);
260    
261                            if (size == 0) {
262                                    mimeType = MimeTypesUtil.getExtensionContentType(extension);
263                            }
264                            else {
265                                    File file = null;
266    
267                                    try {
268                                            file = FileUtil.createTempFile(is);
269    
270                                            return addFileEntry(
271                                                    userId, repositoryId, folderId, sourceFileName,
272                                                    mimeType, title, description, changeLog, file,
273                                                    serviceContext);
274                                    }
275                                    catch (IOException ioe) {
276                                            throw new SystemException(
277                                                    "Unable to write temporary file", ioe);
278                                    }
279                                    finally {
280                                            FileUtil.delete(file);
281                                    }
282                            }
283                    }
284    
285                    LocalRepository localRepository = getLocalRepository(repositoryId);
286    
287                    FileEntry fileEntry = localRepository.addFileEntry(
288                            userId, folderId, sourceFileName, mimeType, title, description,
289                            changeLog, is, size, serviceContext);
290    
291                    dlAppHelperLocalService.addFileEntry(
292                            userId, fileEntry, fileEntry.getFileVersion(), serviceContext);
293    
294                    return fileEntry;
295            }
296    
297            /**
298             * Adds the file rank to the existing file entry. This method is only
299             * supported by the Liferay repository.
300             *
301             * @param  repositoryId the primary key of the repository
302             * @param  companyId the primary key of the company
303             * @param  userId the primary key of the file rank's creator/owner
304             * @param  fileEntryId the primary key of the file entry
305             * @param  serviceContext the service context to be applied
306             * @return the file rank
307             * @throws SystemException if a system exception occurred
308             */
309            @Override
310            public DLFileRank addFileRank(
311                            long repositoryId, long companyId, long userId, long fileEntryId,
312                            ServiceContext serviceContext)
313                    throws SystemException {
314    
315                    return dlFileRankLocalService.addFileRank(
316                            repositoryId, companyId, userId, fileEntryId, serviceContext);
317            }
318    
319            /**
320             * Adds the file shortcut to the existing file entry. This method is only
321             * supported by the Liferay repository.
322             *
323             * @param  userId the primary key of the file shortcut's creator/owner
324             * @param  repositoryId the primary key of the repository
325             * @param  folderId the primary key of the file shortcut's parent folder
326             * @param  toFileEntryId the primary key of the file entry to point to
327             * @param  serviceContext the service context to be applied. Can set the
328             *         asset category IDs, asset tag names, and expando bridge
329             *         attributes for the file entry.
330             * @return the file shortcut
331             * @throws PortalException if the parent folder or file entry could not be
332             *         found, or if the file shortcut's information was invalid
333             * @throws SystemException if a system exception occurred
334             */
335            @Override
336            public DLFileShortcut addFileShortcut(
337                            long userId, long repositoryId, long folderId, long toFileEntryId,
338                            ServiceContext serviceContext)
339                    throws PortalException, SystemException {
340    
341                    return dlFileShortcutLocalService.addFileShortcut(
342                            userId, repositoryId, folderId, toFileEntryId, serviceContext);
343            }
344    
345            /**
346             * Adds a folder.
347             *
348             * @param  userId the primary key of the folder's creator/owner
349             * @param  repositoryId the primary key of the repository
350             * @param  parentFolderId the primary key of the folder's parent folder
351             * @param  name the folder's name
352             * @param  description the folder's description
353             * @param  serviceContext the service context to be applied. In a Liferay
354             *         repository, it may include mountPoint which is a boolean
355             *         specifying whether the folder is a facade for mounting a
356             *         third-party repository
357             * @return the folder
358             * @throws PortalException if the parent folder could not be found or if the
359             *         new folder's information was invalid
360             * @throws SystemException if a system exception occurred
361             */
362            @Override
363            public Folder addFolder(
364                            long userId, long repositoryId, long parentFolderId, String name,
365                            String description, ServiceContext serviceContext)
366                    throws PortalException, SystemException {
367    
368                    LocalRepository localRepository = getLocalRepository(repositoryId);
369    
370                    return localRepository.addFolder(
371                            userId, parentFolderId, name, description, serviceContext);
372            }
373    
374            /**
375             * Delete all data associated to the given repository. This method is only
376             * supported by the Liferay repository.
377             *
378             * @param  repositoryId the primary key of the data's repository
379             * @throws PortalException if the repository could not be found
380             * @throws SystemException if a system exception occurred
381             */
382            @Override
383            public void deleteAll(long repositoryId)
384                    throws PortalException, SystemException {
385    
386                    LocalRepository localRepository = getLocalRepository(repositoryId);
387    
388                    localRepository.deleteAll();
389            }
390    
391            /**
392             * Deletes the file entry.
393             *
394             * @param  fileEntryId the primary key of the file entry
395             * @throws PortalException if the file entry could not be found
396             * @throws SystemException if a system exception occurred
397             */
398            @Override
399            public void deleteFileEntry(long fileEntryId)
400                    throws PortalException, SystemException {
401    
402                    LocalRepository localRepository = getFileEntryLocalRepository(
403                            fileEntryId);
404    
405                    FileEntry fileEntry = localRepository.getFileEntry(fileEntryId);
406    
407                    dlAppHelperLocalService.deleteFileEntry(fileEntry);
408    
409                    localRepository.deleteFileEntry(fileEntryId);
410            }
411    
412            /**
413             * Deletes the file ranks associated to a given file entry. This method is
414             * only supported by the Liferay repository.
415             *
416             * @param  fileEntryId the primary key of the file entry
417             * @throws SystemException if a system exception occurred
418             */
419            @Override
420            public void deleteFileRanksByFileEntryId(long fileEntryId)
421                    throws SystemException {
422    
423                    dlFileRankLocalService.deleteFileRanksByFileEntryId(fileEntryId);
424            }
425    
426            /**
427             * Deletes the file ranks associated to a given user. This method is only
428             * supported by the Liferay repository.
429             *
430             * @param  userId the primary key of the user
431             * @throws SystemException if a system exception occurred
432             */
433            @Override
434            public void deleteFileRanksByUserId(long userId) throws SystemException {
435                    dlFileRankLocalService.deleteFileRanksByUserId(userId);
436            }
437    
438            /**
439             * Deletes the file shortcut. This method is only supported by the Liferay
440             * repository.
441             *
442             * @param  dlFileShortcut the file shortcut
443             * @throws PortalException if the file shortcut could not be found
444             * @throws SystemException if a system exception occurred
445             */
446            @Override
447            public void deleteFileShortcut(DLFileShortcut dlFileShortcut)
448                    throws PortalException, SystemException {
449    
450                    dlFileShortcutLocalService.deleteFileShortcut(dlFileShortcut);
451            }
452    
453            /**
454             * Deletes the file shortcut. This method is only supported by the Liferay
455             * repository.
456             *
457             * @param  fileShortcutId the primary key of the file shortcut
458             * @throws PortalException if the file shortcut could not be found
459             * @throws SystemException if a system exception occurred
460             */
461            @Override
462            public void deleteFileShortcut(long fileShortcutId)
463                    throws PortalException, SystemException {
464    
465                    dlFileShortcutLocalService.deleteFileShortcut(fileShortcutId);
466            }
467    
468            /**
469             * Deletes all file shortcuts associated to the file entry. This method is
470             * only supported by the Liferay repository.
471             *
472             * @param  toFileEntryId the primary key of the associated file entry
473             * @throws PortalException if the file shortcut for the file entry could not
474             *         be found
475             * @throws SystemException if a system exception occurred
476             */
477            @Override
478            public void deleteFileShortcuts(long toFileEntryId)
479                    throws PortalException, SystemException {
480    
481                    dlFileShortcutLocalService.deleteFileShortcuts(toFileEntryId);
482            }
483    
484            /**
485             * Deletes the folder and all of its subfolders and file entries.
486             *
487             * @param  folderId the primary key of the folder
488             * @throws PortalException if the folder could not be found
489             * @throws SystemException if a system exception occurred
490             */
491            @Override
492            public void deleteFolder(long folderId)
493                    throws PortalException, SystemException {
494    
495                    LocalRepository localRepository = getFolderLocalRepository(folderId);
496    
497                    localRepository.deleteFolder(folderId);
498            }
499    
500            /**
501             * Returns the file entry with the primary key.
502             *
503             * @param  fileEntryId the primary key of the file entry
504             * @return the file entry with the primary key
505             * @throws PortalException if the file entry could not be found
506             * @throws SystemException if a system exception occurred
507             */
508            @Override
509            public FileEntry getFileEntry(long fileEntryId)
510                    throws PortalException, SystemException {
511    
512                    LocalRepository localRepository = getFileEntryLocalRepository(
513                            fileEntryId);
514    
515                    return localRepository.getFileEntry(fileEntryId);
516            }
517    
518            /**
519             * Returns the file entry with the title in the folder.
520             *
521             * @param  groupId the primary key of the file entry's group
522             * @param  folderId the primary key of the file entry's folder
523             * @param  title the file entry's title
524             * @return the file entry with the title in the folder
525             * @throws PortalException if the file entry could not be found
526             * @throws SystemException if a system exception occurred
527             */
528            @Override
529            public FileEntry getFileEntry(long groupId, long folderId, String title)
530                    throws PortalException, SystemException {
531    
532                    try {
533                            LocalRepository localRepository = getLocalRepository(groupId);
534    
535                            return localRepository.getFileEntry(folderId, title);
536                    }
537                    catch (NoSuchFileEntryException nsfee) {
538                    }
539    
540                    LocalRepository localRepository = getFolderLocalRepository(folderId);
541    
542                    return localRepository.getFileEntry(folderId, title);
543            }
544    
545            /**
546             * Returns the file entry with the UUID and group.
547             *
548             * @param  uuid the file entry's UUID
549             * @param  groupId the primary key of the file entry's group
550             * @return the file entry with the UUID and group
551             * @throws PortalException if the file entry could not be found
552             * @throws SystemException if a system exception occurred
553             */
554            @Override
555            public FileEntry getFileEntryByUuidAndGroupId(String uuid, long groupId)
556                    throws PortalException, SystemException {
557    
558                    try {
559                            LocalRepository localRepository = getLocalRepository(groupId);
560    
561                            return localRepository.getFileEntryByUuid(uuid);
562                    }
563                    catch (NoSuchFileEntryException nsfee) {
564                    }
565    
566                    List<com.liferay.portal.model.Repository> repositories =
567                            repositoryPersistence.findByGroupId(groupId);
568    
569                    for (Repository repository : repositories) {
570                            try {
571                                    LocalRepository localRepository = getLocalRepository(
572                                            repository.getRepositoryId());
573    
574                                    return localRepository.getFileEntryByUuid(uuid);
575                            }
576                            catch (NoSuchFileEntryException nsfee) {
577                            }
578                    }
579    
580                    StringBundler msg = new StringBundler(6);
581    
582                    msg.append("No DLFileEntry exists with the key {");
583                    msg.append("uuid=");
584                    msg.append(uuid);
585                    msg.append(", groupId=");
586                    msg.append(groupId);
587                    msg.append(StringPool.CLOSE_CURLY_BRACE);
588    
589                    throw new NoSuchFileEntryException(msg.toString());
590            }
591    
592            /**
593             * Returns the file ranks from the user. This method is only supported by
594             * the Liferay repository.
595             *
596             * @param  repositoryId the primary key of the repository
597             * @param  userId the primary key of the user
598             * @return the file ranks from the user
599             * @throws SystemException if a system exception occurred
600             */
601            @Override
602            public List<DLFileRank> getFileRanks(long repositoryId, long userId)
603                    throws SystemException {
604    
605                    return dlFileRankLocalService.getFileRanks(repositoryId, userId);
606            }
607    
608            /**
609             * Returns the file shortcut with the primary key. This method is only
610             * supported by the Liferay repository.
611             *
612             * @param  fileShortcutId the primary key of the file shortcut
613             * @return the file shortcut with the primary key
614             * @throws PortalException if the file shortcut could not be found
615             * @throws SystemException if a system exception occurred
616             */
617            @Override
618            public DLFileShortcut getFileShortcut(long fileShortcutId)
619                    throws PortalException, SystemException {
620    
621                    return dlFileShortcutLocalService.getFileShortcut(fileShortcutId);
622            }
623    
624            /**
625             * Returns the file version with the primary key.
626             *
627             * @param  fileVersionId the primary key of the file version
628             * @return the file version with the primary key
629             * @throws PortalException if the file version could not be found
630             * @throws SystemException if a system exception occurred
631             */
632            @Override
633            public FileVersion getFileVersion(long fileVersionId)
634                    throws PortalException, SystemException {
635    
636                    LocalRepository localRepository = getFileVersionLocalRepository(
637                            fileVersionId);
638    
639                    return localRepository.getFileVersion(fileVersionId);
640            }
641    
642            /**
643             * Returns the folder with the primary key.
644             *
645             * @param  folderId the primary key of the folder
646             * @return the folder with the primary key
647             * @throws PortalException if the folder could not be found
648             * @throws SystemException if a system exception occurred
649             */
650            @Override
651            public Folder getFolder(long folderId)
652                    throws PortalException, SystemException {
653    
654                    LocalRepository localRepository = getFolderLocalRepository(folderId);
655    
656                    return localRepository.getFolder(folderId);
657            }
658    
659            /**
660             * Returns the folder with the name in the parent folder.
661             *
662             * @param  repositoryId the primary key of the folder's repository
663             * @param  parentFolderId the primary key of the folder's parent folder
664             * @param  name the folder's name
665             * @return the folder with the name in the parent folder
666             * @throws PortalException if the folder could not be found
667             * @throws SystemException if a system exception occurred
668             */
669            @Override
670            public Folder getFolder(long repositoryId, long parentFolderId, String name)
671                    throws PortalException, SystemException {
672    
673                    LocalRepository localRepository = getLocalRepository(repositoryId);
674    
675                    return localRepository.getFolder(parentFolderId, name);
676            }
677    
678            /**
679             * Returns the mount folder of the repository with the primary key. This
680             * method is only supported by the Liferay repository.
681             *
682             * @param  repositoryId the primary key of the repository
683             * @return the folder used for mounting third-party repositories
684             * @throws PortalException if the repository or mount folder could not be
685             *         found
686             * @throws SystemException if a system exception occurred
687             */
688            @Override
689            public Folder getMountFolder(long repositoryId)
690                    throws PortalException, SystemException {
691    
692                    DLFolder dlFolder = dlFolderLocalService.getMountFolder(repositoryId);
693    
694                    return new LiferayFolder(dlFolder);
695            }
696    
697            /**
698             * Moves the file entry to the new folder.
699             *
700             * @param  userId the primary key of the user
701             * @param  fileEntryId the primary key of the file entry
702             * @param  newFolderId the primary key of the new folder
703             * @param  serviceContext the service context to be applied
704             * @return the file entry
705             * @throws PortalException if the file entry or the new folder could not be
706             *         found
707             * @throws SystemException if a system exception occurred
708             */
709            @Override
710            public FileEntry moveFileEntry(
711                            long userId, long fileEntryId, long newFolderId,
712                            ServiceContext serviceContext)
713                    throws PortalException, SystemException {
714    
715                    LocalRepository fromLocalRepository = getFileEntryLocalRepository(
716                            fileEntryId);
717                    LocalRepository toLocalRepository = getFolderLocalRepository(
718                            newFolderId, serviceContext.getScopeGroupId());
719    
720                    if (fromLocalRepository.getRepositoryId() ==
721                                    toLocalRepository.getRepositoryId()) {
722    
723                            // Move file entries within repository
724    
725                            return fromLocalRepository.moveFileEntry(
726                                    userId, fileEntryId, newFolderId, serviceContext);
727                    }
728    
729                    // Move file entries between repositories
730    
731                    return moveFileEntries(
732                            userId, fileEntryId, newFolderId, fromLocalRepository,
733                            toLocalRepository, serviceContext);
734            }
735    
736            /**
737             * Moves the file entry with the primary key to the trash portlet.
738             *
739             * @param  userId the primary key of the user
740             * @param  fileEntryId the primary key of the file entry
741             * @return the file entry
742             * @throws PortalException if the file entry could not be found
743             * @throws SystemException if a system exception occurred
744             */
745            @Override
746            public FileEntry moveFileEntryToTrash(long userId, long fileEntryId)
747                    throws PortalException, SystemException {
748    
749                    LocalRepository localRepository = getFileEntryLocalRepository(
750                            fileEntryId);
751    
752                    FileEntry fileEntry = localRepository.getFileEntry(fileEntryId);
753    
754                    return dlAppHelperLocalService.moveFileEntryToTrash(userId, fileEntry);
755            }
756    
757            @Override
758            public Folder moveFolder(
759                            long userId, long folderId, long parentFolderId,
760                            ServiceContext serviceContext)
761                    throws PortalException, SystemException {
762    
763                    LocalRepository sourceLocalRepository = getFolderLocalRepository(
764                            folderId);
765    
766                    LocalRepository destinationLocalRepository = getFolderLocalRepository(
767                            parentFolderId, serviceContext.getScopeGroupId());
768    
769                    if (parentFolderId != DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
770                            Folder toFolder = destinationLocalRepository.getFolder(
771                                    parentFolderId);
772    
773                            if (toFolder.isMountPoint()) {
774                                    destinationLocalRepository = getLocalRepository(
775                                            toFolder.getRepositoryId());
776                            }
777                    }
778    
779                    if (sourceLocalRepository.getRepositoryId() ==
780                                    destinationLocalRepository.getRepositoryId()) {
781    
782                            // Move file entries within repository
783    
784                            Folder folder = sourceLocalRepository.moveFolder(
785                                    userId, folderId, parentFolderId, serviceContext);
786    
787                            return folder;
788                    }
789    
790                    // Move file entries between repositories
791    
792                    return moveFolders(
793                            userId, folderId, parentFolderId, sourceLocalRepository,
794                            destinationLocalRepository, serviceContext);
795            }
796    
797            /**
798             * Restores the file entry with the primary key from the trash portlet.
799             *
800             * @param  userId the primary key of the user
801             * @param  fileEntryId the primary key of the file entry
802             * @throws PortalException if the file entry could not be found
803             * @throws SystemException if a system exception occurred
804             */
805            @Override
806            public void restoreFileEntryFromTrash(long userId, long fileEntryId)
807                    throws PortalException, SystemException {
808    
809                    LocalRepository localRepository = getFileEntryLocalRepository(
810                            fileEntryId);
811    
812                    FileEntry fileEntry = localRepository.getFileEntry(fileEntryId);
813    
814                    dlAppHelperLocalService.restoreFileEntryFromTrash(userId, fileEntry);
815            }
816    
817            /**
818             * Subscribe the user to changes in documents of the file entry type. This
819             * method is only supported by the Liferay repository.
820             *
821             * @param  userId the primary key of the user
822             * @param  groupId the primary key of the file entry type's group
823             * @param  fileEntryTypeId the primary key of the file entry type
824             * @throws PortalException if the user or group could not be found
825             * @throws SystemException if a system exception occurred
826             */
827            @Override
828            public void subscribeFileEntryType(
829                            long userId, long groupId, long fileEntryTypeId)
830                    throws PortalException, SystemException {
831    
832                    if (fileEntryTypeId ==
833                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT) {
834    
835                            fileEntryTypeId = groupId;
836                    }
837    
838                    subscriptionLocalService.addSubscription(
839                            userId, groupId, DLFileEntryType.class.getName(), fileEntryTypeId);
840            }
841    
842            /**
843             * Subscribe the user to document changes in the folder. This method is only
844             * supported by the Liferay repository.
845             *
846             * @param  userId the primary key of the user
847             * @param  groupId the primary key of the folder's group
848             * @param  folderId the primary key of the folder
849             * @throws PortalException if the user or group could not be found
850             * @throws SystemException if a system exception occurred
851             */
852            @Override
853            public void subscribeFolder(long userId, long groupId, long folderId)
854                    throws PortalException, SystemException {
855    
856                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
857                            folderId = groupId;
858                    }
859    
860                    subscriptionLocalService.addSubscription(
861                            userId, groupId, Folder.class.getName(), folderId);
862            }
863    
864            /**
865             * Unsubscribe the user from changes in documents of the file entry type.
866             * This method is only supported by the Liferay repository.
867             *
868             * @param  userId the primary key of the user
869             * @param  groupId the primary key of the file entry type's group
870             * @param  fileEntryTypeId the primary key of the file entry type
871             * @throws PortalException if the user or group could not be found
872             * @throws SystemException if a system exception occurred
873             */
874            @Override
875            public void unsubscribeFileEntryType(
876                            long userId, long groupId, long fileEntryTypeId)
877                    throws PortalException, SystemException {
878    
879                    if (fileEntryTypeId ==
880                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_ID_BASIC_DOCUMENT) {
881    
882                            fileEntryTypeId = groupId;
883                    }
884    
885                    subscriptionLocalService.deleteSubscription(
886                            userId, DLFileEntryType.class.getName(), fileEntryTypeId);
887            }
888    
889            /**
890             * Unsubscribe the user from document changes in the folder. This method is
891             * only supported by the Liferay repository.
892             *
893             * @param  userId the primary key of the user
894             * @param  groupId the primary key of the folder's group
895             * @param  folderId the primary key of the folder
896             * @throws PortalException if the user or group could not be found
897             * @throws SystemException if a system exception occurred
898             */
899            @Override
900            public void unsubscribeFolder(long userId, long groupId, long folderId)
901                    throws PortalException, SystemException {
902    
903                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
904                            folderId = groupId;
905                    }
906    
907                    subscriptionLocalService.deleteSubscription(
908                            userId, Folder.class.getName(), folderId);
909            }
910    
911            /**
912             * Updates the file entry's asset replacing its asset categories, tags, and
913             * links.
914             *
915             * @param  userId the primary key of the user
916             * @param  fileEntry the file entry to update
917             * @param  fileVersion the file version to update
918             * @param  assetCategoryIds the primary keys of the new asset categories
919             * @param  assetTagNames the new asset tag names
920             * @param  assetLinkEntryIds the primary keys of the new asset link entries
921             * @throws PortalException if the file entry or version could not be found
922             * @throws SystemException if a system exception occurred
923             */
924            @Override
925            public void updateAsset(
926                            long userId, FileEntry fileEntry, FileVersion fileVersion,
927                            long[] assetCategoryIds, String[] assetTagNames,
928                            long[] assetLinkEntryIds)
929                    throws PortalException, SystemException {
930    
931                    LocalRepository localRepository = getFileEntryLocalRepository(
932                            fileEntry.getFileEntryId());
933    
934                    localRepository.updateAsset(
935                            userId, fileEntry, fileVersion, assetCategoryIds, assetTagNames,
936                            assetLinkEntryIds);
937            }
938    
939            /**
940             * Updates a file entry and associated metadata based on a byte array
941             * object. If the file data is <code>null</code>, then only the associated
942             * metadata (i.e., <code>title</code>, <code>description</code>, and
943             * parameters in the <code>serviceContext</code>) will be updated.
944             *
945             * <p>
946             * This method takes two file names, the <code>sourceFileName</code> and the
947             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
948             * name of the actual file being uploaded. The <code>title</code>
949             * corresponds to a name the client wishes to assign this file after it has
950             * been uploaded to the portal.
951             * </p>
952             *
953             * @param  userId the primary key of the user
954             * @param  fileEntryId the primary key of the file entry
955             * @param  sourceFileName the original file's name (optionally
956             *         <code>null</code>)
957             * @param  mimeType the file's MIME type (optionally <code>null</code>)
958             * @param  title the new name to be assigned to the file (optionally <code>
959             *         <code>null</code></code>)
960             * @param  description the file's new description
961             * @param  changeLog the file's version change log (optionally
962             *         <code>null</code>)
963             * @param  majorVersion whether the new file version is a major version
964             * @param  bytes the file's data (optionally <code>null</code>)
965             * @param  serviceContext the service context to be applied. Can set the
966             *         asset category IDs, asset tag names, and expando bridge
967             *         attributes for the file entry. In a Liferay repository, it may
968             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
969             *         type </li> <li> fieldsMap - mapping for fields associated with a
970             *         custom file entry type </li> </ul>
971             * @return the file entry
972             * @throws PortalException if the file entry could not be found
973             * @throws SystemException if a system exception occurred
974             */
975            @Override
976            public FileEntry updateFileEntry(
977                            long userId, long fileEntryId, String sourceFileName,
978                            String mimeType, String title, String description, String changeLog,
979                            boolean majorVersion, byte[] bytes, ServiceContext serviceContext)
980                    throws PortalException, SystemException {
981    
982                    File file = null;
983    
984                    try {
985                            if (ArrayUtil.isNotEmpty(bytes)) {
986                                    file = FileUtil.createTempFile(bytes);
987                            }
988    
989                            return updateFileEntry(
990                                    userId, fileEntryId, sourceFileName, mimeType, title,
991                                    description, changeLog, majorVersion, file, serviceContext);
992                    }
993                    catch (IOException ioe) {
994                            throw new SystemException("Unable to write temporary file", ioe);
995                    }
996                    finally {
997                            FileUtil.delete(file);
998                    }
999            }
1000    
1001            /**
1002             * Updates a file entry and associated metadata based on a {@link
1003             * java.io.File} object. If the file data is <code>null</code>, then only
1004             * the associated metadata (i.e., <code>title</code>,
1005             * <code>description</code>, and parameters in the
1006             * <code>serviceContext</code>) will be updated.
1007             *
1008             * <p>
1009             * This method takes two file names, the <code>sourceFileName</code> and the
1010             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
1011             * name of the actual file being uploaded. The <code>title</code>
1012             * corresponds to a name the client wishes to assign this file after it has
1013             * been uploaded to the portal.
1014             * </p>
1015             *
1016             * @param  userId the primary key of the user
1017             * @param  fileEntryId the primary key of the file entry
1018             * @param  sourceFileName the original file's name (optionally
1019             *         <code>null</code>)
1020             * @param  mimeType the file's MIME type (optionally <code>null</code>)
1021             * @param  title the new name to be assigned to the file (optionally <code>
1022             *         <code>null</code></code>)
1023             * @param  description the file's new description
1024             * @param  changeLog the file's version change log (optionally
1025             *         <code>null</code>)
1026             * @param  majorVersion whether the new file version is a major version
1027             * @param  file the file's data (optionally <code>null</code>)
1028             * @param  serviceContext the service context to be applied. Can set the
1029             *         asset category IDs, asset tag names, and expando bridge
1030             *         attributes for the file entry. In a Liferay repository, it may
1031             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
1032             *         type </li> <li> fieldsMap - mapping for fields associated with a
1033             *         custom file entry type </li> </ul>
1034             * @return the file entry
1035             * @throws PortalException if the file entry could not be found
1036             * @throws SystemException if a system exception occurred
1037             */
1038            @Override
1039            public FileEntry updateFileEntry(
1040                            long userId, long fileEntryId, String sourceFileName,
1041                            String mimeType, String title, String description, String changeLog,
1042                            boolean majorVersion, File file, ServiceContext serviceContext)
1043                    throws PortalException, SystemException {
1044    
1045                    if ((file == null) || !file.exists() || (file.length() == 0)) {
1046                            return updateFileEntry(
1047                                    userId, fileEntryId, sourceFileName, mimeType, title,
1048                                    description, changeLog, majorVersion, null, 0, serviceContext);
1049                    }
1050    
1051                    mimeType = DLAppUtil.getMimeType(sourceFileName, mimeType, title, file);
1052    
1053                    LocalRepository localRepository = getFileEntryLocalRepository(
1054                            fileEntryId);
1055    
1056                    FileEntry fileEntry = localRepository.updateFileEntry(
1057                            userId, fileEntryId, sourceFileName, mimeType, title, description,
1058                            changeLog, majorVersion, file, serviceContext);
1059    
1060                    DLProcessorRegistryUtil.cleanUp(fileEntry.getLatestFileVersion());
1061    
1062                    dlAppHelperLocalService.updateFileEntry(
1063                            userId, fileEntry, null, fileEntry.getFileVersion(),
1064                            serviceContext);
1065    
1066                    return fileEntry;
1067            }
1068    
1069            /**
1070             * Updates a file entry and associated metadata based on an {@link
1071             * InputStream} object. If the file data is <code>null</code>, then only the
1072             * associated metadata (i.e., <code>title</code>, <code>description</code>,
1073             * and parameters in the <code>serviceContext</code>) will be updated.
1074             *
1075             * <p>
1076             * This method takes two file names, the <code>sourceFileName</code> and the
1077             * <code>title</code>. The <code>sourceFileName</code> corresponds to the
1078             * name of the actual file being uploaded. The <code>title</code>
1079             * corresponds to a name the client wishes to assign this file after it has
1080             * been uploaded to the portal.
1081             * </p>
1082             *
1083             * @param  userId the primary key of the user
1084             * @param  fileEntryId the primary key of the file entry
1085             * @param  sourceFileName the original file's name (optionally
1086             *         <code>null</code>)
1087             * @param  mimeType the file's MIME type (optionally <code>null</code>)
1088             * @param  title the new name to be assigned to the file (optionally <code>
1089             *         <code>null</code></code>)
1090             * @param  description the file's new description
1091             * @param  changeLog the file's version change log (optionally
1092             *         <code>null</code>)
1093             * @param  majorVersion whether the new file version is a major version
1094             * @param  is the file's data (optionally <code>null</code>)
1095             * @param  size the file's size (optionally <code>0</code>)
1096             * @param  serviceContext the service context to be applied. Can set the
1097             *         asset category IDs, asset tag names, and expando bridge
1098             *         attributes for the file entry. In a Liferay repository, it may
1099             *         include:  <ul> <li> fileEntryTypeId - ID for a custom file entry
1100             *         type </li> <li> fieldsMap - mapping for fields associated with a
1101             *         custom file entry type </li> </ul>
1102             * @return the file entry
1103             * @throws PortalException if the file entry could not be found
1104             * @throws SystemException if a system exception occurred
1105             */
1106            @Override
1107            public FileEntry updateFileEntry(
1108                            long userId, long fileEntryId, String sourceFileName,
1109                            String mimeType, String title, String description, String changeLog,
1110                            boolean majorVersion, InputStream is, long size,
1111                            ServiceContext serviceContext)
1112                    throws PortalException, SystemException {
1113    
1114                    if (Validator.isNull(mimeType) ||
1115                            mimeType.equals(ContentTypes.APPLICATION_OCTET_STREAM)) {
1116    
1117                            String extension = DLAppUtil.getExtension(title, sourceFileName);
1118    
1119                            if (size == 0) {
1120                                    mimeType = MimeTypesUtil.getExtensionContentType(extension);
1121                            }
1122                            else {
1123                                    File file = null;
1124    
1125                                    try {
1126                                            file = FileUtil.createTempFile(is);
1127    
1128                                            return updateFileEntry(
1129                                                    userId, fileEntryId, sourceFileName, mimeType, title,
1130                                                    description, changeLog, majorVersion, file,
1131                                                    serviceContext);
1132                                    }
1133                                    catch (IOException ioe) {
1134                                            throw new SystemException(
1135                                                    "Unable to write temporary file", ioe);
1136                                    }
1137                                    finally {
1138                                            FileUtil.delete(file);
1139                                    }
1140                            }
1141                    }
1142    
1143                    LocalRepository localRepository = getFileEntryLocalRepository(
1144                            fileEntryId);
1145    
1146                    FileEntry oldFileEntry = localRepository.getFileEntry(fileEntryId);
1147    
1148                    FileVersion oldFileVersion = oldFileEntry.getFileVersion();
1149    
1150                    FileEntry fileEntry = localRepository.updateFileEntry(
1151                            userId, fileEntryId, sourceFileName, mimeType, title, description,
1152                            changeLog, majorVersion, is, size, serviceContext);
1153    
1154                    if (is != null) {
1155                            DLProcessorRegistryUtil.cleanUp(fileEntry.getLatestFileVersion());
1156    
1157                            oldFileVersion = null;
1158                    }
1159    
1160                    dlAppHelperLocalService.updateFileEntry(
1161                            userId, fileEntry, oldFileVersion, fileEntry.getFileVersion(),
1162                            serviceContext);
1163    
1164                    return fileEntry;
1165            }
1166    
1167            /**
1168             * Updates a file rank to the existing file entry. This method is only
1169             * supported by the Liferay repository.
1170             *
1171             * @param  repositoryId the primary key of the file rank's repository
1172             * @param  companyId the primary key of the file rank's company
1173             * @param  userId the primary key of the file rank's creator/owner
1174             * @param  fileEntryId the primary key of the file rank's file entry
1175             * @param  serviceContext the service context to be applied
1176             * @return the file rank
1177             * @throws SystemException if a system exception occurred
1178             */
1179            @Override
1180            public DLFileRank updateFileRank(
1181                            long repositoryId, long companyId, long userId, long fileEntryId,
1182                            ServiceContext serviceContext)
1183                    throws SystemException {
1184    
1185                    return dlFileRankLocalService.updateFileRank(
1186                            repositoryId, companyId, userId, fileEntryId, serviceContext);
1187            }
1188    
1189            /**
1190             * Updates a file shortcut to the existing file entry. This method is only
1191             * supported by the Liferay repository.
1192             *
1193             * @param  userId the primary key of the file shortcut's creator/owner
1194             * @param  fileShortcutId the primary key of the file shortcut
1195             * @param  folderId the primary key of the file shortcut's parent folder
1196             * @param  toFileEntryId the primary key of the file shortcut's file entry
1197             * @param  serviceContext the service context to be applied. Can set the
1198             *         asset category IDs, asset tag names, and expando bridge
1199             *         attributes for the file entry.
1200             * @return the file shortcut
1201             * @throws PortalException if the file shortcut, folder, or file entry could
1202             *         not be found
1203             * @throws SystemException if a system exception occurred
1204             */
1205            @Override
1206            public DLFileShortcut updateFileShortcut(
1207                            long userId, long fileShortcutId, long folderId, long toFileEntryId,
1208                            ServiceContext serviceContext)
1209                    throws PortalException, SystemException {
1210    
1211                    return dlFileShortcutLocalService.updateFileShortcut(
1212                            userId, fileShortcutId, folderId, toFileEntryId, serviceContext);
1213            }
1214    
1215            /**
1216             * Updates all file shortcuts to the existing file entry to the new file
1217             * entry. This method is only supported by the Liferay repository.
1218             *
1219             * @param  toRepositoryId the primary key of the repository
1220             * @param  oldToFileEntryId the primary key of the old file entry pointed to
1221             * @param  newToFileEntryId the primary key of the new file entry to point
1222             *         to
1223             * @throws SystemException if a system exception occurred
1224             */
1225            @Override
1226            public void updateFileShortcuts(
1227                            long toRepositoryId, long oldToFileEntryId, long newToFileEntryId)
1228                    throws SystemException {
1229    
1230                    dlFileShortcutLocalService.updateFileShortcuts(
1231                            oldToFileEntryId, newToFileEntryId);
1232            }
1233    
1234            /**
1235             * Updates the folder.
1236             *
1237             * @param  folderId the primary key of the folder
1238             * @param  parentFolderId the primary key of the folder's new parent folder
1239             * @param  name the folder's new name
1240             * @param  description the folder's new description
1241             * @param  serviceContext the service context to be applied. In a Liferay
1242             *         repository, it may include:  <ul> <li> defaultFileEntryTypeId -
1243             *         the file entry type to default all Liferay file entries to </li>
1244             *         <li> dlFileEntryTypesSearchContainerPrimaryKeys - a
1245             *         comma-delimited list of file entry type primary keys allowed in
1246             *         the given folder and all descendants </li> <li>
1247             *         overrideFileEntryTypes - boolean specifying whether to override
1248             *         ancestral folder's restriction of file entry types allowed </li>
1249             *         <li> workflowDefinitionXYZ - the workflow definition name
1250             *         specified per file entry type. The parameter name must be the
1251             *         string <code>workflowDefinition</code> appended by the <code>
1252             *         fileEntryTypeId</code> (optionally <code>0</code>). </li> </ul>
1253             * @return the folder
1254             * @throws PortalException if the current or new parent folder could not be
1255             *         found, or if the new parent folder's information was invalid
1256             * @throws SystemException if a system exception occurred
1257             */
1258            @Override
1259            public Folder updateFolder(
1260                            long folderId, long parentFolderId, String name, String description,
1261                            ServiceContext serviceContext)
1262                    throws PortalException, SystemException {
1263    
1264                    LocalRepository localRepository = getFolderLocalRepository(folderId);
1265    
1266                    return localRepository.updateFolder(
1267                            folderId, parentFolderId, name, description, serviceContext);
1268            }
1269    
1270            protected FileEntry copyFileEntry(
1271                            long userId, LocalRepository toLocalRepository, FileEntry fileEntry,
1272                            long newFolderId, ServiceContext serviceContext)
1273                    throws PortalException, SystemException {
1274    
1275                    List<FileVersion> fileVersions = fileEntry.getFileVersions(
1276                            WorkflowConstants.STATUS_ANY);
1277    
1278                    FileVersion latestFileVersion = fileVersions.get(
1279                            fileVersions.size() - 1);
1280    
1281                    FileEntry destinationFileEntry = toLocalRepository.addFileEntry(
1282                            userId, newFolderId, fileEntry.getTitle(),
1283                            latestFileVersion.getMimeType(), latestFileVersion.getTitle(),
1284                            latestFileVersion.getDescription(), StringPool.BLANK,
1285                            latestFileVersion.getContentStream(false),
1286                            latestFileVersion.getSize(), serviceContext);
1287    
1288                    for (int i = fileVersions.size() - 2; i >= 0; i--) {
1289                            FileVersion fileVersion = fileVersions.get(i);
1290    
1291                            FileVersion previousFileVersion = fileVersions.get(i + 1);
1292    
1293                            try {
1294                                    destinationFileEntry = toLocalRepository.updateFileEntry(
1295                                            userId, destinationFileEntry.getFileEntryId(),
1296                                            fileEntry.getTitle(), destinationFileEntry.getMimeType(),
1297                                            destinationFileEntry.getTitle(),
1298                                            destinationFileEntry.getDescription(), StringPool.BLANK,
1299                                            DLAppUtil.isMajorVersion(fileVersion, previousFileVersion),
1300                                            fileVersion.getContentStream(false), fileVersion.getSize(),
1301                                            serviceContext);
1302                            }
1303                            catch (PortalException pe) {
1304                                    toLocalRepository.deleteFileEntry(
1305                                            destinationFileEntry.getFileEntryId());
1306    
1307                                    throw pe;
1308                            }
1309                    }
1310    
1311                    dlAppHelperLocalService.addFileEntry(
1312                            userId, destinationFileEntry, destinationFileEntry.getFileVersion(),
1313                            serviceContext);
1314    
1315                    return destinationFileEntry;
1316            }
1317    
1318            protected void deleteFileEntry(
1319                            long oldFileEntryId, long newFileEntryId,
1320                            LocalRepository fromLocalRepository,
1321                            LocalRepository toLocalRepository)
1322                    throws PortalException, SystemException {
1323    
1324                    try {
1325                            FileEntry fileEntry = fromLocalRepository.getFileEntry(
1326                                    oldFileEntryId);
1327    
1328                            fromLocalRepository.deleteFileEntry(oldFileEntryId);
1329    
1330                            dlAppHelperLocalService.deleteFileEntry(fileEntry);
1331                    }
1332                    catch (PortalException pe) {
1333                            FileEntry fileEntry = toLocalRepository.getFileEntry(
1334                                    newFileEntryId);
1335    
1336                            toLocalRepository.deleteFileEntry(newFileEntryId);
1337    
1338                            dlAppHelperLocalService.deleteFileEntry(fileEntry);
1339    
1340                            throw pe;
1341                    }
1342            }
1343    
1344            protected LocalRepository getFileEntryLocalRepository(long fileEntryId)
1345                    throws PortalException, SystemException {
1346    
1347                    try {
1348                            return repositoryLocalService.getLocalRepositoryImpl(
1349                                    0, fileEntryId, 0);
1350                    }
1351                    catch (InvalidRepositoryIdException irie) {
1352                            StringBundler sb = new StringBundler(3);
1353    
1354                            sb.append("No FileEntry exists with the key {fileEntryId=");
1355                            sb.append(fileEntryId);
1356                            sb.append("}");
1357    
1358                            throw new NoSuchFileEntryException(sb.toString(), irie);
1359                    }
1360            }
1361    
1362            protected LocalRepository getFileVersionLocalRepository(long fileVersionId)
1363                    throws PortalException, SystemException {
1364    
1365                    try {
1366                            return repositoryLocalService.getLocalRepositoryImpl(
1367                                    0, 0, fileVersionId);
1368                    }
1369                    catch (InvalidRepositoryIdException irie) {
1370                            StringBundler sb = new StringBundler(3);
1371    
1372                            sb.append("No FileVersion exists with the key {fileVersionId=");
1373                            sb.append(fileVersionId);
1374                            sb.append("}");
1375    
1376                            throw new NoSuchFileVersionException(sb.toString(), irie);
1377                    }
1378            }
1379    
1380            protected LocalRepository getFolderLocalRepository(long folderId)
1381                    throws PortalException, SystemException {
1382    
1383                    try {
1384                            return repositoryLocalService.getLocalRepositoryImpl(
1385                                    folderId, 0, 0);
1386                    }
1387                    catch (InvalidRepositoryIdException irie) {
1388                            StringBundler sb = new StringBundler(3);
1389    
1390                            sb.append("No Folder exists with the key {folderId=");
1391                            sb.append(folderId);
1392                            sb.append("}");
1393    
1394                            throw new NoSuchFolderException(sb.toString(), irie);
1395                    }
1396            }
1397    
1398            protected LocalRepository getFolderLocalRepository(
1399                            long folderId, long groupId)
1400                    throws PortalException, SystemException {
1401    
1402                    LocalRepository localRepository = null;
1403    
1404                    if (folderId == DLFolderConstants.DEFAULT_PARENT_FOLDER_ID) {
1405                            localRepository = getLocalRepository(groupId);
1406                    }
1407                    else {
1408                            localRepository = getFolderLocalRepository(folderId);
1409                    }
1410    
1411                    return localRepository;
1412            }
1413    
1414            protected LocalRepository getLocalRepository(long repositoryId)
1415                    throws PortalException, SystemException {
1416    
1417                    try {
1418                            return repositoryLocalService.getLocalRepositoryImpl(repositoryId);
1419                    }
1420                    catch (InvalidRepositoryIdException irie) {
1421                            StringBundler sb = new StringBundler(3);
1422    
1423                            sb.append("No Group exists with the key {repositoryId=");
1424                            sb.append(repositoryId);
1425                            sb.append("}");
1426    
1427                            throw new NoSuchGroupException(sb.toString(), irie);
1428                    }
1429            }
1430    
1431            protected FileEntry moveFileEntries(
1432                            long userId, long fileEntryId, long newFolderId,
1433                            LocalRepository fromLocalRepository,
1434                            LocalRepository toLocalRepository, ServiceContext serviceContext)
1435                    throws PortalException, SystemException {
1436    
1437                    FileEntry sourceFileEntry = fromLocalRepository.getFileEntry(
1438                            fileEntryId);
1439    
1440                    FileEntry destinationFileEntry = copyFileEntry(
1441                            userId, toLocalRepository, sourceFileEntry, newFolderId,
1442                            serviceContext);
1443    
1444                    deleteFileEntry(
1445                            fileEntryId, destinationFileEntry.getFileEntryId(),
1446                            fromLocalRepository, toLocalRepository);
1447    
1448                    return destinationFileEntry;
1449            }
1450    
1451            protected Folder moveFolders(
1452                            long userId, long folderId, long parentFolderId,
1453                            LocalRepository sourceLocalRepository,
1454                            LocalRepository destinationLocalRepository,
1455                            ServiceContext serviceContext)
1456                    throws PortalException, SystemException {
1457    
1458                    Folder sourceFolder = sourceLocalRepository.getFolder(folderId);
1459    
1460                    Folder destinationFolder = destinationLocalRepository.addFolder(
1461                            userId, parentFolderId, sourceFolder.getName(),
1462                            sourceFolder.getDescription(), serviceContext);
1463    
1464                    List<Object> foldersAndFileEntriesAndFileShortcuts =
1465                            dlAppService.getFoldersAndFileEntriesAndFileShortcuts(
1466                                    sourceLocalRepository.getRepositoryId(), folderId,
1467                                    WorkflowConstants.STATUS_ANY, true, QueryUtil.ALL_POS,
1468                                    QueryUtil.ALL_POS);
1469    
1470                    try {
1471                            for (Object folderAndFileEntryAndFileShortcut :
1472                                            foldersAndFileEntriesAndFileShortcuts) {
1473    
1474                                    if (folderAndFileEntryAndFileShortcut instanceof FileEntry) {
1475                                            FileEntry fileEntry =
1476                                                    (FileEntry)folderAndFileEntryAndFileShortcut;
1477    
1478                                            copyFileEntry(
1479                                                    userId, destinationLocalRepository, fileEntry,
1480                                                    destinationFolder.getFolderId(), serviceContext);
1481                                    }
1482                                    else if (folderAndFileEntryAndFileShortcut instanceof Folder) {
1483                                            Folder folder = (Folder)folderAndFileEntryAndFileShortcut;
1484    
1485                                            moveFolders(
1486                                                    userId, folder.getFolderId(),
1487                                                    destinationFolder.getFolderId(), sourceLocalRepository,
1488                                                    destinationLocalRepository, serviceContext);
1489                                    }
1490                                    else if (folderAndFileEntryAndFileShortcut
1491                                                            instanceof DLFileShortcut) {
1492    
1493                                            if (destinationFolder.isSupportsShortcuts()) {
1494                                                    DLFileShortcut dlFileShorcut =
1495                                                            (DLFileShortcut)folderAndFileEntryAndFileShortcut;
1496    
1497                                                    dlFileShortcutLocalService.addFileShortcut(
1498                                                            userId, dlFileShorcut.getGroupId(),
1499                                                            destinationFolder.getFolderId(),
1500                                                            dlFileShorcut.getToFileEntryId(), serviceContext);
1501                                            }
1502                                    }
1503                            }
1504                    }
1505                    catch (PortalException pe) {
1506                            destinationLocalRepository.deleteFolder(
1507                                    destinationFolder.getFolderId());
1508    
1509                            throw pe;
1510                    }
1511    
1512                    try {
1513                            sourceLocalRepository.deleteFolder(folderId);
1514                    }
1515                    catch (PortalException pe) {
1516                            destinationLocalRepository.deleteFolder(
1517                                    destinationFolder.getFolderId());
1518    
1519                            throw pe;
1520                    }
1521    
1522                    return destinationFolder;
1523            }
1524    
1525    }