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