public class Session implements java.io.Serializable {
private static final Map<String, Session> sessions = new HashMap<String, Session>();
+ private static final Map<Request, Session> cache = new WeakHashMap<Request, Session>();
private static final SecureRandom prng;
private static long lastclean = 0;
+ private final String id;
private final Map<Object, Object> props = new HashMap<Object, Object>();
private long ctime = System.currentTimeMillis(), atime = ctime, etime = 86400 * 1000;
private Collection<Listener> ll = new HashSet<Listener>();
}
public static interface Listener {
- public void expire(Session sess);
+ public void destroy(Session sess);
}
- public void listen(Listener l) {
- synchronized(ll) {
- ll.add(l);
- }
+ private Session(String id) {
+ this.id = id;
}
- public Object get(Object key, Object def) {
- synchronized(props) {
- if(props.containsKey(key))
- return(props.get(key));
- else
- return(def);
- }
+ public synchronized void listen(Listener l) {
+ ll.add(l);
}
- public Object put(Object key, Object val) {
- synchronized(props) {
- return(props.put(key, val));
- }
+ public synchronized Object get(Object key, Object def) {
+ if(props.containsKey(key))
+ return(props.get(key));
+ else
+ return(def);
}
- private void expire() {
- synchronized(ll) {
- for(Listener l : ll)
- l.expire(this);
- }
+ public synchronized Object put(Object key, Object val) {
+ return(props.put(key, val));
}
- public static int num() {
- synchronized(sessions) {
- return(sessions.size());
+ public void destroy() {
+ synchronized(Session.class) {
+ sessions.remove(id);
}
+ expire();
+ }
+
+ private synchronized void expire() {
+ for(Listener l : ll)
+ l.destroy(this);
+ }
+
+ public synchronized static int num() {
+ return(sessions.size());
}
private static String newid() {
return(buf.toString());
}
- private static Session create(Request req) {
- Session sess = new Session();
+ private static Session create(Request req, String id) {
+ Session sess = new Session(id);
long etime = 0;
int ct;
ct = Integer.parseInt(req.ctx().libconfig("jsvc.session.expire", "0"));
return(sess);
}
- private static void clean() {
+ private synchronized static void clean() {
long now = System.currentTimeMillis();
- synchronized(sessions) {
- for(Iterator<Session> i = sessions.values().iterator(); i.hasNext();) {
- Session sess = i.next();
- if(now > sess.atime + sess.etime) {
- i.remove();
- sess.expire();
- }
+ for(Iterator<Session> i = sessions.values().iterator(); i.hasNext();) {
+ Session sess = i.next();
+ if(now > sess.atime + sess.etime) {
+ i.remove();
+ sess.expire();
}
}
}
- public static Session get(Request req) {
+ public synchronized static Session get(Request req) {
long now = System.currentTimeMillis();
if(now - lastclean > 3600 * 1000) {
clean();
lastclean = now;
}
+ Session sess = cache.get(req);
+ if(sess != null) {
+ sess.atime = System.currentTimeMillis();
+ return(sess);
+ }
+
MultiMap<String, Cookie> cookies = Cookie.get(req);
Cookie sc = cookies.get("jsvc-session");
- Session sess = null;
- synchronized(sessions) {
- if(sc != null)
- sess = sessions.get(sc.value);
- if(sess == null) {
- String id = newid();
- sess = create(req);
- sessions.put(id, sess);
- sc = new Cookie("jsvc-session", id);
- sc.expires = new Date(System.currentTimeMillis() + (86400L * 365L * 1000L));
- sc.path = req.ctx().sysconfig("jsvc.session.path", req.rooturl().getPath());
- String pd = req.ctx().sysconfig("jsvc.session.domain", null);
- if(pd != null)
- sc.domain = pd;
- sc.addto(req);
- }
+
+ if(sc != null)
+ sess = sessions.get(sc.value);
+ if(sess == null) {
+ sess = create(req, newid());
+ sessions.put(sess.id, sess);
+ sc = new Cookie("jsvc-session", sess.id);
+ sc.expires = new Date(System.currentTimeMillis() + (86400L * 365L * 1000L));
+ sc.path = req.ctx().sysconfig("jsvc.session.path", req.rooturl().getPath());
+ String pd = req.ctx().sysconfig("jsvc.session.domain", null);
+ if(pd != null)
+ sc.domain = pd;
+ sc.addto(req);
}
+
+ cache.put(req, sess);
+ sess.atime = System.currentTimeMillis();
return(sess);
}