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.Hashtable; 27 import java.util.Iterator; 28 import java.util.Map; 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 * deployement descriptor as follows: 40 * 41 * <blockquote><code><pre> 42 * <listener> 43 * <listener-class> 44 * org.apache.turbine.session.SessionListener 45 * </listener-class> 46 * </listener> 47 * </pre></code></blockquote> 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 1066925 2011-02-03 19:44:37Z ludwig $ 53 * @see org.apache.turbine.services.session.TurbineSession 54 * @see org.apache.turbine.services.session.SessionListener 55 */ 56 public class TurbineSessionService 57 extends TurbineBaseService 58 implements SessionService 59 { 60 /** Map of active sessions */ 61 private Map<String, HttpSession> activeSessions; 62 63 /** 64 * Gets a list of the active sessions. 65 * 66 * @return A copy of the list of <code>HttpSession</code> objects. 67 */ 68 public Collection<HttpSession> getActiveSessions() 69 { 70 // Sync externally to allow ArrayList's ctor to iterate 71 // activeSessions' values in a thread-safe fashion. 72 synchronized (activeSessions) 73 { 74 return new ArrayList<HttpSession>(activeSessions.values()); 75 } 76 } 77 78 /** 79 * Adds a session to the current list. This method should only be 80 * called by the listener. 81 * 82 * @param session Session to add 83 */ 84 public void addSession(HttpSession session) 85 { 86 activeSessions.put(session.getId(), session); 87 } 88 89 /** 90 * Removes a session from the current list. This method should only be 91 * called by the listener. 92 * 93 * @param session Session to remove 94 */ 95 public void removeSession(HttpSession session) 96 { 97 activeSessions.remove(session.getId()); 98 } 99 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 }