package org.ant4eclipse.lib.jdt.ecj.internal.tools.loader; import java.util.Arrays; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import org.ant4eclipse.lib.core.Lifecycle; import org.ant4eclipse.lib.core.logging.A4ELogging; import org.ant4eclipse.lib.core.service.ServiceRegistryAccess; import org.ant4eclipse.lib.jdt.ecj.ClassFileLoader; /** * <p> * </p> * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) * @author Nils Hartmann */ public class ClassFileLoaderCache implements Lifecycle { /** * System-Property that enables the ClassFileLoaderCache */ private static final boolean ENABLE_CACHE = Boolean.getBoolean("ant4eclipse.enableClassFileLoaderCache"); /** * System-Property that enables tracing of the cache. <b>This is very verbose!</b> */ private static final boolean TRACE_CACHE = Boolean.getBoolean("ant4eclipse.traceClassFileLoaderCache"); /** the class file loader map */ private Map<Object, ClassFileLoader> _classFileLoaderMap; /** * Hit counter */ private int _hits = 0; /** * Miss counter */ private int _missed = 0; /** - */ private boolean _initialized; /** * <p> * Creates a new instance of type ClassFileLoaderCache. * </p> */ public ClassFileLoaderCache() { this._classFileLoaderMap = new ConcurrentHashMap<Object, ClassFileLoader>(); } /** * {@inheritDoc} */ public boolean isInitialized() { return this._initialized; } /** * {@inheritDoc} */ public void initialize() { this._initialized = true; } /** * {@inheritDoc} */ public void dispose() { this._initialized = false; dump(); } /** * <p> * </p> */ public void clear() { this._classFileLoaderMap.clear(); this._hits = 0; this._missed = 0; } /** * <p> * </p> * * @param key * @param classFileLoader */ public void storeClassFileLoader(Object key, ClassFileLoader classFileLoader) { if (ENABLE_CACHE) { if (TRACE_CACHE) { A4ELogging.debug("Store ClassFileLoader in cache for: '" + key + "' -> " + classFileLoader); A4ELogging.debug(" Packages: " + Arrays.asList(classFileLoader.getAllPackages())); } this._classFileLoaderMap.put(key, classFileLoader); } } /** * <p> * </p> * * @param key * @return */ public ClassFileLoader getClassFileLoader(Object key) { ClassFileLoader classFileLoader = this._classFileLoaderMap.get(key); if (classFileLoader != null) { this._hits++; if (ENABLE_CACHE && TRACE_CACHE) { A4ELogging.debug("Got ClassFileLoader from cache for: " + key); } } else { this._missed++; if (ENABLE_CACHE && TRACE_CACHE) { A4ELogging.debug("Missed ClassFileLoader in cache for: " + key); } } return classFileLoader; } /** * <p> * </p> * * @param key * @return */ public boolean hasClassFileLoader(Object key) { return this._classFileLoaderMap.containsKey(key); } /** * Dumps the current content and hit statistics of the ClassFileLoaderCache via A4ELogging */ public void dump() { if (!ENABLE_CACHE) { A4ELogging.info("ClassFileLoaderCache has been disabled. Anyway there have been " + (this._missed + this._hits) + " calls to the cache."); } else { A4ELogging.info("ClassFileLoaderCache contains " + this._classFileLoaderMap.size() + " entries."); A4ELogging.info("There has been " + this._hits + " hits and " + this._missed + " misses"); for (Map.Entry<Object, ClassFileLoader> entry : this._classFileLoaderMap.entrySet()) { A4ELogging.info(" " + entry.getKey() + " -> " + entry.getValue()); A4ELogging.info(" Packages: " + Arrays.asList(entry.getValue().getAllPackages())); } } } public static ClassFileLoaderCache getInstance() { return ServiceRegistryAccess.instance().getService(ClassFileLoaderCache.class); } }