FileDocCategorySizeDatePackage
PersistentValve.javaAPI DocApache Tomcat 6.0.147958Fri Jul 20 04:20:34 BST 2007org.apache.catalina.valves

PersistentValve

public class PersistentValve extends ValveBase
Valve that implements the default basic behavior for the StandardHost container implementation.

USAGE CONSTRAINT: To work correctly it requires a PersistentManager.

author
Jean-Frederic Clere
version
$Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $

Fields Summary
private static final String
info
The descriptive information related to this implementation.
private static final org.apache.catalina.util.StringManager
sm
The string manager for this package.
Constructors Summary
Methods Summary
public java.lang.StringgetInfo()
Return descriptive information about this Valve implementation.



    // ------------------------------------------------------------- Properties


                
       

        return (info);

    
public voidinvoke(org.apache.catalina.connector.Request request, org.apache.catalina.connector.Response response)
Select the appropriate child Context to process this request, based on the specified request URI. If no matching Context can be found, return an appropriate HTTP error.

param
request Request to be processed
param
response Response to be produced
exception
IOException if an input/output error occurred
exception
ServletException if a servlet error occurred


        // Select the Context to be used for this Request
        StandardHost host = (StandardHost) getContainer();
        Context context = request.getContext();
        if (context == null) {
            response.sendError
                (HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                 sm.getString("standardHost.noContext"));
            return;
        }

        // Bind the context CL to the current thread
        Thread.currentThread().setContextClassLoader
            (context.getLoader().getClassLoader());

        // Update the session last access time for our session (if any)
        String sessionId = request.getRequestedSessionId();
        Manager manager = context.getManager();
        if (sessionId != null && manager != null) {
            if (manager instanceof PersistentManager) {
                Store store = ((PersistentManager) manager).getStore();
                if (store != null) {
                    Session session = null;
                    try {
                        session = store.load(sessionId);
                    } catch (Exception e) {
                        container.getLogger().error("deserializeError");
                    }
                    if (session != null) {
                        if (!session.isValid() ||
                            isSessionStale(session, System.currentTimeMillis())) {
                            if (container.getLogger().isDebugEnabled())
                                container.getLogger().debug("session swapped in is invalid or expired");
                            session.expire();
                            store.remove(sessionId);
                        } else {
                            session.setManager(manager);
                            // session.setId(sessionId); Only if new ???
                            manager.add(session);
                            // ((StandardSession)session).activate();
                            session.access();
                        }
                    }
                }
            }
        }
        if (container.getLogger().isDebugEnabled())
            container.getLogger().debug("sessionId: " + sessionId);

        // Ask the next valve to process the request.
        getNext().invoke(request, response);

        // Read the sessionid after the response.
        // HttpSession hsess = hreq.getSession(false);
        Session hsess;
        try {
            hsess = request.getSessionInternal();
        } catch (Exception ex) {
            hsess = null;
        }
        String newsessionId = null;
        if (hsess!=null)
            newsessionId = hsess.getIdInternal();

        if (container.getLogger().isDebugEnabled())
            container.getLogger().debug("newsessionId: " + newsessionId);
        if (newsessionId!=null) {
            /* store the session in the store and remove it from the manager */
            if (manager instanceof PersistentManager) {
                Session session = manager.findSession(newsessionId);
                Store store = ((PersistentManager) manager).getStore();
                if (store != null && session!=null &&
                    session.isValid() &&
                    !isSessionStale(session, System.currentTimeMillis())) {
                    // ((StandardSession)session).passivate();
                    store.save(session);
                    ((PersistentManager) manager).removeSuper(session);
                    session.recycle();
                } else {
                    if (container.getLogger().isDebugEnabled())
                        container.getLogger().debug("newsessionId store: " + store + " session: " +
                                session + " valid: " + session.isValid() +
                                " Staled: " +
                                isSessionStale(session, System.currentTimeMillis()));

                }
            } else {
                if (container.getLogger().isDebugEnabled())
                    container.getLogger().debug("newsessionId Manager: " + manager);
            }
        }
    
protected booleanisSessionStale(org.apache.catalina.Session session, long timeNow)
Indicate whether the session has been idle for longer than its expiration date as of the supplied time. FIXME: Probably belongs in the Session class.

 
        int maxInactiveInterval = session.getMaxInactiveInterval();
        if (maxInactiveInterval >= 0) {
            int timeIdle = // Truncate, do not round up
                (int) ((timeNow - session.getLastAccessedTime()) / 1000L);
            if (timeIdle >= maxInactiveInterval)
                return true;
        }
 
        return false;