001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.portletfilerepository;
016    
017    import com.liferay.portal.kernel.dao.orm.QueryUtil;
018    import com.liferay.portal.kernel.exception.PortalException;
019    import com.liferay.portal.kernel.exception.SystemException;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.repository.LocalRepository;
023    import com.liferay.portal.kernel.repository.RepositoryProviderUtil;
024    import com.liferay.portal.kernel.repository.model.FileEntry;
025    import com.liferay.portal.kernel.repository.model.Folder;
026    import com.liferay.portal.kernel.search.Hits;
027    import com.liferay.portal.kernel.search.SearchContext;
028    import com.liferay.portal.kernel.security.pacl.DoPrivileged;
029    import com.liferay.portal.kernel.systemevent.SystemEventHierarchyEntryThreadLocal;
030    import com.liferay.portal.kernel.util.ContentTypes;
031    import com.liferay.portal.kernel.util.FileUtil;
032    import com.liferay.portal.kernel.util.HtmlUtil;
033    import com.liferay.portal.kernel.util.HttpUtil;
034    import com.liferay.portal.kernel.util.MimeTypesUtil;
035    import com.liferay.portal.kernel.util.ObjectValuePair;
036    import com.liferay.portal.kernel.util.OrderByComparator;
037    import com.liferay.portal.kernel.util.StringBundler;
038    import com.liferay.portal.kernel.util.StringPool;
039    import com.liferay.portal.kernel.util.UnicodeProperties;
040    import com.liferay.portal.kernel.util.Validator;
041    import com.liferay.portal.model.Group;
042    import com.liferay.portal.model.Repository;
043    import com.liferay.portal.model.User;
044    import com.liferay.portal.repository.portletrepository.PortletRepository;
045    import com.liferay.portal.service.GroupLocalServiceUtil;
046    import com.liferay.portal.service.RepositoryLocalServiceUtil;
047    import com.liferay.portal.service.ServiceContext;
048    import com.liferay.portal.service.UserLocalServiceUtil;
049    import com.liferay.portal.theme.ThemeDisplay;
050    import com.liferay.portal.util.PortalUtil;
051    import com.liferay.portal.webserver.WebServerServlet;
052    import com.liferay.portlet.documentlibrary.NoSuchFileEntryException;
053    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
054    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
055    import com.liferay.portlet.documentlibrary.service.DLTrashLocalServiceUtil;
056    import com.liferay.portlet.documentlibrary.util.DLAppHelperThreadLocal;
057    import com.liferay.portlet.trash.util.TrashUtil;
058    
059    import java.io.File;
060    import java.io.IOException;
061    import java.io.InputStream;
062    
063    import java.util.List;
064    
065    /**
066     * @author Eudaldo Alonso
067     * @author Alexander Chow
068     */
069    @DoPrivileged
070    public class PortletFileRepositoryImpl implements PortletFileRepository {
071    
072            @Override
073            public void addPortletFileEntries(
074                            long groupId, long userId, String className, long classPK,
075                            String portletId, long folderId,
076                            List<ObjectValuePair<String, InputStream>> inputStreamOVPs)
077                    throws PortalException {
078    
079                    for (int i = 0; i < inputStreamOVPs.size(); i++) {
080                            ObjectValuePair<String, InputStream> inputStreamOVP =
081                                    inputStreamOVPs.get(i);
082    
083                            InputStream inputStream = inputStreamOVP.getValue();
084                            String fileName = inputStreamOVP.getKey();
085    
086                            addPortletFileEntry(
087                                    groupId, userId, className, classPK, portletId, folderId,
088                                    inputStream, fileName, StringPool.BLANK, true);
089                    }
090            }
091    
092            @Override
093            public FileEntry addPortletFileEntry(
094                            long groupId, long userId, String className, long classPK,
095                            String portletId, long folderId, byte[] bytes, String fileName,
096                            String mimeType, boolean indexingEnabled)
097                    throws PortalException {
098    
099                    if (bytes == null) {
100                            return null;
101                    }
102    
103                    File file = null;
104    
105                    try {
106                            file = FileUtil.createTempFile(bytes);
107    
108                            return addPortletFileEntry(
109                                    groupId, userId, className, classPK, portletId, folderId, file,
110                                    fileName, mimeType, indexingEnabled);
111                    }
112                    catch (IOException ioe) {
113                            throw new SystemException("Unable to write temporary file", ioe);
114                    }
115                    finally {
116                            FileUtil.delete(file);
117                    }
118            }
119    
120            @Override
121            public FileEntry addPortletFileEntry(
122                            long groupId, long userId, String className, long classPK,
123                            String portletId, long folderId, File file, String fileName,
124                            String mimeType, boolean indexingEnabled)
125                    throws PortalException {
126    
127                    if (Validator.isNull(fileName)) {
128                            return null;
129                    }
130    
131                    ServiceContext serviceContext = new ServiceContext();
132    
133                    serviceContext.setAddGroupPermissions(true);
134                    serviceContext.setAddGuestPermissions(true);
135    
136                    Repository repository = addPortletRepository(
137                            groupId, portletId, serviceContext);
138    
139                    serviceContext.setAttribute("className", className);
140                    serviceContext.setAttribute("classPK", String.valueOf(classPK));
141                    serviceContext.setIndexingEnabled(indexingEnabled);
142    
143                    if (Validator.isNull(mimeType) ||
144                            mimeType.equals(ContentTypes.APPLICATION_OCTET_STREAM)) {
145    
146                            mimeType = MimeTypesUtil.getContentType(file, fileName);
147                    }
148    
149                    boolean dlAppHelperEnabled = DLAppHelperThreadLocal.isEnabled();
150    
151                    try {
152                            DLAppHelperThreadLocal.setEnabled(false);
153    
154                            LocalRepository localRepository =
155                                    RepositoryProviderUtil.getLocalRepository(
156                                            repository.getRepositoryId());
157    
158                            return localRepository.addFileEntry(
159                                    userId, folderId, fileName, mimeType, fileName,
160                                    StringPool.BLANK, StringPool.BLANK, file, serviceContext);
161                    }
162                    finally {
163                            DLAppHelperThreadLocal.setEnabled(dlAppHelperEnabled);
164                    }
165            }
166    
167            @Override
168            public FileEntry addPortletFileEntry(
169                            long groupId, long userId, String className, long classPK,
170                            String portletId, long folderId, InputStream inputStream,
171                            String fileName, String mimeType, boolean indexingEnabled)
172                    throws PortalException {
173    
174                    if (inputStream == null) {
175                            return null;
176                    }
177    
178                    File file = null;
179    
180                    try {
181                            file = FileUtil.createTempFile(inputStream);
182    
183                            return addPortletFileEntry(
184                                    groupId, userId, className, classPK, portletId, folderId, file,
185                                    fileName, mimeType, indexingEnabled);
186                    }
187                    catch (IOException ioe) {
188                            throw new SystemException("Unable to write temporary file", ioe);
189                    }
190                    finally {
191                            FileUtil.delete(file);
192                    }
193            }
194    
195            @Override
196            public Folder addPortletFolder(
197                            long userId, long repositoryId, long parentFolderId,
198                            String folderName, ServiceContext serviceContext)
199                    throws PortalException {
200    
201                    boolean dlAppHelperEnabled = DLAppHelperThreadLocal.isEnabled();
202    
203                    LocalRepository localRepository =
204                            RepositoryProviderUtil.getLocalRepository(repositoryId);
205    
206                    try {
207                            DLAppHelperThreadLocal.setEnabled(false);
208    
209                            return localRepository.getFolder(parentFolderId, folderName);
210                    }
211                    catch (NoSuchFolderException nsfe) {
212                            return localRepository.addFolder(
213                                    userId, parentFolderId, folderName, StringPool.BLANK,
214                                    serviceContext);
215                    }
216                    finally {
217                            DLAppHelperThreadLocal.setEnabled(dlAppHelperEnabled);
218                    }
219            }
220    
221            @Override
222            public Folder addPortletFolder(
223                            long groupId, long userId, String portletId, long parentFolderId,
224                            String folderName, ServiceContext serviceContext)
225                    throws PortalException {
226    
227                    Repository repository = addPortletRepository(
228                            groupId, portletId, serviceContext);
229    
230                    return addPortletFolder(
231                            userId, repository.getRepositoryId(), parentFolderId, folderName,
232                            serviceContext);
233            }
234    
235            @Override
236            public Repository addPortletRepository(
237                            long groupId, String portletId, ServiceContext serviceContext)
238                    throws PortalException {
239    
240                    Repository repository = RepositoryLocalServiceUtil.fetchRepository(
241                            groupId, portletId);
242    
243                    if (repository != null) {
244                            return repository;
245                    }
246    
247                    Group group = GroupLocalServiceUtil.getGroup(groupId);
248    
249                    User user = UserLocalServiceUtil.getDefaultUser(group.getCompanyId());
250    
251                    long classNameId = PortalUtil.getClassNameId(
252                            PortletRepository.class.getName());
253    
254                    UnicodeProperties typeSettingsProperties = new UnicodeProperties();
255    
256                    boolean dlAppHelperEnabled = DLAppHelperThreadLocal.isEnabled();
257    
258                    try {
259                            DLAppHelperThreadLocal.setEnabled(false);
260    
261                            return RepositoryLocalServiceUtil.addRepository(
262                                    user.getUserId(), groupId, classNameId,
263                                    DLFolderConstants.DEFAULT_PARENT_FOLDER_ID, portletId,
264                                    StringPool.BLANK, portletId, typeSettingsProperties, true,
265                                    serviceContext);
266                    }
267                    finally {
268                            DLAppHelperThreadLocal.setEnabled(dlAppHelperEnabled);
269                    }
270            }
271    
272            /**
273             * @deprecated As of 7.0.0, replaced by {@link #deletePortletFolder}
274             */
275            @Deprecated
276            @Override
277            public void deleteFolder(long folderId) throws PortalException {
278                    deletePortletFolder(folderId);
279            }
280    
281            @Override
282            public void deletePortletFileEntries(long groupId, long folderId)
283                    throws PortalException {
284    
285                    LocalRepository localRepository =
286                            RepositoryProviderUtil.getLocalRepository(groupId);
287    
288                    List<FileEntry> fileEntries = localRepository.getFileEntries(
289                            folderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
290    
291                    for (FileEntry fileEntry : fileEntries) {
292                            deletePortletFileEntry(fileEntry.getFileEntryId());
293                    }
294            }
295    
296            @Override
297            public void deletePortletFileEntries(
298                            long groupId, long folderId, int status)
299                    throws PortalException {
300    
301                    LocalRepository localRepository =
302                            RepositoryProviderUtil.getLocalRepository(groupId);
303    
304                    List<FileEntry> fileEntries = localRepository.getFileEntries(
305                            folderId, status, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
306    
307                    for (FileEntry fileEntry : fileEntries) {
308                            deletePortletFileEntry(fileEntry.getFileEntryId());
309                    }
310            }
311    
312            @Override
313            public void deletePortletFileEntry(long fileEntryId)
314                    throws PortalException {
315    
316                    boolean dlAppHelperEnabled = DLAppHelperThreadLocal.isEnabled();
317    
318                    try {
319                            DLAppHelperThreadLocal.setEnabled(false);
320    
321                            SystemEventHierarchyEntryThreadLocal.push(FileEntry.class);
322    
323                            LocalRepository localRepository =
324                                    RepositoryProviderUtil.getFileEntryLocalRepository(fileEntryId);
325    
326                            localRepository.deleteFileEntry(fileEntryId);
327                    }
328                    catch (NoSuchFileEntryException nsfee) {
329                            if (_log.isWarnEnabled()) {
330                                    _log.warn(nsfee, nsfee);
331                            }
332                    }
333                    finally {
334                            DLAppHelperThreadLocal.setEnabled(dlAppHelperEnabled);
335    
336                            SystemEventHierarchyEntryThreadLocal.pop(FileEntry.class);
337                    }
338            }
339    
340            @Override
341            public void deletePortletFileEntry(
342                            long groupId, long folderId, String fileName)
343                    throws PortalException {
344    
345                    LocalRepository localRepository =
346                            RepositoryProviderUtil.getLocalRepository(groupId);
347    
348                    FileEntry fileEntry = localRepository.getFileEntry(folderId, fileName);
349    
350                    deletePortletFileEntry(fileEntry.getFileEntryId());
351            }
352    
353            @Override
354            public void deletePortletFolder(long folderId) throws PortalException {
355                    boolean dlAppHelperEnabled = DLAppHelperThreadLocal.isEnabled();
356    
357                    try {
358                            DLAppHelperThreadLocal.setEnabled(false);
359    
360                            SystemEventHierarchyEntryThreadLocal.push(Folder.class);
361    
362                            LocalRepository localRepository =
363                                    RepositoryProviderUtil.getFolderLocalRepository(folderId);
364    
365                            localRepository.deleteFolder(folderId);
366                    }
367                    catch (NoSuchFolderException nsfe) {
368                            if (_log.isWarnEnabled()) {
369                                    _log.warn(nsfe, nsfe);
370                            }
371                    }
372                    finally {
373                            DLAppHelperThreadLocal.setEnabled(dlAppHelperEnabled);
374    
375                            SystemEventHierarchyEntryThreadLocal.pop(Folder.class);
376                    }
377            }
378    
379            @Override
380            public void deletePortletRepository(long groupId, String portletId)
381                    throws PortalException {
382    
383                    Repository repository = RepositoryLocalServiceUtil.fetchRepository(
384                            groupId, portletId);
385    
386                    if (repository != null) {
387                            RepositoryLocalServiceUtil.deleteRepository(
388                                    repository.getRepositoryId());
389                    }
390            }
391    
392            @Override
393            public Repository fetchPortletRepository(long groupId, String portletId) {
394                    return RepositoryLocalServiceUtil.fetchRepository(groupId, portletId);
395            }
396    
397            @Override
398            public String getDownloadPortletFileEntryURL(
399                    ThemeDisplay themeDisplay, FileEntry fileEntry, String queryString) {
400    
401                    return getDownloadPortletFileEntryURL(
402                            themeDisplay, fileEntry, queryString, true);
403            }
404    
405            @Override
406            public String getDownloadPortletFileEntryURL(
407                    ThemeDisplay themeDisplay, FileEntry fileEntry, String queryString,
408                    boolean absoluteURL) {
409    
410                    String portletFileEntryURL = getPortletFileEntryURL(
411                            themeDisplay, fileEntry, queryString, absoluteURL);
412    
413                    return HttpUtil.addParameter(portletFileEntryURL, "download", true);
414            }
415    
416            @Override
417            public List<FileEntry> getPortletFileEntries(long groupId, long folderId)
418                    throws PortalException {
419    
420                    LocalRepository localRepository =
421                            RepositoryProviderUtil.getLocalRepository(groupId);
422    
423                    return localRepository.getFileEntries(
424                            folderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
425            }
426    
427            @Override
428            public List<FileEntry> getPortletFileEntries(
429                            long groupId, long folderId, int status)
430                    throws PortalException {
431    
432                    return getPortletFileEntries(
433                            groupId, folderId, status, QueryUtil.ALL_POS, QueryUtil.ALL_POS,
434                            null);
435            }
436    
437            @Override
438            public List<FileEntry> getPortletFileEntries(
439                            long groupId, long folderId, int status, int start, int end,
440                            OrderByComparator<FileEntry> obc)
441                    throws PortalException {
442    
443                    LocalRepository localRepository =
444                            RepositoryProviderUtil.getLocalRepository(groupId);
445    
446                    return localRepository.getFileEntries(
447                            folderId, status, start, end, obc);
448            }
449    
450            @Override
451            public List<FileEntry> getPortletFileEntries(
452                            long groupId, long folderId, OrderByComparator<FileEntry> obc)
453                    throws PortalException {
454    
455                    LocalRepository localRepository =
456                            RepositoryProviderUtil.getLocalRepository(groupId);
457    
458                    return localRepository.getFileEntries(
459                            folderId, QueryUtil.ALL_POS, QueryUtil.ALL_POS, obc);
460            }
461    
462            @Override
463            public int getPortletFileEntriesCount(long groupId, long folderId)
464                    throws PortalException {
465    
466                    LocalRepository localRepository =
467                            RepositoryProviderUtil.getLocalRepository(groupId);
468    
469                    return localRepository.getFileEntriesCount(folderId);
470            }
471    
472            @Override
473            public int getPortletFileEntriesCount(
474                            long groupId, long folderId, int status)
475                    throws PortalException {
476    
477                    LocalRepository localRepository =
478                            RepositoryProviderUtil.getLocalRepository(groupId);
479    
480                    return localRepository.getFileEntriesCount(folderId, status);
481            }
482    
483            @Override
484            public FileEntry getPortletFileEntry(long fileEntryId)
485                    throws PortalException {
486    
487                    LocalRepository localRepository =
488                            RepositoryProviderUtil.getFileEntryLocalRepository(fileEntryId);
489    
490                    return localRepository.getFileEntry(fileEntryId);
491            }
492    
493            @Override
494            public FileEntry getPortletFileEntry(
495                            long groupId, long folderId, String fileName)
496                    throws PortalException {
497    
498                    LocalRepository localRepository =
499                            RepositoryProviderUtil.getLocalRepository(groupId);
500    
501                    return localRepository.getFileEntry(folderId, fileName);
502            }
503    
504            @Override
505            public FileEntry getPortletFileEntry(String uuid, long groupId)
506                    throws PortalException {
507    
508                    LocalRepository localRepository =
509                            RepositoryProviderUtil.getLocalRepository(groupId);
510    
511                    return localRepository.getFileEntryByUuid(uuid);
512            }
513    
514            @Override
515            public String getPortletFileEntryURL(
516                    ThemeDisplay themeDisplay, FileEntry fileEntry, String queryString) {
517    
518                    return getPortletFileEntryURL(
519                            themeDisplay, fileEntry, queryString, true);
520            }
521    
522            @Override
523            public String getPortletFileEntryURL(
524                    ThemeDisplay themeDisplay, FileEntry fileEntry, String queryString,
525                    boolean absoluteURL) {
526    
527                    StringBundler sb = new StringBundler(10);
528    
529                    if (themeDisplay != null) {
530                            if (absoluteURL) {
531                                    sb.append(themeDisplay.getPortalURL());
532                            }
533                    }
534    
535                    sb.append(PortalUtil.getPathContext());
536                    sb.append("/documents/");
537                    sb.append(WebServerServlet.PATH_PORTLET_FILE_ENTRY);
538                    sb.append(StringPool.SLASH);
539                    sb.append(fileEntry.getGroupId());
540                    sb.append(StringPool.SLASH);
541    
542                    String title = fileEntry.getTitle();
543    
544                    if (fileEntry.isInTrash()) {
545                            title = TrashUtil.getOriginalTitle(fileEntry.getTitle());
546                    }
547    
548                    sb.append(HttpUtil.encodeURL(HtmlUtil.unescape(title)));
549    
550                    sb.append(StringPool.SLASH);
551                    sb.append(HttpUtil.encodeURL(fileEntry.getUuid()));
552    
553                    if (Validator.isNotNull(queryString)) {
554                            sb.append(StringPool.QUESTION);
555                            sb.append(queryString);
556                    }
557    
558                    String portletFileEntryURL = sb.toString();
559    
560                    if ((themeDisplay != null) && themeDisplay.isAddSessionIdToURL()) {
561                            return PortalUtil.getURLWithSessionId(
562                                    portletFileEntryURL, themeDisplay.getSessionId());
563                    }
564    
565                    return portletFileEntryURL;
566            }
567    
568            @Override
569            public Folder getPortletFolder(long folderId) throws PortalException {
570                    LocalRepository localRepository =
571                            RepositoryProviderUtil.getFolderLocalRepository(folderId);
572    
573                    return localRepository.getFolder(folderId);
574            }
575    
576            @Override
577            public Folder getPortletFolder(
578                            long repositoryId, long parentFolderId, String folderName)
579                    throws PortalException {
580    
581                    LocalRepository localRepository =
582                            RepositoryProviderUtil.getLocalRepository(repositoryId);
583    
584                    return localRepository.getFolder(parentFolderId, folderName);
585            }
586    
587            @Override
588            public Repository getPortletRepository(long groupId, String portletId)
589                    throws PortalException {
590    
591                    return RepositoryLocalServiceUtil.getRepository(groupId, portletId);
592            }
593    
594            @Override
595            public String getUniqueFileName(
596                    long groupId, long folderId, String fileName) {
597    
598                    String uniqueFileName = fileName;
599    
600                    for (int i = 1;; i++) {
601                            try {
602                                    getPortletFileEntry(groupId, folderId, uniqueFileName);
603    
604                                    uniqueFileName = FileUtil.appendParentheticalSuffix(
605                                            fileName, String.valueOf(i));
606                            }
607                            catch (Exception e) {
608                                    break;
609                            }
610                    }
611    
612                    return uniqueFileName;
613            }
614    
615            @Override
616            public FileEntry movePortletFileEntryToTrash(long userId, long fileEntryId)
617                    throws PortalException {
618    
619                    boolean dlAppHelperEnabled = DLAppHelperThreadLocal.isEnabled();
620    
621                    try {
622                            DLAppHelperThreadLocal.setEnabled(false);
623    
624                            LocalRepository localRepository =
625                                    RepositoryProviderUtil.getFileEntryLocalRepository(fileEntryId);
626    
627                            return DLTrashLocalServiceUtil.moveFileEntryToTrash(
628                                    userId, localRepository.getRepositoryId(), fileEntryId);
629                    }
630                    finally {
631                            DLAppHelperThreadLocal.setEnabled(dlAppHelperEnabled);
632                    }
633            }
634    
635            @Override
636            public FileEntry movePortletFileEntryToTrash(
637                            long groupId, long userId, long folderId, String fileName)
638                    throws PortalException {
639    
640                    LocalRepository localRepository =
641                            RepositoryProviderUtil.getLocalRepository(groupId);
642    
643                    FileEntry fileEntry = localRepository.getFileEntry(folderId, fileName);
644    
645                    return movePortletFileEntryToTrash(userId, fileEntry.getFileEntryId());
646            }
647    
648            @Override
649            public void restorePortletFileEntryFromTrash(long userId, long fileEntryId)
650                    throws PortalException {
651    
652                    boolean dlAppHelperEnabled = DLAppHelperThreadLocal.isEnabled();
653    
654                    try {
655                            DLAppHelperThreadLocal.setEnabled(false);
656    
657                            LocalRepository localRepository =
658                                    RepositoryProviderUtil.getFileEntryLocalRepository(fileEntryId);
659    
660                            DLTrashLocalServiceUtil.restoreFileEntryFromTrash(
661                                    userId, localRepository.getRepositoryId(), fileEntryId);
662                    }
663                    finally {
664                            DLAppHelperThreadLocal.setEnabled(dlAppHelperEnabled);
665                    }
666            }
667    
668            @Override
669            public void restorePortletFileEntryFromTrash(
670                            long groupId, long userId, long folderId, String fileName)
671                    throws PortalException {
672    
673                    LocalRepository localRepository =
674                            RepositoryProviderUtil.getLocalRepository(groupId);
675    
676                    FileEntry fileEntry = localRepository.getFileEntry(folderId, fileName);
677    
678                    restorePortletFileEntryFromTrash(userId, fileEntry.getFileEntryId());
679            }
680    
681            @Override
682            public Hits searchPortletFileEntries(
683                            long repositoryId, SearchContext searchContext)
684                    throws PortalException {
685    
686                    com.liferay.portal.kernel.repository.Repository repository =
687                            RepositoryProviderUtil.getRepository(repositoryId);
688    
689                    return repository.search(searchContext);
690            }
691    
692            private static final Log _log = LogFactoryUtil.getLog(
693                    PortletFileRepositoryImpl.class);
694    
695    }