001 package org.apache.turbine.services.session;
002
003
004 /*
005 * Licensed to the Apache Software Foundation (ASF) under one
006 * or more contributor license agreements. See the NOTICE file
007 * distributed with this work for additional information
008 * regarding copyright ownership. The ASF licenses this file
009 * to you under the Apache License, Version 2.0 (the
010 * "License"); you may not use this file except in compliance
011 * with the License. You may obtain a copy of the License at
012 *
013 * http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing,
016 * software distributed under the License is distributed on an
017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018 * KIND, either express or implied. See the License for the
019 * specific language governing permissions and limitations
020 * under the License.
021 */
022
023
024 import java.util.ArrayList;
025 import java.util.Collection;
026 import java.util.Hashtable;
027 import java.util.Iterator;
028 import java.util.Map;
029 import javax.servlet.http.HttpSession;
030
031 import org.apache.turbine.om.security.User;
032 import org.apache.turbine.services.TurbineBaseService;
033
034 /**
035 * The SessionService allows thread-safe access to the current
036 * sessions of the current context. The session objects that are
037 * cached by this service are obtained through a listener, which must
038 * be configured via your web application's <code>web.xml</code>
039 * deployement descriptor as follows:
040 *
041 * <blockquote><code><pre>
042 * <listener>
043 * <listener-class>
044 * org.apache.turbine.session.SessionListener
045 * </listener-class>
046 * </listener>
047 * </pre></code></blockquote>
048 *
049 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
050 * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
051 * @since 2.3
052 * @version $Id: TurbineSessionService.java 1066925 2011-02-03 19:44:37Z ludwig $
053 * @see org.apache.turbine.services.session.TurbineSession
054 * @see org.apache.turbine.services.session.SessionListener
055 */
056 public class TurbineSessionService
057 extends TurbineBaseService
058 implements SessionService
059 {
060 /** Map of active sessions */
061 private Map<String, HttpSession> activeSessions;
062
063 /**
064 * Gets a list of the active sessions.
065 *
066 * @return A copy of the list of <code>HttpSession</code> objects.
067 */
068 public Collection<HttpSession> getActiveSessions()
069 {
070 // Sync externally to allow ArrayList's ctor to iterate
071 // activeSessions' values in a thread-safe fashion.
072 synchronized (activeSessions)
073 {
074 return new ArrayList<HttpSession>(activeSessions.values());
075 }
076 }
077
078 /**
079 * Adds a session to the current list. This method should only be
080 * called by the listener.
081 *
082 * @param session Session to add
083 */
084 public void addSession(HttpSession session)
085 {
086 activeSessions.put(session.getId(), session);
087 }
088
089 /**
090 * Removes a session from the current list. This method should only be
091 * called by the listener.
092 *
093 * @param session Session to remove
094 */
095 public void removeSession(HttpSession session)
096 {
097 activeSessions.remove(session.getId());
098 }
099
100 /**
101 * Determines if a given user is currently logged in. The actual
102 * implementation of the User object must implement the equals()
103 * method. By default, Torque based objects (liek TurbineUser)
104 * have an implementation of equals() that will compare the
105 * result of getPrimaryKey().
106 *
107 * @param user User to check for
108 * @return true if the user is logged in on one of the
109 * active sessions.
110 */
111 public boolean isUserLoggedIn(User user)
112 {
113 return getActiveUsers().contains(user);
114 }
115
116 /**
117 * Gets a collection of all user objects representing the users currently
118 * logged in. This will exclude any instances of anonymous user that
119 * Turbine will use before the user actually logs on.
120 *
121 * @return A set of {@link org.apache.turbine.om.security.User} objects.
122 */
123 public Collection<User> getActiveUsers()
124 {
125 Collection<User> users;
126 synchronized (activeSessions)
127 {
128 // Pre-allocate a list which won't need expansion more
129 // than once.
130 users = new ArrayList<User>((int) (activeSessions.size() * 0.7));
131 for (Iterator<HttpSession> i = activeSessions.values().iterator(); i.hasNext();)
132 {
133 User u = getUserFromSession(i.next());
134 if (u != null && u.hasLoggedIn())
135 {
136 users.add(u);
137 }
138 }
139 }
140
141 return users;
142 }
143
144 /**
145 * Gets the User object of the the specified HttpSession.
146 *
147 * @param session The session from which to extract a user.
148 * @return The Turbine User object.
149 */
150 public User getUserFromSession(HttpSession session)
151 {
152 // Not sure of other containers, but Tomcat 5.0.28 sometimes returns
153 // invalid sessions which will result in IllegalStateException when
154 // session.getAttribute() is invoked below.
155 try
156 {
157 return (User) session.getAttribute(User.SESSION_KEY);
158 }
159 catch (IllegalStateException e)
160 {
161 return null;
162 }
163 }
164
165 /**
166 * Gets the HttpSession by the session identifier
167 *
168 * @param sessionId The unique session identifier.
169 * @return The session keyed by the specified identifier.
170 */
171 public HttpSession getSession(String sessionId)
172 {
173 return this.activeSessions.get(sessionId);
174 }
175
176 /**
177 * Get a collection of all session on which the given user
178 * is logged in.
179 *
180 * @param user the user
181 * @return Collection of HtttSession objects
182 */
183 public Collection<HttpSession> getSessionsForUser(User user)
184 {
185 Collection<HttpSession> sessions = new ArrayList<HttpSession>();
186 synchronized (activeSessions)
187 {
188 for (Iterator<HttpSession> i = activeSessions.values().iterator(); i.hasNext();)
189 {
190 HttpSession session = i.next();
191 User u = this.getUserFromSession(session);
192 if (user.equals(u))
193 {
194 sessions.add(session);
195 }
196 }
197 }
198
199 return sessions;
200 }
201
202
203 // ---- Service initilization ------------------------------------------
204
205 /**
206 * Initializes the service
207 */
208 @Override
209 public void init()
210 {
211 this.activeSessions = new Hashtable<String, HttpSession>();
212
213 setInit(true);
214 }
215
216 /**
217 * Returns to uninitialized state.
218 */
219 @Override
220 public void shutdown()
221 {
222 this.activeSessions = null;
223
224 setInit(false);
225 }
226
227 }