/**
* ESUP-Portail Helpdesk - Copyright (c) 2004-2009 ESUP-Portail consortium.
*/
package org.esupportail.helpdesk.dao;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.esupportail.commons.aop.cache.RequestCache;
import org.esupportail.commons.exceptions.ConfigException;
import org.esupportail.commons.services.logging.Logger;
import org.esupportail.commons.services.logging.LoggerImpl;
import org.esupportail.commons.utils.Assert;
import org.esupportail.helpdesk.domain.beans.ArchivedFileInfo;
import org.esupportail.helpdesk.domain.beans.FileInfo;
import org.esupportail.helpdesk.domain.beans.OldFileInfo;
import org.esupportail.helpdesk.exceptions.FileException;
import org.springframework.beans.factory.InitializingBean;
/**
* A basic implementation of FileManager that stores the content of the files on the filesystem.
*/
public class FileManagerImpl implements FileManager, InitializingBean {
/**
* The serialization id.
*/
private static final long serialVersionUID = 1399412434380258437L;
/**
* A logger.
*/
private final Logger logger = new LoggerImpl(getClass());
/**
* The path where to store the content of the files.
*/
private String path;
/**
* The path where the content of the old v2 files are stored.
*/
private String v2Path;
/**
* Bean constructor.
*/
public FileManagerImpl() {
super();
}
/**
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
Assert.hasLength(this.path,
"property path of class " + this.getClass().getName() + " can not be null");
while (path.endsWith("/")) {
path = path.substring(0, path.length() - 2);
}
checkPath(false);
if (org.springframework.util.StringUtils.hasLength(v2Path)) {
while (v2Path.endsWith("/")) {
v2Path = v2Path.substring(0, v2Path.length() - 2);
}
if (v2Path.equals(path)) {
throw new ConfigException("properties path and v2Path must differ");
}
} else {
v2Path = null;
logger.info("property v2Path is not set, migration process will fail");
}
}
/**
* Check a path.
* @param thePath
* @param create true to create the folder if it does not exist.
* @throws FileException
*/
protected void checkPath(final String thePath, final boolean create) throws FileException {
File dir = new File(thePath);
if (!dir.exists()) {
if (!create) {
throw new FileException("directory [" + thePath + "] does not exist");
}
if (!dir.mkdirs()) {
throw new FileException("could not create directory [" + thePath + "]");
}
logger.info("directory [" + thePath + "] was successfully created.");
}
}
/**
* Check the path.
* @param create true to create the folder if it does not exist.
* @throws FileException
*/
protected void checkPath(final boolean create) throws FileException {
checkPath(path, create);
}
/**
* Check the v2 path.
* @param create true to create the folder if it does not exist.
* @throws FileException
*/
protected void checkV2Path(final boolean create) throws FileException {
Assert.hasLength(v2Path,
"property v2Path of class " + this.getClass().getName() + " can not be null");
checkPath(v2Path, create);
}
/**
* @param fileInfo
* @return the name of the filesystem entry for a FileInfo.
*/
protected String getFilename(final FileInfo fileInfo) {
return path + "/" + fileInfo.getId();
}
/**
* @param oldFileInfo
* @return the name of the filesystem entry for a OldFileInfo.
*/
protected String getFilename(final OldFileInfo oldFileInfo) {
return v2Path + "/" + oldFileInfo.getId();
}
/**
* Write a content to the filesystem.
* @param filename
* @param content
*/
protected void writeContent(final String filename, final byte[] content) {
File file = new File(filename);
if (file.exists()) {
throw new FileException("file [" + file.getAbsolutePath() + "] already exists");
}
try {
FileOutputStream os = new FileOutputStream(file);
os.write(content);
os.close();
} catch (IOException e) {
throw new FileException("could not write file [" + file.getAbsolutePath() + "]", e);
}
}
/**
* @see org.esupportail.helpdesk.dao.FileManager#writeFileInfoContent(
* org.esupportail.helpdesk.domain.beans.FileInfo)
*/
@Override
public void writeFileInfoContent(final FileInfo fileInfo) {
checkPath(true);
writeContent(getFilename(fileInfo), fileInfo.getContent());
}
/**
* @param filename
* @return the content read from the filesystem.
*/
protected byte[] readContent(final String filename) {
File file = new File(filename);
if (!file.exists()) {
throw new FileException("file [" + file.getAbsolutePath() + "] does not exist");
}
if (!file.isFile()) {
throw new FileException("[" + file.getAbsolutePath() + "] is not a file");
}
byte[] content;
try {
InputStream is = new FileInputStream(file);
long length = file.length();
if (length > Integer.MAX_VALUE) {
throw new FileException("file [" + file.getAbsolutePath() + "] is too large");
}
content = new byte[(int) length];
int offset = 0;
int numRead = is.read(content, 0, content.length);
while (offset < content.length && numRead >= 0) {
offset += numRead;
numRead = is.read(content, offset, content.length - offset);
}
if (offset < content.length) {
throw new FileException(
"could not completly read file [" + file.getAbsolutePath() + "]");
}
is.close();
} catch (IOException e) {
throw new FileException("could not read file [" + file.getAbsolutePath() + "]");
}
return content;
}
/**
* @see org.esupportail.helpdesk.dao.FileManager#readFileInfoContent(
* org.esupportail.helpdesk.domain.beans.FileInfo)
*/
@Override
@RequestCache
public byte[] readFileInfoContent(final FileInfo fileInfo) {
if (fileInfo.getContent() == null) {
checkPath(false);
byte[] content = readContent(getFilename(fileInfo));
fileInfo.setContent(content);
}
return fileInfo.getContent();
}
/**
* @return the path
*/
protected String getPath() {
return path;
}
/**
* @param path the path to set
*/
public void setPath(final String path) {
this.path = path;
}
/**
* @param v2Path the v2Path to set
*/
public void setV2Path(final String v2Path) {
this.v2Path = v2Path;
}
/**
* Delete a content.
* @param filename
*/
protected void deleteContent(final String filename) {
File file = new File(filename);
if (file.exists()) {
if (!file.delete()) {
logger.error("could not delete file [" + filename + "]");
}
} else {
logger.error("file [" + filename + "] not found");
}
}
/**
* @see org.esupportail.helpdesk.dao.FileManager#deleteFileInfoContent(
* org.esupportail.helpdesk.domain.beans.FileInfo)
*/
@Override
public void deleteFileInfoContent(final FileInfo fileInfo) {
checkPath(false);
deleteContent(getFilename(fileInfo));
}
/**
* @param archivedFileInfo
* @return the name of the filesystem entry for a ArchivedFileInfo.
*/
protected String getFilename(final ArchivedFileInfo archivedFileInfo) {
return path + "/" + archivedFileInfo.getFileInfoId();
}
/**
* @see org.esupportail.helpdesk.dao.FileManager#readArchivedFileInfoContent(
* org.esupportail.helpdesk.domain.beans.ArchivedFileInfo)
*/
@Override
public byte[] readArchivedFileInfoContent(final ArchivedFileInfo archivedFileInfo) {
if (archivedFileInfo.getContent() == null) {
checkPath(false);
byte[] content = readContent(getFilename(archivedFileInfo));
archivedFileInfo.setContent(content);
}
return archivedFileInfo.getContent();
}
/**
* @see org.esupportail.helpdesk.dao.FileManager#deleteAllContents()
*/
@Override
public void deleteAllContents() throws FileException {
File dir = new File(path);
for (File file : dir.listFiles()) {
file.delete();
}
}
/**
* @see org.esupportail.helpdesk.dao.FileManager#readOldFileInfoContent(
* org.esupportail.helpdesk.domain.beans.OldFileInfo)
*/
@Override
public byte[] readOldFileInfoContent(final OldFileInfo oldFileInfo) {
if (oldFileInfo.getContent() == null) {
checkV2Path(false);
byte[] content = readContent(getFilename(oldFileInfo));
oldFileInfo.setContent(content);
}
return oldFileInfo.getContent();
}
/**
* @see org.esupportail.helpdesk.dao.FileManager#deleteOldFileInfoContent(
* org.esupportail.helpdesk.domain.beans.OldFileInfo)
*/
@Override
public void deleteOldFileInfoContent(final OldFileInfo oldFileInfo) {
checkV2Path(false);
deleteContent(getFilename(oldFileInfo));
}
}