// Path: backend/src/main/java/no/haagensoftware/netty/webserver/response/CachableHttpResponse.java
// public class CachableHttpResponse extends DefaultHttpResponse {
//     private String requestUri;
//     private int cacheMaxAge;
// 
//     public CachableHttpResponse(HttpVersion version, HttpResponseStatus status) {
//         super(version, status);
//     }
// 
//     public String getRequestUri() {
//         return requestUri;
//     }
// 
//     public void setRequestUri(String requestUri) {
//         this.requestUri = requestUri;
//     }
// 
//     public int getCacheMaxAge() {
//         return cacheMaxAge;
//     }
// 
//     public void setCacheMaxAge(int cacheMaxAge) {
//         this.cacheMaxAge = cacheMaxAge;
//     }
// }
// 
// Path: backend/src/main/java/no/haagensoftware/netty/webserver/response/CachedChannelBuffer.java
// public class CachedChannelBuffer {
// 	private ChannelBuffer channelBuffer;
// 	private long expires;
// 	
// 	public CachedChannelBuffer(ChannelBuffer channelBuffer, long expires) {
// 		this.channelBuffer = channelBuffer;
// 		this.expires = expires;
// 	}
// 	
// 	public ChannelBuffer getChannelBuffer() {
// 		return channelBuffer;
// 	}
// 	
// 	public long getExpires() {
// 		return expires;
// 	}
// }
// 
// Path: backend/src/main/java/org/haagensoftware/netty/webserver/util/ContentTypeUtil.java
// public class ContentTypeUtil {
// 	private static Hashtable<String, String> contentTypeHash = new Hashtable<String, String>();
// 	
// 	static {
// 		contentTypeHash.put("png", "image/png");
// 		contentTypeHash.put("PNG", "image/png");
// 		contentTypeHash.put("txt", "text/plain");
// 		contentTypeHash.put("text", "text/plain");
// 		contentTypeHash.put("TXT", "text/plain");
// 		contentTypeHash.put("js", "application/javascript");
// 		contentTypeHash.put("jpg", "image/jpeg");
// 		contentTypeHash.put("jpeg", "image/jpeg");
// 		contentTypeHash.put("JPG", "image/jpeg");
// 		contentTypeHash.put("JPEG", "image/jpeg");
// 		contentTypeHash.put("css", "text/css");
// 		contentTypeHash.put("CSS", "text/css");
// 		contentTypeHash.put("json", "text/json");
// 		contentTypeHash.put("html", "text/html");
// 		contentTypeHash.put("htm", "text/html");
// 	}
// 	
// 	public static String getContentType(String filename) {
// 		String fileEnding = filename.substring(filename.lastIndexOf(".")+1);
// 		System.out.println(fileEnding);
// 		if (contentTypeHash.get(fileEnding) != null) {
// 			return contentTypeHash.get(fileEnding);
// 		}
// 		
// 		return "text/plain";
// 	}
// }


import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
import static org.jboss.netty.handler.codec.http.HttpHeaders.setContentLength;
import static org.jboss.netty.handler.codec.http.HttpMethod.GET;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import java.util.concurrent.ConcurrentHashMap;
import no.haagensoftware.netty.webserver.response.CachableHttpResponse;
import no.haagensoftware.netty.webserver.response.CachedChannelBuffer;
import org.apache.log4j.Logger;
import org.haagensoftware.netty.webserver.util.ContentTypeUtil;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest;
package no.haagensoftware.netty.webserver.handler;






public class CacheableFileServerHandler extends FileServerHandler
{
	private static Logger logger = Logger.getLogger(CacheableFileServerHandler.class.getName());
	
    private static ConcurrentHashMap<String, CachedChannelBuffer> cache = new ConcurrentHashMap<String, CachedChannelBuffer>();
    
	public CacheableFileServerHandler(String rootPath, int cacheMaxAge) {
		super(rootPath, cacheMaxAge);
	}
	
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
		HttpRequest request = (HttpRequest) e.getMessage();
        if (request.getMethod() != GET) {
            sendError(ctx, METHOD_NOT_ALLOWED);
            return;
        }

        String uri = request.getUri();
        
        final String path = sanitizeUri(uri);
        if (path == null) {
            sendError(ctx, FORBIDDEN);
            return;
        }


        ChannelBuffer content = getFileContent(path);
        if (content == null) {
            sendError(ctx, NOT_FOUND);
            return;
        }

