Package org.jboss.seam.wiki.admin

Source Code of org.jboss.seam.wiki.admin.WikiHttpSessionManager$OnlineUser

/*
* JBoss, Home of Professional Open Source
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.seam.wiki.admin;

import org.jboss.seam.ScopeType;
import org.jboss.seam.wiki.core.model.User;
import org.jboss.seam.wiki.core.model.Role;
import org.jboss.seam.wiki.core.dao.UserDAO;
import org.jboss.seam.wiki.util.WikiUtil;
import org.jboss.seam.annotations.*;
import org.jboss.seam.annotations.security.Restrict;
import org.jboss.seam.log.Log;
import org.jboss.seam.security.Identity;

import javax.servlet.http.HttpSession;
import javax.persistence.EntityManager;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*;

/**
* @author Christian Bauer
*/
@Name("wikiHttpSessionManager")
@Scope(ScopeType.CONVERSATION)
@AutoCreate
public class WikiHttpSessionManager implements Serializable {

    protected static final String SESSION_ATTR_IDENTITY     = "org.jboss.seam.security.identity";
    protected static final String SESSION_ATTR_ACCESSLVL    = "currentAccessLevel";
    protected static final String SESSION_ATTR_USER         = "currentUser";

    @Logger
    private Log log;

    @In
    UserDAO userDAO;

    transient private Map<String, Boolean> selectedSessions = new HashMap<String,Boolean>();
    transient private Map<String, Long> sessionsSize = new HashMap<String,Long>();
    transient private List<OnlineUser> onlineMembers;

    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public Map<String, Boolean> getSelectedSessions() { return selectedSessions; }
    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public Map<String, Long> getSessionsSize() { return sessionsSize; }

    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public List<HttpSession> getSessions() {
        return new ArrayList(WikiServletListener.getSessions().values());
    }

    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public HttpSession getSession(String id) {
        return WikiServletListener.getSessions().get(id);
    }

    /**
     * Calculate the size of an HttpSession using serialization.
     * <p>
     * This is extremely crude and a guesstimate, especially because this ignores any
     * serialization errors.
     * </p>
     *
     * @param id the identifier of th HttpSession
     * @return size in bytes
     */
    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public long getSessionSize(String id) {
        HttpSession session = WikiServletListener.getSessions().get(id);
        long sessionSize = 0;
        if (session != null) {
            Enumeration elem = session.getAttributeNames();
            while (elem.hasMoreElements()) {
                String attName = (String)elem.nextElement();
                log.debug("serializing session attribute: " + attName);
                ByteArrayOutputStream bos = null;
                try {
                    bos = new ByteArrayOutputStream();
                    ObjectOutputStream out = new ObjectOutputStream(bos);
                    out.writeObject(
                        session.getAttribute(attName)
                    );
                    out.close();
                } catch (Exception ex) {
                    // Just swallow that
                    log.warn("error during serialization, ignoring: " + ex);
                }
                if (bos != null) {
                    byte[] buf = bos.toByteArray();
                    sessionSize = sessionSize + buf.length;
                }
            }
        }
        return sessionSize;
    }

    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public String getUsername(String id) {
        log.debug("trying to get username of Http session: " + id);
        HttpSession session = WikiServletListener.getSessions().get(id);
        String username = User.GUEST_USERNAME;
        if (session != null) {
            Identity identity = (Identity)session.getAttribute(SESSION_ATTR_IDENTITY);
            if (identity != null && identity.getPrincipal() != null)
                username = identity.getPrincipal().getName();
        }
        return username;
    }

    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public void calculateSelectedSessionsSize() {
        sessionsSize.clear();
        for (Map.Entry<String, Boolean> entry : selectedSessions.entrySet()) {
            if (entry.getValue()) {
                log.debug("calculating size of Http session: " + entry.getKey());
                sessionsSize.put(
                    entry.getKey(),
                    getSessionSize( entry.getKey() )
                );
            }
        }
        selectedSessions.clear();
    }

    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public void refresh() {
        selectedSessions.clear();
    }

