com.marringtons.util
Class Session

java.lang.Object
  extended bycom.marringtons.util.Session
All Implemented Interfaces:
Closeable

public class Session
extends Object
implements Closeable

Session provides support for saving and retrieving information related to one of many session where a session is common to a single client. Tiers and slices are good architectural principles, but their still remains a need to common information related to a session that can be retrieved from any code location. For a stand-alone program static program-wide variables and classes (called singletons) can be used. For an application used by more than one person at the same time, there is need for data unique to the user but common between the tiers. This class encapsulates a generic session object for this sort of data. For the tier that provides access to the session, it can keep a pointer. When retrieving a tier it saves the session name as the thread name. Lower tiers can then have access to the session with a get() command that uses the thread name. For this reason if a process spawns off another thread that requires session data it should be named the same as it's parent thread. A session can hold any class instance in one of three states:

  1. A transient entry is lost when the session closes. Use put() with an Object.
  2. A closeable entry is closed before it is removed. Use put() with a Closeable object.
  3. A persistent entry is written to disk and read when the session is used again. Use save() or getPersistent().
There is an overloaded get() method that takes a class. If the object does not exist then a new one of the class supplied is created. This requires a default public constructor for that class. If the data is to persist to disk, use getPersistent(). getPersistent also does a save() to prepare the data for update.
 private static final Class hashMapClass = HashMap.class;
 private static final Class hashSetClass = HashSet.class;
 private final static String javascriptIncludeCacheKey
     = JavaScript.class.getName() + ".include.cache";
 ...
 HashMap portals = (HashMap) request.session.getPersistent( "Panel.data", hashMapClass);
 Set javascriptIncludeCache = (Set) session.get( javascriptIncludeCacheKey, hashSetClass);
 Map filesToCloseOnSessionExit = (Map) session.get( "ftc", FileMap.class); // has Closeable interface
 
Alternatively, when saving values that are part of immutable classes (String, Integer, etc), use the overloaded get() or getPersistent() that take a default value as the second parameter.
 private static final Integer defaultValue = new Integer( 23);
 Integer value = (Integer) request.session.getPersistent( "number", defaultValue);
 
When adding data keys, they must be unique to the session. Because the can come from parts of the application and libraries that don't know about each other this requirement must be considered with care. One of the best methods is to use all or part of the operating class name or package as part of the key. Examples are "Panel.data" for Pane.java and "JavaScript.include.cache" used by the JavaScript.java class. If there was concern that they may clash with entries from other packages, use the fully qualified name (i.e. "com.marringtons.adept.page.Panel.data" and "com.marringtons.javascript.JavaScript.include.cache"). In fact, using the name of a class directly is probably the clearest and least likely to confuse method:
 private final static String javascriptIncludeCacheKey
     = JavaScript.class.getName() + ".include.cache";
 
Session can be closed when they are done with. They will also close by themselves when the session times out. Use setTimeout() to set a non-standard session timeout value (in minutes).
   String sessionCookie = request.getCookie( sessionCookieKey);
   if (sessionCookie != null)
     request.session = Session.get( sessionCookie);
   else
     {
       request.session = Session.create();
       response.setPermanentCookie( sessionCookieKey, request.session.id);
     }
   // in a lower tier that does not have access to the request object
   Session session = Session.get();
   session.setTimeout( 120);	// 2 hour timeout for this session.
   String userName = session.get( "userName");
   session.put( "databaseConnection", databaseConnection);	// temporary for this session only
  session.put( "dataFile", dataFile);	// of type Closeable and will closewhen session ends
  session.save( "email", email);	// saved to disk and restored when next the session is opened
 

Author:
Paul Marrington

Nested Class Summary
static class Session.Key
          Key is returned by Session factory methods to create a private static key to keep in calling classes to provide class, package or global scope session data.
static class Session.Lifetime
          Lifetime provides typesafe definition of session lifetime, being this session only or persist to disk to load the next time the same client activates a session.
static class Session.PersistentData
          This is DAO class used to persist session data to disk.
 
Field Summary
 String id
          Unique id for the session - used to connect browser/client to this session
 
Method Summary
static Session.Key classScope(Class scope, String key, Class valueClass, Session.Lifetime lifetime)
          Retrieve key for class scope data - to be kept in private static final in using class.
 void close()
          Close the session - closing closeable objects and persisting persistent ones.
static void closeAllSessions()
          When a user exits (as in a server closing), this must be called to persist relevant session data.
 void commit()
          Commit persistent data if it has changed.
static Session create()
          Create a new session.
static Session current()
          Get the current session based on the thread name.
static Session current(String sessionID)
          Get a session given a string key provided by the browser.
 Object get(Session.Key key)
          Retrieve a session data object.
 Object get(Session.Key key, Object defaultValue)
          Retrieve a value from the session.
