tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From craig...@locus.apache.org
Subject cvs commit: jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session Constants.java FileStore.java ManagerBase.java StandardManager.java StandardSession.java LocalStrings.properties
Date Thu, 20 Jan 2000 06:37:30 GMT
craigmcc    00/01/19 22:37:30

  Added:       proposals/catalina/src/share/org/apache/tomcat/session
                        Constants.java FileStore.java ManagerBase.java
                        StandardManager.java StandardSession.java
                        LocalStrings.properties
  Log:
  Check-in of basic Session and Manager component implementations
  for the "Catalina" proposal.
  
  Revision  Changes    Path
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/Constants.java
  
  Index: Constants.java
  ===================================================================
  /*
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  
  package org.apache.tomcat.session;
  
  /**
   * Manifest constants for the <code>org.apache.tomcat.session</code>
   * package.
   *
   * @author Craig R. McClanahan
   */
  
  public class Constants {
  
      public static final String Package = "org.apache.tomcat.session";
  
      public static final String SESSION_COOKIE_NAME = "JSESSIONID";
      public static final String SESSION_PARAMETER_NAME = "jsessionid";
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/FileStore.java
  
  Index: FileStore.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/FileStore.java,v 1.1 2000/01/20 06:37:30 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/01/20 06:37:30 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  
  package org.apache.tomcat.session;
  
  
  import java.io.BufferedInputStream;
  import java.io.BufferedOutputStream;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.Serializable;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import org.apache.tomcat.Lifecycle;
  import org.apache.tomcat.LifecycleException;
  import org.apache.tomcat.Session;
  import org.apache.tomcat.Store;
  import org.apache.tomcat.util.StringManager;
  import org.w3c.dom.NamedNodeMap;
  import org.w3c.dom.Node;
  
  
  /**
   * Concrete implementation of the <b>Store</b> interface that utilizes
   * a file per saved Session in a configured directory.  Sessions that are
   * saved are still subject to being expired based on inactivity.
   * <p>
   * Lifecycle configuration of this component assumes an XML node
   * in the following format:
   * <code>
   *     &lt;Store className="org.apache.tomcat.session.FileStore"
   *            checkInterval="60" directoryPath="./STORE" />
   * </code>
   * where you can adjust the following parameters, with default values
   * in square brackets:
   * <ul>
   * <li><b>checkInterval</b> - The interval (in seconds) between background
   *     thread checks for expired sessions.  [60]
   * <li><b>directoryPath</b> - Pathname of the directory in which saved
   *     Sessions are stored.  [./STORE]
   * </ul>
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/01/20 06:37:30 $
   */
  
  public final class FileStore
      implements Lifecycle, Runnable, Store {
  
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The interval (in seconds) between checks for expired sessions.
       */
      private int checkInterval = 60;
  
  
      /**
       * Has this component been configured yet?
       */
      private boolean configured = false;
  
  
      /**
       * The pathname of the directory in which Sessions are stored.
       */
      private String directoryPath = "./STORE";
  
  
      /**
       * The descriptive information about this implementation.
       */
      private static final String info = "FileStore/1.0";
  
  
      /**
       * The string manager for this package.
       */
      private StringManager sm =
  	StringManager.getManager(Constants.Package);
  
  
      /**
       * Has this component been started yet?
       */
      private boolean started = false;
  
  
      /**
       * The background thread.
       */
      private Thread thread = null;
  
  
      /**
       * The background thread completion semaphore.
       */
      private boolean threadDone = false;
  
  
      /**
       * Name to register for the background thread.
       */
      private String threadName = "FileStore";
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the check interval (in seconds) for this Manager.
       */
      public int getCheckInterval() {
  
  	return (this.checkInterval);
  
      }
  
  
      /**
       * Set the check interval (in seconds) for this Manager.
       *
       * @param checkInterval The new check interval
       */
      public void setCheckInterval(int checkInterval) {
  
  	this.checkInterval = checkInterval;
  
      }
  
  
      /**
       * Return the directory path for this Store.
       */
      public String getDirectoryPath() {
  
  	return (directoryPath);
  
      }
  
  
      /**
       * Set the directory path for this Store.
       *
       * @param path The new directory path
       */
      public void setDirectoryPath(String path) {
  
  	this.directoryPath = path;
  
      }
  
  
      /**
       * Return the number of Sessions present in this Store.
       *
       * @exception IOException if an input/output error occurs
       */
      public int getSize() throws IOException {
  
  	return (0);	// FIXME: getSize()
  
      }
  
  
      /**
       * Return descriptive information about this Store implementation and
       * the corresponding version number, in the format
       * <code>&lt;description&gt;/&lt;version&gt;</code>.
       */
      public String getInfo() {
  
  	return (info);
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Return an array containing the session identifiers of all Sessions
       * currently saved in this Store.  If there are no such Sessions, a
       * zero-length array is returned.
       *
       * @exception IOException if an input/output error occurred
       */
      public String[] keys() throws IOException {
  
  	return (new String[0]);	// FIXME: keys()
  
      }
  
  
      /**
       * Load and return the Session associated with the specified session
       * identifier from this Store, without removing it.  If there is no
       * such stored Session, return <code>null</code>.
       *
       * @param id Session identifier of the session to load
       *
       * @exception ClassNotFoundException if a deserialization error occurs
       * @exception IOException if an input/output error occurs
       */
      public Session load(String id)
          throws ClassNotFoundException, IOException {
  
  	return (null);	// FIXME: load()
  
      }
  
  
      /**
       * Remove the Session with the specified session identifier from
       * this Store, if present.  If no such Session is present, this method
       * takes no action.
       *
       * @param id Session identifier of the Session to be removed
       *
       * @exception IOException if an input/output error occurs
       */
      public void remove(String id) throws IOException {
  
  	;	// FIXME: remove()
  
      }
  
  
      /**
       * Save the specified Session into this Store.  Any previously saved
       * information for the associated session identifier is replaced.
       *
       * @param session Session to be saved
       *
       * @exception IOException if an input/output error occurs
       */
      public void save(Session session) throws IOException {
  
  	;	// FIXME: save()
  
      }
  
  
      // ------------------------------------------------------ Lifecycle Methods
  
  
      /**
       * Configure this component, based on the specified configuration
       * parameters.  This method should be called immediately after the
       * component instance is created, and before <code>start()</code>
       * is called.
       *
       * @param parameters Configuration parameters for this component
       *  (<B>FIXME: What object type should this really be?)
       *
       * @exception IllegalStateException if this component has already been
       *  configured and/or started
       * @exception LifecycleException if this component detects a fatal error
       *  in the configuration parameters it was given
       */
      public void configure(Node parameters)
  	throws LifecycleException {
  
  	// Validate and update our current component state
  	if (configured)
  	    throw new LifecycleException
  		(sm.getString("fileStore.alreadyConfigured"));
  	configured = true;
  	if (parameters == null)
  	    return;
  
  	// Parse and process our configuration parameters
  	if (!("Store".equals(parameters.getNodeName())))
  	    return;
  	NamedNodeMap attributes = parameters.getAttributes();
  	Node node = null;
  
  	node = attributes.getNamedItem("checkInterval");
  	if (node != null) {
  	    try {
  		setCheckInterval(Integer.parseInt(node.getNodeValue()));
  	    } catch (Throwable t) {
  		;	// XXX - Throw exception?
  	    }
  	}
  
  	node = attributes.getNamedItem("directoryPath");
  	if (node != null) {
  	    try {
  		setDirectoryPath(node.getNodeValue());
  	    } catch (Throwable t) {
  		;	// XXX - Throw exception?
  	    }
  	}
  
      }
  
  
      /**
       * Prepare for the beginning of active use of the public methods of this
       * component.  This method should be called after <code>configure()</code>,
       * and before any of the public methods of the component are utilized.
       *
       * @exception IllegalStateException if this component has not yet been
       *  configured (if required for this component)
       * @exception IllegalStateException if this component has already been
       *  started
       * @exception LifecycleException if this component detects a fatal error
       *  that prevents this component from being used
       */
      public void start() throws LifecycleException {
  
  	// Validate and update our current component state
  	if (!configured)
  	    throw new LifecycleException
  		(sm.getString("fileStore.notConfigured"));
  	if (started)
  	    throw new LifecycleException
  		(sm.getString("fileStore.alreadyStarted"));
  	started = true;
  
  	// Start the background reaper thread
  	threadStart();
  
      }
  
  
      /**
       * Gracefully terminate the active use of the public methods of this
       * component.  This method should be the last one called on a given
       * instance of this component.
       *
       * @exception IllegalStateException if this component has not been started
       * @exception IllegalStateException if this component has already
       *  been stopped
       * @exception LifecycleException if this component detects a fatal error
       *  that needs to be reported
       */
      public void stop() throws LifecycleException {
  
  	// Validate and update our current component state
  	if (!started)
  	    throw new LifecycleException
  		(sm.getString("fileStore.notStarted"));
  	started = false;
  
  	// Stop the background reaper thread
  	threadStop();
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
      /**
       * Invalidate all sessions that have expired.
       */
      private void processExpires() {
  
  	long timeNow = System.currentTimeMillis();
  	/*
  	Session sessions[] = findSessions();
  
  	for (int i = 0; i < sessions.length; i++) {
  	    StandardSession session = (StandardSession) sessions[i];
  	    if (!session.isValid())
  		continue;
  	    int maxInactiveInterval = session.getMaxInactiveInterval();
  	    if (maxInactiveInterval < 0)
  		continue;
  	    int timeIdle = // Truncate, do not round up
  		(int) ((timeNow - session.getLastAccessedTime()) / 1000L);
  	    if (timeIdle >= maxInactiveInterval)
  		session.expire();
  	}
  	*/
  
      }
  
  
      /**
       * Sleep for the duration specified by the <code>checkInterval</code>
       * property.
       */
      private void threadSleep() {
  
  	try {
  	    Thread.sleep(checkInterval * 1000L);
  	} catch (InterruptedException e) {
  	    ;
  	}
  
      }
  
  
      /**
       * Start the background thread that will periodically check for
       * session timeouts.
       */
      private void threadStart() {
  
  	if (thread != null)
  	    return;
  
  	threadDone = false;
  	thread = new Thread(this, threadName);
  	thread.setDaemon(true);
  	thread.start();
  
      }
  
  
      /**
       * Stop the background thread that is periodically checking for
       * session timeouts.
       */
      private void threadStop() {
  
  	if (thread == null)
  	    return;
  
  	threadDone = true;
  	thread.interrupt();
  	try {
  	    thread.join();
  	} catch (InterruptedException e) {
  	    ;
  	}
  
  	thread = null;
  
      }
  
  
      // ------------------------------------------------------ Background Thread
  
  
      /**
       * The background thread that checks for session timeouts and shutdown.
       */
      public void run() {
  
  	// Loop until the termination semaphore is set
  	while (!threadDone) {
  	    threadSleep();
  	    processExpires();
  	}
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/ManagerBase.java
  
  Index: ManagerBase.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/ManagerBase.java,v 1.1 2000/01/20 06:37:30 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/01/20 06:37:30 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  
  package org.apache.tomcat.session;
  
  
  import java.io.IOException;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import javax.servlet.http.Cookie;
  import javax.servlet.http.HttpSession;
  import org.apache.tomcat.Container;
  import org.apache.tomcat.Manager;
  import org.apache.tomcat.Request;
  import org.apache.tomcat.Session;
  import org.apache.tomcat.util.SessionUtil;
  
  
  /**
   * Minimal implementation of the <b>Manager</b> interface that supports
   * no session persistence or distributable capabilities.  This class may
   * be subclassed to create more sophisticated Manager implementations.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/01/20 06:37:30 $
   */
  
  public abstract class ManagerBase implements Manager {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The Container with which this Manager is associated.
       */
      protected Container container;
  
  
      /**
       * The distributable flag for Sessions created by this Manager.  If this
       * flag is set to <code>true</code>, any user attributes added to a
       * session controlled by this Manager must be Serializable.
       */
      protected boolean distributable;
  
  
      /**
       * The descriptive information string for this implementation.
       */
      private static final String info = "ManagerBase/1.0";
  
  
      /**
       * The default maximum inactive interval for Sessions created by
       * this Manager.
       */
      protected int maxInactiveInterval = 60;
  
  
      /**
       * The set of previously recycled Sessions for this Manager.
       */
      protected Vector recycled = new Vector();
  
  
      /**
       * The set of currently active Sessions for this Manager, keyed by
       * session identifier.
       */
      protected Hashtable sessions = new Hashtable();
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the Container with which this Manager is associated.
       */
      public Container getContainer() {
  
  	return (this.container);
  
      }
  
  
      /**
       * Set the Container with which this Manager is associated.
       *
       * @param container The newly associated Container
       */
      public void setContainer(Container container) {
  
  	this.container = container;
  
      }
  
  
      /**
       * Return the distributable flag for the sessions supported by
       * this Manager.
       */
      public boolean getDistributable() {
  
  	return (this.distributable);
  
      }
  
  
      /**
       * Set the distributable flag for the sessions supported by this
       * Manager.  If this flag is set, all user data objects added to
       * sessions associated with this manager must implement Serializable.
       *
       * @param distributable The new distributable flag
       */
      public void setDistributable(boolean distributable) {
  
  	this.distributable = distributable;
  
      }
  
  
      /**
       * Return descriptive information about this Manager implementation and
       * the corresponding version number, in the format
       * <code>&lt;description&gt;/&lt;version&gt;</code>.
       */
      public String getInfo() {
  
  	return (this.info);
  
      }
  
  
      /**
       * Return the default maximum inactive interval (in seconds)
       * for Sessions created by this Manager.
       */
      public int getMaxInactiveInterval() {
  
  	return (this.maxInactiveInterval);
  
      }
  
  
      /**
       * Set the default maximum inactive interval (in seconds)
       * for Sessions created by this Manager.
       *
       * @param interval The new default value
       */
      public void setMaxInactiveInterval(int interval) {
  
  	this.maxInactiveInterval = interval;
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Construct and return a new session object, based on the default
       * settings specified by this Manager's properties.  The session
       * id will be assigned by this method, and available via the getId()
       * method of the returned session.  If a new session cannot be created
       * for any reason, return <code>null</code>.
       *
       * @exception IllegalStateException if a new session cannot be
       *  instantiated for any reason
       */
      public Session createSession() {
  
  	// Recycle or create a Session instance
  	StandardSession session = null;
  	synchronized (recycled) {
  	    int size = recycled.size();
  	    if (size > 0) {
  		session = (StandardSession) recycled.elementAt(size - 1);
  		recycled.removeElementAt(size - 1);
  	    }
  	}
  	if (session == null)
  	    session = new StandardSession(this);
  
  	// Initialize the properties of the new session and return it
  	session.setNew(true);
  	session.setValid(true);
  	session.setCreationTime(System.currentTimeMillis());
  	session.setMaxInactiveInterval(this.maxInactiveInterval);
  	session.setId(SessionUtil.generateSessionId());
  
  	return (session);
  
      }
  
  
      /**
       * Return the active Session, associated with this Manager, with the
       * specified session id (if any); otherwise return <code>null</code>.
       *
       * @param id The session id for the session to be returned
       *
       * @exception ClassNotFoundException if a deserialization error occurs
       *  while processing this request
       * @exception IllegalStateException if a new session cannot be
       *  instantiated for any reason
       * @exception IOException if an input/output error occurs while
       *  processing this request
       */
      public Session findSession(String id) throws IOException {
  
  	if (id == null)
  	    return (null);
  	return ((Session) sessions.get(id));
  
      }
  
  
      /**
       * Return the set of active Sessions associated with this Manager.
       * If this Manager has no active Sessions, a zero-length array is returned.
       */
      public Session[] findSessions() {
  
  	synchronized (sessions) {
  	    Vector keys = new Vector();
  	    Enumeration ids = sessions.keys();
  	    while (ids.hasMoreElements()) {
  		String id = (String) ids.nextElement();
  		keys.addElement(id);
  	    }
  	    Session results[] = new Session[keys.size()];
  	    for (int i = 0; i < results.length; i++) {
  		String key = (String) keys.elementAt(i);
  		results[i] = (Session) sessions.get(key);
  	    }
  	    return (results);
  	}
  
      }
  
  
      // -------------------------------------------------------- Package Methods
  
  
      /**
       * Add this Session to the set of active Sessions for this Manager.
       *
       * @param session Session to be added
       */
      void add(StandardSession session) {
  
  	sessions.put(session.getId(), session);
  
      }
  
  
      /**
       * Add this Session to the recycle collection for this Manager.
       *
       * @param session Session to be recycled
       */
      void recycle(StandardSession session) {
  
  	recycled.addElement(session);
  
      }
  
  
      /**
       * Remove this Session from the active Sessions for this Manager.
       *
       * @param session Session to be removed
       */
      void remove(StandardSession session) {
  
  	sessions.remove(session.getId());
  
      }
  
  
  }
  
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/StandardManager.java
  
  Index: StandardManager.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/StandardManager.java,v 1.1 2000/01/20 06:37:30 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/01/20 06:37:30 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  
  package org.apache.tomcat.session;
  
  import java.io.IOException;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import javax.servlet.http.Cookie;
  import javax.servlet.http.HttpSession;
  import org.apache.tomcat.Lifecycle;
  import org.apache.tomcat.LifecycleException;
  import org.apache.tomcat.Manager;
  import org.apache.tomcat.Request;
  import org.apache.tomcat.Session;
  import org.apache.tomcat.util.StringManager;
  import org.w3c.dom.NamedNodeMap;
  import org.w3c.dom.Node;
  
  
  /**
   * Standard implementation of the <b>Manager</b> interface that provides
   * no session persistence or distributable capabilities, but does support
   * an optional, configurable, maximum number of active sessions allowed.
   * <p>
   * Lifecycle configuration of this component assumes an XML node
   * in the following format:
   * <code>
   *     &lt;Manager className="org.apache.tomcat.session.StandardManager"
   *              checkInterval="60" maxActiveSessions="-1"
   *              maxInactiveInterval="-1" />
   * </code>
   * where you can adjust the following parameters, with default values
   * in square brackets:
   * <ul>
   * <li><b>checkInterval</b> - The interval (in seconds) between background
   *     thread checks for expired sessions.  [60]
   * <li><b>maxActiveSessions</b> - The maximum number of sessions allowed to
   *     be active at once, or -1 for no limit.  [-1]
   * <li><b>maxInactiveInterval</b> - The default maximum number of seconds of
   *     inactivity before which the servlet container is allowed to time out
   *     a session, or -1 for no limit.  This value should be overridden from
   *     the default session timeout specified in the web application deployment
   *     descriptor, if any.  [-1]
   * </ul>
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/01/20 06:37:30 $
   */
  
  public final class StandardManager
      extends ManagerBase
      implements Lifecycle, Runnable {
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The interval (in seconds) between checks for expired sessions.
       */
      private int checkInterval = 60;
  
  
      /**
       * Has this component been configured yet?
       */
      private boolean configured = false;
  
  
      /**
       * The descriptive information about this implementation.
       */
      private static final String info = "StandardManager/1.0";
  
  
      /**
       * The maximum number of active Sessions allowed, or -1 for no limit.
       */
      protected int maxActiveSessions = -1;
  
  
      /**
       * The string manager for this package.
       */
      private StringManager sm =
          StringManager.getManager(Constants.Package);
  
  
      /**
       * Has this component been started yet?
       */
      private boolean started = false;
  
  
      /**
       * The background thread.
       */
      private Thread thread = null;
  
  
      /**
       * The background thread completion semaphore.
       */
      private boolean threadDone = false;
  
  
      /**
       * Name to register for the background thread.
       */
      private String threadName = "StandardManager";
  
  
      // ------------------------------------------------------------- Properties
  
  
      /**
       * Return the check interval (in seconds) for this Manager.
       */
      public int getCheckInterval() {
  
  	return (this.checkInterval);
  
      }
  
  
      /**
       * Set the check interval (in seconds) for this Manager.
       *
       * @param checkInterval The new check interval
       */
      public void setCheckInterval(int checkInterval) {
  
  	this.checkInterval = checkInterval;
  
      }
  
  
      /**
       * Return descriptive information about this Manager implementation and
       * the corresponding version number, in the format
       * <code>&lt;description&gt;/&lt;version&gt;</code>.
       */
      public String getInfo() {
  
  	return (this.info);
  
      }
  
  
      /**
       * Return the maximum number of active Sessions allowed, or -1 for
       * no limit.
       */
      public int getMaxActiveSessions() {
  
  	return (this.maxActiveSessions);
  
      }
  
  
      /**
       * Set the maximum number of actives Sessions allowed, or -1 for
       * no limit.
       *
       * @param max The new maximum number of sessions
       */
      public void setMaxActiveSessions(int max) {
  
  	this.maxActiveSessions = max;
  
      }
  
  
      // --------------------------------------------------------- Public Methods
  
  
      /**
       * Construct and return a new session object, based on the default
       * settings specified by this Manager's properties.  The session
       * id will be assigned by this method, and available via the getId()
       * method of the returned session.  If a new session cannot be created
       * for any reason, return <code>null</code>.
       *
       * @exception IllegalStateException if a new session cannot be
       *  instantiated for any reason
       */
      public Session createSession() {
  
  	if ((maxActiveSessions >= 0) &&
  	  (sessions.size() >= maxActiveSessions))
  	    throw new IllegalStateException
  		(sm.getString("standardManager.createSession.ise"));
  
  	return (super.createSession());
  
      }
  
  
      // ------------------------------------------------------ Lifecycle Methods
  
  
      /**
       * Configure this component, based on the specified configuration
       * parameters.  This method should be called immediately after the
       * component instance is created, and before <code>start()</code>
       * is called.
       *
       * @param parameters Configuration parameters for this component
       *  (<B>FIXME: What object type should this really be?)
       *
       * @exception IllegalStateException if this component has already been
       *  configured and/or started
       * @exception LifecycleException if this component detects a fatal error
       *  in the configuration parameters it was given
       */
      public void configure(Node parameters)
  	throws LifecycleException {
  
  	// Validate and update our current component state
  	if (configured)
  	    throw new LifecycleException
  		(sm.getString("standardManager.alreadyConfigured"));
  	configured = true;
  	if (parameters == null)
  	    return;
  
  	// Parse and process our configuration parameters
  	if (!("Manager".equals(parameters.getNodeName())))
  	    return;
  	NamedNodeMap attributes = parameters.getAttributes();
  	Node node = null;
  
  	node = attributes.getNamedItem("checkInterval");
  	if (node != null) {
  	    try {
  		setCheckInterval(Integer.parseInt(node.getNodeValue()));
  	    } catch (Throwable t) {
  		;	// XXX - Throw exception?
  	    }
  	}
  
  	node = attributes.getNamedItem("maxActiveSessions");
  	if (node != null) {
  	    try {
  		setMaxActiveSessions(Integer.parseInt(node.getNodeValue()));
  	    } catch (Throwable t) {
  		;	// XXX - Throw exception?
  	    }
  	}
  
  	node = attributes.getNamedItem("maxInactiveInterval");
  	if (node != null) {
  	    try {
  		setMaxInactiveInterval(Integer.parseInt(node.getNodeValue()));
  	    } catch (Throwable t) {
  		;	// XXX - Throw exception?
  	    }
  	}
  
      }
  
  
      /**
       * Prepare for the beginning of active use of the public methods of this
       * component.  This method should be called after <code>configure()</code>,
       * and before any of the public methods of the component are utilized.
       *
       * @exception IllegalStateException if this component has not yet been
       *  configured (if required for this component)
       * @exception IllegalStateException if this component has already been
       *  started
       * @exception LifecycleException if this component detects a fatal error
       *  that prevents this component from being used
       */
      public void start() throws LifecycleException {
  
  	// Validate and update our current component state
  	if (!configured)
  	    throw new LifecycleException
  		(sm.getString("standardManager.notConfigured"));
  	if (started)
  	    throw new LifecycleException
  		(sm.getString("standardManager.alreadyStarted"));
  	started = true;
  
  	// Start the background reaper thread
  	threadStart();
  
      }
  
  
      /**
       * Gracefully terminate the active use of the public methods of this
       * component.  This method should be the last one called on a given
       * instance of this component.
       *
       * @exception IllegalStateException if this component has not been started
       * @exception IllegalStateException if this component has already
       *  been stopped
       * @exception LifecycleException if this component detects a fatal error
       *  that needs to be reported
       */
      public void stop() throws LifecycleException {
  
  	// Validate and update our current component state
  	if (!started)
  	    throw new LifecycleException
  		(sm.getString("standardManager.notStarted"));
  	started = false;
  
  	// Stop the background reaper thread
  	threadStop();
  
  	// Expire all active sessions
  	Session sessions[] = findSessions();
  	for (int i = 0; i < sessions.length; i++) {
  	    StandardSession session = (StandardSession) sessions[i];
  	    if (!session.isValid())
  		continue;
  	    session.expire();
  	}
  
      }
  
  
      // -------------------------------------------------------- Private Methods
  
  
      /**
       * Invalidate all sessions that have expired.
       */
      private void processExpires() {
  
  	long timeNow = System.currentTimeMillis();
  	Session sessions[] = findSessions();
  
  	for (int i = 0; i < sessions.length; i++) {
  	    StandardSession session = (StandardSession) sessions[i];
  	    if (!session.isValid())
  		continue;
  	    int maxInactiveInterval = session.getMaxInactiveInterval();
  	    if (maxInactiveInterval < 0)
  		continue;
  	    int timeIdle = // Truncate, do not round up
  		(int) ((timeNow - session.getLastAccessedTime()) / 1000L);
  	    if (timeIdle >= maxInactiveInterval)
  		session.expire();
  	}
      }
  
  
      /**
       * Sleep for the duration specified by the <code>checkInterval</code>
       * property.
       */
      private void threadSleep() {
  
  	try {
  	    Thread.sleep(checkInterval * 1000L);
  	} catch (InterruptedException e) {
  	    ;
  	}
  
      }
  
  
      /**
       * Start the background thread that will periodically check for
       * session timeouts.
       */
      private void threadStart() {
  
  	if (thread != null)
  	    return;
  
  	threadDone = false;
  	thread = new Thread(this, threadName);
  	thread.setDaemon(true);
  	thread.start();
  
      }
  
  
      /**
       * Stop the background thread that is periodically checking for
       * session timeouts.
       */
      private void threadStop() {
  
  	if (thread == null)
  	    return;
  
  	threadDone = true;
  	thread.interrupt();
  	try {
  	    thread.join();
  	} catch (InterruptedException e) {
  	    ;
  	}
  
  	thread = null;
  
      }
  
  
      // ------------------------------------------------------ Background Thread
  
  
      /**
       * The background thread that checks for session timeouts and shutdown.
       */
      public void run() {
  
  	// Loop until the termination semaphore is set
  	while (!threadDone) {
  	    threadSleep();
  	    processExpires();
  	}
  
      }
  
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/StandardSession.java
  
  Index: StandardSession.java
  ===================================================================
  /*
   * $Header: /home/cvs/jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/StandardSession.java,v 1.1 2000/01/20 06:37:30 craigmcc Exp $
   * $Revision: 1.1 $
   * $Date: 2000/01/20 06:37:30 $
   *
   * ====================================================================
   *
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999 The Apache Software Foundation.  All rights 
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer. 
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution, if
   *    any, must include the following acknowlegement:  
   *       "This product includes software developed by the 
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written 
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * [Additional notices, if required by prior licensing conditions]
   *
   */ 
  
  
  package org.apache.tomcat.session;
  
  
  import java.io.IOException;
  import java.io.ObjectInputStream;
  import java.io.ObjectOutputStream;
  import java.io.Serializable;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import javax.servlet.ServletException;
  import javax.servlet.http.HttpSession;
  import javax.servlet.http.HttpSessionBindingEvent;
  import javax.servlet.http.HttpSessionBindingListener;
  import javax.servlet.http.HttpSessionContext;
  import org.apache.tomcat.Manager;
  import org.apache.tomcat.Session;
  import org.apache.tomcat.util.StringManager;
  
  
  /**
   * Standard implementation of the <b>Session</b> interface.  This object is
   * serializable, so that it can be stored in persistent storage or transferred
   * to a different JVM for distributable session support.
   * <p>
   * <b>IMPLEMENTATION NOTE</b>:  An instance of this class represents both the
   * internal (Session) and application level (HttpSession) view of the session.
   * However, because the class itself is not declared public, Java logic outside
   * of the <code>org.apache.tomcat.session</code> package cannot cast an
   * HttpSession view of this instance back to a Session view.
   *
   * @author Craig R. McClanahan
   * @version $Revision: 1.1 $ $Date: 2000/01/20 06:37:30 $
   */
  
  final class StandardSession
      implements HttpSession, Session {
  
  
      // ----------------------------------------------------------- Constructors
  
  
      /**
       * Construct a new Session associated with the specified Manager.
       *
       * @param manager The manager with which this Session is associated
       */
      public StandardSession(Manager manager) {
  
  	super();
  	this.manager = manager;
  
      }
  
  
      // ----------------------------------------------------- Instance Variables
  
  
      /**
       * The collection of user data attributes associated with this Session.
       */
      private Hashtable attributes = new Hashtable();
  
  
      /**
       * The time this session was created, in milliseconds since midnight,
       * January 1, 1970 GMT.
       */
      private long creationTime = 0L;
  
  
      /**
       * The session identifier of this Session.
       */
      private String id = null;
  
  
      /**
       * Descriptive information describing this Session implementation.
       */
      private static final String info = "StandardSession/1.0";
  
  
      /**
       * The last accessed time for this Session.
       */
      private long lastAccessedTime = creationTime;
  
  
      /**
       * The Manager with which this Session is associated.
       */
      private Manager manager = null;
  
  
      /**
       * The maximum time interval, in seconds, between client requests before
       * the servlet container may invalidate this session.  A negative time
       * indicates that the session should never time out.
       */
      private int maxInactiveInterval = -1;
  
  
      /**
       * Flag indicating whether this session is new or not.
       */
      private boolean isNew = false;
  
  
      /**
       * Flag indicating whether this session is valid or not.
       */
      private boolean isValid = false;
  
  
      /**
       * The string manager for this package.
       */
      private StringManager sm =
          StringManager.getManager(Constants.Package);
  
  
      /**
       * The HTTP session context associated with this session.
       */
      private static HttpSessionContext sessionContext = null;
  
  
      /**
       * The current accessed time for this session.
       */
      private long thisAccessedTime = creationTime;
  
  
      // ----------------------------------------------------- Session Properties
  
  
      /**
       * Set the creation time for this session.  This method is called by the
       * Manager when an existing Session instance is reused.
       *
       * @param time The new creation time
       */
      public void setCreationTime(long time) {
  
  	this.creationTime = time;
  	this.lastAccessedTime = time;
  	this.thisAccessedTime = time;
  
      }
  
  
      /**
       * Return the session identifier for this session.
       */
      public String getId() {
  
  	return (this.id);
  
      }
  
  
      /**
       * Set the session identifier for this session.
       *
       * @param id The new session identifier
       */
      public void setId(String id) {
  
  	if ((this.id != null) && (manager != null) &&
  	  (manager instanceof ManagerBase))
  	    ((ManagerBase) manager).remove(this);
  
  	this.id = id;
  
  	if ((manager != null) && (manager instanceof ManagerBase))
  	    ((ManagerBase) manager).add(this);
  
      }
  
  
      /**
       * Return descriptive information about this Session implementation and
       * the corresponding version number, in the format
       * <code>&lt;description&gt;/&lt;version&gt;</code>.
       */
      public String getInfo() {
  
  	return (this.info);
  
      }
  
  
      /**
       * Return the last time the client sent a request associated with this
       * session, as the number of milliseconds since midnight, January 1, 1970
       * GMT.  Actions that your application takes, such as getting or setting
       * a value associated with the session, do not affect the access time.
       */
      public long getLastAccessedTime() {
  
  	return (this.lastAccessedTime);
  
      }
  
  
      /**
       * Return the Manager within which this Session is valid.
       */
      public Manager getManager() {
  
  	return (this.manager);
  
      }
  
  
      /**
       * Set the Manager within which this Session is valid.
       *
       * @param manager The new Manager
       */
      public void setManager(Manager manager) {
  
  	this.manager = manager;
  
      }
  
  
      /**
       * Return the maximum time interval, in seconds, between client requests
       * before the servlet container will invalidate the session.  A negative
       * time indicates that the session should never time out.
       *
       * @exception IllegalStateException if this method is called on
       *  an invalidated session
       */
      public int getMaxInactiveInterval() {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.getMaxInactiveInterval.ise"));
  
  	return (this.maxInactiveInterval);
  
      }
  
  
      /**
       * Set the maximum time interval, in seconds, between client requests
       * before the servlet container will invalidate the session.  A negative
       * time indicates that the session should never time out.
       *
       * @param interval The new maximum interval
       */
      public void setMaxInactiveInterval(int interval) {
  
  	this.maxInactiveInterval = interval;
  
      }
  
  
      /**
       * Return the <code>HttpSession</code> for which this object
       * is the facade.
       */
      public HttpSession getSession() {
  
  	return ((HttpSession) this);
  
      }
  
  
      // ------------------------------------------------- Session Public Methods
  
  
      /**
       * Update the accessed time information for this session.  This method
       * should be called by the context when a request comes in for a particular
       * session, even if the application does not reference it.
       */
      public void access() {
  
  	this.lastAccessedTime = this.thisAccessedTime;
  	this.thisAccessedTime = System.currentTimeMillis();
  
      }
  
  
      /**
       * Perform the internal processing required to invalidate this session,
       * without triggering an exception if the session has already expired.
       */
      public void expire() {
  
  	// Remove this session from our manager's active sessions
  	if ((manager != null) && (manager instanceof ManagerBase))
  	    ((ManagerBase) manager).remove(this);
  
  	// Unbind any objects associated with this session
  	Vector results = new Vector();
  	Enumeration attrs = getAttributeNames();
  	while (attrs.hasMoreElements()) {
  	    String attr = (String) attrs.nextElement();
  	    results.addElement(attr);
  	}
  	Enumeration names = results.elements();
  	while (names.hasMoreElements()) {
  	    String name = (String) names.nextElement();
  	    removeAttribute(name);
  	}
  
  	// Mark this session as invalid
  	setValid(false);
  
      }
  
  
      /**
       * Release all object references, and initialize instance variables, in
       * preparation for reuse of this object.
       */
      public void recycle() {
  
  	// Reset the instance variables associated with this Session
  	attributes.clear();
  	creationTime = 0L;
  	id = null;
  	lastAccessedTime = 0L;
  	manager = null;
  	maxInactiveInterval = -1;
  	isNew = false;
  	isValid = false;
  
  	// Tell our Manager that this Session has been recycled
  	if ((manager != null) && (manager instanceof ManagerBase))
  	    ((ManagerBase) manager).recycle(this);
  
      }
  
  
      // ------------------------------------------------ Session Package Methods
  
  
      /**
       * Return the <code>isValid</code> flag for this session.
       */
      boolean isValid() {
  
  	return (this.isValid);
  
      }
  
  
      /**
       * Set the <code>isNew</code> flag for this session.
       *
       * @param isNew The new value for the <code>isNew</code> flag
       */
      void setNew(boolean isNew) {
  
  	this.isNew = isNew;
  
      }
  
  
      /**
       * Set the <code>isValid</code> flag for this session.
       *
       * @param isValid The new value for the <code>isValid</code> flag
       */
      void setValid(boolean isValid) {
  
  	this.isValid = isValid;
      }
  
  
      // ------------------------------------------------- HttpSession Properties
  
  
      /**
       * Return the time when this session was created, in milliseconds since
       * midnight, January 1, 1970 GMT.
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       */
      public long getCreationTime() {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.getCreationTime.ise"));
  
  	return (this.creationTime);
  
      }
  
  
      /**
       * Return the session context with which this session is associated.
       *
       * @deprecated As of Version 2.1, this method is deprecated and has no
       *  replacement.  It will be removed in a future version of the
       *  Java Servlet API.
       */
      public HttpSessionContext getSessionContext() {
  
  	if (sessionContext == null)
  	    sessionContext = new StandardSessionContext();
  	return (sessionContext);
  
      }
  
  
      // ----------------------------------------------HttpSession Public Methods
  
  
      /**
       * Return the object bound with the specified name in this session, or
       * <code>null</code> if no object is bound with that name.
       *
       * @param name Name of the attribute to be returned
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       */
      public Object getAttribute(String name) {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.getAttribute.ise"));
  
  	return (attributes.get(name));
  
      }
  
  
      /**
       * Return an <code>Enumeration</code> of <code>String</code> objects
       * containing the names of the objects bound to this session.
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       */
      public Enumeration getAttributeNames() {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.getAttributeNames.ise"));
  
  	return (attributes.keys());
  
      }
  
  
      /**
       * Return the object bound with the specified name in this session, or
       * <code>null</code> if no object is bound with that name.
       *
       * @param name Name of the value to be returned
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       *
       * @deprecated As of Version 2.2, this method is replaced by
       *  <code>getAttribute()</code>
       */
      public Object getValue(String name) {
  
  	return (getAttribute(name));
  
      }
  
  
      /**
       * Return the set of names of objects bound to this session.  If there
       * are no such objects, a zero-length array is returned.
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       *
       * @deprecated As of Version 2.2, this method is replaced by
       *  <code>getAttributeNames()</code>
       */
      public String[] getValueNames() {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.getValueNames.ise"));
  
  	Vector results = new Vector();
  	Enumeration attrs = getAttributeNames();
  	while (attrs.hasMoreElements()) {
  	    String attr = (String) attrs.nextElement();
  	    results.addElement(attr);
  	}
  	String names[] = new String[results.size()];
  	for (int i = 0; i < names.length; i++)
  	    names[i] = (String) results.elementAt(i);
  	return (names);
  
      }
  
  
      /**
       * Invalidates this session and unbinds any objects bound to it.
       *
       * @exception IllegalStateException if this method is called on
       *  an invalidated session
       */
      public void invalidate() {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.invalidate.ise"));
  
  	// Cause this session to expire
  	expire();
  
      }
  
  
      /**
       * Return <code>true</code> if the client does not yet know about the
       * session, or if the client chooses not to join the session.  For
       * example, if the server used only cookie-based sessions, and the client
       * has disabled the use of cookies, then a session would be new on each
       * request.
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       */
      public boolean isNew() {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.isNew.ise"));
  
  	return (this.isNew);
  
      }
  
  
      /**
       * Bind an object to this session, using the specified name.  If an object
       * of the same name is already bound to this session, the object is
       * replaced.
       * <p>
       * After this method executes, and if the object implements
       * <code>HttpSessionBindingListener</code>, the container calls
       * <code>valueBound()</code> on the object.
       *
       * @param name Name to which the object is bound, cannot be null
       * @param value Object to be bound, cannot be null
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       *
       * @deprecated As of Version 2.2, this method is replaced by
       *  <code>setAttribute()</code>
       */
      public void putValue(String name, Object value) {
  
  	setAttribute(name, value);
  
      }
  
  
      /**
       * Remove the object bound with the specified name from this session.  If
       * the session does not have an object bound with this name, this method
       * does nothing.
       * <p>
       * After this method executes, and if the object implements
       * <code>HttpSessionBindingListener</code>, the container calls
       * <code>valueUnbound()</code> on the object.
       *
       * @param name Name of the object to remove from this session.
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       */
      public void removeAttribute(String name) {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.removeAttribute.ise"));
  
  	synchronized (attributes) {
  	    Object object = attributes.get(name);
  	    if (object == null)
  		return;
  	    attributes.remove(name);
  	    if (object instanceof HttpSessionBindingListener)
  		((HttpSessionBindingListener) object).valueUnbound
  		    (new HttpSessionBindingEvent((HttpSession) this, name));
  	}
  
      }
  
  
      /**
       * Remove the object bound with the specified name from this session.  If
       * the session does not have an object bound with this name, this method
       * does nothing.
       * <p>
       * After this method executes, and if the object implements
       * <code>HttpSessionBindingListener</code>, the container calls
       * <code>valueUnbound()</code> on the object.
       *
       * @param name Name of the object to remove from this session.
       *
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       *
       * @deprecated As of Version 2.2, this method is replaced by
       *  <code>removeAttribute()</code>
       */
      public void removeValue(String name) {
  
  	removeAttribute(name);
  
      }
  
  
      /**
       * Bind an object to this session, using the specified name.  If an object
       * of the same name is already bound to this session, the object is
       * replaced.
       * <p>
       * After this method executes, and if the object implements
       * <code>HttpSessionBindingListener</code>, the container calls
       * <code>valueBound()</code> on the object.
       *
       * @param name Name to which the object is bound, cannot be null
       * @param value Object to be bound, cannot be null
       *
       * @exception IllegalArgumentException if an attempt is made to add a
       *  non-serializable object in an environment marked distributable.
       * @exception IllegalStateException if this method is called on an
       *  invalidated session
       */
      public void setAttribute(String name, Object value) {
  
  	if (!isValid())
  	    throw new IllegalStateException
  		(sm.getString("standardSession.setAttribute.ise"));
  
  	if ((manager != null) && manager.getDistributable() &&
  	  !(value instanceof Serializable))
  	    throw new IllegalArgumentException
  		(sm.getString("standardSession.setAttribute.iae"));
  
  	synchronized (attributes) {
  	    removeAttribute(name);
  	    attributes.put(name, value);
  	    if (value instanceof HttpSessionBindingListener)
  		((HttpSessionBindingListener) value).valueBound
  		    (new HttpSessionBindingEvent((HttpSession) this, name));
  	}
  
      }
  
  
      // -------------------------------------------- HttpSession Private Methods
  
  
      /**
       * Read a serialized version of this session object from the specified
       * object input stream.
       * <p>
       * <b>IMPLEMENTATION NOTE</b>:  The reference to the owning Manager
       * is not restored by this method, and must be set explicitly.
       *
       * @param stream The input stream to read from
       *
       * @exception ClassNotFoundException if an unknown class is specified
       * @exception IOException if an input/output error occurs
       */
      private void readObject(ObjectInputStream stream)
  	throws ClassNotFoundException, IOException {
  
  	// Deserialize the scalar instance variables (except Manager)
  	creationTime = ((Long) stream.readObject()).longValue();
  	id = (String) stream.readObject();
  	lastAccessedTime = ((Long) stream.readObject()).longValue();
  	maxInactiveInterval = ((Integer) stream.readObject()).intValue();
  	isNew = ((Boolean) stream.readObject()).booleanValue();
  	isValid = ((Boolean) stream.readObject()).booleanValue();
  
  	// Deserialize the attribute count and attribute values
  	int n = ((Integer) stream.readObject()).intValue();
  	for (int i = 0; i < n; i++) {
  	    String name = (String) stream.readObject();
  	    Object value = (Object) stream.readObject();
  	    attributes.put(name, value);
  	}
  
      }
  
  
      /**
       * Write a serialized version of this session object to the specified
       * object output stream.
       * <p>
       * <b>IMPLEMENTATION NOTE</b>:  The owning Manager will not be stored
       * in the serialized representation of this Session.  After calling
       * <code>readObject()</code>, you must set the associated Manager
       * explicitly.
       * <p>
       * <b>IMPLEMENTATION NOTE</b>:  Any attribute that is not Serializable
       * will be silently ignored.  If you do not want any such attributes,
       * be sure the <code>distributable</code> property of our associated
       * Manager is set to <code>true</code>.
       *
       * @param stream The output stream to write to
       *
       * @exception IOException if an input/output error occurs
       */
      private void writeObject(ObjectOutputStream stream) throws IOException {
  
  	// Write the scalar instance variables (except Manager)
  	stream.writeObject(new Long(creationTime));
  	stream.writeObject(id);
  	stream.writeObject(new Long(lastAccessedTime));
  	stream.writeObject(new Integer(maxInactiveInterval));
  	stream.writeObject(new Boolean(isNew));
  	stream.writeObject(new Boolean(isValid));
  
  	// Accumulate the names of serializable attributes
  	Vector results = new Vector();
  	Enumeration attrs = getAttributeNames();
  	while (attrs.hasMoreElements()) {
  	    String attr = (String) attrs.nextElement();
  	    Object value = attributes.get(attr);
  	    if (value instanceof Serializable)
  		results.addElement(attr);
  	}
  
  	// Serialize the attribute count and the  attribute values
  	stream.writeObject(new Integer(results.size()));
  	Enumeration names = results.elements();
  	while (names.hasMoreElements()) {
  	    String name = (String) names.nextElement();
  	    stream.writeObject(name);
  	    stream.writeObject(attributes.get(name));
  	}
  
  
      }
  
  
  }
  
  
  // -------------------------------------------------------------- Private Class
  
  
  /**
   * This class is a dummy implementation of the <code>HttpSessionContext</code>
   * interface, to conform to the requirement that such an object be returned
   * when <code>HttpSession.getSessionContext()</code> is called.
   *
   * @author Craig R. McClanahan
   *
   * @deprecated As of Java Servlet API 2.1 with no replacement.  The
   *  interface will be removed in a future version of this API.
   */
  
  final class StandardSessionContext implements HttpSessionContext {
  
  
      private Vector dummy = new Vector();
  
      /**
       * Return the session identifiers of all sessions defined
       * within this context.
       *
       * @deprecated As of Java Servlet API 2.1 with no replacement.
       *  This method must return an empty <code>Enumeration</code>
       *  and will be removed in a future version of the API.
       */
      public Enumeration getIds() {
  
  	return (dummy.elements());
  
      }
  
  
      /**
       * Return the <code>HttpSession</code> associated with the
       * specified session identifier.
       *
       * @param id Session identifier for which to look up a session
       *
       * @deprecated As of Java Servlet API 2.1 with no replacement.
       *  This method must return null and will be removed in a
       *  future version of the API.
       */
      public HttpSession getSession(String id) {
  
  	return (null);
  
      }
  
  
  
  }
  
  
  
  1.1                  jakarta-tomcat/proposals/catalina/src/share/org/apache/tomcat/session/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  applicationSession.session.ise=invalid session state
  applicationSession.value.iae=null value
  fileStore.alreadyConfigured=File Store has already been configured
  fileStore.alreadyStarted=File Store has already been started
  fileStore.notConfigured=File Store has not yet been configured
  fileStore.notStarted=File Store has not yet been started
  serverSession.value.iae=null value
  standardManager.alreadyConfigured=Manager has already been configured
  standardManager.alreadyStarted=Manager has already been started
  standardManager.createSession.ise=createSession: Too many active sessions
  standardManager.notConfigured=Manager has not yet been configured
  standardManager.notStarted=Manager has not yet been started
  standardSession.invalidate.ise=invalidate: Session already invalidated
  standardSession.isNew.ise=isNew: Session already invalidated
  standardSession.getAttribute.ise=getAttribute: Session already invalidated
  standardSession.getAttributeNames.ise=getAttributeNames: Session already invalidated
  standardSession.getCreationTime.ise=getCreationTime: Session already invalidated
  standardSession.getMaxInactiveInterval.ise=getMaxInactiveInterval: Session already invalidated
  standardSession.getValueNames.ise=getAttributeNames: Session already invalidated
  standardSession.removeAttribute.ise=removeAttribute: Session already invalidated
  standardSession.setAttribute.ise=setAttribute: Non-serializable attribute
  standardSession.setAttribute.ise=setAttribute: Session already invalidated
  
  
  
  
  
  

Mime
View raw message