Coverage Report - org.acegisecurity.concurrent.SessionRegistryImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
SessionRegistryImpl
94% 
100% 
3.286
 
 1  
 /* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
 2  
  *
 3  
  * Licensed under the Apache License, Version 2.0 (the "License");
 4  
  * you may not use this file except in compliance with the License.
 5  
  * You may obtain a copy of the License at
 6  
  *
 7  
  *     http://www.apache.org/licenses/LICENSE-2.0
 8  
  *
 9  
  * Unless required by applicable law or agreed to in writing, software
 10  
  * distributed under the License is distributed on an "AS IS" BASIS,
 11  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  
  * See the License for the specific language governing permissions and
 13  
  * limitations under the License.
 14  
  */
 15  
 
 16  
 package org.acegisecurity.concurrent;
 17  
 
 18  
 import org.acegisecurity.ui.session.HttpSessionDestroyedEvent;
 19  
 
 20  
 import org.springframework.context.ApplicationEvent;
 21  
 import org.springframework.context.ApplicationListener;
 22  
 
 23  
 import org.springframework.util.Assert;
 24  
 import org.apache.commons.logging.Log;
 25  
 import org.apache.commons.logging.LogFactory;
 26  
 
 27  
 import java.util.ArrayList;
 28  
 import java.util.Collections;
 29  
 import java.util.Date;
 30  
 import java.util.HashMap;
 31  
 import java.util.HashSet;
 32  
 import java.util.Iterator;
 33  
 import java.util.List;
 34  
 import java.util.Map;
 35  
 import java.util.Set;
 36  
 
 37  
 import javax.servlet.http.HttpSession;
 38  
 
 39  
 /**
 40  
  * Base implementation of {@link org.acegisecurity.concurrent.SessionRegistry}
 41  
  * which also listens for {@link org.acegisecurity.ui.session.HttpSessionDestroyedEvent}s
 42  
  * published in the Spring application context.
 43  
  *
 44  
  * <p>
 45  
  * NB: It is important that you register the {@link org.acegisecurity.ui.session.HttpSessionEventPublisher} in
 46  
  * <code>web.xml</code> so that this class is notified of sessions that expire.
 47  
  * </p>
 48  
  *
 49  
  * @author Ben Alex
 50  
  * @version $Id: SessionRegistryImpl.java 1991 2007-08-30 19:04:18Z luke_t $
 51  
  */
 52  11
 public class SessionRegistryImpl implements SessionRegistry, ApplicationListener {
 53  
     //~ Static fields/initializers =====================================================================================
 54  
 
 55  2
     protected static final Log logger = LogFactory.getLog(SessionRegistryImpl.class);
 56  
 
 57  
     // ~ Instance fields ===============================================================================================
 58  
 
 59  11
         private Map principals = Collections.synchronizedMap(new HashMap()); // <principal:Object,SessionIdSet>
 60  11
         private Map sessionIds = Collections.synchronizedMap(new HashMap()); // <sessionId:Object,SessionInformation>
 61  
 
 62  
         // ~ Methods =======================================================================================================
 63  
 
 64  
         public Object[] getAllPrincipals() {
 65  7096546
                 return principals.keySet().toArray();
 66  
         }
 67  
 
 68  
         public SessionInformation[] getAllSessions(Object principal, boolean includeExpiredSessions) {
 69  14141329
                 Set sessionsUsedByPrincipal = (Set) principals.get(principal);
 70  
 
 71  14188712
         if (sessionsUsedByPrincipal == null) {
 72  14191549
                         return null;
 73  
                 }
 74  
 
 75  38834
                 List list = new ArrayList();
 76  
 
 77  38839
         synchronized (sessionsUsedByPrincipal) {
 78  38843
                         for (Iterator iter = sessionsUsedByPrincipal.iterator(); iter.hasNext();) {
 79  599180
                                 String sessionId = (String) iter.next();
 80  599180
                                 SessionInformation sessionInformation = getSessionInformation(sessionId);
 81  
 
 82  599180
                 if (sessionInformation == null) {
 83  451
                     continue;
 84  
                 }
 85  
 
 86  598729
                 if (includeExpiredSessions || !sessionInformation.isExpired()) {
 87  598729
                                         list.add(sessionInformation);
 88  
                                 }
 89  598729
                         }
 90  38843
                 }
 91  
 
 92  38843
                 return (SessionInformation[]) list.toArray(new SessionInformation[] {});
 93  
         }
 94  
 
 95  
         public SessionInformation getSessionInformation(String sessionId) {
 96  599668
                 Assert.hasText(sessionId, "SessionId required as per interface contract");
 97  
 
 98  599669
                 return (SessionInformation) sessionIds.get(sessionId);
 99  
         }
 100  
 
 101  
         public void onApplicationEvent(ApplicationEvent event) {
 102  1
                 if (event instanceof HttpSessionDestroyedEvent) {
 103  1
                         String sessionId = ((HttpSession) event.getSource()).getId();
 104  1
                         removeSessionInformation(sessionId);
 105  
                 }
 106  1
         }
 107  
 
 108  
         public void refreshLastRequest(String sessionId) {
 109  1
                 Assert.hasText(sessionId, "SessionId required as per interface contract");
 110  
 
 111  1
                 SessionInformation info = getSessionInformation(sessionId);
 112  
 
 113  1
                 if (info != null) {
 114  1
                         info.refreshLastRequest();
 115  
                 }
 116  1
         }
 117  
 
 118  
         public synchronized void registerNewSession(String sessionId, Object principal) {
 119  164
                 Assert.hasText(sessionId, "SessionId required as per interface contract");
 120  164
                 Assert.notNull(principal, "Principal required as per interface contract");
 121  
 
 122  164
         if (logger.isDebugEnabled()) {
 123  0
             logger.debug("Registering session " + sessionId +", for principal " + principal);
 124  
         }
 125  
 
 126  164
         if (getSessionInformation(sessionId) != null) {
 127  1
                         removeSessionInformation(sessionId);
 128  
                 }
 129  
 
 130  164
         sessionIds.put(sessionId, new SessionInformation(principal, sessionId, new Date()));
 131  
 
 132  164
         Set sessionsUsedByPrincipal = (Set) principals.get(principal);
 133  
 
 134  164
                 if (sessionsUsedByPrincipal == null) {
 135  13
                         sessionsUsedByPrincipal = Collections.synchronizedSet(new HashSet());
 136  
                 }
 137  
 
 138  164
                 sessionsUsedByPrincipal.add(sessionId);
 139  
 
 140  164
                 principals.put(principal, sessionsUsedByPrincipal);
 141  164
         }
 142  
 
 143  
         public void removeSessionInformation(String sessionId) {
 144  304
                 Assert.hasText(sessionId, "SessionId required as per interface contract");
 145  
 
 146  304
                 SessionInformation info = getSessionInformation(sessionId);
 147  
 
 148  304
                 if (info != null) {
 149  155
             if (logger.isDebugEnabled()) {
 150  0
                 logger.debug("Removing session " + sessionId + " from set of registered sessions");
 151  
             }
 152  155
             sessionIds.remove(sessionId);
 153  
 
 154  155
             Set sessionsUsedByPrincipal = (Set) principals.get(info.getPrincipal());
 155  
 
 156  155
             if (sessionsUsedByPrincipal != null) {
 157  155
                                 synchronized (sessionsUsedByPrincipal) {
 158  155
                     if (logger.isDebugEnabled()) {
 159  0
                         logger.debug("Removing session " + sessionId + " from principal's set of registered sessions");
 160  
                     }
 161  
 
 162  155
                                         sessionsUsedByPrincipal.remove(sessionId);
 163  
 
 164  155
                                         if (sessionsUsedByPrincipal.size() == 0) {
 165  
                                                 // No need to keep object in principals Map anymore
 166  7
                         if (logger.isDebugEnabled()) {
 167  0
                             logger.debug("Removing principal " + info.getPrincipal() + " from registry");
 168  
                         }
 169  7
                         principals.remove(info.getPrincipal());
 170  
                                         }
 171  155
                                 }
 172  
                         }
 173  
                 }
 174  304
         }
 175  
 }