1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.security.concurrent;
17
18 import org.springframework.security.ui.session.HttpSessionDestroyedEvent;
19
20 import org.springframework.context.ApplicationEvent;
21 import org.springframework.context.ApplicationListener;
22
23 import org.springframework.util.Assert;
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.Date;
30 import java.util.HashMap;
31 import java.util.HashSet;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36
37 import javax.servlet.http.HttpSession;
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 public class SessionRegistryImpl implements SessionRegistry, ApplicationListener {
53
54
55 protected static final Log logger = LogFactory.getLog(SessionRegistryImpl.class);
56
57
58
59 private Map principals = Collections.synchronizedMap(new HashMap());
60 private Map sessionIds = Collections.synchronizedMap(new HashMap());
61
62
63
64 public Object[] getAllPrincipals() {
65 return principals.keySet().toArray();
66 }
67
68 public SessionInformation[] getAllSessions(Object principal, boolean includeExpiredSessions) {
69 Set sessionsUsedByPrincipal = (Set) principals.get(principal);
70
71 if (sessionsUsedByPrincipal == null) {
72 return null;
73 }
74
75 List list = new ArrayList();
76
77 synchronized (sessionsUsedByPrincipal) {
78 for (Iterator iter = sessionsUsedByPrincipal.iterator(); iter.hasNext();) {
79 String sessionId = (String) iter.next();
80 SessionInformation sessionInformation = getSessionInformation(sessionId);
81
82 if (sessionInformation == null) {
83 continue;
84 }
85
86 if (includeExpiredSessions || !sessionInformation.isExpired()) {
87 list.add(sessionInformation);
88 }
89 }
90 }
91
92 return (SessionInformation[]) list.toArray(new SessionInformation[] {});
93 }
94
95 public SessionInformation getSessionInformation(String sessionId) {
96 Assert.hasText(sessionId, "SessionId required as per interface contract");
97
98 return (SessionInformation) sessionIds.get(sessionId);
99 }
100
101 public void onApplicationEvent(ApplicationEvent event) {
102 if (event instanceof HttpSessionDestroyedEvent) {
103 String sessionId = ((HttpSession) event.getSource()).getId();
104 removeSessionInformation(sessionId);
105 }
106 }
107
108 public void refreshLastRequest(String sessionId) {
109 Assert.hasText(sessionId, "SessionId required as per interface contract");
110
111 SessionInformation info = getSessionInformation(sessionId);
112
113 if (info != null) {
114 info.refreshLastRequest();
115 }
116 }
117
118 public synchronized void registerNewSession(String sessionId, Object principal) {
119 Assert.hasText(sessionId, "SessionId required as per interface contract");
120 Assert.notNull(principal, "Principal required as per interface contract");
121
122 if (logger.isDebugEnabled()) {
123 logger.debug("Registering session " + sessionId +", for principal " + principal);
124 }
125
126 if (getSessionInformation(sessionId) != null) {
127 removeSessionInformation(sessionId);
128 }
129
130 sessionIds.put(sessionId, new SessionInformation(principal, sessionId, new Date()));
131
132 Set sessionsUsedByPrincipal = (Set) principals.get(principal);
133
134 if (sessionsUsedByPrincipal == null) {
135 sessionsUsedByPrincipal = Collections.synchronizedSet(new HashSet(4));
136 principals.put(principal, sessionsUsedByPrincipal);
137 }
138
139 sessionsUsedByPrincipal.add(sessionId);
140 }
141
142 public void removeSessionInformation(String sessionId) {
143 Assert.hasText(sessionId, "SessionId required as per interface contract");
144
145 SessionInformation info = getSessionInformation(sessionId);
146
147 if (info == null) {
148 return;
149 }
150
151 if (logger.isDebugEnabled()) {
152 logger.debug("Removing session " + sessionId + " from set of registered sessions");
153 }
154
155 sessionIds.remove(sessionId);
156
157 Set sessionsUsedByPrincipal = (Set) principals.get(info.getPrincipal());
158
159 if (sessionsUsedByPrincipal == null) {
160 return;
161 }
162
163 if (logger.isDebugEnabled()) {
164 logger.debug("Removing session " + sessionId + " from principal's set of registered sessions");
165 }
166
167 synchronized (sessionsUsedByPrincipal) {
168 sessionsUsedByPrincipal.remove(sessionId);
169
170 if (sessionsUsedByPrincipal.size() == 0) {
171
172 if (logger.isDebugEnabled()) {
173 logger.debug("Removing principal " + info.getPrincipal() + " from registry");
174 }
175 principals.remove(info.getPrincipal());
176 }
177 }
178 }
179 }