001: /*
002: * SessionManager.java
003: *
004: * Brazil project web application Framework,
005: * export version: 1.1
006: * Copyright (c) 1998-2000 Sun Microsystems, Inc.
007: *
008: * Sun Public License Notice
009: *
010: * The contents of this file are subject to the Sun Public License Version
011: * 1.0 (the "License"). You may not use this file except in compliance with
012: * the License. A copy of the License is included as the file "license.terms",
013: * and also available at http://www.sun.com/
014: *
015: * The Original Code is from:
016: * Brazil project web application Framework release 1.1.
017: * The Initial Developer of the Original Code is: suhler.
018: * Portions created by suhler are Copyright (C) Sun Microsystems, Inc.
019: * All Rights Reserved.
020: *
021: * Contributor(s): cstevens, rinaldo, suhler.
022: *
023: * Version: 1.12
024: * Created by suhler on 98/09/14
025: * Last modified by suhler on 00/12/08 16:47:54
026: */
027:
028: package sunlabs.brazil.session;
029:
030: import java.util.Hashtable;
031:
032: /**
033: * The <code>SessionManager</code> associates an object with a Session ID
034: * to give Handlers the ability to maintain state that lasts for the
035: * duration of a session instead of just for the duration of a request.
036: * <p>
037: * An example of session-lifetime information is the set of stocks that
038: * a particular user is interested in. When the hypothetical
039: * <code>StockHandler</code> gets a request, it would get determine which
040: * stocks to display based on the Session ID of the request.
041: * <p>
042: * Operating with the <code>SessionManager</code> is the mechanism to
043: * discover the Session ID of a request and/or create new Session IDs.
044: * For example, the first time a user goes to the server providing the stock
045: * market information, they could get a cookie. Subsequently, every time
046: * they visit the stock market page the cookie present in the request
047: * would be decoded and matched with the existing Session ID for use by
048: * the <code>StockHandler</code>.
049: * <p>
050: * The <code>SessionManager</code> operates as a bag of globally
051: * accessible resources. Existing subclasses of the
052: * <code>SessionManager</code> also provide persistence, that is, a way to
053: * recover these resources even if the server process is terminated and
054: * later restarted, to get back to the state things were in.
055: *
056: * @author Stephen Uhler (stephen.uhler@sun.com)
057: * @author Colin Stevens (colin.stevens@sun.com)
058: * @version 1.12, 00/12/08
059: */
060:
061: public class SessionManager {
062: private static SessionManager sm = new SessionManager();
063:
064: /**
065: * Installs the given <code>SessionManager</code> object as the
066: * default session manager to be invoked when <code>getSession</code>
067: * is called.
068: *
069: * @param mgr
070: * The <code>SessionManager</code> object.
071: */
072: public static void setSessionManager(SessionManager mgr) {
073: sm = mgr;
074: }
075:
076: /**
077: * Returns the object associated with the given Session ID. Passing in
078: * the same (hash-key equivalent) Session ID will return the same object.
079: * <p>
080: * This static method will dispatch to the currently installed
081: * <code>SessionManager</code> instance.
082: *
083: * @param session
084: * The Session ID for the persistent session information. If
085: * the session does not exist, a new one is created.
086: * May be <code>null</code> to get information
087: * not associated with a particular Session ID, but that some
088: * <code>Handler</code> wants to make persistent anyhow.
089: *
090: * @param ident
091: * An arbitray identifier used to determine which object
092: * (associated with the given <code>session</code>) the caller
093: * wants. May be <code>null</code> to return the
094: * <code>Hashtable</code> that contains all the objects
095: * associated with the given Session ID.
096: *
097: * @param type
098: * The Class of the object to create. If the given
099: * <code>session</code> and <code>ident</code> did not specify
100: * an existing object, a new one is created by calling
101: * <code>newInstance</code> based on the <code>type</code>.
102: * If <code>null</code>, then this method returns
103: * <code>null</code> if the object didn't exist, instead of
104: * allocating a new object.
105: *
106: * @return The return value depends upon <code>session</code>,
107: * <code>ident</code> and <code>type</code> as follows:
108: * <table border=1>
109: * <tr><th>session <th>ident <th>type <th>result
110: * <tr><td>exists <td>exists <td>--
111: * <td>Returns existing object. <code>type</code> is ignored.
112: * <tr><td>exists <td>doesn't exist <td>class
113: * <td>Returns <code>newInstance</code> of class.
114: * <tr><td>exists <td>doesn't exist <td><code>null</code>
115: * <td>Returns <code>null</code>.
116: * <tr><td>exists <td>null <td>--
117: * <td>Returns <code>Hashtable</code> of all objects for
118: * given session.
119: * <tr><td>doesn't exist <td>specified <td>--
120: * <td>Creates a new session
121: * <tr><td>doesn't exist <td>null <td>--
122: * <td>Returns <code>null</code>.
123: * <tr><td><code>null</code> <td>-- <td>--
124: * <td>As above, but information is about the "no-session".
125: * </table>
126: */
127:
128: public static Object getSession(Object session, Object ident,
129: Class type) {
130: return sm.getSessionObject(session, ident, type);
131: }
132:
133: /**
134: * A <code>Hashtable</code> used when mapping Session IDs to objects.
135: * Keys are <code>session</code> objects. Values are another
136: * <code>Hashtable</code> (hashtable B).
137: * <p>
138: * Each key in hashtable B is the <code>ident</code> and each value is the
139: * persistent object returned by <code>getSession</code>. Also,
140: * hashtable B is the object that is returned by <code>getSession</code>
141: * if the <code>ident</code> is <code>null</code>.
142: */
143: protected Hashtable sessions = new Hashtable();
144:
145: /**
146: * Returns the object associated with the given Session ID and ident.
147: * This is the instance method that is invoked by the static method
148: * <code>SessionManager.getSession</code>. Implementors of Session
149: * Managers provide one of these. Users call {@link #getSession}.
150: */
151: public Object getSessionObject(Object session, Object ident,
152: Class type) {
153: if (session == null) {
154: session = this .getClass();
155: }
156: Hashtable h = (Hashtable) sessions.get(session);
157: if (ident == null) {
158: return h;
159: }
160: if (h == null) {
161: h = new Hashtable();
162: sessions.put(session, h);
163: }
164:
165: Object obj = h.get(ident);
166: if (obj != null) {
167: return obj;
168: } else if (type == null) {
169: return null;
170: } else {
171: try {
172: obj = type.newInstance();
173: } catch (Exception e) {
174: throw new IllegalArgumentException(type.getName());
175: }
176: h.put(ident, obj);
177: return obj;
178: }
179: }
180: }
|