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