001: /*
002: * ============================================================================
003: * GNU Lesser General Public License
004: * ============================================================================
005: *
006: * JasperReports - Free Java report-generating library.
007: * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
008: *
009: * This library is free software; you can redistribute it and/or
010: * modify it under the terms of the GNU Lesser General Public
011: * License as published by the Free Software Foundation; either
012: * version 2.1 of the License, or (at your option) any later version.
013: *
014: * This library is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017: * Lesser General Public License for more details.
018: *
019: * You should have received a copy of the GNU Lesser General Public
020: * License along with this library; if not, write to the Free Software
021: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
022: *
023: * JasperSoft Corporation
024: * 303 Second Street, Suite 450 North
025: * San Francisco, CA 94107
026: * http://www.jaspersoft.com
027: */
028:
029: /*
030: * Contributors:
031: * Peter Severin - peter_p_s@users.sourceforge.net
032: */
033: package net.sf.jasperreports.engine.design;
034:
035: import java.io.Serializable;
036: import java.util.Map;
037:
038: import org.apache.commons.collections.ReferenceMap;
039:
040: import net.sf.jasperreports.engine.JRException;
041: import net.sf.jasperreports.engine.fill.JREvaluator;
042: import net.sf.jasperreports.engine.util.JRClassLoader;
043:
044: /**
045: * @author Teodor Danciu (teodord@users.sourceforge.net)
046: * @version $Id: JRAbstractJavaCompiler.java 1289 2006-06-13 11:54:52Z teodord $
047: */
048: public abstract class JRAbstractJavaCompiler extends JRAbstractCompiler {
049:
050: // @JVM Crash workaround
051: // Reference to the loaded class class in a per thread map
052: private static ThreadLocal classFromBytesRef = new ThreadLocal();
053:
054: private static Object CLASS_CACHE_NULL_KEY = new Object();
055: private static Map classCache = new ReferenceMap(ReferenceMap.WEAK,
056: ReferenceMap.SOFT);
057:
058: protected JRAbstractJavaCompiler(boolean needsSourceFiles) {
059: super (needsSourceFiles);
060: }
061:
062: protected JREvaluator loadEvaluator(Serializable compileData,
063: String className) throws JRException {
064: JREvaluator evaluator = null;
065:
066: try {
067: Class clazz = getClassFromCache(className);
068: if (clazz == null) {
069: clazz = JRClassLoader.loadClassFromBytes(className,
070: (byte[]) compileData);
071: putClassInCache(className, clazz);
072: }
073:
074: //FIXME multiple classes per thread?
075: classFromBytesRef.set(clazz);
076:
077: evaluator = (JREvaluator) clazz.newInstance();
078: } catch (Exception e) {
079: throw new JRException("Error loading expression class : "
080: + className, e);
081: }
082:
083: return evaluator;
084: }
085:
086: protected static Object classCacheKey() {
087: ClassLoader contextClassLoader = Thread.currentThread()
088: .getContextClassLoader();
089: Object key = contextClassLoader == null ? CLASS_CACHE_NULL_KEY
090: : contextClassLoader;
091: return key;
092: }
093:
094: protected static synchronized Class getClassFromCache(
095: String className) {
096: Object key = classCacheKey();
097: Map contextMap = (Map) classCache.get(key);
098: Class cachedClass = null;
099: if (contextMap != null) {
100: cachedClass = (Class) contextMap.get(className);
101: }
102: return cachedClass;
103: }
104:
105: protected static synchronized void putClassInCache(
106: String className, Class loadedClass) {
107: Object key = classCacheKey();
108: Map contextMap = (Map) classCache.get(key);
109: if (contextMap == null) {
110: contextMap = new ReferenceMap(ReferenceMap.HARD,
111: ReferenceMap.SOFT);
112: classCache.put(key, contextMap);
113: }
114: contextMap.put(className, loadedClass);
115: }
116: }
|