package io.github.infolis.datastore; import io.github.infolis.InfolisConfig; import io.github.infolis.model.entity.InfolisFile; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * FileResolver encapsulating file storage in a central directory with files * named with the MD5 sum of the {@link InfolisFile} * * @author kba * */ class CentralFileResolver implements FileResolver { private static final Logger log = LoggerFactory.getLogger(CentralFileResolver.class); private static Logger logger = LoggerFactory.getLogger(CentralFileResolver.class); /* * File IDs should be hexadecimal hashsums, i.e. only alnum, either 32 (md5) * or 40 (sha1) bytes long */ private static Pattern VALID_ID_RE = Pattern .compile("^(?:\\p{Alnum}{32}|\\p{Alnum}{40})$"); /** * Resolve a filename to a {@link java.nio.file.Path} relative to the base * directory defined by the {@link InfolisConfig} * * @param fileId * the id to resolve * @return the absolute path to the file */ protected Path resolvePath(String fileId) { return InfolisConfig.getFileSavePath().resolve(fileId); } @Override public void validateFileId(String fileId) { Matcher matcher = VALID_ID_RE.matcher(fileId); if (!matcher.find()) throw new IllegalArgumentException("Bad File ID: " + fileId); } @Override public InputStream openInputStream(String fileId) throws IOException { Path fileName = resolvePath(fileId); logger.trace("Reading data from file {}", fileName); InputStream ret; if (!Files.exists(fileName)) { throw new FileNotFoundException(fileName.toString()); } else { ret = Files.newInputStream(fileName); } return ret; } @Override public OutputStream openOutputStream(String fileId) throws IOException { Path fileName = resolvePath(fileId); logger.trace("Writing data to file {}", fileName); OutputStream outStream = Files .newOutputStream(fileName, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); return outStream; } @Override public InputStream openInputStream(InfolisFile inputFile) throws IOException{ return openInputStream(inputFile.getMd5()); } @Override public OutputStream openOutputStream(InfolisFile outputFile) throws IOException { return openOutputStream(outputFile.getMd5()); } }