package kornell.server;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import kornell.core.util.StringUtils;
@SuppressWarnings("serial")
public class LocalRepositoryServlet extends HttpServlet {
static final Pattern pattern = Pattern.compile("[/]?repository/([^/]*)/(.*)");
static final String pUUID = "\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12}";
public static final boolean isRepository(File file) {
return file.getName().matches(pUUID);
}
static final Path home = Paths.get(System.getProperty("user.home"));
static final Path repos = home.resolve("Repositories/");
static final Map<String, File> repoPaths = new HashMap<String, File>();
public static void scan(File file) {
assert file.exists() && file.isDirectory();
if (isRepository(file)) {
System.out.println("> Adding repository [" + file+"]");
repoPaths.put(file.getName(), file);
}
File[] children = file.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.isDirectory();
}
});
if(children != null)
for (File child : children)
scan(child);
}
@Override
public void init() throws ServletException {
System.out.println("*** === INIT === ***");
scan(repos.toFile());
System.out.println("*** === LISTEN === ***");
}
@Override
protected void doGet(final HttpServletRequest req,
final HttpServletResponse resp) throws ServletException,
IOException {
StringBuilder msg = new StringBuilder();
try {
String uri = req.getRequestURI();
if (uri.startsWith("/"))
uri = uri.substring(1);
Matcher matcher = pattern.matcher(uri);
if (matcher.matches()) {
String repositoryUUID = matcher.group(1);
msg.append("["+repositoryUUID+"] =>");
String obj = matcher.group(2);
Path repoPath = pathOf(repositoryUUID);
msg.append("["+repoPath+"]");
if (repoPath != null) {
if (obj.startsWith("/")){
obj=obj.substring(1);
}
msg.append("["+obj+"]");
Path file = repoPath.resolve(obj);
msg.append("=>["+file+"]");
if (file.toFile().exists()) {
msg.append("[W]");
setContentTye(file, req, resp);
Files.copy(file, resp.getOutputStream());
} else {
msg.append("[NO_FILE]["+file.toAbsolutePath()+"]");
throw new RuntimeException("# "+msg);
}
} else {
msg.append("[NO_REPO]");
throw new RuntimeException("# "+msg);
}
} else {
msg.append("[NOT_MINE]");
}
} catch (Exception e) {
e.printStackTrace();
resp.sendError(
HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
"500>"+e.getMessage());
}finally{
System.out.println(">"+msg);
}
}
static final Path pathOf(String storeUUID) {
File base = repoPaths.get(storeUUID);
return base != null ? Paths.get(base.toURI()) : null;
}
private void setContentTye(Path file, HttpServletRequest req,
HttpServletResponse resp) {
String fname = file.toString();
String type = StringUtils.getMimeType(fname);
if (StringUtils.isSome(type)) {
resp.setContentType(type);
}
}
}