View Javadoc

1   // ========================================================================
2   // Copyright (c) 2006-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  
14  package org.eclipse.jetty.server.session;
15  
16  import java.lang.ref.WeakReference;
17  import java.util.Collection;
18  import java.util.HashMap;
19  import java.util.HashSet;
20  import java.util.Iterator;
21  import java.util.Map;
22  import java.util.Random;
23  import java.util.Set;
24  
25  import javax.servlet.http.HttpServletRequest;
26  import javax.servlet.http.HttpSession;
27  
28  import org.eclipse.jetty.server.SessionIdManager;
29  
30  /* ------------------------------------------------------------ */
31  /**
32   * HashSessionIdManager. An in-memory implementation of the session ID manager.
33   */
34  public class HashSessionIdManager extends AbstractSessionIdManager
35  {
36      private final Map<String, Set<WeakReference<HttpSession>>> _sessions = new HashMap<String, Set<WeakReference<HttpSession>>>();
37  
38      /* ------------------------------------------------------------ */
39      public HashSessionIdManager()
40      {
41      }
42  
43      /* ------------------------------------------------------------ */
44      public HashSessionIdManager(Random random)
45      {
46          super(random);
47      }
48  
49      /* ------------------------------------------------------------ */
50      /** Get the session ID with any worker ID.
51       * 
52       * @param clusterId
53       * @param request
54       * @return sessionId plus any worker ID.
55       */
56      public String getNodeId(String clusterId,HttpServletRequest request) 
57      {
58          // used in Ajp13Parser
59          String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute");
60          if (worker!=null) 
61              return clusterId+'.'+worker; 
62          
63          if (_workerName!=null) 
64              return clusterId+'.'+_workerName;
65         
66          return clusterId;
67      }
68  
69      /* ------------------------------------------------------------ */
70      /** Get the session ID without any worker ID.
71       * 
72       * @param nodeId the node id
73       * @return sessionId without any worker ID.
74       */
75      public String getClusterId(String nodeId) 
76      {
77          int dot=nodeId.lastIndexOf('.');
78          return (dot>0)?nodeId.substring(0,dot):nodeId;
79      }
80      
81      /* ------------------------------------------------------------ */
82      @Override
83      protected void doStart() throws Exception
84      {        
85          super.doStart();
86      }
87  
88      /* ------------------------------------------------------------ */
89      @Override
90      protected void doStop() throws Exception
91      {
92          _sessions.clear(); 
93          super.doStop();
94      }
95  
96      /* ------------------------------------------------------------ */
97      /**
98       * @see SessionIdManager#idInUse(String)
99       */
100     public boolean idInUse(String id)
101     {
102         synchronized (this)
103         {
104             return _sessions.containsKey(id);
105         }
106     }
107 
108     /* ------------------------------------------------------------ */
109     /**
110      * @see SessionIdManager#addSession(HttpSession)
111      */
112     public void addSession(HttpSession session)
113     {
114         String id = getClusterId(session.getId());
115         WeakReference<HttpSession> ref = new WeakReference<HttpSession>(session);
116         
117         synchronized (this)
118         {
119             Set<WeakReference<HttpSession>> sessions = _sessions.get(id);
120             if (sessions==null)
121             {
122                 sessions=new HashSet<WeakReference<HttpSession>>();
123                 _sessions.put(id,sessions);
124             }
125             sessions.add(ref);
126         }
127     }
128 
129     /* ------------------------------------------------------------ */
130     /**
131      * @see SessionIdManager#removeSession(HttpSession)
132      */
133     public void removeSession(HttpSession session)
134     {
135         String id = getClusterId(session.getId());
136         
137         synchronized (this)
138         {
139             Collection<WeakReference<HttpSession>> sessions = _sessions.get(id);
140             if (sessions!=null)
141             {
142                 for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();)
143                 {
144                     WeakReference<HttpSession> ref = iter.next();
145                     HttpSession s=ref.get();
146                     if (s==null)
147                     {
148                         iter.remove();
149                         continue;
150                     }
151                     if (s==session)
152                     {
153                         iter.remove();
154                         break;
155                     }
156                 }
157                 if (sessions.isEmpty())
158                     _sessions.remove(id);
159             }
160         }
161     }
162 
163     /* ------------------------------------------------------------ */
164     /**
165      * @see SessionIdManager#invalidateAll(String)
166      */
167     public void invalidateAll(String id)
168     {
169         Collection<WeakReference<HttpSession>> sessions;
170         synchronized (this)
171         {
172             sessions = _sessions.remove(id);
173         }
174         
175         if (sessions!=null)
176         {
177             for (WeakReference<HttpSession> ref: sessions)
178             {
179                 AbstractSession session=(AbstractSession)ref.get();
180                 if (session!=null && session.isValid())
181                     session.invalidate();
182             }
183             sessions.clear();
184         }
185     }
186 
187 }