View Javadoc
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   * &lt;listener&gt;
43   *   &lt;listener-class&gt;
44   *     org.apache.turbine.session.SessionListener
45   *   &lt;/listener-class&gt;
46   * &lt;/listener&gt;
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 }