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