    001package org.apache.turbine.services.session;
    002
    003
    004/*
    005 * Licensed to the Apache Software Foundation (ASF) under one
    006 * or more contributor license agreements.  See the NOTICE file
    007 * distributed with this work for additional information
    008 * regarding copyright ownership.  The ASF licenses this file
    009 * to you under the Apache License, Version 2.0 (the
    010 * "License"); you may not use this file except in compliance
    011 * with the License.  You may obtain a copy of the License at
    012 *
    013 *   http://www.apache.org/licenses/LICENSE-2.0
    014 *
    015 * Unless required by applicable law or agreed to in writing,
    016 * software distributed under the License is distributed on an
    017 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    018 * KIND, either express or implied.  See the License for the
    019 * specific language governing permissions and limitations
    020 * under the License.
    021 */
    022
    023
    024import java.util.ArrayList;
    025import java.util.Collection;
    026import java.util.concurrent.ConcurrentHashMap;
    027import java.util.concurrent.ConcurrentMap;
    028
    029import javax.servlet.http.HttpSession;
    030
    031import org.apache.turbine.om.security.User;
    032import org.apache.turbine.services.TurbineBaseService;
    033
    034/**
    035 * The SessionService allows thread-safe access to the current
    036 * sessions of the current context.  The session objects that are
    037 * cached by this service are obtained through a listener, which must
    038 * be configured via your web application's <code>web.xml</code>
    039 * deployment descriptor as follows:
    040 *
    041 * <pre>
    042 * &lt;listener&gt;
    043 *   &lt;listener-class&gt;
    044 *     org.apache.turbine.session.SessionListener
    045 *   &lt;/listener-class&gt;
    046 * &lt;/listener&gt;
    047 * </pre>
    048 *
    049 * @author <a href="mailto:quintonm@bellsouth.net">Quinton McCombs</a>
    050 * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
    051 * @since 2.3
    052 * @version $Id: TurbineSessionService.java 1773378 2016-12-09 13:19:59Z tv $
    053 * @see org.apache.turbine.services.session.SessionListener
    054 */
    055public class TurbineSessionService
    056        extends TurbineBaseService
    057        implements SessionService
    058{
    059    /** Map of active sessions */
    060    private ConcurrentMap<String, HttpSession> activeSessions;
    061
    062    /**
    063     * Gets a list of the active sessions.
    064     *
    065     * @return A copy of the list of <code>HttpSession</code> objects.
    066     */
    067    @Override
    068    public Collection<HttpSession> getActiveSessions()
    069    {
    070        return new ArrayList<HttpSession>(activeSessions.values());
    071    }
    072
    073    /**
    074     * Adds a session to the current list.  This method should only be
    075     * called by the listener.
    076     *
    077     * @param session Session to add
    078     */
    079    @Override
    080    public void addSession(HttpSession session)
    081    {
    082        activeSessions.put(session.getId(), session);
    083    }
    084
    085    /**
    086     * Removes a session from the current list.  This method should only be
    087     * called by the listener.
    088     *
    089     * @param session Session to remove
    090     */
    091    @Override
    092    public void removeSession(HttpSession session)
    093    {
    094        activeSessions.remove(session.getId());
    095    }
    096
    097    /**
    098     * Determines if a given user is currently logged in.  The actual
    099     * 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<User>((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<HttpSession>();
    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<String, HttpSession>();
    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}