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