View Javadoc

    1   // ========================================================================
    2   // Copyright 2004-2008 Mort Bay Consulting Pty. Ltd.
    3   // ------------------------------------------------------------------------
    4   // Licensed under the Apache License, Version 2.0 (the "License");
    5   // you may not use this file except in compliance with the License.
    6   // You may obtain a copy of the License at
    7   // http://www.apache.org/licenses/LICENSE-2.0
    8   // Unless required by applicable law or agreed to in writing, software
    9   // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  // ========================================================================
    14
    15  package org.mortbay.terracotta.servlet;
    16
    17  import java.io.IOException;
    18
    19  import javax.servlet.ServletException;
    20  import javax.servlet.http.Cookie;
    21  import javax.servlet.http.HttpServletRequest;
    22  import javax.servlet.http.HttpServletResponse;
    23  import javax.servlet.http.HttpSession;
    24
    25  import org.mortbay.jetty.HttpConnection;
    26  import org.mortbay.jetty.Request;
    27  import org.mortbay.jetty.RetryRequest;
    28  import org.mortbay.jetty.SessionManager;
    29  import org.mortbay.jetty.servlet.SessionHandler;
    30  import org.mortbay.log.Log;
    31
    32  /**
    33   * A specific subclass of {@link SessionHandler} that sets a contract between
    34   * this class and {@link TerracottaSessionManager}.
    35   * The contract requires that a Terracotta named lock will be held for the duration
    36   * of the request, where the lock name depends on the session id.
    37   * To achieve this, we call {@link TerracottaSessionManager#enter(Request)} and
    38   * {@link TerracottaSessionManager#exit(Request)}, in order to be able to obtain
    39   * and release the Terracotta lock.
    40   * See the {@link TerracottaSessionManager} javadocs for implementation notes.
    41   *
    42   * @version $Revision: 1308 $ $Date: 2008-11-07 11:50:17 +0100 (Fri, 07 Nov 2008) $
    43   */
    44  public class TerracottaSessionHandler extends SessionHandler
    45  {
    46      public TerracottaSessionHandler()
    47      {
    48      }
    49
    50      public TerracottaSessionHandler(SessionManager manager)
    51      {
    52          super(manager);
    53      }
    54
    55      @Override
    56      public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException
    57      {
    58          setRequestedId(request, dispatch);
    59
    60          Request currentRequest = (request instanceof Request) ? (Request)request : HttpConnection.getCurrentConnection().getRequest();
    61
    62          SessionManager requestSessionManager = currentRequest.getSessionManager();
    63          HttpSession requestSession = currentRequest.getSession(false);
    64
    65          TerracottaSessionManager sessionManager = (TerracottaSessionManager)getSessionManager();
    66          Log.debug("SessionManager = {}", sessionManager);
    67
    68          // Is it a cross context dispatch or a direct hit to this context ?
    69          if (sessionManager != requestSessionManager)
    70          {
    71              // Setup the request for this context
    72              currentRequest.setSessionManager(sessionManager);
    73              currentRequest.setSession(null);
    74          }
    75
    76          // Tell the session manager that the request is entering
    77          if (sessionManager != null) sessionManager.enter(currentRequest);
    78          try
    79          {
    80              HttpSession currentSession = null;
    81              if (sessionManager != null)
    82              {
    83                  currentSession = currentRequest.getSession(false);
    84                  if (currentSession != null)
    85                  {
    86                      if (currentSession != requestSession)
    87                      {
    88                          // Access the session only if we did not already
    89                          Cookie cookie = sessionManager.access(currentSession, request.isSecure());
    90                          if (cookie != null)
    91                          {
    92                              // Handle changed session id or cookie max-age refresh
    93                              response.addCookie(cookie);
    94                          }
    95                      }
    96                      else
    97                      {
    98                          // Handle resume of the request
    99                          currentSession = currentRequest.recoverNewSession(sessionManager);
    100                         if (currentSession != null) currentRequest.setSession(currentSession);
    101                     }
    102                 }
    103             }
    104             Log.debug("Session = {}", currentSession);
    105
    106             getHandler().handle(target, request, response, dispatch);
    107         }
    108         catch (RetryRequest x)
    109         {
    110             // User may have invalidated the session, must get it again
    111             HttpSession currentSession = currentRequest.getSession(false);
    112             if (currentSession != null && currentSession.isNew())
    113                 currentRequest.saveNewSession(sessionManager, currentSession);
    114
    115             throw x;
    116         }
    117         finally
    118         {
    119             if (sessionManager != null)
    120             {
    121                 // User may have invalidated the session, must get it again
    122                 HttpSession currentSession = currentRequest.getSession(false);
    123                 if (currentSession != null) sessionManager.complete(currentSession);
    124
    125                 sessionManager.exit(currentRequest);
    126             }
    127
    128             // Restore cross context dispatch
    129             if (sessionManager != requestSessionManager)
    130             {
    131                 currentRequest.setSessionManager(requestSessionManager);
    132                 currentRequest.setSession(requestSession);
    133             }
    134         }
    135     }
    136 }