package org.solmix.fmk.cache; import java.util.Collections; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.solmix.commons.io.SlxFile; public abstract class ProcessedFileCache { static class CacheEntry { public Object cachedObject; public long timeStamp; public long lastStalenessCheck; CacheEntry() { } } public ProcessedFileCache() { stalenessCheckInterval = 500L; cache = Collections.synchronizedMap( new HashMap<String,CacheEntry>() ); } public void setStalenessCheckInterval( long millis ) { stalenessCheckInterval = millis; } public long getStalenessCheckInterval() { return stalenessCheckInterval; } public void clearCacheEntry( Object key ) { cache.remove( key ); } public Object getObjectFromFile( SlxFile file ) throws Exception { return getObjectFromFile( file, null ); } /** * Load Object form file. * <p> * At first,look in cache.if Staleness Check success,directly return the Object.Then no found,load from file. * * @param file * @param flags file's state table,if the file is staleness put objectWasStale = true. * @return * @throws Exception */ public Object getObjectFromFile( SlxFile file, Map flags ) throws Exception { String name = file.getCanonicalPath(); CacheEntry entry = cache.get( name ); long timeStamp = file.lastModified(); if ( entry != null ) { long currentTime = System.currentTimeMillis(); if ( currentTime - entry.lastStalenessCheck <= stalenessCheckInterval ) return entry.cachedObject; if ( timeStamp == 0L ) log.warn( ( new StringBuilder() ).append( "Can't perform staleness checking for " ).append( name ).toString() ); if ( entry.timeStamp == timeStamp ) { entry.lastStalenessCheck = currentTime; return entry.cachedObject; } if ( log.isDebugEnabled() ) log.debug( ( new StringBuilder() ).append( "STALE object for file '" ).append( name ).append( "', reloading " ).append( "(file timestamp " ).append( timeStamp ).append( ", cache timestamp " ).append( entry.timeStamp ).append( ")" ).toString() ); if ( flags != null ) flags.put( "objectWasStale", Boolean.TRUE ); } Object loadedObject = loadObjectFromFile( file ); cacheObject( name, loadedObject, timeStamp ); return loadedObject; } /** * 从配置文件中加载实例 * * @param fileName 文件名 * @return * @throws Exception */ public Object getObjectFromFile( String fileName ) throws Exception { return getObjectFromFile( new SlxFile( fileName ) ); } /** * Load Object form configuration file. * * @param SlxFile config file. * @return * @throws Exception */ public abstract Object loadObjectFromFile( SlxFile slxFile ) throws Exception; /** * * @param name * @param object * @param timeStamp */ public void cacheObject( String name, Object object, long timeStamp ) { CacheEntry entry = new CacheEntry(); entry.timeStamp = timeStamp; entry.cachedObject = object; entry.lastStalenessCheck = System.currentTimeMillis(); cache.put( name, entry ); } private static Logger log = LoggerFactory.getLogger( ProcessedFileCache.class.getName() ); private long stalenessCheckInterval; Map<String,CacheEntry> cache; }