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