/* * Copyright 2006 www.webtair.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.webtair.session; import java.util.*; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.webtair.session.artifact.SessionInfo; import com.webtair.session.config.ConfigBean; /** * Entry poin of SessionMan library. * Class that implements all buisness logic * for session management. * * @author Vaclav (Vyacheslav Yakovenko) */ public class SessionMan { /** Config info of SessionMan */ private ConfigBean config; /** Logger for SessionMan */ @SuppressWarnings("unused") private static Log logger = LogFactory.getLog(SessionMan.class); /** Repository of idSessions and corresponded data */ private HashMap sessions; /** * Constructor that populate SessionMan * by provided config information * @param config - config bean */ public SessionMan(ConfigBean config) { if (config == null){ this.config = new ConfigBean(); }else{ this.config = config; } sessions = new HashMap(this.config.getUserCount()); new SessionsCleaner().start(); } /** * Default constructor */ public SessionMan(){ this(null); } /** * Generates unique session id for current login * * @param login * @return unique idSession */ public static String generateSessionId(String login) { return DigestUtils.md5Hex(login + Calendar.getInstance() + java.lang.Math.random()); } /** * Register new user at SessionMan's HashMap. * Each user can have so much sessions as he want. * * @param user - user info * @return idSession - newly created session */ public String putSessionInfo(String login, T sessionInfo) { // create new session id String idSession = SessionMan.generateSessionId(login); synchronized (sessions) { sessions.put(idSession, sessionInfo); } return idSession; } /** * Check if session is alive and update lastSessionUsedTime if true. * * @param idSession * @return true if session is alive, and false if idSession not found or * session is expired. */ public boolean validateSession(String idSession) { if (isSessionExpired(idSession)) { synchronized (sessions) { sessions.remove(idSession); return false; } } else { SessionInfo info = sessions.get(idSession); synchronized (sessions) { if (info != null) { info.setLastTimeUsed(Calendar.getInstance() .getTimeInMillis()); return true; } else { return false; }// if } }// if } /** * Check if session expired or not. * * @param idSession * @return true if and only if session expired. */ public boolean isSessionExpired(String idSession) { SessionInfo info = sessions.get(idSession); if (info == null) { return true; } long interval = Calendar.getInstance().getTimeInMillis() - info.getLastTimeUsed(); if (interval > config.getSessionLifeTime() ) { return true; } else { return false; } } /** * Remove session from session handler map * @param idSession - session id */ public void removeSession(String idSession) { synchronized(sessions){ sessions.remove(idSession); } System.out.println("removeSession(), after idSession: " + sessions.containsKey(idSession) ); } /** * Util class, that periodicaly must clean sessions HashMap from expired * session to prevent from memory leak. * * @author vaclav */ private class SessionsCleaner extends Thread { /** * run-method that'll stroll throughout HashMap * and cleanup it from expired sessions */ public void run() { while (true) { System.out.println("SessionsCleaner : thread sleep"); logger.debug("SessionsCleaner : thread sleep"); try { Thread.sleep(config.getCleanupInterval() ); } catch (InterruptedException e) { return; } synchronized (sessions) { System.out .println("SessionsCleaner : hashmap size before cleanup: " + sessions.size()); logger .debug("SessionsCleaner : hashmap size before cleanup: " + sessions.size()); Set sessToRemove = new HashSet(); for (String key : sessions.keySet()) { // collect all expired session's id if (isSessionExpired(key)) { sessToRemove.add(key); } } // remove all expired sessions for (String key : sessToRemove) { sessions.remove(key); } System.out .println("SessionsCleaner : hashmap size after cleanup: " + sessions.size()); logger .debug("SessionsCleaner : hashmap size after cleanup: " + sessions.size()); } } } }// SessionsCleaner }