/* * Copyright 2003 Jayson Falkner (jayson@jspinsider.com) * This code is from "Servlets and JavaServer pages; the J2EE Web Tier", * http://www.jspbook.com. You may freely use the code both commercially * and non-commercially. If you like the code, please pick up a copy of * the book and help support the authors, development of more free code, * and the JSP/Servlet/J2EE community. * * See http://www.onjava.com/pub/a/onjava/2003/11/19/filters.html */ package org.freehep.webutil.cache; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.util.*; import org.freehep.webutil.cache.CacheResponseWrapper; public class CacheFilter implements Filter { ServletContext sc; FilterConfig fc; long cacheTimeout = Long.MAX_VALUE; public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; // check if was a resource that shouldn't be cached. String r = sc.getRealPath(""); String path = fc.getInitParameter(request.getRequestURI()); if (path!= null && path.equals("nocache")) { chain.doFilter(request, response); return; } path = r+path; // customize to match parameters String id = request.getRequestURI()+request.getQueryString(); // optionally append i18n sensitivity String localeSensitive = fc.getInitParameter("locale-sensitive"); if (localeSensitive != null) { StringWriter ldata = new StringWriter(); Enumeration locales = request.getLocales(); while (locales.hasMoreElements()) { Locale locale = (Locale)locales.nextElement(); ldata.write(locale.getISO3Language()); } id = id + ldata.toString(); } File tempDir = (File)sc.getAttribute( "javax.servlet.context.tempdir"); // get possible cache String temp = tempDir.getAbsolutePath(); File file = new File(temp+id); // get current resource if (path == null) { path = sc.getRealPath(request.getRequestURI()); } File current = new File(path); try { long now = Calendar.getInstance().getTimeInMillis(); //set timestamp check if (!file.exists() || (file.exists() && current.lastModified() > file.lastModified()) || cacheTimeout < now - file.lastModified()) { String name = file.getAbsolutePath(); name = name.substring(0,name.lastIndexOf("/")==-1?0:name.lastIndexOf("/")); new File(name).mkdirs(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); CacheResponseWrapper wrappedResponse = new CacheResponseWrapper(response, baos); chain.doFilter(req, wrappedResponse); FileOutputStream fos = new FileOutputStream(file); fos.write(baos.toByteArray()); fos.flush(); fos.close(); } } catch (ServletException e) { if (!file.exists()) { throw new ServletException(e); } } catch (IOException e) { if (!file.exists()) { throw e; } } FileInputStream fis = new FileInputStream(file); String mt = sc.getMimeType(request.getRequestURI()); response.setContentType(mt); ServletOutputStream sos = res.getOutputStream(); for (int i = fis.read(); i!= -1; i = fis.read()) { sos.write((byte)i); } } public void init(FilterConfig filterConfig) { this.fc = filterConfig; String ct = fc.getInitParameter("cacheTimeout"); if (ct != null) { cacheTimeout = 60*1000*Long.parseLong(ct); } this.sc = filterConfig.getServletContext(); } public void destroy() { this.sc = null; this.fc = null; } }