package org.gaecounter; import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; import javax.jdo.JDOCanRetryException; import javax.jdo.JDOObjectNotFoundException; import javax.jdo.PersistenceManager; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; import org.gaecounter.data.Counter; import org.gaecounter.data.Counter.Type; import org.gaecounter.data.PMF; import org.joda.time.DateTime; public class CountDownloadsFilter implements Filter { @Override public void init(FilterConfig xiConfig) throws ServletException { // Do nothing } @Override public void doFilter(ServletRequest xiReq, ServletResponse xiResp, FilterChain xiChain) throws IOException, ServletException { final AtomicInteger error = new AtomicInteger(-1); if (xiResp instanceof HttpServletResponse) { xiResp = new HttpServletResponseWrapper((HttpServletResponse)xiResp) { @Override public void sendError(int sc) throws IOException { error.set(sc); super.sendError(sc); } @Override public void sendError(int sc, String msg) throws IOException { error.set(sc); super.sendError(sc, msg); } }; } xiChain.doFilter(xiReq, xiResp); if (error.get() == -1 && xiReq instanceof HttpServletRequest) { HttpServletRequest lHttpReq = (HttpServletRequest)xiReq; String lReqURI = lHttpReq.getRequestURI(); DateTime lNow = new DateTime(); countDownload(lReqURI, lNow.getYear(), lNow.getMonthOfYear(), lNow.getDayOfMonth()); if (lReqURI.endsWith(".so")) { xiResp.setContentType("application/octet-stream"); } } } public static void countDownload(String xiReqURI, int y, int m, int d) { String lYStr = Type.YEAR.getPartialStr(y, m, d); String lYStrKey = Counter.getKey(xiReqURI, lYStr); String lYMStr = Type.MONTH.getPartialStr(y, m, d); String lYMStrKey = Counter.getKey(xiReqURI, lYMStr); String lYMDStr = Type.DAY.getPartialStr(y, m, d); String lYMDStrKey = Counter.getKey(xiReqURI, lYMDStr); PersistenceManager pm = PMF.get().getPersistenceManager(); try { incrementCounter(pm, lYStrKey, Type.YEAR, lYStr, xiReqURI); incrementCounter(pm, lYMStrKey, Type.MONTH, lYMStr, xiReqURI); incrementCounter(pm, lYMDStrKey, Type.DAY, lYMDStr, xiReqURI); } finally { pm.close(); } } private static void incrementCounter(PersistenceManager xiPm, String xiKey, Type xiType, String xiDateStr, String xiReqURI) { try { int retries = 0; int NUM_RETRIES = 10; while (true) // break out below { retries++; xiPm.currentTransaction().begin(); Counter lCounter = null; try { lCounter = xiPm.getObjectById(Counter.class, xiKey); lCounter.incrementCount(); } catch (JDOObjectNotFoundException ex) { lCounter = new Counter(xiType, xiDateStr, xiReqURI); } xiPm.makePersistent(lCounter); try { xiPm.currentTransaction().commit(); break; } catch (JDOCanRetryException ex) { if (retries == NUM_RETRIES) { throw ex; } } } } finally { if (xiPm.currentTransaction().isActive()) { xiPm.currentTransaction().commit(); } } } @Override public void destroy() { // Do nothing } }