package org.appfuse.webapp.listener;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
import org.acegisecurity.context.HttpSessionContextIntegrationFilter;
import org.acegisecurity.context.SecurityContext;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.Authentication;
import org.acegisecurity.AuthenticationTrustResolver;
import org.acegisecurity.AuthenticationTrustResolverImpl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.appfuse.model.User;
public class UserCounterListener implements ServletContextListener, HttpSessionAttributeListener {
public static final String COUNT_KEY = "userCounter";
public static final String USERS_KEY = "userNames";
public static final String EVENT_KEY = HttpSessionContextIntegrationFilter.ACEGI_SECURITY_CONTEXT_KEY;
private final transient Log log = LogFactory.getLog(UserCounterListener.class);
private transient ServletContext servletContext;
private int counter;
private Set users;
public synchronized void contextInitialized(ServletContextEvent sce) {
servletContext = sce.getServletContext();
servletContext.setAttribute((COUNT_KEY), Integer.toString(counter));
}
public synchronized void contextDestroyed(ServletContextEvent event) {
servletContext = null;
users = null;
counter = 0;
}
synchronized void incrementUserCounter() {
counter =
Integer.parseInt((String) servletContext.getAttribute(COUNT_KEY));
counter++;
servletContext.setAttribute(COUNT_KEY, Integer.toString(counter));
if (log.isDebugEnabled()) {
log.debug("User Count: " + counter);
}
}
synchronized void decrementUserCounter() {
int counter =
Integer.parseInt((String) servletContext.getAttribute(COUNT_KEY));
counter--;
if (counter < 0) {
counter = 0;
}
servletContext.setAttribute(COUNT_KEY, Integer.toString(counter));
if (log.isDebugEnabled()) {
log.debug("User Count: " + counter);
}
}
synchronized void addUsername(Object user) {
users = (Set) servletContext.getAttribute(USERS_KEY);
if (users == null) {
users = new HashSet();
}
if (log.isDebugEnabled()) {
if (users.contains(user)) {
log.debug("User already logged in, adding anyway...");
}
}
users.add(user);
servletContext.setAttribute(USERS_KEY, users);
incrementUserCounter();
}
synchronized void removeUsername(Object user) {
users = (Set) servletContext.getAttribute(USERS_KEY);
if (users != null) {
users.remove(user);
}
servletContext.setAttribute(USERS_KEY, users);
decrementUserCounter();
}
public void attributeAdded(HttpSessionBindingEvent event) {
log.debug("event.name: " + event.getName());
if (event.getName().equals(EVENT_KEY) && !isAnonymous()) {
SecurityContext securityContext = (SecurityContext) event.getValue();
User user = (User) securityContext.getAuthentication().getPrincipal();
addUsername(user);
}
}
private boolean isAnonymous() {
AuthenticationTrustResolver resolver = new AuthenticationTrustResolverImpl();
SecurityContext ctx = SecurityContextHolder.getContext();
if (ctx != null) {
Authentication auth = ctx.getAuthentication();
return resolver.isAnonymous(auth);
}
return true;
}
public void attributeRemoved(HttpSessionBindingEvent event) {
if (event.getName().equals(EVENT_KEY) && !isAnonymous()) {
SecurityContext securityContext = (SecurityContext) event.getValue();
Authentication auth = securityContext.getAuthentication();
if (auth != null && (auth.getPrincipal() instanceof User)) {
User user = (User) auth.getPrincipal();
removeUsername(user);
}
}
}
public void attributeReplaced(HttpSessionBindingEvent event) {
if (event.getName().equals(EVENT_KEY) && !isAnonymous()) {
SecurityContext securityContext = (SecurityContext) event.getValue();
if (securityContext.getAuthentication() != null) {
User user = (User) securityContext.getAuthentication().getPrincipal();
addUsername(user);
}
}
}
}