View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.server.session;
20  
21  import java.lang.ref.WeakReference;
22  import java.util.ArrayList;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.HashMap;
26  import java.util.HashSet;
27  import java.util.Iterator;
28  import java.util.Map;
29  import java.util.Random;
30  import java.util.Set;
31  
32  import javax.servlet.http.HttpServletRequest;
33  import javax.servlet.http.HttpSession;
34  
35  /* ------------------------------------------------------------ */
36  /**
37   * HashSessionIdManager. An in-memory implementation of the session ID manager.
38   */
39  public class HashSessionIdManager extends AbstractSessionIdManager
40  {
41      private final Map<String, Set<WeakReference<HttpSession>>> _sessions = new HashMap<String, Set<WeakReference<HttpSession>>>();
42  
43      /* ------------------------------------------------------------ */
44      public HashSessionIdManager()
45      {
46      }
47  
48      /* ------------------------------------------------------------ */
49      public HashSessionIdManager(Random random)
50      {
51          super(random);
52      }
53  
54      /* ------------------------------------------------------------ */
55      /**
56       * @return Collection of String session IDs
57       */
58      public Collection<String> getSessions()
59      {
60          return Collections.unmodifiableCollection(_sessions.keySet());
61      }
62  
63      /* ------------------------------------------------------------ */
64      /**
65       * @return Collection of Sessions for the passed session ID
66       */
67      public Collection<HttpSession> getSession(String id)
68      {
69          ArrayList<HttpSession> sessions = new ArrayList<HttpSession>();
70          Set<WeakReference<HttpSession>> refs =_sessions.get(id);
71          if (refs!=null)
72          {
73              for (WeakReference<HttpSession> ref: refs)
74              {
75                  HttpSession session = ref.get();
76                  if (session!=null)
77                      sessions.add(session);
78              }
79          }
80          return sessions;
81      }
82      
83      /* ------------------------------------------------------------ */
84      @Override
85      protected void doStart() throws Exception
86      {
87          super.doStart();
88      }
89  
90      /* ------------------------------------------------------------ */
91      @Override
92      protected void doStop() throws Exception
93      {
94          _sessions.clear();
95          super.doStop();
96      }
97  
98      /* ------------------------------------------------------------ */
99      /**
100      * @see SessionIdManager#idInUse(String)
101      */
102     @Override
103     public boolean idInUse(String id)
104     {
105         synchronized (this)
106         {
107             return _sessions.containsKey(id);
108         }
109     }
110 
111     /* ------------------------------------------------------------ */
112     /**
113      * @see SessionIdManager#addSession(HttpSession)
114      */
115     @Override
116     public void addSession(HttpSession session)
117     {
118         String id = getClusterId(session.getId());
119         WeakReference<HttpSession> ref = new WeakReference<HttpSession>(session);
120 
121         synchronized (this)
122         {
123             Set<WeakReference<HttpSession>> sessions = _sessions.get(id);
124             if (sessions==null)
125             {
126                 sessions=new HashSet<WeakReference<HttpSession>>();
127                 _sessions.put(id,sessions);
128             }
129             sessions.add(ref);
130         }
131     }
132 
133     /* ------------------------------------------------------------ */
134     /**
135      * @see SessionIdManager#removeSession(HttpSession)
136      */
137     @Override
138     public void removeSession(HttpSession session)
139     {
140         String id = getClusterId(session.getId());
141 
142         synchronized (this)
143         {
144             Collection<WeakReference<HttpSession>> sessions = _sessions.get(id);
145             if (sessions!=null)
146             {
147                 for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();)
148                 {
149                     WeakReference<HttpSession> ref = iter.next();
150                     HttpSession s=ref.get();
151                     if (s==null)
152                     {
153                         iter.remove();
154                         continue;
155                     }
156                     if (s==session)
157                     {
158                         iter.remove();
159                         break;
160                     }
161                 }
162                 if (sessions.isEmpty())
163                     _sessions.remove(id);
164             }
165         }
166     }
167 
168     /* ------------------------------------------------------------ */
169     /**
170      * @see SessionIdManager#invalidateAll(String)
171      */
172     @Override
173     public void invalidateAll(String id)
174     {
175         Collection<WeakReference<HttpSession>> sessions;
176         synchronized (this)
177         {
178             sessions = _sessions.remove(id);
179         }
180 
181         if (sessions!=null)
182         {
183             for (WeakReference<HttpSession> ref: sessions)
184             {
185                 AbstractSession session=(AbstractSession)ref.get();
186                 if (session!=null && session.isValid())
187                     session.invalidate();
188             }
189             sessions.clear();
190         }
191     }
192     
193     
194     /* ------------------------------------------------------------ */
195     @Override
196     public void renewSessionId (String oldClusterId, String oldNodeId, HttpServletRequest request)
197     {
198         //generate a new id
199         String newClusterId = newSessionId(request.hashCode());
200 
201 
202         synchronized (this)
203         {
204             Set<WeakReference<HttpSession>> sessions = _sessions.remove(oldClusterId); //get the list of sessions with same id from other contexts
205             if (sessions!=null)
206             {
207                 for (Iterator<WeakReference<HttpSession>> iter = sessions.iterator(); iter.hasNext();)
208                 {
209                     WeakReference<HttpSession> ref = iter.next();
210                     HttpSession s = ref.get();
211                     if (s == null)
212                     {
213                         continue;
214                     }
215                     else
216                     {
217                         if (s instanceof AbstractSession)
218                         {
219                             AbstractSession abstractSession = (AbstractSession)s;
220                             abstractSession.getSessionManager().renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
221                         }
222                     }
223                 }
224                 _sessions.put(newClusterId, sessions);
225             }
226         }
227     }
228 
229 }