1 package org.apache.turbine.services.session;
2
3
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one
6 * or more contributor license agreements. See the NOTICE file
7 * distributed with this work for additional information
8 * regarding copyright ownership. The ASF licenses this file
9 * to you under the Apache License, Version 2.0 (the
10 * "License"); you may not use this file except in compliance
11 * with the License. You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing,
16 * software distributed under the License is distributed on an
17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
18 * KIND, either express or implied. See the License for the
19 * specific language governing permissions and limitations
20 * under the License.
21 */
22
23
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.ConcurrentMap;
28
29 import javax.servlet.http.HttpSession;
30
31 import org.apache.turbine.om.security.User;
32 import org.apache.turbine.services.TurbineBaseService;
33
34 /**
35 * The SessionService allows thread-safe access to the current
36 * sessions of the current context. The session objects that are
37 * cached by this service are obtained through a listener, which must
38 * be configured via your web application's <code>web.xml</code>
39 * deployment descriptor as follows:
40 *
41 * <pre>
42 * <listener>
43 * <listener-class>
44 * org.apache.turbine.session.SessionListener
45 * </listener-class>
46 * </listener>
47 * </pre>
48 *
49 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
50 * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
51 * @since 2.3
52 * @version $Id: TurbineSessionService.java 1773378 2016-12-09 13:19:59Z tv $
53 * @see org.apache.turbine.services.session.SessionListener
54 */
55 public class TurbineSessionService
56 extends TurbineBaseService
57 implements SessionService
58 {
59 /** Map of active sessions */
60 private ConcurrentMap<String, HttpSession> activeSessions;
61
62 /**
63 * Gets a list of the active sessions.
64 *
65 * @return A copy of the list of <code>HttpSession</code> objects.
66 */
67 @Override
68 public Collection<HttpSession> getActiveSessions()
69 {
70 return new ArrayList<HttpSession>(activeSessions.values());
71 }
72
73 /**
74 * Adds a session to the current list. This method should only be
75 * called by the listener.
76 *
77 * @param session Session to add
78 */
79 @Override
80 public void addSession(HttpSession session)
81 {
82 activeSessions.put(session.getId(), session);
83 }
84
85 /**
86 * Removes a session from the current list. This method should only be
87 * called by the listener.
88 *
89 * @param session Session to remove
90 */
91 @Override
92 public void removeSession(HttpSession session)
93 {
94 activeSessions.remove(session.getId());
95 }
96
97 /**
98 * Determines if a given user is currently logged in. The actual
99 * implementation of the User object must implement the equals()
100 * method. By default, Torque based objects (liek TurbineUser)
101 * have an implementation of equals() that will compare the
102 * result of getPrimaryKey().
103 *
104 * @param user User to check for
105 * @return true if the user is logged in on one of the
106 * active sessions.
107 */
108 @Override
109 public boolean isUserLoggedIn(User user)
110 {
111 return getActiveUsers().contains(user);
112 }
113
114 /**
115 * Gets a collection of all user objects representing the users currently
116 * logged in. This will exclude any instances of anonymous user that
117 * Turbine will use before the user actually logs on.
118 *
119 * @return A set of {@link org.apache.turbine.om.security.User} objects.
120 */
121 @Override
122 public Collection<User> getActiveUsers()
123 {
124 Collection<User> users;
125 // Pre-allocate a list which won't need expansion more
126 // than once.
127 users = new ArrayList<User>((int) (activeSessions.size() * 0.7));
128 for (HttpSession session : activeSessions.values())
129 {
130 User u = getUserFromSession(session);
131 if (u != null && u.hasLoggedIn())
132 {
133 users.add(u);
134 }
135 }
136
137 return users;
138 }
139
140 /**
141 * Gets the User object of the the specified HttpSession.
142 *
143 * @param session The session from which to extract a user.
144 * @return The Turbine User object.
145 */
146 @Override
147 public User getUserFromSession(HttpSession session)
148 {
149 // Not sure of other containers, but Tomcat 5.0.28 sometimes returns
150 // invalid sessions which will result in IllegalStateException when
151 // session.getAttribute() is invoked below.
152 try
153 {
154 return (User) session.getAttribute(User.SESSION_KEY);
155 }
156 catch (IllegalStateException e)
157 {
158 return null;
159 }
160 }
161
162 /**
163 * Gets the HttpSession by the session identifier
164 *
165 * @param sessionId The unique session identifier.
166 * @return The session keyed by the specified identifier.
167 */
168 @Override
169 public HttpSession getSession(String sessionId)
170 {
171 return this.activeSessions.get(sessionId);
172 }
173
174 /**
175 * Get a collection of all session on which the given user
176 * is logged in.
177 *
178 * @param user the user
179 * @return Collection of HtttSession objects
180 */
181 @Override
182 public Collection<HttpSession> getSessionsForUser(User user)
183 {
184 Collection<HttpSession> sessions = new ArrayList<HttpSession>();
185 for (HttpSession session : activeSessions.values())
186 {
187 User u = this.getUserFromSession(session);
188 if (user.equals(u))
189 {
190 sessions.add(session);
191 }
192 }
193
194 return sessions;
195 }
196
197
198 // ---- Service initialization ------------------------------------------
199
200 /**
201 * Initializes the service
202 */
203 @Override
204 public void init()
205 {
206 this.activeSessions = new ConcurrentHashMap<String, HttpSession>();
207
208 setInit(true);
209 }
210
211 /**
212 * Returns to uninitialized state.
213 */
214 @Override
215 public void shutdown()
216 {
217 this.activeSessions = null;
218
219 setInit(false);
220 }
221
222 }