package org.uncertweb.ps.storage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.UUID;
import org.apache.commons.codec.digest.DigestUtils;
import org.joda.time.DateTime;
import org.joda.time.format.ISODateTimeFormat;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class FlatFileStorage extends Storage {
private Path base;
public FlatFileStorage(Path base) {
super();
this.base = base;
}
public String put(byte[] content, String mimeType, String storedBy) throws StorageException {
// generate id
String id = UUID.randomUUID().toString();
// write content
try {
Files.write(base.resolve(id), content);
}
catch (IOException e) {
throw new StorageException("Couldn't write content to file.", e);
}
// generate entry json
String md5 = DigestUtils.md5Hex(content);
String json = "{\"mimeType\":\"" + mimeType + "\"," +
"\"storedBy\":\"" + storedBy + "\"," +
"\"storedAt\":\"" + ISODateTimeFormat.dateTime().print(new DateTime()) + "\"," +
"\"checksum\":\"" + md5 + "\"}";
// write entry
try {
Files.write(base.resolve(id + ".entry"), json.getBytes());
}
catch (IOException e) {
throw new StorageException("Couldn't write storage entry file.", e);
}
return id;
}
public StorageEntry get(String id) throws StorageException {
if (id == null) {
throw new IllegalArgumentException("ID cannot be null.");
}
Path contentPath = base.resolve(id);
Path entryPath = base.resolve(id + ".entry");
// get entry
String mimeType;
String storedBy;
DateTime storedAt;
String md5;
try {
byte[] entryBytes = Files.readAllBytes(entryPath);
JsonObject entryObject = new JsonParser().parse(new String(entryBytes)).getAsJsonObject();
mimeType = entryObject.get("mimeType").getAsString();
storedBy = entryObject.get("storedBy").getAsString();
storedAt = ISODateTimeFormat.dateTime().parseDateTime(entryObject.get("storedAt").getAsString());
md5 = entryObject.get("checksum").getAsString();
}
catch (IOException e) {
throw new StorageException("Couldn't read storage entry file, is the ID valid?", e);
}
// get content
byte[] contentBytes;
try {
contentBytes = Files.readAllBytes(contentPath);
}
catch (IOException e) {
throw new StorageException("Couldn't read content from file.", e);
}
// verify
String newMD5 = DigestUtils.md5Hex(contentBytes);
if (!md5.equals(newMD5)) {
throw new StorageException("File failed checksum verification.");
}
return new StorageEntry(contentBytes, mimeType, storedBy, storedAt);
}
public boolean remove(String id) throws StorageException {
if (id == null) {
throw new IllegalArgumentException("ID cannot be null.");
}
// remove files
Path contentPath = base.resolve(id);
Path entryPath = base.resolve(id + ".entry");
try {
Files.delete(contentPath);
Files.delete(entryPath);
}
catch (IOException e) {
throw new StorageException("Couldn't remove files.", e);
}
return !Files.exists(contentPath) && !Files.exists(entryPath);
}
}