KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > icesoft > faces > webapp > http > servlet > SessionDispatcher


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 JavaDoc;
7 import javax.servlet.ServletContextListener JavaDoc;
8 import javax.servlet.ServletException JavaDoc;
9 import javax.servlet.http.HttpServletRequest JavaDoc;
10 import javax.servlet.http.HttpServletResponse JavaDoc;
11 import javax.servlet.http.HttpSession JavaDoc;
12 import javax.servlet.http.HttpSessionEvent JavaDoc;
13 import javax.servlet.http.HttpSessionListener JavaDoc;
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.Iterator JavaDoc;
17 import java.util.List JavaDoc;
18 import java.util.Map JavaDoc;
19
20 public abstract class SessionDispatcher implements PseudoServlet {
21     //having a static field here is ok because web applications are started in separate classloaders
22
private static final Log Log = LogFactory.getLog(SessionDispatcher.class);
23     private final static List JavaDoc SessionDispatchers = new ArrayList JavaDoc();
24     private Map JavaDoc sessionBoundServers = new HashMap JavaDoc();
25
26     protected SessionDispatcher() {
27         SessionDispatchers.add(this);
28     }
29
30     public void service(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws Exception JavaDoc {
31         HttpSession JavaDoc session = request.getSession(true);
32         //test if session is still around
33
if (sessionBoundServers.containsKey(session.getId())) {
34             PseudoServlet server = (PseudoServlet) sessionBoundServers.get(session.getId());
35             server.service(request, response);
36         } else {
37             //session has expired in the mean time, server removed by the session listener
38
throw new ServletException JavaDoc("Session expired");
39         }
40     }
41
42     public void shutdown() {
43         Iterator JavaDoc 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 JavaDoc session) {
51         try {
52             sessionBoundServers.put(session.getId(), this.newServlet(session,Listener.lookupSessionMonitor(session)));
53         } catch (Exception JavaDoc e) {
54             Log.warn(e);
55             throw new RuntimeException JavaDoc(e);
56         } catch (Throwable JavaDoc t) {
57             Log.warn(t);
58             throw new RuntimeException JavaDoc(t);
59         }
60     }
61
62     private void sessionShutdown(HttpSession JavaDoc session) {
63         PseudoServlet server = (PseudoServlet) sessionBoundServers.get(session.getId());
64         server.shutdown();
65     }
66
67     private void sessionDestroyed(HttpSession JavaDoc session) {
68         sessionBoundServers.remove(session.getId());
69     }
70
71     //Exposing MainSessionBoundServlet for Tomcat 6 Ajax Push
72
public static PseudoServlet getSingletonSessionServlet(HttpSession JavaDoc session) {
73         return ((SessionDispatcher) SessionDispatchers.get(0))
74                     .getSessionServlet(session);
75     }
76
77     public PseudoServlet getSessionServlet(HttpSession JavaDoc session) {
78         return (PseudoServlet) sessionBoundServers.get(session.getId());
79     }
80
81     protected abstract PseudoServlet newServlet(HttpSession JavaDoc session, Listener.Monitor JavaDoc sessionMonitor) throws Exception JavaDoc;
82
83     public static class Listener implements HttpSessionListener JavaDoc, ServletContextListener JavaDoc {
84         private static Map JavaDoc sessionMonitors = new HashMap JavaDoc();
85         private boolean run = true;
86
87         public void sessionCreated(HttpSessionEvent JavaDoc event) {
88             HttpSession JavaDoc session = event.getSession();
89             sessionMonitors.put(session, new Monitor(session));
90
91             Iterator JavaDoc i = SessionDispatchers.iterator();
92             while (i.hasNext()) {
93                 try {
94                     SessionDispatcher sessionDispatcher = (SessionDispatcher) i.next();
95                     sessionDispatcher.sessionCreated(session);
96                 } catch (Exception JavaDoc e) {
97                     new RuntimeException JavaDoc(e);
98                 }
99             }
100         }
101
102         public void sessionShutdown(HttpSession JavaDoc session) {
103             Iterator JavaDoc i = SessionDispatchers.iterator();
104             while (i.hasNext()) {
105                 try {
106                     SessionDispatcher sessionDispatcher = (SessionDispatcher) i.next();
107                     sessionDispatcher.sessionShutdown(session);
108                 } catch (Exception JavaDoc e) {
109                     new RuntimeException JavaDoc(e);
110                 }
111             }
112             session.invalidate();
113         }
114
115         public void sessionDestroyed(HttpSessionEvent JavaDoc event) {
116             HttpSession JavaDoc session = event.getSession();
117
118             Iterator JavaDoc i = SessionDispatchers.iterator();
119             while (i.hasNext()) {
120                 try {
121                     SessionDispatcher sessionDispatcher = (SessionDispatcher) i.next();
122                     sessionDispatcher.sessionDestroyed(session);
123                 } catch (Exception JavaDoc e) {
124                     new RuntimeException JavaDoc(e);
125                 }
126             }
127         }
128
129         public void contextInitialized(ServletContextEvent JavaDoc servletContextEvent) {
130             Thread JavaDoc monitor = new Thread JavaDoc("Session Monitor") {
131                 public void run() {
132                     while (run) {
133                         try {
134                             //iterate over the sessions using a copying iterator
135
Iterator JavaDoc iterator = new ArrayList JavaDoc(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 JavaDoc e) {
143                             //ignore interrupts
144
}
145                     }
146                 }
147             };
148             monitor.setDaemon(true);
149             monitor.start();
150         }
151
152         public void contextDestroyed(ServletContextEvent JavaDoc servletContextEvent) {
153             run = false;
154         }
155
156         public static Monitor lookupSessionMonitor(HttpSession JavaDoc session) {
157             return (Monitor) sessionMonitors.get(session);
158         }
159
160         public class Monitor {
161             private HttpSession JavaDoc session;
162             private long lastAccess;
163
164             public Monitor(HttpSession JavaDoc 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                 //shutdown the session a bit (15s) before session actually expires
177
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 JavaDoc e) {
187                     //session was already invalidated by the container
188
} catch (Throwable JavaDoc t) {
189                     //just inform that something went wrong
190
Log.warn("Failed to monitor session expiry", t);
191                 }
192             }
193         }
194     }
195 }
196
Popular Tags