blob: 7c54658feb0ac34fb0a54a228d88e5bd4d56c046 [file] [log] [blame]
/*
* Copyright 2005-2008 Les Hazlewood
*
* 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 org.jsecurity.session.mgt.eis;
import org.jsecurity.cache.HashtableCacheManager;
import org.jsecurity.session.Session;
import org.jsecurity.session.mgt.SimpleSession;
import org.jsecurity.util.ClassUtils;
import org.jsecurity.util.JavaEnvironment;
import java.io.Serializable;
import java.util.Random;
/**
* Simple memory-based implementation of the SessionDAO that relies on its configured
* {@link #setCacheManager CacheManager} for Session caching and in-memory persistence.
*
* <p><b>PLEASE NOTE</b> the default CacheManager internal to this implementation is a
* {@link org.jsecurity.cache.HashtableCacheManager HashtableCacheManager}, which IS NOT RECOMMENDED for production environments.
*
* <p>If you
* want to use the MemorySessionDAO in production environments, such as those that require session data to be
* recoverable in case of a server restart, you should do one of two things (or both):
*
* <ul>
* <li>Configure it with a production-quality CacheManager. The
* {@link org.jsecurity.cache.ehcache.EhCacheManager EhCacheManager} is one such implementation. It is not used by default
* to prevent a forced runtime dependency on ehcache.jar that may not be required in many environments)</li><br/>
* <li>If you need session information beyond their transient start/stop lifetimes, you should subclass this one and
* override the <tt>do*</tt> methods to perform CRUD operations using an EIS-tier API (e.g. Hibernate/JPA/JCR/etc).
* This class implementation does not retain sessions after they have been stopped or expired, so you would need to
* override these methods to ensure Sessions can be accessed beyond JSecurity's needs.</li>
* </ul>
*
* @since 0.1
*
* @author Les Hazlewood
*/
public class MemorySessionDAO extends CachingSessionDAO {
private static final String VALID_JUG_CLASS_NAME = "org.safehaus.uuid.UUIDGenerator";
private static final String RANDOM_NUM_GENERATOR_ALGORITHM_NAME = "SHA1PRNG";
private Random randomNumberGenerator = null;
public MemorySessionDAO() {
setCacheManager( new HashtableCacheManager() );
}
private Random getRandomNumberGenerator() {
if ( randomNumberGenerator == null ) {
if ( log.isWarnEnabled() ) {
String msg = "On JDK 1.4 platforms and below, please ensure the JUG jar file is in the classpath for " +
"valid Session ID generation. Defaulting to SecureRandom based id generation for now " +
"(NOT recommended for production systems - please add the JUG jar as soon as convenient).";
log.warn( msg );
}
try {
randomNumberGenerator = java.security.SecureRandom.getInstance( RANDOM_NUM_GENERATOR_ALGORITHM_NAME );
} catch ( java.security.NoSuchAlgorithmException e ) {
randomNumberGenerator = new java.security.SecureRandom();
}
}
return randomNumberGenerator;
}
protected Serializable generateNewSessionId() {
if ( JavaEnvironment.isAtLeastVersion15() ) {
return java.util.UUID.randomUUID().toString();
} else if ( ClassUtils.isAvailable( VALID_JUG_CLASS_NAME ) ) {
//JUG library is available, lets use it to generate an ID:
return org.safehaus.uuid.UUIDGenerator.getInstance().generateRandomBasedUUID().toString();
} else {
return Long.toString( getRandomNumberGenerator().nextLong() );
}
}
protected Serializable doCreate( Session session ) {
Serializable sessionId = generateNewSessionId();
assignSessionId( session, sessionId );
return sessionId;
}
protected void assignSessionId( Session session, Serializable sessionId ) {
((SimpleSession)session).setId( sessionId );
}
protected Session doReadSession( Serializable sessionId ) {
return null; //should never execute because this implementation relies on parent class to access cache, which
//is where all sessions reside - it is the cache implementation that determines if the
//cache is memory only or disk-persistent, etc.
}
protected void doUpdate(Session session) {
//does nothing - parent class persists to cache.
}
protected void doDelete(Session session) {
//does nothing - parent class removes from cache.
}
}