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