/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.portal.repository.capabilities;
import com.liferay.document.library.kernel.exception.NoSuchFolderException;
import com.liferay.document.library.kernel.model.DLFolderConstants;
import com.liferay.portal.kernel.dao.orm.QueryUtil;
import com.liferay.portal.kernel.exception.NoSuchModelException;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.repository.DocumentRepository;
import com.liferay.portal.kernel.repository.capabilities.BulkOperationCapability;
import com.liferay.portal.kernel.repository.capabilities.ConfigurationCapability;
import com.liferay.portal.kernel.repository.capabilities.TemporaryFileEntriesCapability;
import com.liferay.portal.kernel.repository.capabilities.TemporaryFileEntriesScope;
import com.liferay.portal.kernel.repository.model.BaseRepositoryModelOperation;
import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portal.kernel.repository.model.Folder;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.StringPool;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.portal.kernel.workflow.WorkflowConstants;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Date;
import java.util.List;
/**
* @author Iván Zaera
*/
public class TemporaryFileEntriesCapabilityImpl
implements TemporaryFileEntriesCapability {
public TemporaryFileEntriesCapabilityImpl(
DocumentRepository documentRepository) {
_documentRepository = documentRepository;
}
@Override
public FileEntry addTemporaryFileEntry(
TemporaryFileEntriesScope temporaryFileEntriesScope,
String fileName, String mimeType, InputStream inputStream)
throws PortalException {
Folder folder = addTempFolder(temporaryFileEntriesScope);
File file = null;
try {
if (inputStream == null) {
inputStream = new UnsyncByteArrayInputStream(new byte[0]);
}
file = FileUtil.createTempFile(inputStream);
ServiceContext serviceContext = new ServiceContext();
serviceContext.setAddGroupPermissions(true);
serviceContext.setAddGuestPermissions(true);
return _documentRepository.addFileEntry(
temporaryFileEntriesScope.getUserId(), folder.getFolderId(),
fileName, mimeType, fileName, StringPool.BLANK,
StringPool.BLANK, file, serviceContext);
}
catch (IOException ioe) {
throw new SystemException("Unable to write temporary file", ioe);
}
finally {
FileUtil.delete(file);
}
}
@Override
public void deleteExpiredTemporaryFileEntries() throws PortalException {
BulkOperationCapability bulkOperationCapability =
_documentRepository.getCapability(BulkOperationCapability.class);
BulkOperationCapability.Filter<Date> bulkFilter =
new BulkOperationCapability.Filter<>(
BulkOperationCapability.Field.CreateDate.class,
BulkOperationCapability.Operator.LT,
new Date(
System.currentTimeMillis() -
getTemporaryFileEntriesTimeout()));
bulkOperationCapability.execute(
bulkFilter,
new DeleteExpiredTemporaryFilesRepositoryModelOperation());
}
@Override
public void deleteTemporaryFileEntry(
TemporaryFileEntriesScope temporaryFileEntriesScope,
String fileName)
throws PortalException {
try {
FileEntry fileEntry = getTemporaryFileEntry(
temporaryFileEntriesScope, fileName);
_documentRepository.deleteFileEntry(fileEntry.getFileEntryId());
}
catch (NoSuchModelException nsme) {
// LPS-52675
if (_log.isDebugEnabled()) {
_log.debug(nsme, nsme);
}
}
}
@Override
public List<FileEntry> getTemporaryFileEntries(
TemporaryFileEntriesScope temporaryFileEntriesScope)
throws PortalException {
try {
Folder folder = addTempFolder(temporaryFileEntriesScope);
return _documentRepository.getRepositoryFileEntries(
temporaryFileEntriesScope.getUserId(), folder.getFolderId(),
QueryUtil.ALL_POS, QueryUtil.ALL_POS, null);
}
catch (NoSuchModelException nsme) {
// LPS-52675
if (_log.isDebugEnabled()) {
_log.debug(nsme, nsme);
}
return Collections.emptyList();
}
}
@Override
public long getTemporaryFileEntriesTimeout() {
ConfigurationCapability configurationCapability =
_documentRepository.getCapability(ConfigurationCapability.class);
String temporaryFileEntriesTimeout =
configurationCapability.getProperty(
getClass(), _PROPERTY_TEMPORARY_FILE_ENTRIES_TIMEOUT);
if (temporaryFileEntriesTimeout == null) {
return _TEMPORARY_FILE_ENTRIES_TIMEOUT_DEFAULT;
}
return GetterUtil.getLong(temporaryFileEntriesTimeout);
}
@Override
public FileEntry getTemporaryFileEntry(
TemporaryFileEntriesScope temporaryFileEntriesScope,
String fileName)
throws PortalException {
Folder folder = getTempFolder(temporaryFileEntriesScope);
return _documentRepository.getFileEntry(folder.getFolderId(), fileName);
}
@Override
public void setTemporaryFileEntriesTimeout(
long temporaryFileEntriesTimeout) {
ConfigurationCapability configurationCapability =
_documentRepository.getCapability(ConfigurationCapability.class);
configurationCapability.setProperty(
getClass(), _PROPERTY_TEMPORARY_FILE_ENTRIES_TIMEOUT,
String.valueOf(temporaryFileEntriesTimeout));
}
protected Folder addFolder(
long userId, long parentFolderId, String folderName,
ServiceContext serviceContext)
throws PortalException {
try {
return _documentRepository.getFolder(parentFolderId, folderName);
}
catch (NoSuchFolderException nsfe) {
// LPS-52675
if (_log.isDebugEnabled()) {
_log.debug(nsfe, nsfe);
}
return _documentRepository.addFolder(
userId, parentFolderId, folderName, StringPool.BLANK,
serviceContext);
}
}
protected Folder addFolders(
long userId, long folderId, String folderPath,
ServiceContext serviceContext)
throws PortalException {
Folder folder = null;
String[] folderNames = StringUtil.split(folderPath, StringPool.SLASH);
for (String folderName : folderNames) {
folder = addFolder(userId, folderId, folderName, serviceContext);
folderId = folder.getFolderId();
}
return folder;
}
protected Folder addTempFolder(
TemporaryFileEntriesScope temporaryFileEntriesScope)
throws PortalException {
ServiceContext serviceContext = new ServiceContext();
serviceContext.setAddGroupPermissions(true);
serviceContext.setAddGuestPermissions(true);
return addFolders(
temporaryFileEntriesScope.getUserId(),
DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
_getFolderPath(temporaryFileEntriesScope), serviceContext);
}
protected Folder getDeepestFolder(long parentFolderId, String folderPath)
throws PortalException {
Folder folder = null;
String[] folderNames = StringUtil.split(folderPath, StringPool.SLASH);
for (String folderName : folderNames) {
folder = _documentRepository.getFolder(parentFolderId, folderName);
parentFolderId = folder.getFolderId();
}
return folder;
}
protected Folder getTempFolder(
TemporaryFileEntriesScope temporaryFileEntriesScope)
throws PortalException {
ServiceContext serviceContext = new ServiceContext();
serviceContext.setAddGroupPermissions(true);
serviceContext.setAddGuestPermissions(true);
return getDeepestFolder(
DLFolderConstants.DEFAULT_PARENT_FOLDER_ID,
_getFolderPath(temporaryFileEntriesScope));
}
private String _getFolderPath(
TemporaryFileEntriesScope temporaryFileEntriesScope) {
StringBundler sb = new StringBundler(7);
sb.append(_FOLDER_NAME_TEMP);
sb.append(StringPool.SLASH);
sb.append(temporaryFileEntriesScope.getCallerUuid());
sb.append(StringPool.SLASH);
sb.append(temporaryFileEntriesScope.getUserId());
sb.append(StringPool.SLASH);
sb.append(temporaryFileEntriesScope.getFolderPath());
return sb.toString();
}
private static final String _FOLDER_NAME_TEMP = "temp";
private static final String _PROPERTY_TEMPORARY_FILE_ENTRIES_TIMEOUT =
"temporaryFilesTimeout";
private static final long _TEMPORARY_FILE_ENTRIES_TIMEOUT_DEFAULT =
12 * 60 * 60 * 1000;
private static final Log _log = LogFactoryUtil.getLog(
TemporaryFileEntriesCapabilityImpl.class);
private final DocumentRepository _documentRepository;
private class DeleteExpiredTemporaryFilesRepositoryModelOperation
extends BaseRepositoryModelOperation {
@Override
public void execute(FileEntry fileEntry) throws PortalException {
Folder folder = fileEntry.getFolder();
_documentRepository.deleteFileEntry(fileEntry.getFileEntryId());
Folder mountFolder = _documentRepository.getFolder(
DLFolderConstants.DEFAULT_PARENT_FOLDER_ID);
while ((folder.getFolderId() != mountFolder.getFolderId()) &&
(_documentRepository.getFileEntriesCount(
folder.getFolderId(),
WorkflowConstants.STATUS_ANY) == 0)) {
long folderId = folder.getFolderId();
folder = folder.getParentFolder();
_documentRepository.deleteFolder(folderId);
}
}
}
}