|
What this is
Other links
The source code/* * Copyright 1999-2004 The Apache Sofware Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.tomcat.modules.session; import java.io.Serializable; import java.util.Enumeration; import java.util.Hashtable; import org.apache.tomcat.core.BaseInterceptor; import org.apache.tomcat.core.Context; import org.apache.tomcat.core.ContextManager; import org.apache.tomcat.core.Request; import org.apache.tomcat.core.ServerSession; import org.apache.tomcat.core.TomcatException; import org.apache.tomcat.util.ObjectSerializer; import org.apache.tomcat.util.buf.TimeStamp; import org.apache.tomcat.util.collections.SimplePool; /** * A simple session store plugin. It will create, store and maintain * session objects using a simple in-memory pool. * * It must be inserted after SessionId, which does common * session stuff ( cookie, rewrite, etc) * * @author costin@eng.sun.com * @author hans@gefionsoftware.com * @author pfrieden@dChain.com * @author Shai Fultheim [shai@brm.com] */ public final class SimpleSessionStore extends BaseInterceptor { int manager_note; int maxActiveSessions = -1; int size=16; int max=256; static final String SESSIONS_RELOAD = "tomcat.sessions.reload"; public SimpleSessionStore() { } // -------------------- Configuration properties -------------------- public void setMaxActiveSessions( int count ) { maxActiveSessions=count; } public void setInitialPool( int initial ) { size=initial; } public void setMaxPool( int max ) { this.max=max; } // -------------------- Tomcat request events -------------------- public void engineInit( ContextManager cm ) throws TomcatException { // set-up a per/container note for StandardManager manager_note = cm.getNoteId( ContextManager.CONTAINER_NOTE, "tomcat.standardManager"); } public void copyContext(Request req, Context oldC, Context newC) throws TomcatException { contextInit(newC); ClassLoader oldLoader = oldC.getClassLoader(); SimpleSessionManager sM = getManager( oldC ); SimpleSessionManager sMnew = getManager( newC ); // remove all non-serializable objects from session Enumeration sessionEnum=sM.getSessions(); while( sessionEnum.hasMoreElements() ) { ServerSession session = (ServerSession)sessionEnum.nextElement(); ServerSession newS = sMnew.cloneSession(req, newC, session.getId().toString()); Enumeration e = session.getAttributeNames(); while( e.hasMoreElements() ) { String key = (String) e.nextElement(); Object value = session.getAttribute(key); newS.setAttribute(key, value); } } newC.getContainer().setNote(SESSIONS_RELOAD, req); } private void processSession(ServerSession session, ClassLoader oldCL, ClassLoader newCL) throws TomcatException { Hashtable newSession=new Hashtable(); Enumeration e = session.getAttributeNames(); while( e.hasMoreElements() ) { String key = (String) e.nextElement(); Object value = session.getAttribute(key); if ( value instanceof Serializable ) { Object newValue = ObjectSerializer.doSerialization( newCL, value); newSession.put( key, newValue ); } else if( value.getClass().getClassLoader() != oldCL ) { // it's loaded by the parent loader, no need to reload newSession.put( key, value ); } } // If saving back to the same session. // Remove all objects we know how to handle e=newSession.keys(); while( e.hasMoreElements() ) { String key = (String) e.nextElement(); session.removeAttribute(key); } if( debug > 0 ) log("Prepare for reloading, SUSPEND " + session ); // If anyone can save the rest of the attributes or at least notify // the owner... session.setState( ServerSession.STATE_SUSPEND, null ); if( debug > 0 ) log("After reloading, RESTORED " + session ); session.setState( ServerSession.STATE_RESTORED, null ); /* now put back all attributes */ e=newSession.keys(); while(e.hasMoreElements() ) { String key = (String) e.nextElement(); Object value=newSession.get(key ); session.setAttribute( key, value ); } } public void reload( Request req, Context ctx ) throws TomcatException { ClassLoader newLoader = ctx.getClassLoader(); ClassLoader oldLoader=(ClassLoader)ctx.getContainer(). getNote("oldLoader"); SimpleSessionManager sM = getManager( ctx ); // remove all non-serializable objects from session Enumeration sessionEnum=sM.getSessions(); while( sessionEnum.hasMoreElements() ) { ServerSession session = (ServerSession)sessionEnum.nextElement(); processSession(session, oldLoader, newLoader); } } /** The session store hook */ public ServerSession findSession( Request request, String sessionId, boolean create) { Context ctx=request.getContext(); if( ctx==null ) return null; SimpleSessionManager sM = getManager( ctx ); ServerSession sess=sM.findSession( sessionId ); if( sess!= null ) return sess; if( ! create ) return null; // not found, don't create if ((maxActiveSessions >= 0) && (sM.getSessionCount() >= maxActiveSessions)) { log( "Too many sessions " + maxActiveSessions ); return null; } ServerSession newS=sM.getNewSession(request, ctx); if( newS==null ) { log( "Create session failed " ); return null; } return newS; } //-------------------- Tomcat context events -------------------- /** Init session management stuff for this context. */ public void contextInit(Context ctx) throws TomcatException { // Defaults !! SimpleSessionManager sm= getManager( ctx ); if( sm == null ) { sm=new SimpleSessionManager(); sm.setDebug( debug ); sm.setModule( this ); ctx.getContainer().setNote( manager_note, sm ); } if(ctx.getContainer().getNote(SESSIONS_RELOAD) != null ) { Request req = (Request)ctx.getContainer().getNote(SESSIONS_RELOAD); reload(req, ctx); // Dump for GC. ctx.getContainer().setNote(SESSIONS_RELOAD,null); } } /** Notification of context shutdown. * We should clean up any resources that are used by our * session management code. */ public void contextShutdown( Context ctx ) throws TomcatException { if( debug > 0 ) log("Removing sessions from " + ctx ); SimpleSessionManager sm=getManager(ctx); Enumeration ids = sm.getSessionIds(); while (ids.hasMoreElements()) { String id = (String) ids.nextElement(); ServerSession session = sm.findSession(id); if (!session.getTimeStamp().isValid()) continue; if( debug > 0 ) log( "Shuting down " + id ); session.setState( ServerSession.STATE_SUSPEND ); session.setState( ServerSession.STATE_EXPIRED ); session.setState( ServerSession.STATE_INVALID ); } } public int sessionState( Request req, ServerSession session, int state ) { TimeStamp ts=session.getTimeStamp(); if( state==ServerSession.STATE_INVALID ) { // session moved to expire state - remove all attributes from // storage SimpleSessionManager ssm=(SimpleSessionManager)session.getManager(); ssm.removeSession( session ); } return state; } // -------------------- State Info -------------------- public Enumeration getSessionIds(Context ctx) { SimpleSessionManager sm= getManager( ctx ); return sm.getSessionIds(); } public Enumeration getSessions(Context ctx) { SimpleSessionManager sm= getManager( ctx ); return sm.getSessions(); } public int getSessionCount(Context ctx) { SimpleSessionManager sm= getManager( ctx ); return sm.getSessionCount(); } public int getRecycledCount(Context ctx) { SimpleSessionManager sm= getManager( ctx ); return sm.getRecycledCount(); } public ServerSession findSession( Context ctx, String sessionId) { SimpleSessionManager sM = getManager( ctx ); return sM.findSession( sessionId ); } // -------------------- Internal methods -------------------- private SimpleSessionManager getManager( Context ctx ) { return (SimpleSessionManager)ctx.getContainer().getNote(manager_note); } /** * The actual "simple" manager * */ public static class SimpleSessionManager { private int debug=0; private BaseInterceptor mod; /** The set of previously recycled Sessions for this Manager. */ protected SimplePool recycled = new SimplePool(); /** * The set of currently active Sessions for this Manager, keyed by * session identifier. */ protected Hashtable sessions = new Hashtable(); public SimpleSessionManager() { } public void setDebug( int l ) { debug=l; } public void setModule( BaseInterceptor bi ) { mod=bi; } // --------------------------------------------- Public Methods public Enumeration getSessionIds() { return sessions.keys(); } public Enumeration getSessions() { return sessions.elements(); } public int getSessionCount() { return sessions.size(); } public int getRecycledCount() { return recycled.getCount(); } public ServerSession findSession(String id) { if (id == null) return null; return (ServerSession)sessions.get(id); } /** * Remove this Session from the active Sessions for this Manager. * * @param session Session to be removed */ public void removeSession(ServerSession session) { if( debug>0 ) mod.log( "removeSession " + session ); sessions.remove(session.getId().toString()); recycled.put(session); session.setValid(false); // Do not recycle it yet - whoever expires it should also recyle. // Otherwise we may miss something // session.recycle(); // session.removeAllAttributes(); } public ServerSession getNewSession(Request req, Context ctx) { // Recycle or create a Session instance ServerSession session = (ServerSession)recycled.get(); if (session == null) { session = ctx.getContextManager().createServerSession(); session.setManager( this ); session.setDebug( debug ); } session.setContext( ctx ); session.setState( ServerSession.STATE_NEW, req ); // The id will be set by one of the modules String newId=session.getId().toString(); //XXXXX - the following is a temporary fix only! Underlying problem // is: Why is the newId==null? newId=(newId==null)?"null":newId; // What if the newId belongs to an existing session ? // This shouldn't happen ( maybe we can try again ? ) ServerSession oldS=findSession( newId ); if( oldS!=null) { // that's what the original code did oldS.setState( ServerSession.STATE_EXPIRED ); oldS.recycle(); oldS.setState( ServerSession.STATE_INVALID ); } sessions.put( newId, session ); return (session); } public ServerSession cloneSession(Request req, Context ctx, String oldS) { // Recycle or create a Session instance ServerSession session = (ServerSession)recycled.get(); if (session == null) { session = ctx.getContextManager().createServerSession(); session.setManager( this ); session.setDebug( debug ); } session.setContext( ctx ); session.setState( ServerSession.STATE_NEW, req ); session.getId().setString(oldS); // The id will be set by one of the modules String newId=session.getId().toString(); //XXXXX - the following is a temporary fix only! Underlying problem // is: Why is the newId==null? newId=(newId==null)?"null":newId; sessions.put( newId, session ); return (session); } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.