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