package net.sf.jasperreports.engine.design; import java.io.Serializable; import java.util.Map; import net.sf.jasperreports.engine.JRException; import net.sf.jasperreports.engine.fill.JREvaluator; import net.sf.jasperreports.engine.util.JRClassLoader; import net.sf.jasperreports.engine.util.JRProperties; import org.apache.commons.collections.ReferenceMap; public abstract class JRAbstractJavaCompiler extends JRAbstractCompiler { public static final String PROPERTY_EVALUATOR_CLASS_REFERENCE_FIX_ENABLED = "net.sf.jasperreports.evaluator.class.reference.fix.enabled"; private static ThreadLocal classFromBytesRef = new ThreadLocal(); private static Object CLASS_CACHE_NULL_KEY = new Object(); private static Map classCache = (Map)new ReferenceMap(2, 1); protected JRAbstractJavaCompiler(boolean needsSourceFiles) { super(needsSourceFiles); } protected JREvaluator loadEvaluator(Serializable compileData, String className) throws JRException { JREvaluator evaluator = null; try { Class clazz = getClassFromCache(className); if (clazz == null) { clazz = JRClassLoader.loadClassFromBytes(className, (byte[])compileData); putClassInCache(className, clazz); } if (JRProperties.getBooleanProperty("net.sf.jasperreports.evaluator.class.reference.fix.enabled")) classFromBytesRef.set(clazz); evaluator = (JREvaluator)clazz.newInstance(); } catch (Exception e) { throw new JRException("Error loading expression class : " + className, e); } return evaluator; } protected static Object classCacheKey() { ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); Object key = (contextClassLoader == null) ? CLASS_CACHE_NULL_KEY : contextClassLoader; return key; } protected static synchronized Class getClassFromCache(String className) { Object key = classCacheKey(); Map contextMap = (Map)classCache.get(key); Class cachedClass = null; if (contextMap != null) cachedClass = (Class)contextMap.get(className); return cachedClass; } protected static synchronized void putClassInCache(String className, Class loadedClass) { ReferenceMap referenceMap; Object key = classCacheKey(); Map contextMap = (Map)classCache.get(key); if (contextMap == null) { referenceMap = new ReferenceMap(0, 1); classCache.put(key, referenceMap); } referenceMap.put(className, loadedClass); } }