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