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.ArrayList;
18  import java.util.Collection;
19  import java.util.Collections;
20  import java.util.HashMap;
21  import java.util.HashSet;
22  import java.util.Iterator;
23  import java.util.Map;
24  import java.util.Random;
25  import java.util.Set;
26  
27  import javax.servlet.http.HttpServletRequest;
28  import javax.servlet.http.HttpSession;
29  
30  import org.eclipse.jetty.server.SessionIdManager;
31  
32  /* ------------------------------------------------------------ */
33  /**
34   * HashSessionIdManager. An in-memory implementation of the session ID manager.
35   */
36  public class HashSessionIdManager extends AbstractSessionIdManager
37  {
38      private final Map<String, Set<WeakReference<HttpSession>>> _sessions = new HashMap<String, Set<WeakReference<HttpSession>>>();
39  
40      /* ------------------------------------------------------------ */
41      public HashSessionIdManager()
42      {
43      }
44  
45      /* ------------------------------------------------------------ */
46      public HashSessionIdManager(Random random)
47      {
48          super(random);
49      }
50  
51      /* ------------------------------------------------------------ */
52      /**
53       * @return Collection of String session IDs
54       */
55      public Collection<String> getSessions()
56      {
57          return Collections.unmodifiableCollection(_sessions.keySet());
58      }
59      
60      /* ------------------------------------------------------------ */
61      /**
62       * @return Collection of Sessions for the passed session ID
63       */
64      public Collection<HttpSession> getSession(String id)
65      {
66          ArrayList<HttpSession> sessions = new ArrayList<HttpSession>();
67          Set<WeakReference<HttpSession>> refs =_sessions.get(id);
68          if (refs!=null)
69          {
70              for (WeakReference<HttpSession> ref: refs)
71              {
72                  HttpSession session = ref.get();
73                  if (session!=null)
74                      sessions.add(session);
75              }
76          }
77          return sessions;
78      }
79      /* ------------------------------------------------------------ */
80      /** Get the session ID with any worker ID.
81       * 
82       * @param clusterId
83       * @param request
84       * @return sessionId plus any worker ID.
85       */
86      public String getNodeId(String clusterId,HttpServletRequest request) 
87      {
88          // used in Ajp13Parser
89          String worker=request==null?null:(String)request.getAttribute("org.eclipse.jetty.ajp.JVMRoute");
90          if (worker!=null) 
91              return clusterId+'.'+worker; 
92          
93          if (_workerName!=null) 
94              return clusterId+'.'+_workerName;
95         
96          return clusterId;
97      }
98  
99      /* ------------------------------------------------------------ */
100     /** Get the session ID without any worker ID.
101      * 
102      * @param nodeId the node id
103      * @return sessionId without any worker ID.
104      */
105     public String getClusterId(String nodeId) 
106     {
107         int dot=nodeId.lastIndexOf('.');
108         return (dot>0)?nodeId.substring(0,dot):nodeId;
109     }
110     
111     /* ------------------------------------------------------------ */
112     @Override
113     protected void doStart() throws Exception
114     {        
115         super.doStart();
116     }
117 
118     /* ------------------------------------------------------------ */
119     @Override
120     protected void doStop() throws Exception
121     {
122         _sessions.clear(); 
123         super.doStop();
124     }
125 
126     /* ------------------------------------------------------------ */
127     /**
128      * @see SessionIdManager#idInUse(String)
129      */
130     public boolean idInUse(String id)
131     {
132         synchronized (this)
133         {
134             return _sessions.containsKey(id);
135         }
136     }
137 
138     /* ------------------------------------------------------------ */
139     /**
140      * @see SessionIdManager#addSession(HttpSession)
141      */
142     public void addSession(HttpSession session)
143     {
144         String id = getClusterId(session.getId());
145         WeakReference<HttpSession> ref = new WeakReference<HttpSession>(session);
146         
147         synchronized (this)
148         {
149             Set<WeakReference<HttpSession>> sessions = _sessions.get(id);
150             if (sessions==null)
151             {
152                 sessions=new HashSet<WeakReference<HttpSession>>();
153                 _sessions.put(id,sessions);
154             }
155             sessions.add(ref);
156         }
157     }
158 
159     /* ------------------------------------------------------------ */
160     /**
161      * @see SessionIdManager#removeSession(HttpSession)
162      */
163     public void removeSession(HttpSession session)
164     {
165         String id = getClusterId(session.getId());
166         
167         synchronized (this)
168         {
169             Collection<WeakReference<HttpSession>> sessions = _sessions.get(id);
170             if (sessions!=null)
171             {
172                 for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();)
173                 {
174                     WeakReference<HttpSession> ref = iter.next();
175                     HttpSession s=ref.get();
176                     if (s==null)
177                     {
178                         iter.remove();
179                         continue;
180                     }
181                     if (s==session)
182                     {
183                         iter.remove();
184                         break;
185                     }
186                 }
187                 if (sessions.isEmpty())
188                     _sessions.remove(id);
189             }
190         }
191     }
192 
193     /* ------------------------------------------------------------ */
194     /**
195      * @see SessionIdManager#invalidateAll(String)
196      */
197     public void invalidateAll(String id)
198     {
199         Collection<WeakReference<HttpSession>> sessions;
200         synchronized (this)
201         {
202             sessions = _sessions.remove(id);
203         }
204         
205         if (sessions!=null)
206         {
207             for (WeakReference<HttpSession> ref: sessions)
208             {
209                 AbstractSession session=(AbstractSession)ref.get();
210                 if (session!=null && session.isValid())
211                     session.invalidate();
212             }
213             sessions.clear();
214         }
215     }
216 
217 }