package hu.sch.ejb.image;
import hu.sch.util.config.ImageUploadConfig;
import hu.sch.domain.user.User;
import hu.sch.services.exceptions.PekException;
import hu.sch.services.exceptions.PekErrorCode;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Saves an image to the right location in the file system.
*
* If necessary it creates the folders too.
*
* @author tomi
*/
public final class ImageSaver {
private static final Logger logger = LoggerFactory.getLogger(ImageSaver.class);
private final User user;
private Path lastPath = null;
private ImageUploadConfig imageConfig;
public ImageSaver(User user, ImageUploadConfig config) {
this.user = user;
imageConfig = config;
}
public ImageSaver copy(String sourcePath) {
File img = new File(sourcePath);
byte[] bytes;
try {
bytes = Files.readAllBytes(img.toPath());
} catch (IOException ex) {
logger.warn(String.format("Could not read file %s", sourcePath), ex);
bytes = new byte[0];
}
return save(img.getName(), bytes);
}
public ImageSaver save(String filename, byte[] data) {
try {
lastPath = Files.write(buildImagePath(filename), data);
return this;
} catch (IOException ex) {
final String msg = "Could not save image to disk.";
logger.error(msg, ex);
throw new PekException(PekErrorCode.FILE_CREATE_FAILED, msg, ex);
}
}
/**
* Gets the last processed images' path relative to the uploads base path.
*
* @return
*/
public String getRelativePath() {
if (lastPath == null) {
throw new IllegalStateException("There is no last saved file path. Call save() first.");
}
Path base = Paths.get(imageConfig.getBasePath());
Path relative = base.relativize(lastPath);
return relative.toString();
}
/**
* Builds the path of the image. Also create the folder if they don't exist.
*
* Eg. /path/to/upload/base/u/username/image-hash.ext
*
* @param user
* @param filename
* @return
*/
private Path buildImagePath(String filename) {
// NOTE: file path (relative to base path) needs to be all downcase
Path dir = Paths.get(
imageConfig.getBasePath(),
filename.substring(0, 1),
filename.substring(0, 2));
dir.toFile().mkdirs();
return Paths.get(dir.toString(), filename);
}
}