View Javadoc

    1   /* Copyright 2004, 2005 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 java.util.ArrayList;
    19  import java.util.Collections;
    20  import java.util.Date;
    21  import java.util.HashMap;
    22  import java.util.HashSet;
    23  import java.util.Iterator;
    24  import java.util.List;
    25  import java.util.Map;
    26  import java.util.Set;
    27
    28  import javax.servlet.http.HttpSession;
    29
    30  import org.acegisecurity.ui.session.HttpSessionDestroyedEvent;
    31
    32  import org.springframework.context.ApplicationEvent;
    33  import org.springframework.context.ApplicationListener;
    34  import org.springframework.util.Assert;
    35
    36
    37  /***
    38   * Base implementation of {@link
    39   * org.acegisecurity.concurrent.SessionRegistry} which also listens for
    40   * {@link org.acegisecurity.ui.session.HttpSessionDestroyedEvent}s
    41   * published in the Spring application context.
    42   *
    43   * <p>
    44   * NB: It is important that you register the {@link
    45   * org.acegisecurity.ui.session.HttpSessionEventPublisher} in
    46   * <code>web.xml</code> so that this class is notified of sessions that
    47   * expire.
    48   * </p>
    49   *
    50   * @author Ben Alex
    51   * @version $Id: SessionRegistryImpl.java,v 1.2 2005/11/17 00:55:56 benalex Exp ${date}
    52   */
    53  public class SessionRegistryImpl implements SessionRegistry,
    54      ApplicationListener {
    55      //~ Instance fields ========================================================
    56
    57      private Map principals = Collections.synchronizedMap(new HashMap()); // <principal:Object,SessionIdSet>
    58      private Map sessionIds = Collections.synchronizedMap(new HashMap()); // <sessionId:Object,SessionInformation>
    59
    60      //~ Methods ================================================================
    61
    62      public SessionInformation[] getAllSessions(Object principal) {
    63          Set sessionsUsedByPrincipal = (Set) principals.get(principal);
    64
    65          if (sessionsUsedByPrincipal == null) {
    66              return null;
    67          }
    68
    69          List list = new ArrayList();
    70          Iterator iter = sessionsUsedByPrincipal.iterator();
    71          while (iter.hasNext()) {
    72          	String sessionId = (String) iter.next();
    73          	list.add(getSessionInformation(sessionId));
    74          }
    75
    76          return (SessionInformation[]) list.toArray(new SessionInformation[] {});
    77      }
    78
    79      public SessionInformation getSessionInformation(String sessionId) {
    80          Assert.hasText(sessionId, "SessionId required as per inerface contract");
    81
    82          return (SessionInformation) sessionIds.get(sessionId);
    83      }
    84
    85      public void onApplicationEvent(ApplicationEvent event) {
    86          if (event instanceof HttpSessionDestroyedEvent) {
    87              String sessionId = ((HttpSession) event.getSource()).getId();
    88              removeSessionInformation(sessionId);
    89          }
    90      }
    91
    92      public void refreshLastRequest(String sessionId) {
    93          Assert.hasText(sessionId, "SessionId required as per inerface contract");
    94
    95          SessionInformation info = getSessionInformation(sessionId);
    96
    97          if (info != null) {
    98              info.refreshLastRequest();
    99          }
    100     }
    101
    102     public void registerNewSession(String sessionId, Object principal)
    103         throws SessionAlreadyUsedException {
    104         Assert.hasText(sessionId, "SessionId required as per inerface contract");
    105         Assert.notNull(principal, "Principal required as per inerface contract");
    106
    107         if (getSessionInformation(sessionId) != null) {
    108             throw new SessionAlreadyUsedException("Session " + sessionId
    109                 + " is already is use");
    110         }
    111
    112         sessionIds.put(sessionId,
    113             new SessionInformation(principal, sessionId, new Date()));
    114
    115         Set sessionsUsedByPrincipal = (Set) principals.get(principal);
    116
    117         if (sessionsUsedByPrincipal == null) {
    118             sessionsUsedByPrincipal = Collections.synchronizedSet(new HashSet());
    119         }
    120
    121         sessionsUsedByPrincipal.add(sessionId);
    122
    123         principals.put(principal, sessionsUsedByPrincipal);
    124     }
    125
    126     public void removeSessionInformation(String sessionId) {
    127         Assert.hasText(sessionId, "SessionId required as per inerface contract");
    128
    129         SessionInformation info = getSessionInformation(sessionId);
    130
    131         if (info != null) {
    132             sessionIds.remove(sessionId);
    133
    134             Set sessionsUsedByPrincipal = (Set) principals.get(info
    135                     .getPrincipal());
    136
    137             if (sessionsUsedByPrincipal != null) {
    138                 sessionsUsedByPrincipal.remove(sessionId);
    139
    140                 if (sessionsUsedByPrincipal.size() == 0) {
    141                 	// No need to keep pbject in principals Map anymore
    142                 	principals.remove(info.getPrincipal());
    143                 }
    144             }
    145         }
    146     }
    147 }