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>
* <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><description>/<version></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><description>/<version></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>
* <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><description>/<version></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><description>/<version></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
|