    /* TODO: The way Seam handles sessions conflicts with "destroying" it from the "outside"
    @Restrict("#{s:hasPermission('User', 'isAdmin', currentUser)}")
    public void invalidateSelectedSessions() {
        for (Map.Entry<String, Boolean> entry : selectedSessions.entrySet()) {
            if (entry.getValue()) {
                HttpSession s = getSession(entry.getKey());
                if (s != null) {
                    log.debug("########### invalidating Http session: " + entry.getKey());
                    Session seamSession = (Session)s.getAttribute("org.jboss.seam.web.session");
                    seamSession.invalidate();
                }
            }
        }
        selectedSessions.clear();
    }
    */

    public long getTotalMembers() {
        return userDAO.findTotalNoOfUsers();
    }

    public List<OnlineUser> getOnlineMembers() {
        if (onlineMembers == null) loadOnlineMembers();
        return onlineMembers;
    }

    public long getNumberOfOnlineMembers() {
        if (onlineMembers == null) loadOnlineMembers();
        return onlineMembers.size();
    }

    public long getNumberOfOnlineGuests() {
        return WikiServletListener.getSessions().values().size() - getNumberOfOnlineMembers();
    }

    private void loadOnlineMembers() {
        onlineMembers = new ArrayList<OnlineUser>();

        // First get the usernames of members out of all sessions
        Map<String,HttpSession> onlineUsernames = new HashMap<String, HttpSession>();
        Collection<HttpSession> sessions = WikiServletListener.getSessions().values();
        for (HttpSession session : sessions) {
            Integer userLevel = (Integer)session.getAttribute(SESSION_ATTR_ACCESSLVL);
            if (userLevel != null && userLevel > Role.GUESTROLE_ACCESSLEVEL) {
                String username = ((User)session.getAttribute(SESSION_ATTR_USER)).getUsername();

                // Try to get the session with the smallest idle time
                if (onlineUsernames.containsKey(username)) {
                    try {
                        if (session.getLastAccessedTime() > onlineUsernames.get(username).getLastAccessedTime()) {
                            onlineUsernames.put(username, session);
                        }
                    } catch (IllegalStateException ex) {
                        // Just ignore that:
                        /*
                        Caused by: java.lang.IllegalStateException: getLastAccessedTime: Session already invalidated
                        at org.apache.catalina.session.StandardSession.getLastAccessedTime(StandardSession.java:439)
                        at org.apache.catalina.session.StandardSessionFacade.getLastAccessedTime(StandardSessionFacade.java:84)
                         */
                    }
                } else {
                    onlineUsernames.put(username, session);
                }
            }
        }

        // Then load these guys into a current persistence context
        List<User> userInstances = userDAO.findUsersWithUsername(onlineUsernames.keySet());

        for (User userInstance : userInstances) {
            // Now fill the OnlineUser DTO which is needed by the UI
            try {
                onlineMembers.add(
                    new OnlineUser(
                        userInstance,
                        onlineUsernames.get(userInstance.getUsername()).getLastAccessedTime()
                    )
                );
            } catch (IllegalStateException ex) {
                // Just ignore that:
                /*
                Caused by: java.lang.IllegalStateException: getLastAccessedTime: Session already invalidated
                at org.apache.catalina.session.StandardSession.getLastAccessedTime(StandardSession.java:439)
                at org.apache.catalina.session.StandardSessionFacade.getLastAccessedTime(StandardSessionFacade.java:84)
                 */
            }
        }

        Collections.sort(onlineMembers);
    }

    public static class OnlineUser implements Comparable {
        private User user;
        private long lastAccessedTime;

        public OnlineUser(User user, long lastAccessedTime) {
            this.user = user;
            this.lastAccessedTime = lastAccessedTime;
        }

        public User getUser() {
            return user;
        }

        public void setUser(User user) {
            this.user = user;
        }

        public long getLastAccessedTime() {
            return lastAccessedTime;
        }

        public void setLastAccessedTime(long lastAccessedTime) {
            this.lastAccessedTime = lastAccessedTime;
        }

        public String getIdleTime() {
            return WikiUtil.getTimeDifferenceToCurrent(WikiUtil.toDate(lastAccessedTime));
        }

        public int compareTo(Object o) {
            OnlineUser other = (OnlineUser) o;
            if (getLastAccessedTime() > other.getLastAccessedTime()) return -1;
            return (getLastAccessedTime() == other.getLastAccessedTime() ? 0 : 1);
        }
    }

}
TOP

Related Classes of org.jboss.seam.wiki.admin.WikiHttpSessionManager$OnlineUser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.