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 }