/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.mifosplatform.infrastructure.documentmanagement.contentrepository;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.mifosplatform.infrastructure.core.domain.Base64EncodedImage;
import org.mifosplatform.infrastructure.core.service.ThreadLocalContextUtil;
import org.mifosplatform.infrastructure.documentmanagement.command.DocumentCommand;
import org.mifosplatform.infrastructure.documentmanagement.data.DocumentData;
import org.mifosplatform.infrastructure.documentmanagement.data.FileData;
import org.mifosplatform.infrastructure.documentmanagement.data.ImageData;
import org.mifosplatform.infrastructure.documentmanagement.domain.StorageType;
import org.mifosplatform.infrastructure.documentmanagement.exception.ContentManagementException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.lowagie.text.pdf.codec.Base64;
public class FileSystemContentRepository implements ContentRepository {
private final static Logger logger = LoggerFactory.getLogger(FileSystemContentRepository.class);
public static final String MIFOSX_BASE_DIR = System.getProperty("user.home") + File.separator + ".mifosx";
@Override
public String saveFile(final InputStream uploadedInputStream, final DocumentCommand documentCommand) {
final String fileName = documentCommand.getFileName();
final String uploadDocumentLocation = generateFileParentDirectory(documentCommand.getParentEntityType(),
documentCommand.getParentEntityId());
ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(documentCommand.getSize(), fileName);
makeDirectories(uploadDocumentLocation);
final String fileLocation = uploadDocumentLocation + File.separator + fileName;
writeFileToFileSystem(fileName, uploadedInputStream, fileLocation);
return fileLocation;
}
@Override
public String saveImage(final InputStream uploadedInputStream, final Long resourceId, final String imageName, final Long fileSize) {
final String uploadImageLocation = generateClientImageParentDirectory(resourceId);
ContentRepositoryUtils.validateFileSizeWithinPermissibleRange(fileSize, imageName);
makeDirectories(uploadImageLocation);
final String fileLocation = uploadImageLocation + File.separator + imageName;
writeFileToFileSystem(imageName, uploadedInputStream, fileLocation);
return fileLocation;
}
@Override
public String saveImage(final Base64EncodedImage base64EncodedImage, final Long resourceId, final String imageName) {
final String uploadImageLocation = generateClientImageParentDirectory(resourceId);
makeDirectories(uploadImageLocation);
final String fileLocation = uploadImageLocation + File.separator + imageName + base64EncodedImage.getFileExtension();
try {
final OutputStream out = new FileOutputStream(new File(fileLocation));
final byte[] imgBytes = Base64.decode(base64EncodedImage.getBase64EncodedString());
out.write(imgBytes);
out.flush();
out.close();
} catch (final IOException ioe) {
throw new ContentManagementException(imageName, ioe.getMessage());
}
return fileLocation;
}
@Override
public void deleteImage(final Long resourceId, final String location) {
final boolean fileDeleted = deleteFile(location);
if (!fileDeleted) {
// no need to throw an Error, simply log a warning
logger.warn("Unable to delete image associated with clients with Id " + resourceId);
}
}
@Override
public void deleteFile(final String fileName, final String documentPath) {
final boolean fileDeleted = deleteFile(documentPath);
if (!fileDeleted) { throw new ContentManagementException(fileName, null); }
}
private boolean deleteFile(final String documentPath) {
final File fileToBeDeleted = new File(documentPath);
return fileToBeDeleted.delete();
}
@Override
public StorageType getStorageType() {
return StorageType.FILE_SYSTEM;
}
@Override
public FileData fetchFile(final DocumentData documentData) {
final File file = new File(documentData.fileLocation());
return new FileData(file, documentData.fileName(), documentData.contentType());
}
@Override
public ImageData fetchImage(final ImageData imageData) {
final File file = new File(imageData.location());
imageData.updateContent(file);
return imageData;
}
/**
* Generate the directory path for storing the new document
*
* @param entityType
* @param entityId
* @return
*/
private String generateFileParentDirectory(final String entityType, final Long entityId) {
return FileSystemContentRepository.MIFOSX_BASE_DIR + File.separator
+ ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim() + File.separator + "documents" + File.separator
+ entityType + File.separator + entityId + File.separator + ContentRepositoryUtils.generateRandomString();
}
/**
* Generate directory path for storing new Image
*/
private String generateClientImageParentDirectory(final Long resourceId) {
return FileSystemContentRepository.MIFOSX_BASE_DIR + File.separator
+ ThreadLocalContextUtil.getTenant().getName().replaceAll(" ", "").trim() + File.separator + "images" + File.separator
+ "clients" + File.separator + resourceId;
}
/**
* Recursively create the directory if it does not exist *
*/
private void makeDirectories(final String uploadDocumentLocation) {
if (!new File(uploadDocumentLocation).isDirectory()) {
new File(uploadDocumentLocation).mkdirs();
}
}
private void writeFileToFileSystem(final String fileName, final InputStream uploadedInputStream, final String fileLocation) {
try {
final OutputStream out = new FileOutputStream(new File(fileLocation));
int read = 0;
final byte[] bytes = new byte[1024];
while ((read = uploadedInputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
out.flush();
out.close();
} catch (final IOException ioException) {
throw new ContentManagementException(fileName, ioException.getMessage());
}
}
}