static Session.Key globalScope(String key, Class valueClass, Session.Lifetime lifetime)
          Retrieve key for package scope data - to be kept in private static final in using class.
static Session.Key packageScope(Class scope, String key, Class valueClass, Session.Lifetime lifetime)
          Retrieve key for package scope data - to be kept in private static final in using class.
 void put(Session.Key key, Object item)
          Enter a general object.
 void remove(Session.Key key)
          Remove the object from the store.
 void setTimeout(int minutes)
          Change from the default timeout when a session closes.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

id

public String id
Unique id for the session - used to connect browser/client to this session

Method Detail

create

public static Session create()
Create a new session. Only called if system does not have a persistent session cookie. Basically generates a unique key then uses get() to prepare it.

Returns:
new session with unique name
See Also:
current()

current

public static Session current(String sessionID)
Get a session given a string key provided by the browser. The session may not exist in memory if the browser has kept the key from a previous run or a different server.

Parameters:
sessionID - predefined session name.
Returns:
active session if there is one - otherwise create one.

current

public static Session current()
Get the current session based on the thread name.

Returns:
The current sessions stored in the thread name.

setTimeout

public void setTimeout(int minutes)
Change from the default timeout when a session closes.

Parameters:
minutes - of inactivity after which this session is discarded.

close

public void close()
Close the session - closing closeable objects and persisting persistent ones.

Specified by:
close in interface Closeable
See Also:
Closeable.close()

closeAllSessions

public static void closeAllSessions()
When a user exits (as in a server closing), this must be called to persist relevant session data.


get

public Object get(Session.Key key)
Retrieve a session data object. Looks in all 3 maps.

Parameters:
key - - to find in in the data map. It is advisable to cache it as a static value of the calling class since xxx.class is (surprisingly) a non-trivial library operation using Class.forName (at least using the Sun 1.4 JVM).
Returns:
the value for this key or null if the key does not exist.

get

public Object get(Session.Key key,
                  Object defaultValue)
Retrieve a value from the session. If it does not exists, return a provided default.

Parameters:
key - used to find the value.
defaultValue - default value to use if the item does not exist in the session cache.
Returns:
object related to the key - or default object if none found.

put

public void put(Session.Key key,
                Object item)
Enter a general object. When the session ends the item is discarded silently. Use a value with a Closeable interface if you want to be told when the item is finished with.

Parameters:
key -
item -

remove

public void remove(Session.Key key)
Remove the object from the store.

Parameters:
key -

commit

public void commit()
Commit persistent data if it has changed.


classScope

public static Session.Key classScope(Class scope,
                                     String key,
                                     Class valueClass,
                                     Session.Lifetime lifetime)
Retrieve key for class scope data - to be kept in private static final in using class.
 public class Panel extends Page
   {
      private static final Session.Key panelCacheKey =
        Session.classScope( Panel.class, "data", HashMap.class, true);
   }
 

Parameters:
scope - - Class used to define scope for this data.
key - that defines data uniquely within scope.
valueClass - Class used to create new instances for values.
lifetime - - Session.persistentLifetime to save to disk between sessions or Session.transientLifetime to be discarded when session closes.
Returns:
Key instance used to create, retrieve and save session data instances.

packageScope

public static Session.Key packageScope(Class scope,
                                       String key,
                                       Class valueClass,
                                       Session.Lifetime lifetime)
Retrieve key for package scope data - to be kept in private static final in using class.
 public class Panel extends Page
   {
      private static final Session.Key panelCacheKey =
        Session.packageScope( Panel.class, "data", HashMap.class, false);
   }
 

Parameters:
scope - - Class used to define scope for this data.
key - that defines data uniquely within scope.
valueClass - Class used to create new instances for values.
lifetime - - Session.persistentLifetime to save to disk between sessions or Session.transientLifetime to be discarded when session closes.
Returns:
Key instance used to create, retrieve and save session data instances.

globalScope

public static Session.Key globalScope(String key,
                                      Class valueClass,
                                      Session.Lifetime lifetime)
Retrieve key for package scope data - to be kept in private static final in using class.
 public class Panel extends Page
   {
      private static final Session.Key panelCacheKey =
        Session.globalScope( "Panel.data", HashMap.class, true);
   }
 

Parameters:
key - that defines data uniquely within scope.
valueClass - Class used to create new instances for values. Use null or Closeable for no creation. The latter allows it to be closeable.
lifetime - - Session.persistentLifetime to save to disk between sessions or Session.transientLifetime to be discarded when session closes.
Returns:
Key instance used to create, retrieve and save session data instances.


Copyright © 2005 Paul Marrington http://library.marringtons.com