alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

jforum example source code file (SessionFacade.java)

This example jforum source code file (SessionFacade.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - jforum tags/keywords

anonymous_count, connection, fqn, fqn, hashmap, integer, integer, jdbc, logged_count, map, object, sql, string, string, usersession, usersession, util

The jforum SessionFacade.java source code

/*
 * Copyright (c) JForum Team
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, 
 * with or without modification, are permitted provided 
 * that the following conditions are met:
 * 
 * 1) Redistributions of source code must retain the above 
 * copyright notice, this list of conditions and the 
 * following  disclaimer.
 * 2)  Redistributions in binary form must reproduce the 
 * above copyright notice, this list of conditions and 
 * the following disclaimer in the documentation and/or 
 * other materials provided with the distribution.
 * 3) Neither the name of "Rafael Steil" nor 
 * the names of its contributors may be used to endorse 
 * or promote products derived from this software without 
 * specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT 
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
 * IN CONTRACT, STRICT LIABILITY, OR TORT 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
 * 
 * This file creation date: 12/03/2004 - 18:47:26
 * The JForum Project
 * http://www.jforum.net
 */
package net.jforum;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.jforum.cache.CacheEngine;
import net.jforum.cache.Cacheable;
import net.jforum.dao.DataAccessDriver;
import net.jforum.entities.UserSession;
import net.jforum.repository.SecurityRepository;
import net.jforum.util.preferences.ConfigKeys;
import net.jforum.util.preferences.SystemGlobals;

import org.apache.log4j.Logger;

/**
 * @author Rafael Steil
 * @version $Id: SessionFacade.java,v 1.40 2007/09/20 16:07:10 rafaelsteil Exp $
 */
public class SessionFacade implements Cacheable
{
	private static final Logger logger = Logger.getLogger(SessionFacade.class);
	
	private static final String FQN = "sessions";
	private static final String FQN_LOGGED = FQN + "/logged";
	private static final String FQN_COUNT = FQN + "/count";
	private static final String FQN_USER_ID = FQN + "/userId";
	private static final String ANONYMOUS_COUNT = "anonymousCount";
	private static final String LOGGED_COUNT = "loggedCount";
	
	private static CacheEngine cache;

	/**
	 * @see net.jforum.cache.Cacheable#setCacheEngine(net.jforum.cache.CacheEngine)
	 */
	public void setCacheEngine(CacheEngine engine)
	{
		cache = engine;
	}
	
	/**
	 * Add a new <code>UserSession entry to the session.
	 * This method will make a call to <code>JForum.getRequest.getSession().getId()
	 * to retrieve the session's id
	 * 
	 * @param us The user session objetc to add
	 * @see #add(UserSession, String)
	 */
	public static void add(UserSession us)
	{
		add(us, JForumExecutionContext.getRequest().getSessionContext().getId());
	}

	/**
	 * Registers a new {@link UserSession}.
	 * <p>
	 * If a call to {@link UserSession#getUserId()} return a value different 
	 * of <code>SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID), then 
	 * the user will be registered as "logged". Otherwise it will enter as anonymous.
	 * </p>
	 * 
	 * <p>
	 * Please note that, in order to keep the number of guest and logged users correct, 
	 * it's caller's responsability to {@link #remove(String)} the record before adding it
	 * again if the current session is currently represented as "guest". 
	 * </p>
	 *  
	 * @param us the UserSession to add
	 * @param sessionId the user's session id
	 */
	public static void add(UserSession us, String sessionId)
	{
		if (us.getSessionId() == null || us.getSessionId().equals("")) {
			us.setSessionId(sessionId);
		}
		
		synchronized (FQN) {
			cache.add(FQN, us.getSessionId(), us);
			
			if (!JForumExecutionContext.getForumContext().isBot()) {
				if (us.getUserId() != SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID)) {
					changeUserCount(LOGGED_COUNT, true);
					cache.add(FQN_LOGGED, us.getSessionId(), us);
					cache.add(FQN_USER_ID, Integer.toString(us.getUserId()), us.getSessionId());
				}
				else {
					// TODO: check the anonymous IP constraint
					changeUserCount(ANONYMOUS_COUNT, true);
				}
			}
		}
	}
	
	private static void changeUserCount(String cacheEntryName, boolean increment)
	{
		Integer count = (Integer)cache.get(FQN_COUNT, cacheEntryName);
		
		if (count == null) {
			count = new Integer(0);
		}
		
		if (increment) {
			count = new Integer(count.intValue() + 1);
		}
		else if (count.intValue() > 0) {
			count = new Integer(count.intValue() - 1);
		}
		
		cache.add(FQN_COUNT, cacheEntryName, count);
	}
	
	/**
	 * Add a new entry to the user's session
	 * 
	 * @param name The attribute name
	 * @param value The attribute value
	 */
	public static void setAttribute(String name, Object value)
	{
		JForumExecutionContext.getRequest().getSessionContext().setAttribute(name, value);
	}
	
	/**
	 * Removes an attribute from the session
	 * 
	 * @param name The key associated to the the attribute to remove
	 */
	public static void removeAttribute(String name)
	{
		JForumExecutionContext.getRequest().getSessionContext().removeAttribute(name);
	}
	
	/**
	 * Gets an attribute value given its name
	 * 
	 * @param name The attribute name to retrieve the value
	 * @return The value as an Object, or null if no entry was found
	 */
	public static Object getAttribute(String name)
	{
		return JForumExecutionContext.getRequest().getSessionContext().getAttribute(name);
	}

	/**
	 * Remove an entry fro the session map
	 * 
	 * @param sessionId The session id to remove
	 */
	public static void remove(String sessionId)
	{
		if (cache == null) {
			logger.warn("Got a null cache instance. #" + sessionId);
			return;
		}
		
		logger.debug("Removing session " + sessionId);
		
		synchronized (FQN) {
			UserSession us = getUserSession(sessionId);
			
			if (us != null) {
				cache.remove(FQN_LOGGED, sessionId);
				cache.remove(FQN_USER_ID, Integer.toString(us.getUserId()));
				
				if (us.getUserId() != SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID)) {
					changeUserCount(LOGGED_COUNT, false);
				}
				else {
					changeUserCount(ANONYMOUS_COUNT, false);
				}
			}
			
			cache.remove(FQN, sessionId);
		}
	}
	
	/**
	 * Get all registered sessions
	 * 
	 * @return <code>ArrayList with the sessions. Each entry
	 * is an <code>UserSession object.
	 */
	public static List getAllSessions()
	{
		synchronized (FQN) {
			return new ArrayList(cache.getValues(FQN));
		}
	}
	
	/**
	 * Gets the {@link UserSession} instance of all logged users
	 * @return A list with the user sessions
	 */
	public static List getLoggedSessions()
	{
		synchronized (FQN) {
			return new ArrayList(cache.getValues(FQN_LOGGED));
		}
	}
	
	/**
	 * Get the number of logged users
	 * @return the number of logged users
	 */
	public static int registeredSize()
	{
		Integer count = (Integer)cache.get(FQN_COUNT, LOGGED_COUNT);

		return (count == null ? 0 : count.intValue());
	}
	
	/**
	 * Get the number of anonymous users
	 * @return the nuber of anonymous users
	 */
	public static int anonymousSize()
	{
		Integer count = (Integer)cache.get(FQN_COUNT, ANONYMOUS_COUNT);

		return (count == null ? 0 : count.intValue());
	}
	
	public static void clear()
	{
		synchronized (FQN) {
			cache.add(FQN, new HashMap());
			cache.add(FQN_COUNT, LOGGED_COUNT, new Integer(0));
			cache.add(FQN_COUNT, ANONYMOUS_COUNT, new Integer(0));
			cache.remove(FQN_LOGGED);
			cache.remove(FQN_USER_ID);
		}
	}
	
	/**
	 * Gets the user's <code>UserSession object
	 * 
	 * @return The <code>UserSession associated to the user's session
	 */
	public static UserSession getUserSession()
	{
		return getUserSession(JForumExecutionContext.getRequest().getSessionContext().getId());
	}
	
	/**
	 * Gets an {@link UserSession} by the session id.
	 * 
	 * @param sessionId the session's id
	 * @return an <b>immutable UserSession, or null if no entry found
	 */
	public static UserSession getUserSession(String sessionId)
	{
		if (cache != null) {
			UserSession us = (UserSession)cache.get(FQN, sessionId);
			return (us != null ? us : null);
		}

		logger.warn("Got a null cache in getUserSession. #" + sessionId);
		return null;
	}

	/**
	 * Gets the number of session elements.
	 * 
	 * @return The number of session elements currently online (without bots)
	 */
	public static int size()
	{
		return (anonymousSize() + registeredSize());
	}
	
	/**
	 * Verify if the user in already loaded
	 * 
	 * @param username The username to check
	 * @return The session id if the user is already registered into the session, 
	 * or <code>null if it is not.
	 */
	public static String isUserInSession(String username)
	{
		int aid = SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID);
		
		synchronized (FQN) {
			for (Iterator iter = cache.getValues(FQN).iterator(); iter.hasNext(); ) {
				UserSession us = (UserSession)iter.next();
				String thisUsername = us.getUsername();
				
				if (thisUsername == null) {
					continue;
				}
				
				if (us.getUserId() != aid && thisUsername.equals(username)) {
					return us.getSessionId();
				}
			}
		}
		
		return null;
	}
	
	/**
	 * Verify if there is an user in the session with the 
	 * user id passed as parameter.
	 * 
	 * @param userId The user id to check for existance in the session
	 * @return The session id if the user is already registered into the session, 
	 * or <code>null if it is not.
	 */
	public static String isUserInSession(int userId)
	{
		return (String)cache.get(FQN_USER_ID, Integer.toString(userId));
	}
	
	/**
	 * Verify is the user is logged in.
	 * 
	 * @return <code>true if the user is logged, or false if is 
	 * an anonymous user.
	 */
	public static boolean isLogged()
	{
		return "1".equals(SessionFacade.getAttribute(ConfigKeys.LOGGED));
	}
	
	/**
	 * Marks the current user session as "logged" in 
	 */
	public static void makeLogged()
	{
		SessionFacade.setAttribute(ConfigKeys.LOGGED, "1");
	}
	
	/**
	 * Marks the current user session as "logged" out
	 *
	 */
	public static void makeUnlogged()
	{
		SessionFacade.removeAttribute(ConfigKeys.LOGGED);
	}
	
	/**
	 * Returns a map containing information about read time of a set of topics.
	 * @return a map where the key is the topicId represented as an Integer, and the
	 * value is a Long representing the read time of such topic. 
	 */
	public static Map getTopicsReadTime()
	{
		Map tracking = (Map)getAttribute(ConfigKeys.TOPICS_READ_TIME);
		
		if (tracking == null) {
			tracking = new HashMap();
			setAttribute(ConfigKeys.TOPICS_READ_TIME, tracking);
		}
		
		return tracking;
	}
	
	/**
	 * Returns a map with "all topics read" flags for some forum 
	 * @return a map where the key is the forum id represented as an Integer, 
	 * and the value is a Long representing the read time to be used in the verifications.
	 */
	public static Map getTopicsReadTimeByForum()
	{
		return (Map)getAttribute(ConfigKeys.TOPICS_READ_TIME_BY_FORUM);
	}

	/**
	 * Persists user session information.
	 * This method will get a <code>Connection making a call to
	 * <code>DBConnection.getImplementation().getConnection(), and
	 * then releasing the connection after the method is processed.   
	 * 
	 * @param sessionId The session which we're going to persist information
	 * @see #storeSessionData(String, Connection)
	 */
	public static void storeSessionData(String sessionId)
	{
		Connection conn = null;
		try {
			conn = DBConnection.getImplementation().getConnection();
			SessionFacade.storeSessionData(sessionId, conn);
		}
		finally {
			if (conn != null) {
				try {
					DBConnection.getImplementation().releaseConnection(conn);
				}
				catch (Exception e) {
					logger.warn("Error while releasing a connection: " + e);
				}
			}
		}
	}

	/**
	 * Persists user session information.
	 * 
	 * @param sessionId The session which we're going to persist
	 * @param conn A <code>Connection to be used to connect to
	 * the database. 
	 * @see #storeSessionData(String)
	 */
	public static void storeSessionData(String sessionId, Connection conn) 
	{
		UserSession us = SessionFacade.getUserSession(sessionId);
		if (us != null) {
			try {
				if (us.getUserId() != SystemGlobals.getIntValue(ConfigKeys.ANONYMOUS_USER_ID)) {
					DataAccessDriver.getInstance().newUserSessionDAO().update(us, conn);
				}
				
				SecurityRepository.remove(us.getUserId());
			}
			catch (Exception e) {
				logger.warn("Error storing user session data: " + e, e);
			}
		}
	}
}

Other jforum examples (source code examples)

Here is a short list of links related to this jforum SessionFacade.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.