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.repository.capabilities;
016    
017    import com.liferay.portal.NoSuchModelException;
018    import com.liferay.portal.kernel.dao.orm.QueryUtil;
019    import com.liferay.portal.kernel.exception.PortalException;
020    import com.liferay.portal.kernel.exception.SystemException;
021    import com.liferay.portal.kernel.repository.DocumentRepository;
022    import com.liferay.portal.kernel.repository.capabilities.BulkOperationCapability;
023    import com.liferay.portal.kernel.repository.capabilities.ConfigurationCapability;
024    import com.liferay.portal.kernel.repository.capabilities.TemporaryFileEntriesCapability;
025    import com.liferay.portal.kernel.repository.capabilities.TemporaryFileEntriesScope;
026    import com.liferay.portal.kernel.repository.model.BaseRepositoryModelOperation;
027    import com.liferay.portal.kernel.repository.model.FileEntry;
028    import com.liferay.portal.kernel.repository.model.Folder;
029    import com.liferay.portal.kernel.util.FileUtil;
030    import com.liferay.portal.kernel.util.GetterUtil;
031    import com.liferay.portal.kernel.util.StringBundler;
032    import com.liferay.portal.kernel.util.StringPool;
033    import com.liferay.portal.kernel.util.StringUtil;
034    import com.liferay.portal.service.ServiceContext;
035    import com.liferay.portlet.documentlibrary.NoSuchFolderException;
036    import com.liferay.portlet.documentlibrary.model.DLFolderConstants;
037    
038    import java.io.File;
039    import java.io.IOException;
040    import java.io.InputStream;
041    
042    import java.util.Collections;
043    import java.util.Date;
044    import java.util.List;
045    
046    /**
047     * @author Iv??n Zaera
048     */
049    public class TemporaryFileEntriesCapabilityImpl
050            implements TemporaryFileEntriesCapability {
051    
052            public TemporaryFileEntriesCapabilityImpl(
053                    DocumentRepository documentRepository) {
054    
055                    _documentRepository = documentRepository;
056            }
057    
058            @Override
059            public FileEntry addTemporaryFileEntry(
060                            TemporaryFileEntriesScope temporaryFileEntriesScope,
061                            String fileName, String mimeType, InputStream inputStream)
062                    throws PortalException {
063    
064                    Folder folder = addTempFolder(temporaryFileEntriesScope);
065    
066                    File file = null;
067    
068                    try {
069                            file = FileUtil.createTempFile(inputStream);
070    
071                            ServiceContext serviceContext = new ServiceContext();
072    
073                            serviceContext.setAddGroupPermissions(true);
074                            serviceContext.setAddGuestPermissions(true);
075    
076                            return _documentRepository.addFileEntry(
077                                    temporaryFileEntriesScope.getUserId(), folder.getFolderId(),
078                                    fileName, mimeType, fileName, StringPool.BLANK,
079                                    StringPool.BLANK, file, serviceContext);
080                    }
081                    catch (IOException ioe) {
082                            throw new SystemException("Unable to write temporary file", ioe);
083                    }
084                    finally {
085                            FileUtil.delete(file);
086                    }
087            }
088    
089            @Override
090            public void deleteExpiredTemporaryFileEntries() throws PortalException {
091                    BulkOperationCapability bulkOperationCapability =
092                            _documentRepository.getCapability(BulkOperationCapability.class);
093    
094                    BulkOperationCapability.Filter<Date> bulkFilter =
095                            new BulkOperationCapability.Filter<>(
096                                    BulkOperationCapability.Field.CreateDate.class,
097                                    BulkOperationCapability.Operator.LT,
098                                    new Date(
099                                            System.currentTimeMillis() -
100                                                    getTemporaryFileEntriesTimeout()));
101    
102                    bulkOperationCapability.execute(
103                            bulkFilter,
104                            new DeleteExpiredTemporaryFilesRepositoryModelOperation());
105            }
106    
107            @Override
108            public void deleteTemporaryFileEntry(
109                            TemporaryFileEntriesScope temporaryFileEntriesScope,
110                            String fileName)
111                    throws PortalException {
112    
113                    try {
114                            FileEntry fileEntry = getTemporaryFileEntry(
115                                    temporaryFileEntriesScope, fileName);
116    
117                            _documentRepository.deleteFileEntry(fileEntry.getFileEntryId());
118                    }
119                    catch (NoSuchModelException nsme) {
120                    }
121            }
122    
123            @Override
124            public List<FileEntry> getTemporaryFileEntries(
125                            TemporaryFileEntriesScope temporaryFileEntriesScope)
126                    throws PortalException {
127    
128                    try {
129                            Folder folder = addTempFolder(temporaryFileEntriesScope);
130    
131                            return _documentRepository.getRepositoryFileEntries(
132                                    temporaryFileEntriesScope.getUserId(), folder.getFolderId(),
133                                    QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
134                    }
135                    catch (NoSuchModelException nsme) {
136                            return Collections.emptyList();
137                    }
138            }
139    
140            @Override
141            public long getTemporaryFileEntriesTimeout() {
142                    ConfigurationCapability configurationCapability =
143                            _documentRepository.getCapability(ConfigurationCapability.class);
144    
145                    String temporaryFileEntriesTimeout =
146                            configurationCapability.getProperty(
147                                    getClass(), _PROPERTY_TEMPORARY_FILE_ENTRIES_TIMEOUT);
148    
149                    if (temporaryFileEntriesTimeout == null) {
150                            return _TEMPORARY_FILE_ENTRIES_TIMEOUT_DEFAULT;
151                    }
152    
153                    return GetterUtil.getLong(temporaryFileEntriesTimeout);
154            }
155    
156            @Override
157            public FileEntry getTemporaryFileEntry(
158                            TemporaryFileEntriesScope temporaryFileEntriesScope,
159                            String fileName)
160                    throws PortalException {
161    
162                    Folder folder = getTempFolder(temporaryFileEntriesScope);
163    
164                    return _documentRepository.getFileEntry(folder.getFolderId(), fileName);
165            }
166    
167            @Override
168            public void setTemporaryFileEntriesTimeout(
169                    long temporaryFileEntriesTimeout) {
170    
171                    ConfigurationCapability configurationCapability =
172                            _documentRepository.getCapability(ConfigurationCapability.class);
173    
174                    configurationCapability.setProperty(
175                            getClass(), _PROPERTY_TEMPORARY_FILE_ENTRIES_TIMEOUT,
176                            String.valueOf(temporaryFileEntriesTimeout));
177            }
178    
179            protected Folder addFolder(
180                            long userId, long parentFolderId, String folderName,
181                            ServiceContext serviceContext)
182                    throws PortalException {
183    
184                    try {
185                            return _documentRepository.getFolder(parentFolderId, folderName);
186                    }
187                    catch (NoSuchFolderException nsfe) {
188                            return _documentRepository.addFolder(
189                                    userId, parentFolderId, folderName, StringPool.BLANK,
190                                    serviceContext);
191                    }
192            }
193    
194            protected Folder addFolders(
195                            long userId, long folderId, String folderPath,
196                            ServiceContext serviceContext)
197                    throws PortalException {
198    
199                    Folder folder = null;
200    
201                    String[] folderNames = StringUtil.split(folderPath, StringPool.SLASH);
202    
203                    for (String folderName : folderNames) {
204                            folder = addFolder(userId, folderId, folderName, serviceContext);
205    
206                            folderId = folder.getFolderId();
207                    }
208    
209                    return folder;
210            }
211    
212            protected Folder addTempFolder(
213                            TemporaryFileEntriesScope temporaryFileEntriesScope)
214                    throws PortalException {
215    
216                    ServiceContext serviceContext = new ServiceContext();
217    
218                    serviceContext.setAddGroupPermissions(true);
219                    serviceContext.setAddGuestPermissions(true);
220    
221                    return addFolders(
222                            temporaryFileEntriesScope.getUserId(),
223                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
224                            _getFolderPath(temporaryFileEntriesScope), serviceContext);
225            }
226    
227            protected Folder getDeepestFolder(long parentFolderId, String folderPath)
228                    throws PortalException {
229    
230                    Folder folder = null;
231    
232                    String[] folderNames = StringUtil.split(folderPath, StringPool.SLASH);
233    
234                    for (String folderName : folderNames) {
235                            folder = _documentRepository.getFolder(parentFolderId, folderName);
236    
237                            parentFolderId = folder.getFolderId();
238                    }
239    
240                    return folder;
241            }
242    
243            protected Folder getTempFolder(
244                            TemporaryFileEntriesScope temporaryFileEntriesScope)
245                    throws PortalException {
246    
247                    ServiceContext serviceContext = new ServiceContext();
248    
249                    serviceContext.setAddGroupPermissions(true);
250                    serviceContext.setAddGuestPermissions(true);
251    
252                    return getDeepestFolder(
253                            DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
254                            _getFolderPath(temporaryFileEntriesScope));
255            }
256    
257            private String _getFolderPath(
258                    TemporaryFileEntriesScope temporaryFileEntriesScope) {
259    
260                    StringBundler sb = new StringBundler(7);
261    
262                    sb.append(_FOLDER_NAME_TEMP);
263                    sb.append(StringPool.SLASH);
264                    sb.append(temporaryFileEntriesScope.getCallerUuid());
265                    sb.append(StringPool.SLASH);
266                    sb.append(temporaryFileEntriesScope.getUserId());
267                    sb.append(StringPool.SLASH);
268                    sb.append(temporaryFileEntriesScope.getFolderPath());
269    
270                    return sb.toString();
271            }
272    
273            private static final String _FOLDER_NAME_TEMP = "temp";
274    
275            private static final String _PROPERTY_TEMPORARY_FILE_ENTRIES_TIMEOUT =
276                    "temporaryFilesTimeout";
277    
278            private static final long _TEMPORARY_FILE_ENTRIES_TIMEOUT_DEFAULT =
279                    12 * 60 * 60 * 1000;
280    
281            private final DocumentRepository _documentRepository;
282    
283            private class DeleteExpiredTemporaryFilesRepositoryModelOperation
284                    extends BaseRepositoryModelOperation {
285    
286                    @Override
287                    public void execute(FileEntry fileEntry) throws PortalException {
288                            _documentRepository.deleteFileEntry(fileEntry.getFileEntryId());
289                    }
290    
291            }
292    
293    }