to.etc.domui.state
Class AppSession

java.lang.Object
  extended by to.etc.domui.state.AppSession
All Implemented Interfaces:
java.util.EventListener, javax.servlet.http.HttpSessionBindingListener, IAttributeContainer

public class AppSession
extends java.lang.Object
implements javax.servlet.http.HttpSessionBindingListener, IAttributeContainer

Generic session implementation. The session is specific for the application, and the session type can be overridden by letting DomApplication return a new instance that extends this class.

The AppSession also handles user request locking. To prevent us from having to synchronize the entire DOM and PAGE contexts all over the place we lock access to all session-related data as soon as a request touches the session. All requests to get the session pass thru RequestContext.getSession(). So this indicates that per-session data is needed. Before returning the session we check if another call is currently using the session; if so we block until that call leaves the session. When the session is free the current request will claim it using a lock in the session object. When a request terminates it is the responsibility of the toplevel request handler to always unlock the request.

Author:
Frits Jalvingh Created on May 22, 2008

Constructor Summary
AppSession(DomApplication da)
           
 
Method Summary
 WindowSession createWindowSession()
          Create a new WindowSession.
 void destroy()
          Override to get control when this user's session is destroyed.
 void dump()
          Helper utility to dump the session's conversational state.
 WindowSession findWindowSession(java.lang.String wid)
          Try to locate the WindowSession with the specified ID in this HttpSession.
 DomApplication getApplication()
          Questionable use.
 java.lang.Object getAttribute(java.lang.String name)
           
 void internalCheckExpiredWindowSessions()
          Walks all WindowSessions and checks to see if they have not been used for more than the window session timeout.
 void internalDestroy()
           
 void internalLockSession()
          INTERNAL USE ONLY.
 void internalObituaryReceived(java.lang.String cid, int obitPageTag)
          Mark the WindowSession as "possibly deleted".
 void internalUnlockSession()
          INTERNAL USE ONLY.
 void setAttribute(java.lang.String name, java.lang.Object value)
           
 void valueBound(javax.servlet.http.HttpSessionBindingEvent arg0)
          Unused, needed for interface.
 void valueUnbound(javax.servlet.http.HttpSessionBindingEvent arg0)
          Called for non-debug sessions, where this is directly bound to a HttpSession.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

AppSession

public AppSession(DomApplication da)
Method Detail

internalDestroy

public final void internalDestroy()

getApplication

public DomApplication getApplication()
Questionable use.

Returns:

destroy

public void destroy()
Override to get control when this user's session is destroyed.


valueBound

public final void valueBound(javax.servlet.http.HttpSessionBindingEvent arg0)
Unused, needed for interface.

Specified by:
valueBound in interface javax.servlet.http.HttpSessionBindingListener
See Also:
HttpSessionBindingListener.valueBound(javax.servlet.http.HttpSessionBindingEvent)

valueUnbound

public final void valueUnbound(javax.servlet.http.HttpSessionBindingEvent arg0)
Called for non-debug sessions, where this is directly bound to a HttpSession. When that session closes this causes the destroy() methods to be called.

Specified by:
valueUnbound in interface javax.servlet.http.HttpSessionBindingListener
See Also:
HttpSessionBindingListener.valueUnbound(javax.servlet.http.HttpSessionBindingEvent)

internalLockSession

public void internalLockSession()
INTERNAL USE ONLY. Enter the session-controlled monitor: only one thread at-a-time may access session-related data. This call can be called multiple times for a thread and will not block. But it is not nested: a single call to unlockSession() will release the lock.


internalUnlockSession

public void internalUnlockSession()
INTERNAL USE ONLY. Leave the session-controlled monitor. THIS CALL DOES NOT NEST!


internalCheckExpiredWindowSessions

public final void internalCheckExpiredWindowSessions()
Walks all WindowSessions and checks to see if they have not been used for more than the window session timeout. All WindowSessions that have expired will then be destroyed. This only checks the "normal" timestamp. Obituary handling is elsewhere.


createWindowSession

public final WindowSession createWindowSession()
Create a new WindowSession. The thingy has a new, globally-unique ID.

Returns:

findWindowSession

public final WindowSession findWindowSession(java.lang.String wid)
Try to locate the WindowSession with the specified ID in this HttpSession. Returns null if not found.

Parameters:
wid -
Returns:

internalObituaryReceived

public void internalObituaryReceived(java.lang.String cid,
                                     int obitPageTag)
                              throws java.lang.Exception
Mark the WindowSession as "possibly deleted". Called from the server when an Obituary has been received, indicating that some page in the window was closed. This state causes the window to be discarded if no request to it is received within a minute. For normal navigation this always works, because the destruction of an old page is followed immediately by the restore of another page in the same window, hence a request on the windowSession.

Problems with obituary receive order

To bloody ^**^&)*&^)&*%&^% complicate matters further the reception of the Obituary is often out-of-order, meaning that the request for the NEW page is received BEFORE the Obituary of the old page is received. This of course f*cks up the process, again. To fix this we keep track of when the last request was received, keeping in mind that the request and the obituary are always close together in time. For now we do not mark a WindowSession as possibly deleted if it's previous request is before but close to the obituary's request.

Parameters:
cm - The WindowSession for which the obituary was received.
obitPageTag - The page tag of the page that has died.
Throws:
java.lang.Exception

dump

public void dump()
Helper utility to dump the session's conversational state.


getAttribute

public java.lang.Object getAttribute(java.lang.String name)
Specified by:
getAttribute in interface IAttributeContainer
See Also:
IAttributeContainer.getAttribute(java.lang.String)

setAttribute

public void setAttribute(java.lang.String name,
                         java.lang.Object value)
Specified by:
setAttribute in interface IAttributeContainer