1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.acegisecurity.concurrent;
17
18 import java.util.ArrayList;
19 import java.util.Collections;
20 import java.util.Date;
21 import java.util.HashMap;
22 import java.util.HashSet;
23 import java.util.Iterator;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27
28 import javax.servlet.http.HttpSession;
29
30 import org.acegisecurity.ui.session.HttpSessionDestroyedEvent;
31
32 import org.springframework.context.ApplicationEvent;
33 import org.springframework.context.ApplicationListener;
34 import org.springframework.util.Assert;
35
36
37 /***
38 * Base implementation of {@link
39 * org.acegisecurity.concurrent.SessionRegistry} which also listens for
40 * {@link org.acegisecurity.ui.session.HttpSessionDestroyedEvent}s
41 * published in the Spring application context.
42 *
43 * <p>
44 * NB: It is important that you register the {@link
45 * org.acegisecurity.ui.session.HttpSessionEventPublisher} in
46 * <code>web.xml</code> so that this class is notified of sessions that
47 * expire.
48 * </p>
49 *
50 * @author Ben Alex
51 * @version $Id: SessionRegistryImpl.java,v 1.2 2005/11/17 00:55:56 benalex Exp ${date}
52 */
53 public class SessionRegistryImpl implements SessionRegistry,
54 ApplicationListener {
55
56
57 private Map principals = Collections.synchronizedMap(new HashMap());
58 private Map sessionIds = Collections.synchronizedMap(new HashMap());
59
60
61
62 public SessionInformation[] getAllSessions(Object principal) {
63 Set sessionsUsedByPrincipal = (Set) principals.get(principal);
64
65 if (sessionsUsedByPrincipal == null) {
66 return null;
67 }
68
69 List list = new ArrayList();
70 Iterator iter = sessionsUsedByPrincipal.iterator();
71 while (iter.hasNext()) {
72 String sessionId = (String) iter.next();
73 list.add(getSessionInformation(sessionId));
74 }
75
76 return (SessionInformation[]) list.toArray(new SessionInformation[] {});
77 }
78
79 public SessionInformation getSessionInformation(String sessionId) {
80 Assert.hasText(sessionId, "SessionId required as per inerface contract");
81
82 return (SessionInformation) sessionIds.get(sessionId);
83 }
84
85 public void onApplicationEvent(ApplicationEvent event) {
86 if (event instanceof HttpSessionDestroyedEvent) {
87 String sessionId = ((HttpSession) event.getSource()).getId();
88 removeSessionInformation(sessionId);
89 }
90 }
91
92 public void refreshLastRequest(String sessionId) {
93 Assert.hasText(sessionId, "SessionId required as per inerface contract");
94
95 SessionInformation info = getSessionInformation(sessionId);
96
97 if (info != null) {
98 info.refreshLastRequest();
99 }
100 }
101
102 public void registerNewSession(String sessionId, Object principal)
103 throws SessionAlreadyUsedException {
104 Assert.hasText(sessionId, "SessionId required as per inerface contract");
105 Assert.notNull(principal, "Principal required as per inerface contract");
106
107 if (getSessionInformation(sessionId) != null) {
108 throw new SessionAlreadyUsedException("Session " + sessionId
109 + " is already is use");
110 }
111
112 sessionIds.put(sessionId,
113 new SessionInformation(principal, sessionId, new Date()));
114
115 Set sessionsUsedByPrincipal = (Set) principals.get(principal);
116
117 if (sessionsUsedByPrincipal == null) {
118 sessionsUsedByPrincipal = Collections.synchronizedSet(new HashSet());
119 }
120
121 sessionsUsedByPrincipal.add(sessionId);
122
123 principals.put(principal, sessionsUsedByPrincipal);
124 }
125
126 public void removeSessionInformation(String sessionId) {
127 Assert.hasText(sessionId, "SessionId required as per inerface contract");
128
129 SessionInformation info = getSessionInformation(sessionId);
130
131 if (info != null) {
132 sessionIds.remove(sessionId);
133
134 Set sessionsUsedByPrincipal = (Set) principals.get(info
135 .getPrincipal());
136
137 if (sessionsUsedByPrincipal != null) {
138 sessionsUsedByPrincipal.remove(sessionId);
139
140 if (sessionsUsedByPrincipal.size() == 0) {
141
142 principals.remove(info.getPrincipal());
143 }
144 }
145 }
146 }
147 }