        String contentType = ContentTypeUtil.getContentType(path);
        logger.info("contentType: " + contentType + " for path: " + path);
        
// Path: backend/src/main/java/no/haagensoftware/netty/webserver/response/CachableHttpResponse.java
// public class CachableHttpResponse extends DefaultHttpResponse {
//     private String requestUri;
//     private int cacheMaxAge;
// 
//     public CachableHttpResponse(HttpVersion version, HttpResponseStatus status) {
//         super(version, status);
//     }
// 
//     public String getRequestUri() {
//         return requestUri;
//     }
// 
//     public void setRequestUri(String requestUri) {
//         this.requestUri = requestUri;
//     }
// 
//     public int getCacheMaxAge() {
//         return cacheMaxAge;
//     }
// 
//     public void setCacheMaxAge(int cacheMaxAge) {
//         this.cacheMaxAge = cacheMaxAge;
//     }
// }
// 
// Path: backend/src/main/java/no/haagensoftware/netty/webserver/response/CachedChannelBuffer.java
// public class CachedChannelBuffer {
// 	private ChannelBuffer channelBuffer;
// 	private long expires;
// 	
// 	public CachedChannelBuffer(ChannelBuffer channelBuffer, long expires) {
// 		this.channelBuffer = channelBuffer;
// 		this.expires = expires;
// 	}
// 	
// 	public ChannelBuffer getChannelBuffer() {
// 		return channelBuffer;
// 	}
// 	
// 	public long getExpires() {
// 		return expires;
// 	}
// }
// 
// Path: backend/src/main/java/org/haagensoftware/netty/webserver/util/ContentTypeUtil.java
// public class ContentTypeUtil {
// 	private static Hashtable<String, String> contentTypeHash = new Hashtable<String, String>();
// 	
// 	static {
// 		contentTypeHash.put("png", "image/png");
// 		contentTypeHash.put("PNG", "image/png");
// 		contentTypeHash.put("txt", "text/plain");
// 		contentTypeHash.put("text", "text/plain");
// 		contentTypeHash.put("TXT", "text/plain");
// 		contentTypeHash.put("js", "application/javascript");
// 		contentTypeHash.put("jpg", "image/jpeg");
// 		contentTypeHash.put("jpeg", "image/jpeg");
// 		contentTypeHash.put("JPG", "image/jpeg");
// 		contentTypeHash.put("JPEG", "image/jpeg");
// 		contentTypeHash.put("css", "text/css");
// 		contentTypeHash.put("CSS", "text/css");
// 		contentTypeHash.put("json", "text/json");
// 		contentTypeHash.put("html", "text/html");
// 		contentTypeHash.put("htm", "text/html");
// 	}
// 	
// 	public static String getContentType(String filename) {
// 		String fileEnding = filename.substring(filename.lastIndexOf(".")+1);
// 		System.out.println(fileEnding);
// 		if (contentTypeHash.get(fileEnding) != null) {
// 			return contentTypeHash.get(fileEnding);
// 		}
// 		
// 		return "text/plain";
// 	}
// }


// Path: backend/src/main/java/no/haagensoftware/netty/webserver/handler/CacheableFileServerHandler.java
import static org.jboss.netty.handler.codec.http.HttpHeaders.isKeepAlive;
import static org.jboss.netty.handler.codec.http.HttpHeaders.setContentLength;
import static org.jboss.netty.handler.codec.http.HttpMethod.GET;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.FORBIDDEN;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.METHOD_NOT_ALLOWED;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.NOT_FOUND;
import static org.jboss.netty.handler.codec.http.HttpResponseStatus.OK;
import static org.jboss.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import java.util.concurrent.ConcurrentHashMap;
import no.haagensoftware.netty.webserver.response.CachableHttpResponse;
import no.haagensoftware.netty.webserver.response.CachedChannelBuffer;
import org.apache.log4j.Logger;
import org.haagensoftware.netty.webserver.util.ContentTypeUtil;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest;

package no.haagensoftware.netty.webserver.handler;






public class CacheableFileServerHandler extends FileServerHandler
{
	private static Logger logger = Logger.getLogger(CacheableFileServerHandler.class.getName());
	
    private static ConcurrentHashMap<String, CachedChannelBuffer> cache = new ConcurrentHashMap<String, CachedChannelBuffer>();
    
	public CacheableFileServerHandler(String rootPath, int cacheMaxAge) {
		super(rootPath, cacheMaxAge);
	}
	
	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
		HttpRequest request = (HttpRequest) e.getMessage();
        if (request.getMethod() != GET) {
            sendError(ctx, METHOD_NOT_ALLOWED);
            return;
        }

        String uri = request.getUri();
        
        final String path = sanitizeUri(uri);
        if (path == null) {
            sendError(ctx, FORBIDDEN);
            return;
        }


        ChannelBuffer content = getFileContent(path);
        if (content == null) {
            sendError(ctx, NOT_FOUND);
            return;
        }

        String contentType = ContentTypeUtil.getContentType(path);
        logger.info("contentType: " + contentType + " for path: " + path);
        
        CachableHttpResponse response = new CachableHttpResponse(HTTP_1_1, OK);