1 package com.icesoft.faces.webapp.http.servlet; 2 3 import org.apache.commons.logging.Log; 4 import org.apache.commons.logging.LogFactory; 5 6 import javax.servlet.ServletContextEvent ; 7 import javax.servlet.ServletContextListener ; 8 import javax.servlet.ServletException ; 9 import javax.servlet.http.HttpServletRequest ; 10 import javax.servlet.http.HttpServletResponse ; 11 import javax.servlet.http.HttpSession ; 12 import javax.servlet.http.HttpSessionEvent ; 13 import javax.servlet.http.HttpSessionListener ; 14 import java.util.ArrayList ; 15 import java.util.HashMap ; 16 import java.util.Iterator ; 17 import java.util.List ; 18 import java.util.Map ; 19 20 public abstract class SessionDispatcher implements PseudoServlet { 21 private static final Log Log = LogFactory.getLog(SessionDispatcher.class); 23 private final static List SessionDispatchers = new ArrayList (); 24 private Map sessionBoundServers = new HashMap (); 25 26 protected SessionDispatcher() { 27 SessionDispatchers.add(this); 28 } 29 30 public void service(HttpServletRequest request, HttpServletResponse response) throws Exception { 31 HttpSession session = request.getSession(true); 32 if (sessionBoundServers.containsKey(session.getId())) { 34 PseudoServlet server = (PseudoServlet) sessionBoundServers.get(session.getId()); 35 server.service(request, response); 36 } else { 37 throw new ServletException ("Session expired"); 39 } 40 } 41 42 public void shutdown() { 43 Iterator i = sessionBoundServers.values().iterator(); 44 while (i.hasNext()) { 45 PseudoServlet server = (PseudoServlet) i.next(); 46 server.shutdown(); 47 } 48 } 49 50 private void sessionCreated(HttpSession session) { 51 try { 52 sessionBoundServers.put(session.getId(), this.newServlet(session,Listener.lookupSessionMonitor(session))); 53 } catch (Exception e) { 54 Log.warn(e); 55 throw new RuntimeException (e); 56 } catch (Throwable t) { 57 Log.warn(t); 58 throw new RuntimeException (t); 59 } 60 } 61 62 private void sessionShutdown(HttpSession session) { 63 PseudoServlet server = (PseudoServlet) sessionBoundServers.get(session.getId()); 64 server.shutdown(); 65 } 66 67 private void sessionDestroyed(HttpSession session) { 68 sessionBoundServers.remove(session.getId()); 69 } 70 71 public static PseudoServlet getSingletonSessionServlet(HttpSession session) { 73 return ((SessionDispatcher) SessionDispatchers.get(0)) 74 .getSessionServlet(session); 75 } 76 77 public PseudoServlet getSessionServlet(HttpSession session) { 78 return (PseudoServlet) sessionBoundServers.get(session.getId()); 79 } 80 81 protected abstract PseudoServlet newServlet(HttpSession session, Listener.Monitor sessionMonitor) throws Exception ; 82 83 public static class Listener implements HttpSessionListener , ServletContextListener { 84 private static Map sessionMonitors = new HashMap (); 85 private boolean run = true; 86 87 public void sessionCreated(HttpSessionEvent event) { 88 HttpSession session = event.getSession(); 89 sessionMonitors.put(session, new Monitor(session)); 90 91 Iterator i = SessionDispatchers.iterator(); 92 while (i.hasNext()) { 93 try { 94 SessionDispatcher sessionDispatcher = (SessionDispatcher) i.next(); 95 sessionDispatcher.sessionCreated(session); 96 } catch (Exception e) { 97 new RuntimeException (e); 98 } 99 } 100 } 101 102 public void sessionShutdown(HttpSession session) { 103 Iterator i = SessionDispatchers.iterator(); 104 while (i.hasNext()) { 105 try { 106 SessionDispatcher sessionDispatcher = (SessionDispatcher) i.next(); 107 sessionDispatcher.sessionShutdown(session); 108 } catch (Exception e) { 109 new RuntimeException (e); 110 } 111 } 112 session.invalidate(); 113 } 114 115 public void sessionDestroyed(HttpSessionEvent event) { 116 HttpSession session = event.getSession(); 117 118 Iterator i = SessionDispatchers.iterator(); 119 while (i.hasNext()) { 120 try { 121 SessionDispatcher sessionDispatcher = (SessionDispatcher) i.next(); 122 sessionDispatcher.sessionDestroyed(session); 123 } catch (Exception e) { 124 new RuntimeException (e); 125 } 126 } 127 } 128 129 public void contextInitialized(ServletContextEvent servletContextEvent) { 130 Thread monitor = new Thread ("Session Monitor") { 131 public void run() { 132 while (run) { 133 try { 134 Iterator iterator = new ArrayList (sessionMonitors.values()).iterator(); 136 while (iterator.hasNext()) { 137 final Monitor sessionMonitor = (Monitor) iterator.next(); 138 sessionMonitor.shutdownIfExpired(); 139 } 140 141 Thread.sleep(10000); 142 } catch (InterruptedException e) { 143 } 145 } 146 } 147 }; 148 monitor.setDaemon(true); 149 monitor.start(); 150 } 151 152 public void contextDestroyed(ServletContextEvent servletContextEvent) { 153 run = false; 154 } 155 156 public static Monitor lookupSessionMonitor(HttpSession session) { 157 return (Monitor) sessionMonitors.get(session); 158 } 159 160 public class Monitor { 161 private HttpSession session; 162 private long lastAccess; 163 164 public Monitor(HttpSession session) { 165 this.session = session; 166 this.lastAccess = session.getLastAccessedTime(); 167 } 168 169 public void touchSession() { 170 lastAccess = System.currentTimeMillis(); 171 } 172 173 private boolean isExpired() { 174 long elapsedInterval = System.currentTimeMillis() - lastAccess; 175 long maxInterval = session.getMaxInactiveInterval() * 1000; 176 return elapsedInterval + 15000 > maxInterval; 178 } 179 180 private void shutdownIfExpired() { 181 try { 182 if (isExpired()) { 183 sessionMonitors.remove(session); 184 sessionShutdown(session); 185 } 186 } catch (IllegalStateException e) { 187 } catch (Throwable t) { 189 Log.warn("Failed to monitor session expiry", t); 191 } 192 } 193 } 194 } 195 } 196 | Popular Tags |