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