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$ 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<>(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<>((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<>(); 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<>(); 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 }